1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svimpbox.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include <vcl/svapp.hxx>
34 #include <vcl/salnativewidgets.hxx>
37 #include <vcl/help.hxx>
46 #include <svtools/svtreebx.hxx>
47 #include <svtools/svlbox.hxx>
48 #include <svimpbox.hxx>
49 #include <rtl/instance.hxx>
50 #include <svtools/svtdata.hxx>
53 #include <svtools/svtools.hrc>
56 // #102891# --------------------
57 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
58 #include <comphelper/processfactory.hxx>
61 #define NODE_BMP_TABDIST_NOTVALID -2000000
62 #define FIRST_ENTRY_TAB 1
64 // #i27063# (pl), #i32300# (pb) never access VCL after DeInitVCL - also no destructors
65 Image
* SvImpLBox::s_pDefCollapsed
= NULL
;
66 Image
* SvImpLBox::s_pDefExpanded
= NULL
;
67 Image
* SvImpLBox::s_pDefCollapsedHC
= NULL
;
68 Image
* SvImpLBox::s_pDefExpandedHC
= NULL
;
69 sal_Int32
SvImpLBox::s_nImageRefCount
= 0;
71 SvImpLBox::SvImpLBox( SvTreeListBox
* pLBView
, SvLBoxTreeList
* pLBTree
, WinBits nWinStyle
) :
74 aVerSBar( pLBView
, WB_DRAG
| WB_VSCROLL
),
75 aHorSBar( pLBView
, WB_DRAG
| WB_HSCROLL
),
76 aScrBarBox( pLBView
),
78 aSelEng( pLBView
, (FunctionSet
*)0 ),
79 aFctSet( this, &aSelEng
, pLBView
),
80 nExtendedWinBits( 0 ),
81 bAreChildrenTransient( sal_True
),
82 pIntlWrapper( NULL
) // #102891# -----------------------
84 osl_incrementInterlockedCount(&s_nImageRefCount
);
87 aSelEng
.SetFunctionSet( (FunctionSet
*)&aFctSet
);
88 aSelEng
.ExpandSelectionOnMouseMove( FALSE
);
89 SetWindowBits( nWinStyle
);
90 SetSelectionMode( SINGLE_SELECTION
);
93 aVerSBar
.SetScrollHdl( LINK( this, SvImpLBox
, ScrollUpDownHdl
) );
94 aHorSBar
.SetScrollHdl( LINK( this, SvImpLBox
, ScrollLeftRightHdl
) );
95 aHorSBar
.SetEndScrollHdl( LINK( this, SvImpLBox
, EndScrollHdl
) );
96 aVerSBar
.SetEndScrollHdl( LINK( this, SvImpLBox
, EndScrollHdl
) );
97 aVerSBar
.SetRange( Range(0,0) );
99 aHorSBar
.SetRange( Range(0,0) );
100 aHorSBar
.SetPageSize( 24 ); // Pixel
101 aHorSBar
.SetLineSize( 8 ); // Pixel
103 nHorSBarHeight
= (short)aHorSBar
.GetSizePixel().Height();
104 nVerSBarWidth
= (short)aVerSBar
.GetSizePixel().Width();
109 nVisibleCount
= 0; // Anzahl Daten-Zeilen im Control
110 nNodeBmpTabDistance
= NODE_BMP_TABDIST_NOTVALID
;
114 bAsyncBeginDrag
= FALSE
;
115 aAsyncBeginDragTimer
.SetTimeout( 0 );
116 aAsyncBeginDragTimer
.SetTimeoutHdl( LINK(this,SvImpLBox
,BeginDragHdl
));
117 // Button-Animation in Listbox
123 nCurTabPos
= FIRST_ENTRY_TAB
;
125 aEditTimer
.SetTimeout( 800 );
126 aEditTimer
.SetTimeoutHdl( LINK(this,SvImpLBox
,EditTimerCall
) );
130 nCurUserEvent
= 0xffffffff;
133 bInVScrollHdl
= FALSE
;
136 bSubLstOpRet
= bSubLstOpLR
= bContextMenuHandling
= bIsCellFocusEnabled
= FALSE
;
139 SvImpLBox::~SvImpLBox()
144 // #102891# ---------------------
147 if ( osl_decrementInterlockedCount(&s_nImageRefCount
) == 0 )
149 DELETEZ(s_pDefCollapsed
);
150 DELETEZ(s_pDefExpanded
);
151 DELETEZ(s_pDefCollapsedHC
);
152 DELETEZ(s_pDefExpandedHC
);
156 // #102891# --------------------
157 void SvImpLBox::UpdateIntlWrapper()
159 const ::com::sun::star::lang::Locale
& aNewLocale
= Application::GetSettings().GetLocale();
161 pIntlWrapper
= new IntlWrapper( ::comphelper::getProcessServiceFactory(), aNewLocale
);
164 const ::com::sun::star::lang::Locale
&aLocale
= pIntlWrapper
->getLocale();
165 if( aLocale
.Language
!= aNewLocale
.Language
|| // different Locale from the older one
166 aLocale
.Country
!= aNewLocale
.Country
||
167 aLocale
.Variant
!= aNewLocale
.Variant
)
170 pIntlWrapper
= new IntlWrapper( ::comphelper::getProcessServiceFactory(), aNewLocale
);
175 // #97680# ----------------------
176 short SvImpLBox::UpdateContextBmpWidthVector( SvLBoxEntry
* pEntry
, short nWidth
)
178 DBG_ASSERT( pView
->pModel
, "View and Model aren't valid!" );
180 USHORT nDepth
= pView
->pModel
->GetDepth( pEntry
);
181 // initialize vector if necessary
182 std::vector
< short >::size_type nSize
= aContextBmpWidthVector
.size();
183 while ( nDepth
> nSize
)
185 aContextBmpWidthVector
.resize( nSize
+ 1 );
186 aContextBmpWidthVector
.at( nSize
) = nWidth
;
189 if( aContextBmpWidthVector
.size() == nDepth
)
191 aContextBmpWidthVector
.resize( nDepth
+ 1 );
192 aContextBmpWidthVector
.at( nDepth
) = 0;
194 short nContextBmpWidth
= aContextBmpWidthVector
[ nDepth
];
195 if( nContextBmpWidth
< nWidth
)
197 aContextBmpWidthVector
.at( nDepth
) = nWidth
;
201 return nContextBmpWidth
;
204 void SvImpLBox::UpdateContextBmpWidthVectorFromMovedEntry( SvLBoxEntry
* pEntry
)
206 DBG_ASSERT( pEntry
, "Moved Entry is invalid!" );
208 SvLBoxContextBmp
* pBmpItem
= static_cast< SvLBoxContextBmp
* >( pEntry
->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP
) );
209 short nExpWidth
= (short)pBmpItem
->GetBitmap1().GetSizePixel().Width();
210 short nColWidth
= (short)pBmpItem
->GetBitmap2().GetSizePixel().Width();
211 short nMax
= Max(nExpWidth
, nColWidth
);
212 UpdateContextBmpWidthVector( pEntry
, nMax
);
214 if( pEntry
->HasChilds() ) // recursive call, whether expanded or not
216 SvLBoxEntry
* pChild
= pView
->FirstChild( pEntry
);
217 DBG_ASSERT( pChild
, "The first child is invalid!" );
220 UpdateContextBmpWidthVectorFromMovedEntry( pChild
);
221 pChild
= pView
->Next( pChild
);
226 void SvImpLBox::UpdateContextBmpWidthMax( SvLBoxEntry
* pEntry
)
228 USHORT nDepth
= pView
->pModel
->GetDepth( pEntry
);
229 if( aContextBmpWidthVector
.size() < 1 )
231 short nWidth
= aContextBmpWidthVector
[ nDepth
];
232 if( nWidth
!= pView
->nContextBmpWidthMax
) {
233 pView
->nContextBmpWidthMax
= nWidth
;
234 nFlags
|= F_IGNORE_CHANGED_TABS
;
236 nFlags
&= ~F_IGNORE_CHANGED_TABS
;
240 void SvImpLBox::CalcCellFocusRect( SvLBoxEntry
* pEntry
, Rectangle
& rRect
)
242 if ( pEntry
&& bIsCellFocusEnabled
)
244 if ( nCurTabPos
> FIRST_ENTRY_TAB
)
246 SvLBoxItem
* pItem
= pCursor
->GetItem( nCurTabPos
);
247 rRect
.Left() = pView
->GetTab( pCursor
, pItem
)->GetPos();
249 if ( pCursor
->ItemCount() > ( nCurTabPos
+ 1 ) )
251 SvLBoxItem
* pNextItem
= pCursor
->GetItem( nCurTabPos
+ 1 );
252 long nRight
= pView
->GetTab( pCursor
, pNextItem
)->GetPos() - 1;
253 if ( nRight
< rRect
.Right() )
254 rRect
.Right() = nRight
;
259 void SvImpLBox::SetWindowBits( WinBits nWinStyle
)
261 nWinBits
= nWinStyle
;
262 if((nWinStyle
& WB_SIMPLEMODE
) && aSelEng
.GetSelectionMode()==MULTIPLE_SELECTION
)
263 aSelEng
.AddAlways( TRUE
);
266 void SvImpLBox::SetExtendedWindowBits( ExtendedWinBits _nBits
)
268 nExtendedWinBits
= _nBits
;
271 // Das Model darf hier nicht mehr angefasst werden
272 void SvImpLBox::Clear()
285 // Der Cursor darf hier nicht mehr angefasst werden!
288 if( pView
->HasFocus() )
293 aVerSBar
.SetThumbPos( 0 );
294 Range
aRange( 0, 0 );
295 aVerSBar
.SetRange( aRange
);
296 aOutputSize
= pView
->Control::GetOutputSizePixel();
297 nFlags
&= ~(F_VER_SBARSIZE_WITH_HBAR
| F_HOR_SBARSIZE_WITH_VBAR
);
300 aOutputSize
.Height() -= nHorSBarHeight
;
301 nFlags
|= F_VER_SBARSIZE_WITH_HBAR
;
305 aHorSBar
.SetThumbPos( 0 );
306 MapMode
aMapMode( pView
->GetMapMode());
307 aMapMode
.SetOrigin( Point(0,0) );
308 pView
->Control::SetMapMode( aMapMode
);
309 aHorSBar
.SetRange( aRange
);
310 aHorSBar
.SetSizePixel(Size(aOutputSize
.Width(),nHorSBarHeight
));
311 pView
->SetClipRegion();
312 if( GetUpdateMode() )
313 pView
->Invalidate( GetVisibleArea() );
315 if( !aHorSBar
.IsVisible() && !aVerSBar
.IsVisible() )
319 aContextBmpWidthVector
.clear();
322 // *********************************************************************
323 // Painten, Navigieren, Scrollen
324 // *********************************************************************
326 IMPL_LINK_INLINE_START( SvImpLBox
, EndScrollHdl
, ScrollBar
*, EMPTYARG
)
328 if( nFlags
& F_ENDSCROLL_SET_VIS_SIZE
)
330 aVerSBar
.SetVisibleSize( nNextVerVisSize
);
331 nFlags
&= ~F_ENDSCROLL_SET_VIS_SIZE
;
336 IMPL_LINK_INLINE_END( SvImpLBox
, EndScrollHdl
, ScrollBar
*, pScrollBar
)
339 // Handler vertikale ScrollBar
341 IMPL_LINK( SvImpLBox
, ScrollUpDownHdl
, ScrollBar
*, pScrollBar
)
343 DBG_ASSERT(!bInVScrollHdl
,"Scroll-Handler ueberholt sich!");
344 long nDelta
= pScrollBar
->GetDelta();
348 nFlags
&= (~F_FILLING
);
350 bInVScrollHdl
= TRUE
;
352 if( pView
->IsEditingActive() )
354 pView
->EndEditing( TRUE
); // Cancel
364 PageDown( (USHORT
) nDelta
);
372 PageUp( (USHORT
) nDelta
);
374 bInVScrollHdl
= FALSE
;
379 void SvImpLBox::CursorDown()
381 SvLBoxEntry
* pNextFirstToDraw
= (SvLBoxEntry
*)(pView
->NextVisible( pStartEntry
));
382 if( pNextFirstToDraw
)
384 nFlags
&= (~F_FILLING
);
385 pView
->NotifyScrolling( -1 );
388 pStartEntry
= pNextFirstToDraw
;
389 Rectangle
aArea( GetVisibleArea() );
390 pView
->Scroll( 0, -(pView
->GetEntryHeight()), aArea
, SCROLL_NOCHILDREN
);
393 pView
->NotifyScrolled();
397 void SvImpLBox::CursorUp()
399 SvLBoxEntry
* pPrevFirstToDraw
= (SvLBoxEntry
*)(pView
->PrevVisible( pStartEntry
));
400 if( pPrevFirstToDraw
)
402 nFlags
&= (~F_FILLING
);
403 long nEntryHeight
= pView
->GetEntryHeight();
404 pView
->NotifyScrolling( 1 );
407 pStartEntry
= pPrevFirstToDraw
;
408 Rectangle
aArea( GetVisibleArea() );
409 aArea
.Bottom() -= nEntryHeight
;
410 pView
->Scroll( 0, nEntryHeight
, aArea
, SCROLL_NOCHILDREN
);
413 pView
->NotifyScrolled();
417 void SvImpLBox::PageDown( USHORT nDelta
)
419 USHORT nRealDelta
= nDelta
;
425 pNext
= (SvLBoxEntry
*)(pView
->NextVisible( pStartEntry
, nRealDelta
));
426 if( (ULONG
)pNext
== (ULONG
)pStartEntry
)
431 nFlags
&= (~F_FILLING
);
435 if( nRealDelta
>= nVisibleCount
)
437 pView
->Invalidate( GetVisibleArea() );
442 long nScroll
= nRealDelta
* (-1);
443 pView
->NotifyScrolling( nScroll
);
444 Rectangle
aArea( GetVisibleArea() );
445 nScroll
= pView
->GetEntryHeight()*nRealDelta
;
448 pView
->Scroll( 0, nScroll
, aArea
, SCROLL_NOCHILDREN
);
450 pView
->NotifyScrolled();
456 void SvImpLBox::PageUp( USHORT nDelta
)
458 USHORT nRealDelta
= nDelta
;
462 SvLBoxEntry
* pPrev
= (SvLBoxEntry
*)(pView
->PrevVisible( pStartEntry
, nRealDelta
));
463 if( (ULONG
)pPrev
== (ULONG
)pStartEntry
)
466 nFlags
&= (~F_FILLING
);
471 if( nRealDelta
>= nVisibleCount
)
473 pView
->Invalidate( GetVisibleArea() );
478 long nEntryHeight
= pView
->GetEntryHeight();
479 pView
->NotifyScrolling( (long)nRealDelta
);
480 Rectangle
aArea( GetVisibleArea() );
482 pView
->Scroll( 0, nEntryHeight
*nRealDelta
, aArea
, SCROLL_NOCHILDREN
);
484 pView
->NotifyScrolled();
490 void SvImpLBox::KeyUp( BOOL bPageUp
, BOOL bNotifyScroll
)
492 if( !aVerSBar
.IsVisible() )
497 nDelta
= aVerSBar
.GetPageSize();
501 long nThumbPos
= aVerSBar
.GetThumbPos();
503 if( nThumbPos
< nDelta
)
509 nFlags
&= (~F_FILLING
);
513 aVerSBar
.SetThumbPos( nThumbPos
- nDelta
);
515 PageUp( (short)nDelta
);
524 void SvImpLBox::KeyDown( BOOL bPageDown
, BOOL bNotifyScroll
)
526 if( !aVerSBar
.IsVisible() )
531 nDelta
= aVerSBar
.GetPageSize();
535 long nThumbPos
= aVerSBar
.GetThumbPos();
536 long nVisibleSize
= aVerSBar
.GetVisibleSize();
537 long nRange
= aVerSBar
.GetRange().Len();
539 long nTmp
= nThumbPos
+nVisibleSize
;
540 while( (nDelta
> 0) && (nTmp
+nDelta
) >= nRange
)
546 nFlags
&= (~F_FILLING
);
550 aVerSBar
.SetThumbPos( nThumbPos
+nDelta
);
552 PageDown( (short)nDelta
);
562 void SvImpLBox::InvalidateEntriesFrom( long nY
) const
564 if( !(nFlags
& F_IN_PAINT
))
566 Rectangle
aRect( GetVisibleArea() );
568 pView
->Invalidate( aRect
);
572 void SvImpLBox::InvalidateEntry( long nY
) const
574 if( !(nFlags
& F_IN_PAINT
))
576 Rectangle
aRect( GetVisibleArea() );
577 long nMaxBottom
= aRect
.Bottom();
579 aRect
.Bottom() = nY
; aRect
.Bottom() += pView
->GetEntryHeight();
580 if( aRect
.Top() > nMaxBottom
)
582 if( aRect
.Bottom() > nMaxBottom
)
583 aRect
.Bottom() = nMaxBottom
;
584 pView
->Invalidate( aRect
);
588 void SvImpLBox::InvalidateEntry( SvLBoxEntry
* pEntry
)
590 if( GetUpdateMode() )
592 long nPrev
= nMostRight
;
593 SetMostRight( pEntry
);
594 if( nPrev
< nMostRight
)
597 if( !(nFlags
& F_IN_PAINT
))
599 BOOL bHasFocusRect
= FALSE
;
600 if( pEntry
==pCursor
&& pView
->HasFocus() )
602 bHasFocusRect
= TRUE
;
605 InvalidateEntry( GetEntryLine( pEntry
) );
612 void SvImpLBox::RecalcFocusRect()
614 if( pView
->HasFocus() && pCursor
)
617 long nY
= GetEntryLine( pCursor
);
618 Rectangle aRect
= pView
->GetFocusRect( pCursor
, nY
);
619 CalcCellFocusRect( pCursor
, aRect
);
620 Region
aOldClip( pView
->GetClipRegion());
621 Region
aClipRegion( GetClipRegionRect() );
622 pView
->SetClipRegion( aClipRegion
);
623 pView
->ShowFocus( aRect
);
624 pView
->SetClipRegion( aOldClip
);
629 // Setzt Cursor. Passt bei SingleSelection die Selektion an
632 void SvImpLBox::SetCursor( SvLBoxEntry
* pEntry
, BOOL bForceNoSelect
)
634 SvViewDataEntry
* pViewDataNewCur
= 0;
636 pViewDataNewCur
= pView
->GetViewDataEntry(pEntry
);
639 pViewDataNewCur
->HasFocus() &&
640 pViewDataNewCur
->IsSelected())
645 // if this cursor is not selectable, find first visible that is and use it
646 while( pEntry
&& pViewDataNewCur
&& !pViewDataNewCur
->IsSelectable() )
648 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
649 pViewDataNewCur
= pEntry
? pView
->GetViewDataEntry(pEntry
) : 0;
652 SvLBoxEntry
* pOldCursor
= pCursor
;
653 if( pCursor
&& pEntry
!= pCursor
)
655 pView
->SetEntryFocus( pCursor
, FALSE
);
657 pView
->Select( pCursor
, FALSE
);
663 pViewDataNewCur
->SetFocus( TRUE
);
664 if(!bForceNoSelect
&& bSimpleTravel
&& !(nFlags
& F_DESEL_ALL
) && GetUpdateMode())
666 pView
->Select( pCursor
, TRUE
);
668 // Mehrfachselektion: Im Cursor-Move selektieren, wenn
669 // nicht im Add-Mode (Ctrl-F8)
670 else if( GetUpdateMode() &&
671 pView
->GetSelectionMode() == MULTIPLE_SELECTION
&&
672 !(nFlags
& F_DESEL_ALL
) && !aSelEng
.IsAddMode() &&
675 pView
->Select( pCursor
, TRUE
);
684 DBG_ASSERT(aSelEng
.GetSelectionMode() != SINGLE_SELECTION
,"Mode?");
685 SetAnchorSelection( pOldCursor
, pCursor
);
688 nFlags
&= (~F_DESEL_ALL
);
691 void SvImpLBox::ShowCursor( BOOL bShow
)
693 if( !bShow
|| !pCursor
|| !pView
->HasFocus() )
695 Region
aOldClip( pView
->GetClipRegion());
696 Region
aClipRegion( GetClipRegionRect() );
697 pView
->SetClipRegion( aClipRegion
);
699 pView
->SetClipRegion( aOldClip
);
703 long nY
= GetEntryLine( pCursor
);
704 Rectangle aRect
= pView
->GetFocusRect( pCursor
, nY
);
705 CalcCellFocusRect( pCursor
, aRect
);
706 Region
aOldClip( pView
->GetClipRegion());
707 Region
aClipRegion( GetClipRegionRect() );
708 pView
->SetClipRegion( aClipRegion
);
709 pView
->ShowFocus( aRect
);
710 pView
->SetClipRegion( aOldClip
);
716 void SvImpLBox::UpdateAll( BOOL bInvalidateCompleteView
,
717 BOOL bUpdateVerScrollBar
)
719 if( bUpdateVerScrollBar
)
721 aVerSBar
.SetRange( Range(0, pView
->GetVisibleCount()-1 ) );
725 if( bSimpleTravel
&& pCursor
&& pView
->HasFocus() )
726 pView
->Select( pCursor
, TRUE
);
728 if( bInvalidateCompleteView
)
731 pView
->Invalidate( GetVisibleArea() );
734 IMPL_LINK_INLINE_START( SvImpLBox
, ScrollLeftRightHdl
, ScrollBar
*, pScrollBar
)
736 long nDelta
= pScrollBar
->GetDelta();
739 if( pView
->IsEditingActive() )
741 pView
->EndEditing( TRUE
); // Cancel
744 pView
->nFocusWidth
= -1;
745 KeyLeftRight( nDelta
);
749 IMPL_LINK_INLINE_END( SvImpLBox
, ScrollLeftRightHdl
, ScrollBar
*, pScrollBar
)
751 void SvImpLBox::KeyLeftRight( long nDelta
)
753 if( !(nFlags
& F_IN_RESIZE
) )
756 nFlags
&= (~F_FILLING
);
757 pView
->NotifyScrolling( 0 ); // 0 == horizontales Scrolling
760 // neuen Origin berechnen
761 long nPos
= aHorSBar
.GetThumbPos();
762 Point
aOrigin( -nPos
, 0 );
764 MapMode
aMapMode( pView
->GetMapMode() );
765 aMapMode
.SetOrigin( aOrigin
);
766 pView
->SetMapMode( aMapMode
);
768 if( !(nFlags
& F_IN_RESIZE
) )
770 Rectangle
aRect( GetVisibleArea() );
771 pView
->Scroll( -nDelta
, 0, aRect
, SCROLL_NOCHILDREN
);
777 pView
->NotifyScrolled();
781 // gibt letzten Eintrag zurueck, wenn Position unter
782 // dem letzten Eintrag ist
783 SvLBoxEntry
* SvImpLBox::GetClickedEntry( const Point
& rPoint
) const
785 DBG_ASSERT( pView
->GetModel(), "SvImpLBox::GetClickedEntry: how can this ever happen? Please tell me (frank.schoenheit@sun.com) how to reproduce!" );
786 if ( !pView
->GetModel() )
787 // this is quite impossible. Nevertheless, stack traces from the crash reporter
788 // suggest it isn't. Okay, make it safe, and wait for somebody to reproduce it
790 // #122359# / 2005-05-23 / frank.schoenheit@sun.com
792 if( pView
->GetEntryCount() == 0 || !pStartEntry
|| !pView
->GetEntryHeight())
795 USHORT nClickedEntry
= (USHORT
)(rPoint
.Y() / pView
->GetEntryHeight() );
796 USHORT nTemp
= nClickedEntry
;
797 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pStartEntry
, nTemp
));
802 // prueft, ob der Eintrag "richtig" getroffen wurde
803 // (Focusrect+ ContextBitmap bei TreeListBox)
805 BOOL
SvImpLBox::EntryReallyHit(SvLBoxEntry
* pEntry
,const Point
& rPosPixel
,long nLine
)
808 // bei "besonderen" Entries (mit CheckButtons usw.) sind wir
810 if( pEntry
->ItemCount() >= 3 )
813 Rectangle
aRect( pView
->GetFocusRect( pEntry
, nLine
));
814 aRect
.Right() = GetOutputSize().Width() - pView
->GetMapMode().GetOrigin().X();
815 if( pView
->IsA() == SV_LISTBOX_ID_TREEBOX
)
817 SvLBoxContextBmp
* pBmp
= (SvLBoxContextBmp
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
818 aRect
.Left() -= pBmp
->GetSize(pView
,pEntry
).Width();
819 aRect
.Left() -= 4; // etwas Speilraum lassen
821 Point
aPos( rPosPixel
);
822 aPos
-= pView
->GetMapMode().GetOrigin();
823 if( aRect
.IsInside( aPos
) )
831 // gibt 0 zurueck, wenn Position unter dem letzten Eintrag ist
832 SvLBoxEntry
* SvImpLBox::GetEntry( const Point
& rPoint
) const
834 if( (pView
->GetEntryCount() == 0) || !pStartEntry
||
835 (rPoint
.Y() > aOutputSize
.Height())
836 || !pView
->GetEntryHeight())
839 USHORT nClickedEntry
= (USHORT
)(rPoint
.Y() / pView
->GetEntryHeight() );
840 USHORT nTemp
= nClickedEntry
;
841 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pStartEntry
, nTemp
));
842 if( nTemp
!= nClickedEntry
)
848 SvLBoxEntry
* SvImpLBox::MakePointVisible(const Point
& rPoint
,BOOL bNotifyScroll
)
852 long nY
= rPoint
.Y();
853 SvLBoxEntry
* pEntry
= 0;
854 long nMax
= aOutputSize
.Height();
855 if( nY
< 0 || nY
>= nMax
) // aOutputSize.Height() )
858 pEntry
= (SvLBoxEntry
*)(pView
->PrevVisible( pCursor
));
860 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pCursor
));
862 if( pEntry
&& pEntry
!= pCursor
)
863 pView
->SetEntryFocus( pCursor
, FALSE
);
866 KeyUp( FALSE
, bNotifyScroll
);
868 KeyDown( FALSE
, bNotifyScroll
);
872 pEntry
= GetClickedEntry( rPoint
);
875 USHORT nSteps
= 0xFFFF;
876 // LastVisible ist noch nicht implementiert!
877 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pStartEntry
, nSteps
));
881 if( pEntry
!= pCursor
&&
882 aSelEng
.GetSelectionMode() == SINGLE_SELECTION
884 pView
->Select( pCursor
, FALSE
);
890 Rectangle
SvImpLBox::GetClipRegionRect() const
892 Point
aOrigin( pView
->GetMapMode().GetOrigin() );
893 aOrigin
.X() *= -1; // Umrechnung Dokumentkoord.
894 Rectangle
aClipRect( aOrigin
, aOutputSize
);
895 aClipRect
.Bottom()++;
900 void SvImpLBox::Paint( const Rectangle
& rRect
)
902 if( !pView
->GetVisibleCount() )
905 nFlags
|= F_IN_PAINT
;
907 if( nFlags
& F_FILLING
)
909 SvLBoxEntry
* pFirst
= pView
->First();
910 if( pFirst
!= pStartEntry
)
913 pStartEntry
= pView
->First();
914 aVerSBar
.SetThumbPos( 0 );
917 nCurUserEvent
= Application::PostUserEvent(LINK(this,SvImpLBox
,MyUserEvent
),(void*)1);
924 pStartEntry
= pView
->First();
928 ULONG nXAbsPos
= (USHORT
)pTree
->GetAbsPos( pStartEntry
);
929 ULONG nXVisPos
= pView
->GetVisiblePos( pStartEntry
);
930 SvLBoxString
* pXStr
= (SvLBoxString
*)pStartEntry
->GetFirstItem( SV_ITEM_ID_LBOXSTRING
);
935 if( nNodeBmpTabDistance
== NODE_BMP_TABDIST_NOTVALID
)
936 SetNodeBmpTabDistance();
938 long nRectHeight
= rRect
.GetHeight();
939 long nEntryHeight
= pView
->GetEntryHeight();
941 // Bereich der zu zeichnenden Entries berechnen
942 USHORT nStartLine
= (USHORT
)( rRect
.Top() / nEntryHeight
);
943 USHORT nCount
= (USHORT
)( nRectHeight
/ nEntryHeight
);
944 nCount
+= 2; // keine Zeile vergessen
946 long nY
= nStartLine
* nEntryHeight
;
947 SvLBoxEntry
* pEntry
= pStartEntry
;
948 while( nStartLine
&& pEntry
)
950 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
954 Region
aClipRegion( GetClipRegionRect() );
956 // erst die Linien Zeichnen, dann clippen!
957 pView
->SetClipRegion();
958 if( nWinBits
& ( WB_HASLINES
| WB_HASLINESATROOT
) )
961 pView
->SetClipRegion( aClipRegion
);
963 for( USHORT n
=0; n
< nCount
&& pEntry
; n
++ )
966 pView
->PaintEntry1( pEntry
, nY
, 0xffff, TRUE
);
968 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
971 if ( !pCursor
&& ( ( nExtendedWinBits
& EWB_NO_AUTO_CURENTRY
) == 0 ) )
973 // do not select if multiselection or explicit set
974 BOOL bNotSelect
= ( aSelEng
.GetSelectionMode() == MULTIPLE_SELECTION
)
975 || ( ( nWinBits
& WB_NOINITIALSELECTION
) == WB_NOINITIALSELECTION
);
976 SetCursor( pStartEntry
, bNotSelect
);
979 nFlags
&= (~F_DESEL_ALL
);
980 pView
->SetClipRegion();
982 if( !(nFlags
& F_PAINTED
) )
987 nFlags
&= (~F_IN_PAINT
);
990 void SvImpLBox::MakeVisible( SvLBoxEntry
* pEntry
, BOOL bMoveToTop
)
995 BOOL bInView
= IsEntryInView( pEntry
);
997 if( bInView
&& (!bMoveToTop
|| pStartEntry
== pEntry
) )
998 return; // ist schon sichtbar
1000 if( pStartEntry
|| (nWinBits
& WB_FORCE_MAKEVISIBLE
) )
1001 nFlags
&= (~F_FILLING
);
1004 if( !pView
->IsEntryVisible(pEntry
) ) // Parent(s) zugeklappt ?
1006 SvLBoxEntry
* pParent
= pView
->GetParent( pEntry
);
1009 if( !pView
->IsExpanded( pParent
) )
1014 pView
->Expand( pParent
);
1015 DBG_ASSERT(bRet
,"Not expanded!");
1017 pParent
= pView
->GetParent( pParent
);
1019 // Passen Childs der Parents in View oder muessen wir scrollen ?
1020 if( IsEntryInView( pEntry
) && !bMoveToTop
)
1021 return; // Scrollen nicht noetig -> tschuess
1025 pStartEntry
= pEntry
;
1026 ShowCursor( FALSE
);
1028 aVerSBar
.SetThumbPos( (long)(pView
->GetVisiblePos( pStartEntry
)) );
1030 pView
->Invalidate();
1034 void SvImpLBox::RepaintSelectionItems()
1036 if( !pView
->GetVisibleCount() )
1040 pStartEntry
= pView
->First();
1042 if( nNodeBmpTabDistance
== NODE_BMP_TABDIST_NOTVALID
)
1043 SetNodeBmpTabDistance();
1045 ShowCursor( FALSE
);
1047 long nEntryHeight
= pView
->GetEntryHeight();
1049 ULONG nCount
= nVisibleCount
;
1051 SvLBoxEntry
* pEntry
= pStartEntry
;
1052 for( ULONG n
=0; n
< nCount
&& pEntry
; n
++ )
1054 pView
->PaintEntry1( pEntry
, nY
, 0xffff ); //wg. ItemsetBrowser SV_LBOXTAB_SHOW_SELECTION );
1056 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
1063 void SvImpLBox::DrawNet()
1065 if( pView
->GetVisibleCount() < 2 && !pStartEntry
->HasChildsOnDemand() &&
1066 !pStartEntry
->HasChilds() )
1069 //for platforms who don't have nets, DrawNativeControl does nothing and return true
1070 //so that SvImpLBox::DrawNet() doesn't draw anything too
1071 if(pView
->IsNativeControlSupported( CTRL_LISTNET
, PART_ENTIRE_CONTROL
)) {
1072 ImplControlValue aControlValue
;
1073 Point
aTemp(0,0); // temporary needed for g++ 3.3.5
1074 Region
aCtrlRegion( Rectangle(aTemp
, Size( 0, 0 )) );
1075 ControlState nState
= CTRL_STATE_ENABLED
;
1076 if( pView
->DrawNativeControl( CTRL_LISTNET
, PART_ENTIRE_CONTROL
,
1077 aCtrlRegion
, nState
, aControlValue
, rtl::OUString() ) )
1084 long nEntryHeight
= pView
->GetEntryHeight();
1085 long nEntryHeightDIV2
= nEntryHeight
/ 2;
1086 if( nEntryHeightDIV2
&& !(nEntryHeight
& 0x0001))
1089 SvLBoxEntry
* pChild
;
1090 SvLBoxEntry
* pEntry
= pStartEntry
;
1092 SvLBoxTab
* pFirstDynamicTab
= pView
->GetFirstDynamicTab();
1093 while( pTree
->GetDepth( pEntry
) > 0 )
1094 pEntry
= pView
->GetParent( pEntry
);
1095 USHORT nOffs
= (USHORT
)(pView
->GetVisiblePos( pStartEntry
) -
1096 pView
->GetVisiblePos( pEntry
));
1098 nY
-= ( nOffs
* nEntryHeight
);
1100 DBG_ASSERT(pFirstDynamicTab
,"No Tree!");
1102 Color aOldLineColor
= pView
->GetLineColor();
1103 const StyleSettings
& rStyleSettings
= pView
->GetSettings().GetStyleSettings();
1104 Color aCol
= rStyleSettings
.GetFaceColor();
1106 if( aCol
.IsRGBEqual( pView
->GetBackground().GetColor()) )
1107 aCol
= rStyleSettings
.GetShadowColor();
1108 pView
->SetLineColor( aCol
);
1111 ULONG nMax
= nVisibleCount
+ nOffs
+ 1;
1113 const Image
& rExpandedNodeBitmap
= GetExpandedNodeBmp();
1115 for( ULONG n
=0; n
< nMax
&& pEntry
; n
++ )
1117 if( pView
->IsExpanded(pEntry
) )
1119 aPos1
.X() = pView
->GetTabPos(pEntry
, pFirstDynamicTab
);
1120 // wenn keine ContextBitmap, dann etwas nach rechts
1121 // unter den ersten Text (Node.Bmp ebenfalls
1122 if( !pView
->nContextBmpWidthMax
)
1123 aPos1
.X() += rExpandedNodeBitmap
.GetSizePixel().Width() / 2;
1126 aPos1
.Y() += nEntryHeightDIV2
;
1128 pChild
= pView
->FirstChild( pEntry
);
1129 DBG_ASSERT(pChild
,"Child?");
1130 pChild
= pTree
->LastSibling( pChild
);
1131 nDistance
= (USHORT
)(pView
->GetVisiblePos(pChild
) -
1132 pView
->GetVisiblePos(pEntry
));
1134 aPos2
.Y() += nDistance
* nEntryHeight
;
1135 pView
->DrawLine( aPos1
, aPos2
);
1137 // Sichtbar im Control ?
1138 if( n
>= nOffs
&& ((nWinBits
& WB_HASLINESATROOT
) || !pTree
->IsAtRootDepth(pEntry
)))
1140 // kann aPos1 recyclet werden ?
1141 if( !pView
->IsExpanded(pEntry
) )
1144 aPos1
.X() = pView
->GetTabPos(pEntry
, pFirstDynamicTab
);
1145 // wenn keine ContextBitmap, dann etwas nach rechts
1146 // unter den ersten Text (Node.Bmp ebenfalls
1147 if( !pView
->nContextBmpWidthMax
)
1148 aPos1
.X() += rExpandedNodeBitmap
.GetSizePixel().Width() / 2;
1150 aPos1
.Y() += nEntryHeightDIV2
;
1151 aPos2
.X() = aPos1
.X();
1153 aPos2
.Y() = aPos1
.Y();
1154 aPos2
.X() -= pView
->GetIndent();
1155 pView
->DrawLine( aPos1
, aPos2
);
1158 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
1160 if( nWinBits
& WB_HASLINESATROOT
)
1162 pEntry
= pView
->First();
1163 aPos1
.X() = pView
->GetTabPos( pEntry
, pFirstDynamicTab
);
1164 // wenn keine ContextBitmap, dann etwas nach rechts
1165 // unter den ersten Text (Node.Bmp ebenfalls
1166 if( !pView
->nContextBmpWidthMax
)
1167 aPos1
.X() += rExpandedNodeBitmap
.GetSizePixel().Width() / 2;
1168 aPos1
.X() -= pView
->GetIndent();
1169 aPos1
.Y() = GetEntryLine( pEntry
);
1170 aPos1
.Y() += nEntryHeightDIV2
;
1171 pChild
= pTree
->LastSibling( pEntry
);
1172 aPos2
.X() = aPos1
.X();
1173 aPos2
.Y() = GetEntryLine( pChild
);
1174 aPos2
.Y() += nEntryHeightDIV2
;
1175 pView
->DrawLine( aPos1
, aPos2
);
1177 pView
->SetLineColor( aOldLineColor
);
1181 static long GetOptSize( TabBar
* pTabBar
)
1183 return pTabBar
->CalcWindowSizePixel().Width();
1186 void SvImpLBox::PositionScrollBars( Size
& rSize
, USHORT nMask
)
1190 Size
aVerSize( nVerSBarWidth
, rSize
.Height() );
1191 Size
aHorSize( rSize
.Width(), nHorSBarHeight
);
1192 long nTabBarWidth
= 0;
1195 nTabBarWidth
= GetOptSize( pTabBar
);
1196 long nMaxWidth
= (rSize
.Width() * 700) / 1000;
1197 if( nTabBarWidth
> nMaxWidth
)
1199 nTabBarWidth
= nMaxWidth
;
1200 pTabBar
->SetStyle( pTabBar
->GetStyle() | WB_MINSCROLL
);
1204 WinBits nStyle
= pTabBar
->GetStyle();
1205 nStyle
&= ~(WB_MINSCROLL
);
1206 pTabBar
->SetStyle( nStyle
);
1208 aHorSize
.Width() -= nTabBarWidth
;
1209 Size
aTabSize( pTabBar
->GetSizePixel() );
1210 aTabSize
.Width() = nTabBarWidth
;
1211 pTabBar
->SetSizePixel( aTabSize
);
1213 if( nMask
& 0x0001 )
1214 aHorSize
.Width() -= nVerSBarWidth
;
1215 if( nMask
& 0x0002 )
1216 aVerSize
.Height() -= nHorSBarHeight
;
1218 aVerSize
.Height() += 2 * nOverlap
;
1219 Point
aVerPos( rSize
.Width() - aVerSize
.Width() + nOverlap
, -nOverlap
);
1220 aVerSBar
.SetPosSizePixel( aVerPos
, aVerSize
);
1222 aHorSize
.Width() += 2 * nOverlap
;
1223 Point
aHorPos( -nOverlap
, rSize
.Height() - aHorSize
.Height() + nOverlap
);
1225 pTabBar
->SetPosPixel( aHorPos
);
1226 aHorPos
.X() += nTabBarWidth
;
1227 aHorSBar
.SetPosSizePixel( aHorPos
, aHorSize
);
1229 if( nMask
& 0x0001 )
1230 rSize
.Width() = aVerPos
.X();
1231 if( nMask
& 0x0002 )
1232 rSize
.Height() = aHorPos
.Y();
1236 if( (nMask
& (0x0001|0x0002)) == (0x0001|0x0002) )
1243 // nResult: Bit0 == VerSBar Bit1 == HorSBar
1244 USHORT
SvImpLBox::AdjustScrollBars( Size
& rSize
)
1246 long nEntryHeight
= pView
->GetEntryHeight();
1252 Size
aOSize( pView
->Control::GetOutputSizePixel() );
1254 BOOL bVerSBar
= ( pView
->nWindowStyle
& WB_VSCROLL
) != 0;
1255 BOOL bHorBar
= FALSE
;
1256 long nMaxRight
= aOSize
.Width(); //GetOutputSize().Width();
1257 Point
aOrigin( pView
->GetMapMode().GetOrigin() );
1259 nMaxRight
+= aOrigin
.X() - 1;
1260 long nVis
= nMostRight
- aOrigin
.X();
1262 (pView
->nWindowStyle
& WB_HSCROLL
) &&
1263 (nVis
< nMostRight
|| nMaxRight
< nMostRight
) ))
1266 // Anzahl aller nicht eingeklappten Eintraege
1267 ULONG nTotalCount
= pView
->GetVisibleCount();
1269 // Anzahl in der View sichtbarer Eintraege
1270 nVisibleCount
= aOSize
.Height() / nEntryHeight
;
1272 // muessen wir eine vertikale Scrollbar einblenden?
1273 if( bVerSBar
|| nTotalCount
> nVisibleCount
)
1276 nFlags
|= F_HOR_SBARSIZE_WITH_VBAR
;
1277 nMaxRight
-= nVerSBarWidth
;
1280 if( (pView
->nWindowStyle
& WB_HSCROLL
) &&
1281 (nVis
< nMostRight
|| nMaxRight
< nMostRight
) )
1286 // muessen wir eine horizontale Scrollbar einblenden?
1290 // die Anzahl der in der View sichtbaren Eintraege
1291 // muss neu berechnet werden, da die horizontale
1292 // ScrollBar eingeblendet wird
1293 nVisibleCount
= (aOSize
.Height() - nHorSBarHeight
) / nEntryHeight
;
1294 // eventuell brauchen wir jetzt doch eine vertikale ScrollBar
1295 if( !(nResult
& 0x0001) &&
1296 ((nTotalCount
> nVisibleCount
) || bVerSBar
) )
1299 nFlags
|= F_VER_SBARSIZE_WITH_HBAR
;
1303 PositionScrollBars( aOSize
, nResult
);
1305 // Range, VisibleRange usw. anpassen
1307 // Output-Size aktualisieren, falls wir scrollen muessen
1309 aRect
.SetSize( aOSize
);
1310 aSelEng
.SetVisibleArea( aRect
);
1312 // Vertikale ScrollBar
1313 long nTemp
= (long)nVisibleCount
;
1315 if( nTemp
!= aVerSBar
.GetVisibleSize() )
1317 if( !bInVScrollHdl
)
1319 aVerSBar
.SetPageSize( nTemp
- 1 );
1320 aVerSBar
.SetVisibleSize( nTemp
);
1324 nFlags
|= F_ENDSCROLL_SET_VIS_SIZE
;
1325 nNextVerVisSize
= nTemp
;
1329 // Horizontale ScrollBar
1330 nTemp
= aHorSBar
.GetThumbPos();
1331 aHorSBar
.SetVisibleSize( aOSize
.Width() );
1332 long nNewThumbPos
= aHorSBar
.GetThumbPos();
1333 Range
aRange( aHorSBar
.GetRange() );
1334 if( aRange
.Max() < nMostRight
+25 )
1336 aRange
.Max() = nMostRight
+25;
1337 aHorSBar
.SetRange( aRange
);
1340 if( nTemp
!= nNewThumbPos
)
1342 nTemp
= nNewThumbPos
- nTemp
;
1343 if( pView
->IsEditingActive() )
1345 pView
->EndEditing( TRUE
); // Cancel
1348 pView
->nFocusWidth
= -1;
1349 KeyLeftRight( nTemp
);
1352 if( nResult
& 0x0001 )
1357 if( nResult
& 0x0002 )
1368 void SvImpLBox::InitScrollBarBox()
1370 aScrBarBox
.SetSizePixel( Size(nVerSBarWidth
, nHorSBarHeight
) );
1371 Size
aSize( pView
->Control::GetOutputSizePixel() );
1372 aScrBarBox
.SetPosPixel( Point(aSize
.Width()-nVerSBarWidth
, aSize
.Height()-nHorSBarHeight
));
1375 void SvImpLBox::Resize()
1377 Size
aSize( pView
->Control::GetOutputSizePixel());
1378 if( aSize
.Width() <= 0 || aSize
.Height() <= 0 )
1380 nFlags
|= F_IN_RESIZE
;
1383 if( pView
->GetEntryHeight())
1385 AdjustScrollBars( aOutputSize
);
1388 // !!!HACK, da in Floating- & Docking-Windows nach Resizes
1389 // die Scrollbars nicht richtig, bzw. ueberhaupt nicht gezeichnet werden
1390 if( aHorSBar
.IsVisible())
1391 aHorSBar
.Invalidate();
1392 if( aVerSBar
.IsVisible())
1393 aVerSBar
.Invalidate();
1394 nFlags
&= (~(F_IN_RESIZE
| F_PAINTED
));
1397 void SvImpLBox::FillView()
1401 USHORT nVisibleViewCount
= (USHORT
)(pView
->GetVisibleCount());
1402 USHORT nTempThumb
= (USHORT
)aVerSBar
.GetThumbPos();
1403 if( nTempThumb
>= nVisibleViewCount
)
1404 nTempThumb
= nVisibleViewCount
- 1;
1405 pStartEntry
= (SvLBoxEntry
*)(pView
->GetEntryAtVisPos(nTempThumb
));
1409 USHORT nLast
= (USHORT
)(pView
->GetVisiblePos( (SvLBoxEntry
*)(pView
->LastVisible())));
1410 USHORT nThumb
= (USHORT
)(pView
->GetVisiblePos( pStartEntry
));
1411 USHORT nCurDispEntries
= nLast
-nThumb
+1;
1412 if( nCurDispEntries
< nVisibleCount
)
1414 ShowCursor( FALSE
);
1415 // Fenster fuellen, indem der Thumb schrittweise
1416 // nach oben bewegt wird
1417 BOOL bFound
= FALSE
;
1418 SvLBoxEntry
* pTemp
= pStartEntry
;
1419 while( nCurDispEntries
< nVisibleCount
&& pTemp
)
1421 pTemp
= (SvLBoxEntry
*)(pView
->PrevVisible(pStartEntry
));
1425 pStartEntry
= pTemp
;
1432 aVerSBar
.SetThumbPos( nThumb
);
1433 ShowCursor( TRUE
); // Focusrect neu berechnen
1434 pView
->Invalidate();
1443 void SvImpLBox::ShowVerSBar()
1445 BOOL bVerBar
= ( pView
->nWindowStyle
& WB_VSCROLL
) != 0;
1448 nVis
= pView
->GetVisibleCount();
1449 if( bVerBar
|| (nVisibleCount
&& nVis
> (ULONG
)(nVisibleCount
-1)) )
1451 if( !aVerSBar
.IsVisible() )
1453 pView
->nFocusWidth
= -1;
1454 AdjustScrollBars( aOutputSize
);
1455 if( GetUpdateMode() )
1461 if( aVerSBar
.IsVisible() )
1463 pView
->nFocusWidth
= -1;
1464 AdjustScrollBars( aOutputSize
);
1468 long nMaxRight
= GetOutputSize().Width();
1469 Point
aPos( pView
->GetMapMode().GetOrigin() );
1470 aPos
.X() *= -1; // Umrechnung Dokumentkoord.
1471 nMaxRight
= nMaxRight
+ aPos
.X() - 1;
1472 if( nMaxRight
< nMostRight
)
1474 if( !aHorSBar
.IsVisible() )
1476 pView
->nFocusWidth
= -1;
1477 AdjustScrollBars( aOutputSize
);
1478 if( GetUpdateMode() )
1483 Range
aRange( aHorSBar
.GetRange() );
1484 if( aRange
.Max() < nMostRight
+25 )
1486 aRange
.Max() = nMostRight
+25;
1487 aHorSBar
.SetRange( aRange
);
1491 pView
->nFocusWidth
= -1;
1492 AdjustScrollBars( aOutputSize
);
1498 if( aHorSBar
.IsVisible() )
1500 pView
->nFocusWidth
= -1;
1501 AdjustScrollBars( aOutputSize
);
1507 void SvImpLBox::SyncVerThumb()
1511 long nEntryPos
= pView
->GetVisiblePos( pStartEntry
);
1512 aVerSBar
.SetThumbPos( nEntryPos
);
1515 aVerSBar
.SetThumbPos( 0 );
1518 BOOL
SvImpLBox::IsEntryInView( SvLBoxEntry
* pEntry
) const
1520 // Parent eingeklappt
1521 if( !pView
->IsEntryVisible(pEntry
) )
1523 long nY
= GetEntryLine( pEntry
);
1526 long nMax
= nVisibleCount
* pView
->GetEntryHeight();
1533 long SvImpLBox::GetEntryLine( SvLBoxEntry
* pEntry
) const
1536 return -1; // unsichtbare Position
1538 long nFirstVisPos
= pView
->GetVisiblePos( pStartEntry
);
1539 long nEntryVisPos
= pView
->GetVisiblePos( pEntry
);
1540 nFirstVisPos
= nEntryVisPos
- nFirstVisPos
;
1541 nFirstVisPos
*= pView
->GetEntryHeight();
1542 return nFirstVisPos
;
1545 void SvImpLBox::SetEntryHeight( short /* nHeight */ )
1547 SetNodeBmpYOffset( GetExpandedNodeBmp() );
1548 SetNodeBmpYOffset( GetCollapsedNodeBmp() );
1549 if(!pView
->HasViewData()) // stehen wir im Clear?
1551 Size aSize
= pView
->Control::GetOutputSizePixel();
1552 AdjustScrollBars( aSize
);
1557 if( GetUpdateMode() )
1558 pView
->Invalidate();
1564 // ***********************************************************************
1565 // Callback-Functions
1566 // ***********************************************************************
1568 void SvImpLBox::IndentChanged( short /* nIndentPixel */ ) {}
1570 void SvImpLBox::EntryExpanded( SvLBoxEntry
* pEntry
)
1572 // SelAllDestrAnch( FALSE, TRUE ); //DeselectAll();
1573 if( GetUpdateMode() )
1575 ShowCursor( FALSE
);
1576 long nY
= GetEntryLine( pEntry
);
1577 if( IsLineVisible(nY
) )
1579 InvalidateEntriesFrom( nY
);
1580 FindMostRight( pEntry
, 0 );
1582 aVerSBar
.SetRange( Range(0, pView
->GetVisibleCount()-1 ) );
1583 // falls vor dem Thumb expandiert wurde, muss
1584 // die Thumb-Position korrigiert werden.
1591 void SvImpLBox::EntryCollapsed( SvLBoxEntry
* pEntry
)
1593 if( !pView
->IsEntryVisible( pEntry
) )
1596 ShowCursor( FALSE
);
1598 if( !pMostRightEntry
|| pTree
->IsChild( pEntry
,pMostRightEntry
) )
1605 long nOldThumbPos
= aVerSBar
.GetThumbPos();
1606 ULONG nVisList
= pView
->GetVisibleCount();
1607 aVerSBar
.SetRange( Range(0, nVisList
-1) );
1608 long nNewThumbPos
= aVerSBar
.GetThumbPos();
1609 if( nNewThumbPos
!= nOldThumbPos
)
1611 pStartEntry
= pView
->First();
1612 USHORT nDistance
= (USHORT
)nNewThumbPos
;
1614 pStartEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pStartEntry
,
1616 if( GetUpdateMode() )
1617 pView
->Invalidate();
1623 // wurde Cursor eingeklappt ?
1624 if( pTree
->IsChild( pEntry
, pCursor
) )
1625 SetCursor( pEntry
);
1626 if( GetUpdateMode() )
1629 if( GetUpdateMode() && pCursor
)
1630 pView
->Select( pCursor
, TRUE
);
1633 void SvImpLBox::CollapsingEntry( SvLBoxEntry
* pEntry
)
1635 if( !pView
->IsEntryVisible( pEntry
) || !pStartEntry
)
1638 SelAllDestrAnch( FALSE
, TRUE
); // deselectall
1640 // ist der eingeklappte Parent sichtbar ?
1641 long nY
= GetEntryLine( pEntry
);
1642 if( IsLineVisible(nY
) )
1644 if( GetUpdateMode() )
1645 InvalidateEntriesFrom( nY
);
1649 if( pTree
->IsChild(pEntry
, pStartEntry
) )
1651 pStartEntry
= pEntry
;
1652 if( GetUpdateMode() )
1653 pView
->Invalidate();
1659 void SvImpLBox::SetNodeBmpYOffset( const Image
& rBmp
)
1662 nYoffsNodeBmp
= pView
->GetHeightOffset( rBmp
, aSize
);
1663 nNodeBmpWidth
= aSize
.Width();
1666 void SvImpLBox::SetNodeBmpTabDistance()
1668 nNodeBmpTabDistance
= -pView
->GetIndent();
1669 if( pView
->nContextBmpWidthMax
)
1671 // nur, wenn der erste dynamische Tab zentriert ist
1672 // (setze ich momentan voraus)
1673 Size aSize
= GetExpandedNodeBmp().GetSizePixel();
1674 nNodeBmpTabDistance
-= aSize
.Width() / 2;
1679 // korrigiert bei SingleSelection den Cursor
1681 void SvImpLBox::EntrySelected( SvLBoxEntry
* pEntry
, BOOL bSelect
)
1683 if( nFlags
& F_IGNORE_SELECT
)
1687 if( (nWinBits & WB_HIDESELECTION) && pEntry && !pView->HasFocus() )
1689 SvViewData* pViewData = pView->GetViewData( pEntry );
1690 pViewData->SetCursored( bSelect );
1694 nFlags
&= (~F_DESEL_ALL
);
1696 aSelEng
.GetSelectionMode() == SINGLE_SELECTION
&&
1699 SetCursor( pEntry
);
1700 DBG_ASSERT(pView
->GetSelectionCount()==1,"selection count?");
1703 if( GetUpdateMode() && pView
->IsEntryVisible(pEntry
) )
1705 long nY
= GetEntryLine( pEntry
);
1706 if( IsLineVisible( nY
) )
1708 ShowCursor( FALSE
);
1709 pView
->PaintEntry1( pEntry
, nY
, 0xffff ); // wg. ItemsetBrowser SV_LBOXTAB_SHOW_SELECTION );
1716 void SvImpLBox::RemovingEntry( SvLBoxEntry
* pEntry
)
1720 if( !pView
->IsEntryVisible( pEntry
) )
1722 // wenn Parent eingeklappt, dann tschuess
1723 nFlags
|= F_REMOVED_ENTRY_INVISIBLE
;
1727 if( pEntry
== pMostRightEntry
|| (
1728 pEntry
->HasChilds() && pView
->IsExpanded(pEntry
) &&
1729 pTree
->IsChild(pEntry
, pMostRightEntry
)))
1731 nFlags
|= F_REMOVED_RECALC_MOST_RIGHT
;
1734 SvLBoxEntry
* pOldStartEntry
= pStartEntry
;
1736 SvLBoxEntry
* pParent
= (SvLBoxEntry
*)(pView
->GetModel()->GetParent(pEntry
));
1738 if( pParent
&& pView
->GetModel()->GetChildList(pParent
)->Count() == 1 )
1740 DBG_ASSERT( pView
->IsExpanded( pParent
), "Parent not expanded");
1741 pParent
->SetFlags( pParent
->GetFlags() | SV_ENTRYFLAG_NO_NODEBMP
);
1742 InvalidateEntry( pParent
);
1745 if( pCursor
&& pTree
->IsChild( pEntry
, pCursor
) )
1747 if( pStartEntry
&& pTree
->IsChild(pEntry
,pStartEntry
) )
1748 pStartEntry
= pEntry
;
1751 if( pCursor
&& pCursor
== pEntry
)
1754 pView
->Select( pCursor
, FALSE
);
1755 ShowCursor( FALSE
); // Focus-Rect weg
1756 // NextSibling, weil auch Childs des Cursors geloescht werden
1757 pTemp
= pView
->NextSibling( pCursor
);
1759 pTemp
= (SvLBoxEntry
*)(pView
->PrevVisible( pCursor
));
1761 SetCursor( pTemp
, TRUE
);
1763 if( pStartEntry
&& pStartEntry
== pEntry
)
1765 pTemp
= pView
->NextSibling( pStartEntry
);
1767 pTemp
= (SvLBoxEntry
*)(pView
->PrevVisible( pStartEntry
));
1768 pStartEntry
= pTemp
;
1770 if( GetUpdateMode())
1772 // wenns der letzte ist, muss invalidiert werden, damit die Linien
1773 // richtig gezeichnet (in diesem Fall geloescht) werden.
1774 if( pStartEntry
&& (pStartEntry
!= pOldStartEntry
|| pEntry
== (SvLBoxEntry
*)pView
->GetModel()->Last()) )
1776 aVerSBar
.SetThumbPos( pView
->GetVisiblePos( pStartEntry
));
1777 pView
->Invalidate( GetVisibleArea() );
1780 InvalidateEntriesFrom( GetEntryLine( pEntry
) );
1784 void SvImpLBox::EntryRemoved()
1786 if( nFlags
& F_REMOVED_ENTRY_INVISIBLE
)
1788 nFlags
&= (~F_REMOVED_ENTRY_INVISIBLE
);
1792 pStartEntry
= pTree
->First();
1794 SetCursor( pStartEntry
, TRUE
);
1796 if( pCursor
&& (bSimpleTravel
|| !pView
->GetSelectionCount() ))
1797 pView
->Select( pCursor
, TRUE
);
1799 if( GetUpdateMode())
1801 if( nFlags
& F_REMOVED_RECALC_MOST_RIGHT
)
1803 aVerSBar
.SetRange( Range(0, pView
->GetVisibleCount()-1 ) );
1806 // falls ueber dem Thumb geloescht wurde
1807 aVerSBar
.SetThumbPos( pView
->GetVisiblePos( pStartEntry
) );
1810 if( pCursor
&& pView
->HasFocus() && !pView
->IsSelected(pCursor
) )
1812 if( pView
->GetSelectionCount() )
1814 // ist ein benachbarter Eintrag selektiert?
1815 SvLBoxEntry
* pNextCursor
= (SvLBoxEntry
*)pView
->PrevVisible( pCursor
);
1816 if( !pNextCursor
|| !pView
->IsSelected( pNextCursor
))
1817 pNextCursor
= (SvLBoxEntry
*)pView
->NextVisible( pCursor
);
1818 if( !pNextCursor
|| !pView
->IsSelected( pNextCursor
))
1819 // kein Nachbar selektiert: Ersten selektierten nehmen
1820 pNextCursor
= pView
->FirstSelected();
1821 SetCursor( pNextCursor
);
1822 MakeVisible( pCursor
);
1825 pView
->Select( pCursor
, TRUE
);
1829 nFlags
&= (~F_REMOVED_RECALC_MOST_RIGHT
);
1833 void SvImpLBox::MovingEntry( SvLBoxEntry
* pEntry
)
1835 int bDeselAll
= nFlags
& F_DESEL_ALL
;
1836 SelAllDestrAnch( FALSE
, TRUE
); // DeselectAll();
1838 nFlags
&= (~F_DESEL_ALL
);
1840 if( pEntry
== pCursor
)
1841 ShowCursor( FALSE
);
1842 if( IsEntryInView( pEntry
) )
1843 pView
->Invalidate();
1844 if( pEntry
== pStartEntry
)
1846 SvLBoxEntry
* pNew
= 0;
1847 if( !pEntry
->HasChilds() )
1849 pNew
= (SvLBoxEntry
*)(pView
->NextVisible( pStartEntry
));
1851 pNew
= (SvLBoxEntry
*)(pView
->PrevVisible( pStartEntry
));
1855 pNew
= pTree
->NextSibling( pEntry
);
1857 pNew
= pTree
->PrevSibling( pEntry
);
1863 void SvImpLBox::EntryMoved( SvLBoxEntry
* pEntry
)
1865 // #97680# --------------
1866 UpdateContextBmpWidthVectorFromMovedEntry( pEntry
);
1869 // this might happen if the only entry in the view is moved to its very same position
1871 pStartEntry
= pView
->First();
1873 aVerSBar
.SetRange( Range(0, pView
->GetVisibleCount()-1));
1874 USHORT nFirstPos
= (USHORT
)pTree
->GetAbsPos( pStartEntry
);
1875 USHORT nNewPos
= (USHORT
)pTree
->GetAbsPos( pEntry
);
1877 if( nNewPos
< nFirstPos
) //!!!Notloesung
1878 pStartEntry
= pEntry
;
1879 // #97702# ---------------
1881 if( pEntry
== pCursor
)
1883 if( pView
->IsEntryVisible( pCursor
) )
1887 SvLBoxEntry
* pParent
= pEntry
;
1889 pParent
= pTree
->GetParent( pParent
);
1891 while( !pView
->IsEntryVisible( pParent
) );
1892 SetCursor( pParent
);
1895 if( IsEntryInView( pEntry
) )
1896 pView
->Invalidate();
1901 void SvImpLBox::EntryInserted( SvLBoxEntry
* pEntry
)
1903 if( GetUpdateMode() )
1905 SvLBoxEntry
* pParent
= (SvLBoxEntry
*)pTree
->GetParent(pEntry
);
1906 if( pParent
&& pTree
->GetChildList(pParent
)->Count() == 1 )
1907 // Pluszeichen zeichnen
1908 pTree
->InvalidateEntry( pParent
);
1910 if( !pView
->IsEntryVisible( pEntry
) )
1912 int bDeselAll
= nFlags
& F_DESEL_ALL
;
1914 SelAllDestrAnch( FALSE
, TRUE
);
1917 // nFlags &= (~F_DESEL_ALL);
1918 // ShowCursor( FALSE ); // falls sich Cursor nach unten verschiebt
1919 long nY
= GetEntryLine( pEntry
);
1920 BOOL bEntryVisible
= IsLineVisible( nY
);
1923 ShowCursor( FALSE
); // falls sich Cursor nach unten verschiebt
1924 nY
-= pView
->GetEntryHeight(); // wg. Linien
1925 InvalidateEntriesFrom( nY
);
1927 else if( pStartEntry
&& nY
< GetEntryLine(pStartEntry
) )
1929 // pruefen, ob die View komplett gefuellt ist. Wenn
1930 // nicht, dann pStartEntry und den Cursor anpassen
1931 // (automatisches scrollen)
1932 USHORT nLast
= (USHORT
)(pView
->GetVisiblePos( (SvLBoxEntry
*)(pView
->LastVisible())));
1933 USHORT nThumb
= (USHORT
)(pView
->GetVisiblePos( pStartEntry
));
1934 USHORT nCurDispEntries
= nLast
-nThumb
+1;
1935 if( nCurDispEntries
< nVisibleCount
)
1937 // beim naechsten Paint-Event setzen
1940 pView
->Invalidate();
1943 else if( !pStartEntry
)
1944 pView
->Invalidate();
1946 // die Linien invalidieren
1948 if( (bEntryVisible || bPrevEntryVisible) &&
1949 (nWinBits & ( WB_HASLINES | WB_HASLINESATROOT )) )
1951 SvLBoxTab* pTab = pView->GetFirstDynamicTab();
1954 long nDX = pView->GetTabPos( pEntry, pTab );
1956 Size aSize( nDX, nY );
1957 Rectangle aRect( aTmpPoint, aSize );
1958 pView->Invalidate( aRect );
1963 SetMostRight( pEntry
);
1964 aVerSBar
.SetRange( Range(0, pView
->GetVisibleCount()-1));
1965 SyncVerThumb(); // falls vor Thumb eingefuegt wurde
1968 if( pStartEntry
!= pView
->First() && (nFlags
& F_FILLING
) )
1975 // ********************************************************************
1977 // ********************************************************************
1980 // ****** Steuerung der Controlanimation
1982 BOOL
SvImpLBox::ButtonDownCheckCtrl(const MouseEvent
& rMEvt
, SvLBoxEntry
* pEntry
,
1985 SvLBoxItem
* pItem
= pView
->GetItem(pEntry
,rMEvt
.GetPosPixel().X(),&pActiveTab
);
1986 if( pItem
&& (pItem
->IsA()==SV_ITEM_ID_LBOXBUTTON
))
1988 pActiveButton
= (SvLBoxButton
*)pItem
;
1989 pActiveEntry
= pEntry
;
1990 if( pCursor
== pActiveEntry
)
1992 pView
->CaptureMouse();
1993 pActiveButton
->SetStateHilighted( TRUE
);
1994 pView
->PaintEntry1( pActiveEntry
, nY
,
1995 SV_LBOXTAB_PUSHABLE
| SV_LBOXTAB_ADJUST_CENTER
|
1996 SV_LBOXTAB_ADJUST_RIGHT
);
2004 BOOL
SvImpLBox::MouseMoveCheckCtrl( const MouseEvent
& rMEvt
, SvLBoxEntry
* pEntry
)
2009 long nMouseX
= rMEvt
.GetPosPixel().X();
2010 if( pEntry
== pActiveEntry
&&
2011 pView
->GetItem(pActiveEntry
, nMouseX
) == pActiveButton
)
2013 if( !pActiveButton
->IsStateHilighted() )
2015 pActiveButton
->SetStateHilighted(TRUE
);
2016 nY
= GetEntryLine( pActiveEntry
);
2017 pView
->PaintEntry1( pActiveEntry
, nY
,
2018 SV_LBOXTAB_PUSHABLE
| SV_LBOXTAB_ADJUST_CENTER
|
2019 SV_LBOXTAB_ADJUST_RIGHT
);
2024 if( pActiveButton
->IsStateHilighted() )
2026 pActiveButton
->SetStateHilighted(FALSE
);
2027 nY
= GetEntryLine( pActiveEntry
);
2028 pView
->PaintEntry1( pActiveEntry
, nY
, SV_LBOXTAB_PUSHABLE
);
2036 BOOL
SvImpLBox::ButtonUpCheckCtrl( const MouseEvent
& rMEvt
)
2040 pView
->ReleaseMouse();
2041 SvLBoxEntry
* pEntry
= GetClickedEntry( rMEvt
.GetPosPixel() );
2042 long nY
= GetEntryLine( pActiveEntry
);
2043 pActiveButton
->SetStateHilighted( FALSE
);
2044 long nMouseX
= rMEvt
.GetPosPixel().X();
2045 if( pEntry
== pActiveEntry
&&
2046 pView
->GetItem( pActiveEntry
, nMouseX
) == pActiveButton
)
2047 pActiveButton
->ClickHdl( pView
, pActiveEntry
);
2048 pView
->PaintEntry1( pActiveEntry
, nY
,
2049 SV_LBOXTAB_PUSHABLE
| SV_LBOXTAB_ADJUST_CENTER
|
2050 SV_LBOXTAB_ADJUST_RIGHT
);
2051 if( pCursor
== pActiveEntry
)
2061 // ******* Steuerung Plus/Minus-Button zum Expandieren/Kollabieren
2063 // FALSE == kein Expand/Collapse-Button getroffen
2064 BOOL
SvImpLBox::IsNodeButton( const Point
& rPosPixel
, SvLBoxEntry
* pEntry
) const
2066 if( !pEntry
->HasChilds() && !pEntry
->HasChildsOnDemand() )
2069 SvLBoxTab
* pFirstDynamicTab
= pView
->GetFirstDynamicTab();
2070 if( !pFirstDynamicTab
)
2073 long nMouseX
= rPosPixel
.X();
2074 // in Doc-Koords umrechnen
2075 Point
aOrigin( pView
->GetMapMode().GetOrigin() );
2076 nMouseX
-= aOrigin
.X();
2078 long nX
= pView
->GetTabPos( pEntry
, pFirstDynamicTab
);
2079 nX
+= nNodeBmpTabDistance
;
2082 nX
+= nNodeBmpWidth
;
2088 // FALSE == hit no node button
2089 BOOL
SvImpLBox::ButtonDownCheckExpand( const MouseEvent
& rMEvt
, SvLBoxEntry
* pEntry
, long /* nY */ )
2093 if ( pView
->IsEditingActive() && pEntry
== pView
->pEdEntry
)
2094 // inplace editing -> nothing to do
2096 else if ( IsNodeButton( rMEvt
.GetPosPixel(), pEntry
) )
2098 if ( pView
->IsExpanded( pEntry
) )
2100 pView
->EndEditing( TRUE
);
2101 pView
->Collapse( pEntry
);
2105 // you can expand an entry, which is in editing
2106 pView
->Expand( pEntry
);
2114 void SvImpLBox::MouseButtonDown( const MouseEvent
& rMEvt
)
2116 if ( !rMEvt
.IsLeft() && !rMEvt
.IsRight())
2120 // unter OS/2 kommt zwischen MouseButtonDown und
2121 // MouseButtonUp ein MouseMove
2122 nFlags
|= F_IGNORE_NEXT_MOUSEMOVE
;
2125 Point
aPos( rMEvt
.GetPosPixel());
2127 if( aPos
.X() > aOutputSize
.Width() || aPos
.Y() > aOutputSize
.Height() )
2130 SvLBoxEntry
* pEntry
= GetEntry( aPos
);
2131 if ( pEntry
!= pCursor
)
2132 // new entry selected -> reset current tab position to first tab
2133 nCurTabPos
= FIRST_ENTRY_TAB
;
2134 nFlags
&= (~F_FILLING
);
2136 // #120417# the entry can still be invalid!
2137 if( !pEntry
|| !pView
->GetViewData( pEntry
))
2140 long nY
= GetEntryLine( pEntry
);
2142 if( ButtonDownCheckExpand( rMEvt
, pEntry
, nY
) )
2145 if( !EntryReallyHit(pEntry
,aPos
,nY
))
2148 SvLBoxItem
* pXItem
= pView
->GetItem( pEntry
, aPos
.X() );
2151 SvLBoxTab
* pXTab
= pView
->GetTab( pEntry
, pXItem
);
2152 if ( !rMEvt
.IsMod1() && !rMEvt
.IsMod2() && rMEvt
.IsLeft() && pXTab
->IsEditable()
2153 && pEntry
== pView
->FirstSelected() && NULL
== pView
->NextSelected( pEntry
) )
2154 // #i8234# FirstSelected() and NextSelected() ensures, that inplace editing is only triggered, when only one entry is selected
2155 nFlags
|= F_START_EDITTIMER
;
2156 if ( !pView
->IsSelected( pEntry
) )
2157 nFlags
&= ~F_START_EDITTIMER
;
2161 if( (rMEvt
.GetClicks() % 2) == 0 )
2163 nFlags
&= (~F_START_EDITTIMER
);
2164 pView
->pHdlEntry
= pEntry
;
2165 if( pView
->DoubleClickHdl() )
2167 // falls im Handler der Eintrag geloescht wurde
2168 pEntry
= GetClickedEntry( aPos
);
2171 if( pEntry
!= pView
->pHdlEntry
)
2173 // neu selektieren & tschuess
2174 if( !bSimpleTravel
&& !aSelEng
.IsAlwaysAdding())
2175 SelAllDestrAnch( FALSE
, TRUE
); // DeselectAll();
2176 SetCursor( pEntry
);
2178 DBG_ERROR( "Please report what you did to get this assertion to FS!" );
2179 // The entry which has been double-clicked changed - and we select it, again.
2180 // I have situations where this behaviour does not make any sense at all - even more, it
2181 // leads to hacks to revert it's results.
2182 // So I'm not sure if this behaviour here is nonsense (which I believe at the moment),
2183 // or if there are really scenarious where it dones make sense ....
2184 // 07.12.2001 - 95727 - fs@openoffice.org
2188 if( pEntry
->HasChilds() || pEntry
->HasChildsOnDemand() )
2190 if( pView
->IsExpanded(pEntry
) )
2191 pView
->Collapse( pEntry
);
2193 pView
->Expand( pEntry
);
2194 if( pEntry
== pCursor
) // nur wenn Entryitem angeklickt wurde
2195 // (Nodebutton ist kein Entryitem!)
2196 pView
->Select( pCursor
, TRUE
);
2203 // CheckButton? (TreeListBox: Check + Info)
2204 if( ButtonDownCheckCtrl(rMEvt
, pEntry
, nY
) == TRUE
)
2208 if( rMEvt
.IsMod2() && pView
->IsInplaceEditingEnabled() )
2210 SvLBoxItem
* pItem
= pView
->GetItem( pEntry
, aPos
.X() );
2212 pView
->EditingRequest( pEntry
, pItem
, aPos
);
2217 if ( aSelEng
.GetSelectionMode() != NO_SELECTION
)
2218 aSelEng
.SelMouseButtonDown( rMEvt
);
2221 void SvImpLBox::MouseButtonUp( const MouseEvent
& rMEvt
)
2224 nFlags
&= (~F_IGNORE_NEXT_MOUSEMOVE
);
2226 if ( !ButtonUpCheckCtrl( rMEvt
) && ( aSelEng
.GetSelectionMode() != NO_SELECTION
) )
2227 aSelEng
.SelMouseButtonUp( rMEvt
);
2229 if( nFlags
& F_START_EDITTIMER
)
2231 nFlags
&= (~F_START_EDITTIMER
);
2232 aEditClickPos
= rMEvt
.GetPosPixel();
2239 void SvImpLBox::MouseMove( const MouseEvent
& rMEvt
)
2242 if( nFlags
& F_IGNORE_NEXT_MOUSEMOVE
)
2244 nFlags
&= (~F_IGNORE_NEXT_MOUSEMOVE
);
2248 SvLBoxEntry
* pEntry
= GetClickedEntry( rMEvt
.GetPosPixel() );
2249 if ( !MouseMoveCheckCtrl( rMEvt
, pEntry
) && ( aSelEng
.GetSelectionMode() != NO_SELECTION
) )
2250 aSelEng
.SelMouseMove( rMEvt
);
2254 BOOL
SvImpLBox::KeyInput( const KeyEvent
& rKEvt
)
2257 const KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
2259 if( rKeyCode
.IsMod2() )
2260 return FALSE
; // Alt-Taste nicht auswerten
2262 nFlags
&= (~F_FILLING
);
2265 pCursor
= pStartEntry
;
2269 BOOL bKeyUsed
= TRUE
;
2271 USHORT nDelta
= (USHORT
)aVerSBar
.GetPageSize();
2272 USHORT aCode
= rKeyCode
.GetCode();
2274 BOOL bShift
= rKeyCode
.IsShift();
2275 BOOL bMod1
= rKeyCode
.IsMod1();
2277 SvLBoxEntry
* pNewCursor
;
2282 if( !IsEntryInView( pCursor
) )
2283 MakeVisible( pCursor
);
2285 pNewCursor
= pCursor
;
2288 pNewCursor
= (SvLBoxEntry
*)(pView
->PrevVisible( pNewCursor
));
2289 } while( pNewCursor
&& !IsSelectable(pNewCursor
) );
2292 // new entry selected -> reset current tab position to first tab
2293 nCurTabPos
= FIRST_ENTRY_TAB
;
2294 // if there is no next entry, take the current one
2295 // this ensures that in case of _one_ entry in the list, this entry is selected when pressing
2297 // 06.09.20001 - 83416 - fs@openoffice.org
2298 if ( !pNewCursor
&& pCursor
)
2299 pNewCursor
= pCursor
;
2303 aSelEng
.CursorPosChanging( bShift
, bMod1
);
2304 SetCursor( pNewCursor
, bMod1
); // no selection, when Ctrl is on
2305 if( !IsEntryInView( pNewCursor
) )
2311 if( !IsEntryInView( pCursor
) )
2312 MakeVisible( pCursor
);
2314 pNewCursor
= pCursor
;
2317 pNewCursor
= (SvLBoxEntry
*)(pView
->NextVisible( pNewCursor
));
2318 } while( pNewCursor
&& !IsSelectable(pNewCursor
) );
2321 // new entry selected -> reset current tab position to first tab
2322 nCurTabPos
= FIRST_ENTRY_TAB
;
2324 // if there is no next entry, take the current one
2325 // this ensures that in case of _one_ entry in the list, this entry is selected when pressing
2327 // 06.09.20001 - 83416 - frank.schoenheit@sun.com
2328 if ( !pNewCursor
&& pCursor
)
2329 pNewCursor
= pCursor
;
2333 aSelEng
.CursorPosChanging( bShift
, bMod1
);
2334 if( IsEntryInView( pNewCursor
) )
2335 SetCursor( pNewCursor
, bMod1
); // no selection, when Ctrl is on
2339 pView
->Select( pCursor
, FALSE
);
2341 SetCursor( pNewCursor
, bMod1
); // no selection, when Ctrl is on
2345 KeyDown( FALSE
); // weil ScrollBar-Range evtl. noch
2351 if( bSubLstOpLR
&& IsNowExpandable() )
2352 pView
->Expand( pCursor
);
2353 else if ( bIsCellFocusEnabled
&& pCursor
)
2355 if ( nCurTabPos
< ( pView
->TabCount() - 1 /*!2*/ ) )
2359 CallEventListeners( VCLEVENT_LISTBOX_SELECT
, pCursor
);
2362 else if( pView
->nWindowStyle
& WB_HSCROLL
)
2364 long nThumb
= aHorSBar
.GetThumbPos();
2365 nThumb
+= aHorSBar
.GetLineSize();
2366 long nOldThumb
= aHorSBar
.GetThumbPos();
2367 aHorSBar
.SetThumbPos( nThumb
);
2369 nThumb
-= aHorSBar
.GetThumbPos();
2373 KeyLeftRight( nThumb
);
2384 if ( bIsCellFocusEnabled
)
2386 if ( nCurTabPos
> FIRST_ENTRY_TAB
)
2390 CallEventListeners( VCLEVENT_LISTBOX_SELECT
, pCursor
);
2393 else if ( pView
->nWindowStyle
& WB_HSCROLL
)
2395 long nThumb
= aHorSBar
.GetThumbPos();
2396 nThumb
-= aHorSBar
.GetLineSize();
2397 long nOldThumb
= aHorSBar
.GetThumbPos();
2398 aHorSBar
.SetThumbPos( nThumb
);
2400 nThumb
-= aHorSBar
.GetThumbPos();
2403 KeyLeftRight( -nThumb
);
2406 else if( bSubLstOpLR
)
2408 if( IsExpandable() && pView
->IsExpanded( pCursor
) )
2409 pView
->Collapse( pCursor
);
2412 pNewCursor
= pView
->GetParent( pCursor
);
2414 SetCursor( pNewCursor
);
2418 else if( bSubLstOpLR
&& IsExpandable() )
2419 pView
->Collapse( pCursor
);
2428 pNewCursor
= (SvLBoxEntry
*)(pView
->PrevVisible( pCursor
, nDelta
));
2430 while( nDelta
&& pNewCursor
&& !IsSelectable(pNewCursor
) )
2432 pNewCursor
= (SvLBoxEntry
*)(pView
->NextVisible( pNewCursor
));
2438 DBG_ASSERT(pNewCursor
&&(ULONG
)pNewCursor
!=(ULONG
)pCursor
,"Cursor?");
2439 aSelEng
.CursorPosChanging( bShift
, bMod1
);
2440 if( IsEntryInView( pNewCursor
) )
2441 SetCursor( pNewCursor
);
2444 SetCursor( pNewCursor
);
2456 pNewCursor
= (SvLBoxEntry
*)(pView
->NextVisible( pCursor
, nDelta
));
2458 while( nDelta
&& pNewCursor
&& !IsSelectable(pNewCursor
) )
2460 pNewCursor
= (SvLBoxEntry
*)(pView
->PrevVisible( pNewCursor
));
2466 DBG_ASSERT(pNewCursor
&&(ULONG
)pNewCursor
!=(ULONG
)pCursor
,"Cursor?");
2467 aSelEng
.CursorPosChanging( bShift
, bMod1
);
2468 if( IsEntryInView( pNewCursor
) )
2469 SetCursor( pNewCursor
);
2472 SetCursor( pNewCursor
);
2477 KeyDown( FALSE
); // siehe KEY_DOWN
2484 if ( pView
->GetSelectionMode() != NO_SELECTION
)
2488 if ( pView
->GetSelectionMode() == MULTIPLE_SELECTION
&& !bShift
)
2490 pView
->Select( pCursor
, !pView
->IsSelected( pCursor
) );
2492 else if ( !bShift
/*&& !bMod1*/ )
2494 if ( aSelEng
.IsAddMode() )
2496 pView
->Select( pCursor
, !pView
->IsSelected( pCursor
) );
2499 SelAllDestrAnch( FALSE
);
2500 pView
->Select( pCursor
, TRUE
);
2511 if( bSubLstOpRet
&& IsExpandable() )
2513 if( pView
->IsExpanded( pCursor
) )
2514 pView
->Collapse( pCursor
);
2516 pView
->Expand( pCursor
);
2523 if( !bShift
&& !bMod1
)
2525 aEditClickPos
= Point( -1, -1 );
2533 if( bShift
&& pView
->GetSelectionMode()==MULTIPLE_SELECTION
&&
2534 !(nWinBits
& WB_SIMPLEMODE
))
2536 if( aSelEng
.IsAlwaysAdding() )
2537 aSelEng
.AddAlways( FALSE
);
2539 aSelEng
.AddAlways( TRUE
);
2548 MakeVisible( pCursor
);
2551 pView
->RemoveSelection();
2554 pView
->RemoveEntry( pCursor
);
2561 if( !pView
->IsExpanded(pCursor
))
2562 pView
->Expand( pCursor
);
2565 USHORT nRefDepth
= pTree
->GetDepth( pCursor
);
2566 SvLBoxEntry
* pCur
= pTree
->Next( pCursor
);
2567 while( pCur
&& pTree
->GetDepth(pCur
) > nRefDepth
)
2569 if( pCur
->HasChilds() && !pView
->IsExpanded(pCur
))
2570 pView
->Expand( pCur
);
2571 pCur
= pTree
->Next( pCur
);
2581 SelAllDestrAnch( TRUE
);
2583 // bKeyUsed = FALSE; #105907# assume user wants to use quicksearch with key "a", so key is handled!
2589 if( pView
->IsExpanded(pCursor
))
2590 pView
->Collapse( pCursor
);
2593 // bis zur Root alle Parents einklappen
2594 SvLBoxEntry
* pParentToCollapse
= (SvLBoxEntry
*)pTree
->GetRootLevelParent(pCursor
);
2595 if( pParentToCollapse
)
2598 // Sonderbehandlung Explorer: Befindet sich auf der
2599 // Root nur ein Eintrag,dann den Root-Entry nicht
2601 if( pTree
->GetChildList(0)->Count() < 2 )
2604 pParentToCollapse
= pCursor
;
2605 while( pTree
->GetParent(pParentToCollapse
) &&
2606 pTree
->GetDepth( pTree
->GetParent(pParentToCollapse
)) > 0)
2608 pParentToCollapse
= pTree
->GetParent(pParentToCollapse
);
2614 if( pView
->IsExpanded(pParentToCollapse
) )
2615 pView
->Collapse( pParentToCollapse
);
2616 SvLBoxEntry
* pCur
= pTree
->Next( pParentToCollapse
);
2617 while( pCur
&& pTree
->GetDepth(pCur
) > nRefDepth
)
2619 if( pCur
->HasChilds() && pView
->IsExpanded(pCur
) )
2620 pView
->Collapse( pCur
);
2621 pCur
= pTree
->Next( pCur
);
2632 SelAllDestrAnch( TRUE
);
2639 SelAllDestrAnch( FALSE
);
2645 pNewCursor
= pView
->GetModel()->First();
2647 while( pNewCursor
&& !IsSelectable(pNewCursor
) )
2649 pNewCursor
= (SvLBoxEntry
*)(pView
->NextVisible( pNewCursor
));
2652 if( pNewCursor
&& pNewCursor
!= pCursor
)
2654 // SelAllDestrAnch( FALSE );
2655 aSelEng
.CursorPosChanging( bShift
, bMod1
);
2656 SetCursor( pNewCursor
);
2657 if( !IsEntryInView( pNewCursor
) )
2658 MakeVisible( pNewCursor
);
2665 pNewCursor
= pView
->GetModel()->Last();
2667 while( pNewCursor
&& !IsSelectable(pNewCursor
) )
2669 pNewCursor
= (SvLBoxEntry
*)(pView
->PrevVisible( pNewCursor
));
2672 if( pNewCursor
&& pNewCursor
!= pCursor
)
2674 // SelAllDestrAnch( FALSE );
2675 aSelEng
.CursorPosChanging( bShift
, bMod1
);
2676 SetCursor( pNewCursor
);
2677 if( !IsEntryInView( pNewCursor
) )
2678 MakeVisible( pNewCursor
);
2688 // #105907# must not be handled because this quits dialogs and does other magic things...
2689 // if there are other single keys which should not be handled, they can be added here
2694 if( bMod1
|| rKeyCode
.GetGroup() == KEYGROUP_FKEYS
)
2695 // #105907# CTRL or Function key is pressed, assume user don't want to use quicksearch...
2696 // if there are groups of keys which should not be handled, they can be added here
2702 void __EXPORT
SvImpLBox::GetFocus()
2706 pView
->SetEntryFocus( pCursor
, TRUE
);
2708 // auskommentiert wg. deselectall
2709 // if( bSimpleTravel && !pView->IsSelected(pCursor) )
2710 // pView->Select( pCursor, TRUE );
2712 if( nWinBits
& WB_HIDESELECTION
)
2714 SvLBoxEntry
* pEntry
= pView
->FirstSelected();
2717 InvalidateEntry( pEntry
);
2718 pEntry
= pView
->NextSelected( pEntry
);
2721 SvLBoxEntry* pEntry = pView->GetModel()->First();
2724 SvViewData* pViewData = pView->GetViewData( pEntry );
2725 if( pViewData->IsCursored() )
2727 pViewData->SetCursored( FALSE );
2728 InvalidateEntry( pEntry );
2730 pEntry = pView->GetModel()->Next( pEntry );
2738 void __EXPORT
SvImpLBox::LoseFocus()
2742 pView
->SetEntryFocus( pCursor
,FALSE
);
2743 ShowCursor( FALSE
);
2745 if( nWinBits
& WB_HIDESELECTION
)
2747 SvLBoxEntry
* pEntry
= pView
->FirstSelected();
2750 //SvViewData* pViewData = pView->GetViewData( pEntry );
2751 //pViewData->SetCursored( TRUE );
2752 InvalidateEntry( pEntry
);
2753 pEntry
= pView
->NextSelected( pEntry
);
2759 // ********************************************************************
2761 // ********************************************************************
2763 inline void SvImpLBox::SelectEntry( SvLBoxEntry
* pEntry
, BOOL bSelect
)
2765 pView
->Select( pEntry
, bSelect
);
2768 __EXPORT
ImpLBSelEng::ImpLBSelEng( SvImpLBox
* pImpl
, SelectionEngine
* pSEng
,
2776 __EXPORT
ImpLBSelEng::~ImpLBSelEng()
2780 void __EXPORT
ImpLBSelEng::BeginDrag()
2786 void __EXPORT ImpLBSelEng::EndDrag( const Point& )
2791 void __EXPORT
ImpLBSelEng::CreateAnchor()
2793 pImp
->pAnchor
= pImp
->pCursor
;
2796 void __EXPORT
ImpLBSelEng::DestroyAnchor()
2802 void __EXPORT ImpLBSelEng::CreateCursor()
2809 BOOL __EXPORT
ImpLBSelEng::SetCursorAtPoint(const Point
& rPoint
, BOOL bDontSelectAtCursor
)
2811 SvLBoxEntry
* pNewCursor
= pImp
->MakePointVisible( rPoint
);
2812 if( pNewCursor
!= pImp
->pCursor
)
2813 pImp
->BeginScroll();
2817 // bei SimpleTravel wird in SetCursor selektiert und
2818 // der Select-Handler gerufen
2819 //if( !bDontSelectAtCursor && !pImp->bSimpleTravel )
2820 // pImp->SelectEntry( pNewCursor, TRUE );
2821 pImp
->SetCursor( pNewCursor
, bDontSelectAtCursor
);
2827 BOOL __EXPORT
ImpLBSelEng::IsSelectionAtPoint( const Point
& rPoint
)
2829 SvLBoxEntry
* pEntry
= pImp
->MakePointVisible( rPoint
);
2831 return pView
->IsSelected(pEntry
);
2835 void __EXPORT
ImpLBSelEng::DeselectAtPoint( const Point
& rPoint
)
2837 SvLBoxEntry
* pEntry
= pImp
->MakePointVisible( rPoint
);
2840 pImp
->SelectEntry( pEntry
, FALSE
);
2844 void __EXPORT ImpLBSelEng::SelectAtPoint( const Point& rPoint )
2846 SvLBoxEntry* pEntry = pImp->MakePointVisible( rPoint );
2849 pImp->SelectEntry( pEntry, TRUE );
2853 void __EXPORT
ImpLBSelEng::DeselectAll()
2855 pImp
->SelAllDestrAnch( FALSE
, FALSE
); // SelectionEngine nicht resetten!
2856 pImp
->nFlags
&= (~F_DESEL_ALL
);
2859 // ***********************************************************************
2861 // ***********************************************************************
2863 void SvImpLBox::SetAnchorSelection(SvLBoxEntry
* pOldCursor
,SvLBoxEntry
* pNewCursor
)
2865 SvLBoxEntry
* pEntry
;
2866 ULONG nAnchorVisPos
= pView
->GetVisiblePos( pAnchor
);
2867 ULONG nOldVisPos
= pView
->GetVisiblePos( pOldCursor
);
2868 ULONG nNewVisPos
= pView
->GetVisiblePos( pNewCursor
);
2870 if( nOldVisPos
> nAnchorVisPos
||
2871 ( nAnchorVisPos
==nOldVisPos
&& nNewVisPos
> nAnchorVisPos
) )
2873 if( nNewVisPos
> nOldVisPos
)
2875 pEntry
= pOldCursor
;
2876 while( pEntry
&& pEntry
!= pNewCursor
)
2878 pView
->Select( pEntry
, TRUE
);
2879 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
2882 pView
->Select( pEntry
, TRUE
);
2886 if( nNewVisPos
< nAnchorVisPos
)
2889 while( pEntry
&& pEntry
!= pOldCursor
)
2891 pView
->Select( pEntry
, FALSE
);
2892 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
2895 pView
->Select( pEntry
, FALSE
);
2897 pEntry
= pNewCursor
;
2898 while( pEntry
&& pEntry
!= pAnchor
)
2900 pView
->Select( pEntry
, TRUE
);
2901 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
2904 pView
->Select( pEntry
, TRUE
);
2908 if( nNewVisPos
< nOldVisPos
)
2910 pEntry
= pNewCursor
;
2911 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
2912 while( pEntry
&& pEntry
!= pOldCursor
)
2914 pView
->Select( pEntry
, FALSE
);
2915 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
2918 pView
->Select( pEntry
, FALSE
);
2924 if( nNewVisPos
< nOldVisPos
) // Vergroessern der Selektion
2926 pEntry
= pNewCursor
;
2927 while( pEntry
&& pEntry
!= pOldCursor
)
2929 pView
->Select( pEntry
, TRUE
);
2930 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
2933 pView
->Select( pEntry
, TRUE
);
2937 if( nNewVisPos
> nAnchorVisPos
)
2939 pEntry
= pOldCursor
;
2940 while( pEntry
&& pEntry
!= pAnchor
)
2942 pView
->Select( pEntry
, FALSE
);
2943 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
2946 pView
->Select( pEntry
, FALSE
);
2948 while( pEntry
&& pEntry
!= pNewCursor
)
2950 pView
->Select( pEntry
, TRUE
);
2951 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
2954 pView
->Select( pEntry
, TRUE
);
2958 if( nNewVisPos
> nOldVisPos
)
2960 pEntry
= pOldCursor
;
2961 while( pEntry
&& pEntry
!= pNewCursor
)
2963 pView
->Select( pEntry
, FALSE
);
2964 pEntry
= (SvLBoxEntry
*)(pView
->NextVisible( pEntry
));
2971 void SvImpLBox::SelAllDestrAnch( BOOL bSelect
, BOOL bDestroyAnchor
,
2972 BOOL bSingleSelToo
)
2974 SvLBoxEntry
* pEntry
;
2975 nFlags
&= (~F_DESEL_ALL
);
2976 if( bSelect
&& bSimpleTravel
)
2978 if( pCursor
&& !pView
->IsSelected( pCursor
))
2980 pView
->Select( pCursor
, TRUE
);
2984 if( !bSelect
&& pView
->GetSelectionCount() == 0 )
2986 if( bSimpleTravel
&& ( !GetUpdateMode() || !pCursor
) )
2987 nFlags
|= F_DESEL_ALL
;
2990 if( bSelect
&& pView
->GetSelectionCount() == pView
->GetEntryCount())
2992 if( !bSingleSelToo
&& bSimpleTravel
)
2995 if( !bSelect
&& pView
->GetSelectionCount()==1 && pCursor
&&
2996 pView
->IsSelected( pCursor
))
2998 pView
->Select( pCursor
, FALSE
);
2999 if( bDestroyAnchor
)
3000 DestroyAnchor(); // Anker loeschen & SelectionEngine zuruecksetzen
3002 pAnchor
= 0; // internen Anker immer loeschen
3006 if( bSimpleTravel
&& !pCursor
&& !GetUpdateMode() )
3007 nFlags
|= F_DESEL_ALL
;
3009 ShowCursor( FALSE
);
3010 BOOL bUpdate
= GetUpdateMode();
3012 nFlags
|= F_IGNORE_SELECT
; // EntryInserted soll nix tun
3013 pEntry
= pTree
->First();
3016 if( pView
->Select( pEntry
, bSelect
) )
3018 if( bUpdate
&& pView
->IsEntryVisible(pEntry
) )
3020 long nY
= GetEntryLine( pEntry
);
3021 if( IsLineVisible( nY
) )
3022 pView
->PaintEntry1( pEntry
, nY
, 0xffff ); // wg. ItemsetBrowser SV_LBOXTAB_SHOW_SELECTION );
3025 pEntry
= pTree
->Next( pEntry
);
3027 nFlags
&= ~F_IGNORE_SELECT
;
3029 if( bDestroyAnchor
)
3030 DestroyAnchor(); // Anker loeschen & SelectionEngine zuruecksetzen
3032 pAnchor
= 0; // internen Anker immer loeschen
3036 void SvImpLBox::SetSelectionMode( SelectionMode eSelMode
)
3038 aSelEng
.SetSelectionMode( eSelMode
);
3039 if( eSelMode
== SINGLE_SELECTION
)
3040 bSimpleTravel
= TRUE
;
3042 bSimpleTravel
= FALSE
;
3043 if( (nWinBits
& WB_SIMPLEMODE
) && (eSelMode
== MULTIPLE_SELECTION
) )
3044 aSelEng
.AddAlways( TRUE
);
3047 // ***********************************************************************
3049 // ***********************************************************************
3051 void SvImpLBox::SetDragDropMode( DragDropMode eDDMode
)
3053 if( eDDMode
&& eDDMode
!= SV_DRAGDROP_APP_DROP
)
3055 aSelEng
.ExpandSelectionOnMouseMove( FALSE
);
3056 aSelEng
.EnableDrag( TRUE
);
3060 aSelEng
.ExpandSelectionOnMouseMove( TRUE
);
3061 aSelEng
.EnableDrag( FALSE
);
3065 void SvImpLBox::BeginDrag()
3067 nFlags
&= (~F_FILLING
);
3068 if( !bAsyncBeginDrag
)
3071 pView
->StartDrag( 0, aSelEng
.GetMousePosPixel() );
3076 aAsyncBeginDragPos
= aSelEng
.GetMousePosPixel();
3077 aAsyncBeginDragTimer
.Start();
3081 IMPL_LINK( SvImpLBox
, BeginDragHdl
, void*, EMPTYARG
)
3083 pView
->StartDrag( 0, aAsyncBeginDragPos
);
3087 void SvImpLBox::PaintDDCursor( SvLBoxEntry
* pInsertionPos
)
3092 nY
= GetEntryLine( pInsertionPos
);
3093 nY
+= pView
->GetEntryHeight();
3097 RasterOp eOldOp
= pView
->GetRasterOp();
3098 pView
->SetRasterOp( ROP_INVERT
);
3099 Color aOldLineColor
= pView
->GetLineColor();
3100 pView
->SetLineColor( Color( COL_BLACK
) );
3101 pView
->DrawLine( Point( 0, nY
), Point( aOutputSize
.Width(), nY
) );
3102 pView
->SetLineColor( aOldLineColor
);
3103 pView
->SetRasterOp( eOldOp
);
3105 /* -----------------26.08.2003 12:52-----------------
3106 Delete all sub menues of a PopupMenu, recursively
3107 --------------------------------------------------*/
3108 void lcl_DeleteSubPopups(PopupMenu
* pPopup
)
3110 for(USHORT i
= 0; i
< pPopup
->GetItemCount(); i
++)
3112 PopupMenu
* pSubPopup
= pPopup
->GetPopupMenu( pPopup
->GetItemId( i
));
3115 lcl_DeleteSubPopups(pSubPopup
);
3121 void SvImpLBox::Command( const CommandEvent
& rCEvt
)
3123 USHORT nCommand
= rCEvt
.GetCommand();
3125 if( nCommand
== COMMAND_CONTEXTMENU
)
3129 if( ( ( nCommand
== COMMAND_WHEEL
) || ( nCommand
== COMMAND_STARTAUTOSCROLL
) || ( nCommand
== COMMAND_AUTOSCROLL
) )
3130 && pView
->HandleScrollCommand( rCEvt
, &aHorSBar
, &aVerSBar
) )
3133 if( bContextMenuHandling
&& nCommand
== COMMAND_CONTEXTMENU
)
3136 BOOL bClickedIsFreePlace
= FALSE
;
3137 std::stack
<SvLBoxEntry
*> aSelRestore
;
3139 if( rCEvt
.IsMouseEvent() )
3140 { // change selection, if mouse pos doesn't fit to selection
3142 aPopupPos
= rCEvt
.GetMousePosPixel();
3144 SvLBoxEntry
* pClickedEntry
= GetEntry( aPopupPos
);
3146 { // mouse in non empty area
3147 BOOL bClickedIsSelected
= FALSE
;
3149 // collect the currently selected entries
3150 SvLBoxEntry
* pSelected
= pView
->FirstSelected();
3153 bClickedIsSelected
|= ( pClickedEntry
== pSelected
);
3154 pSelected
= pView
->NextSelected( pSelected
);
3157 // if the entry which the user clicked at is not selected
3158 if( !bClickedIsSelected
)
3159 { // deselect all other and select the clicked one
3160 pView
->SelectAll( FALSE
);
3161 pView
->SetCursor( pClickedEntry
);
3164 else if( aSelEng
.GetSelectionMode() == SINGLE_SELECTION
)
3165 {//modified by BerryJia for fixing Bug102739 2002-9-9 17:00(Beijing Time)
3166 bClickedIsFreePlace
= TRUE
;
3167 INT32 nSelectedEntries
= pView
->GetSelectionCount();
3168 SvLBoxEntry
* pSelected
= pView
->FirstSelected();
3169 for(USHORT nSel
= 0; nSel
< nSelectedEntries
; nSel
++ )
3171 aSelRestore
.push(pSelected
);
3172 pSelected
= pView
->NextSelected( pSelected
);
3174 pView
->SelectAll( FALSE
);
3178 pView
->SelectAll( FALSE
);
3184 { // key event (or at least no mouse event)
3185 INT32 nSelectionCount
= pView
->GetSelectionCount();
3187 if( nSelectionCount
)
3188 { // now allways take first visible as base for positioning the menu
3189 SvLBoxEntry
* pSelected
= pView
->FirstSelected();
3192 if( IsEntryInView( pSelected
) )
3195 pSelected
= pView
->NextSelected( pSelected
);
3200 // no one was visible
3201 pSelected
= pView
->FirstSelected();
3202 pView
->MakeVisible( pSelected
);
3205 aPopupPos
= pView
->GetFocusRect( pSelected
, pView
->GetEntryPosition( pSelected
).Y() ).Center();
3208 aPopupPos
= Point( 0, 0 );
3211 PopupMenu
* pPopup
= pView
->CreateContextMenu();
3215 // do action for selected entry in popup menu
3216 USHORT nMenuAction
= pPopup
->Execute( pView
, aPopupPos
);
3218 pView
->ExcecuteContextMenuAction( nMenuAction
);
3219 lcl_DeleteSubPopups(pPopup
);
3222 //added by BerryJia for fixing Bug102739 2002-9-9 17:00(Beijing Time)
3223 if( bClickedIsFreePlace
)
3225 while(!aSelRestore
.empty())
3227 SvLBoxEntry
* pEntry
= aSelRestore
.top();
3228 //#i19717# the entry is maybe already deleted
3229 bool bFound
= false;
3230 for(ULONG nEntry
= 0; nEntry
< pView
->GetEntryCount(); nEntry
++)
3231 if(pEntry
== pView
->GetEntry(nEntry
))
3237 SetCurEntry( pEntry
);
3245 const Point
& rPos
= rCEvt
.GetMousePosPixel();
3246 if( rPos
.X() < aOutputSize
.Width() && rPos
.Y() < aOutputSize
.Height() )
3247 aSelEng
.Command( rCEvt
);
3252 void SvImpLBox::BeginScroll()
3254 if( !(nFlags
& F_IN_SCROLLING
))
3256 pView
->NotifyBeginScroll();
3257 nFlags
|= F_IN_SCROLLING
;
3261 void SvImpLBox::EndScroll()
3263 if( nFlags
& F_IN_SCROLLING
)
3265 pView
->NotifyEndScroll();
3266 nFlags
&= (~F_IN_SCROLLING
);
3271 Rectangle
SvImpLBox::GetVisibleArea() const
3273 Point
aPos( pView
->GetMapMode().GetOrigin() );
3275 Rectangle
aRect( aPos
, aOutputSize
);
3279 void SvImpLBox::Invalidate()
3281 pView
->SetClipRegion();
3284 void SvImpLBox::SetCurEntry( SvLBoxEntry
* pEntry
)
3286 if ( ( aSelEng
.GetSelectionMode() != SINGLE_SELECTION
)
3287 && ( aSelEng
.GetSelectionMode() != NO_SELECTION
)
3289 SelAllDestrAnch( FALSE
, TRUE
, FALSE
);
3291 MakeVisible( pEntry
);
3292 SetCursor( pEntry
);
3293 if ( pEntry
&& ( aSelEng
.GetSelectionMode() != NO_SELECTION
) )
3294 pView
->Select( pEntry
, TRUE
);
3297 IMPL_LINK( SvImpLBox
, EditTimerCall
, Timer
*, EMPTYARG
)
3299 if( pView
->IsInplaceEditingEnabled() )
3301 sal_Bool bIsMouseTriggered
= aEditClickPos
.X() >= 0;
3302 if ( bIsMouseTriggered
)
3304 Point aCurrentMousePos
= pView
->GetPointerPosPixel();
3305 if ( ( abs( aCurrentMousePos
.X() - aEditClickPos
.X() ) > 5 )
3306 || ( abs( aCurrentMousePos
.Y() - aEditClickPos
.Y() ) > 5 )
3313 SvLBoxEntry
* pEntry
= GetCurEntry();
3316 ShowCursor( FALSE
);
3317 pView
->ImplEditEntry( pEntry
);
3324 BOOL
SvImpLBox::RequestHelp( const HelpEvent
& rHEvt
)
3326 if( rHEvt
.GetMode() & HELPMODE_QUICK
)
3328 Point
aPos( pView
->ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ));
3329 if( !GetVisibleArea().IsInside( aPos
))
3332 SvLBoxEntry
* pEntry
= GetEntry( aPos
);
3335 // Rechteck des Textes berechnen
3337 SvLBoxString
* pItem
= (SvLBoxString
*)(pView
->GetItem( pEntry
, aPos
.X(), &pTab
));
3338 if( !pItem
|| pItem
->IsA() != SV_ITEM_ID_LBOXSTRING
)
3341 aPos
= GetEntryPosition( pEntry
);
3342 aPos
.X() = pView
->GetTabPos( pEntry
, pTab
); //pTab->GetPos();
3343 Size
aSize( pItem
->GetSize( pView
, pEntry
) );
3344 SvLBoxTab
* pNextTab
= NextTab( pTab
);
3345 BOOL bItemClipped
= FALSE
;
3346 // wurde das Item von seinem rechten Nachbarn abgeschnitten?
3347 if( pNextTab
&& pView
->GetTabPos(pEntry
,pNextTab
) < aPos
.X()+aSize
.Width() )
3349 aSize
.Width() = pNextTab
->GetPos() - pTab
->GetPos();
3350 bItemClipped
= TRUE
;
3352 Rectangle
aItemRect( aPos
, aSize
);
3354 Rectangle
aViewRect( GetVisibleArea() );
3356 if( bItemClipped
|| !aViewRect
.IsInside( aItemRect
) )
3358 // rechten Item-Rand am View-Rand clippen
3359 //if( aItemRect.Right() > aViewRect.Right() )
3360 // aItemRect.Right() = aViewRect.Right();
3362 Point aPt
= pView
->OutputToScreenPixel( aItemRect
.TopLeft() );
3363 aItemRect
.Left() = aPt
.X();
3364 aItemRect
.Top() = aPt
.Y();
3365 aPt
= pView
->OutputToScreenPixel( aItemRect
.BottomRight() );
3366 aItemRect
.Right() = aPt
.X();
3367 aItemRect
.Bottom() = aPt
.Y();
3369 Help::ShowQuickHelp( pView
, aItemRect
,
3370 pItem
->GetText(), QUICKHELP_LEFT
| QUICKHELP_VCENTER
);
3378 SvLBoxTab
* SvImpLBox::NextTab( SvLBoxTab
* pTab
)
3380 USHORT nTabCount
= pView
->TabCount();
3381 if( nTabCount
<= 1 )
3383 for( USHORT nTab
=0; nTab
< (nTabCount
-1); nTab
++)
3385 if( pView
->aTabs
[nTab
]==pTab
)
3386 return (SvLBoxTab
*)(pView
->aTabs
[nTab
+1]);
3391 void SvImpLBox::EndSelection()
3394 nFlags
&= ~F_START_EDITTIMER
;
3397 void SvImpLBox::RepaintScrollBars()
3401 void SvImpLBox::SetUpdateMode( BOOL bMode
)
3403 if( bUpdateMode
!= bMode
)
3405 bUpdateMode
= bMode
;
3411 void SvImpLBox::SetUpdateModeFast( BOOL bMode
)
3413 if( bUpdateMode
!= bMode
)
3415 bUpdateMode
= bMode
;
3417 UpdateAll( FALSE
, FALSE
);
3422 BOOL
SvImpLBox::SetMostRight( SvLBoxEntry
* pEntry
)
3424 if( pView
->nTreeFlags
& TREEFLAG_RECALCTABS
)
3426 nFlags
|= F_IGNORE_CHANGED_TABS
;
3428 nFlags
&= ~F_IGNORE_CHANGED_TABS
;
3431 USHORT nLastTab
= pView
->aTabs
.Count() - 1;
3432 USHORT nLastItem
= pEntry
->ItemCount() - 1;
3433 if( nLastTab
!= USHRT_MAX
&& nLastItem
!= USHRT_MAX
)
3435 if( nLastItem
< nLastTab
)
3436 nLastTab
= nLastItem
;
3438 SvLBoxTab
* pTab
= (SvLBoxTab
*)pView
->aTabs
[ nLastTab
];
3439 SvLBoxItem
* pItem
= pEntry
->GetItem( nLastTab
);
3441 long nTabPos
= pView
->GetTabPos( pEntry
, pTab
);
3443 long nMaxRight
= GetOutputSize().Width();
3444 Point
aPos( pView
->GetMapMode().GetOrigin() );
3445 aPos
.X() *= -1; // Umrechnung Dokumentkoord.
3446 nMaxRight
= nMaxRight
+ aPos
.X() - 1;
3448 long nNextTab
= nTabPos
< nMaxRight
? nMaxRight
: nMaxRight
+ 50;
3449 long nTabWidth
= nNextTab
- nTabPos
+ 1;
3450 long nItemSize
= pItem
->GetSize(pView
,pEntry
).Width();
3451 long nOffset
= pTab
->CalcOffset( nItemSize
, nTabWidth
);
3453 long nRight
= nTabPos
+ nOffset
+ nItemSize
;
3454 if( nRight
> nMostRight
)
3456 nMostRight
= nRight
;
3457 pMostRightEntry
= pEntry
;
3464 void SvImpLBox::FindMostRight( SvLBoxEntry
* pEntryToIgnore
)
3467 pMostRightEntry
= 0;
3468 if( !pView
->GetModel() )
3471 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)pView
->FirstVisible();
3474 if( pEntry
!= pEntryToIgnore
)
3475 SetMostRight( pEntry
);
3476 pEntry
= (SvLBoxEntry
*)pView
->NextVisible( pEntry
);
3480 void SvImpLBox::FindMostRight( SvLBoxEntry
* pParent
, SvLBoxEntry
* pEntryToIgnore
)
3483 FindMostRight( pEntryToIgnore
);
3485 FindMostRight_Impl( pParent
, pEntryToIgnore
);
3488 void SvImpLBox::FindMostRight_Impl( SvLBoxEntry
* pParent
, SvLBoxEntry
* pEntryToIgnore
)
3490 SvTreeEntryList
* pList
= pTree
->GetChildList( pParent
);
3495 ULONG nCount
= pList
->Count();
3496 for( ULONG nCur
= 0; nCur
< nCount
; nCur
++ )
3498 SvLBoxEntry
* pChild
= (SvLBoxEntry
*)pList
->GetObject( nCur
);
3499 if( pChild
!= pEntryToIgnore
)
3501 SetMostRight( pChild
);
3502 if( pChild
->HasChilds() && pView
->IsExpanded( pChild
))
3503 FindMostRight_Impl( pChild
, pEntryToIgnore
);
3508 void SvImpLBox::NotifyTabsChanged()
3510 if( GetUpdateMode() && !(nFlags
& F_IGNORE_CHANGED_TABS
) &&
3511 nCurUserEvent
== 0xffffffff )
3513 nCurUserEvent
= Application::PostUserEvent(LINK(this,SvImpLBox
,MyUserEvent
),(void*)0);
3517 IMPL_LINK(SvImpLBox
,MyUserEvent
,void*, pArg
)
3519 nCurUserEvent
= 0xffffffff;
3522 pView
->Invalidate();
3529 pView
->Invalidate( GetVisibleArea() );
3535 void SvImpLBox::StopUserEvent()
3537 if( nCurUserEvent
!= 0xffffffff )
3539 Application::RemoveUserEvent( nCurUserEvent
);
3540 nCurUserEvent
= 0xffffffff;
3544 void SvImpLBox::ShowFocusRect( const SvLBoxEntry
* pEntry
)
3548 long nY
= GetEntryLine( (SvLBoxEntry
*)pEntry
);
3549 Rectangle aRect
= pView
->GetFocusRect( (SvLBoxEntry
*)pEntry
, nY
);
3550 Region
aOldClip( pView
->GetClipRegion());
3551 Region
aClipRegion( GetClipRegionRect() );
3552 pView
->SetClipRegion( aClipRegion
);
3553 pView
->ShowFocus( aRect
);
3554 pView
->SetClipRegion( aOldClip
);
3563 void SvImpLBox::SetTabBar( TabBar
* _pTabBar
)
3568 void SvImpLBox::CancelPendingEdit()
3570 if( aEditTimer
.IsActive() )
3572 nFlags
&= ~F_START_EDITTIMER
;
3575 // -----------------------------------------------------------------------
3576 void SvImpLBox::implInitDefaultNodeImages()
3578 if ( s_pDefCollapsed
)
3579 // assume that all or nothing is initialized
3582 s_pDefCollapsed
= new Image( SvtResId( RID_IMG_TREENODE_COLLAPSED
) );
3583 s_pDefCollapsedHC
= new Image( SvtResId( RID_IMG_TREENODE_COLLAPSED_HC
) );
3584 s_pDefExpanded
= new Image( SvtResId( RID_IMG_TREENODE_EXPANDED
) );
3585 s_pDefExpandedHC
= new Image( SvtResId( RID_IMG_TREENODE_EXPANDED_HC
) );
3588 // -----------------------------------------------------------------------
3589 const Image
& SvImpLBox::GetDefaultExpandedNodeImage( BmpColorMode _eMode
)
3591 implInitDefaultNodeImages();
3592 return ( BMP_COLOR_NORMAL
== _eMode
) ? *s_pDefExpanded
: *s_pDefExpandedHC
;
3595 // -----------------------------------------------------------------------
3596 const Image
& SvImpLBox::GetDefaultCollapsedNodeImage( BmpColorMode _eMode
)
3598 implInitDefaultNodeImages();
3599 return ( BMP_COLOR_NORMAL
== _eMode
) ? *s_pDefCollapsed
: *s_pDefCollapsedHC
;
3602 // -----------------------------------------------------------------------
3603 void SvImpLBox::CallEventListeners( ULONG nEvent
, void* pData
)
3606 pView
->CallImplEventListeners( nEvent
, pData
);
3609 // -----------------------------------------------------------------------
3611 bool SvImpLBox::SetCurrentTabPos( USHORT _nNewPos
)
3615 if ( pView
&& _nNewPos
< ( pView
->TabCount() - 2 ) )
3617 nCurTabPos
= _nNewPos
;
3625 // -----------------------------------------------------------------------
3627 bool SvImpLBox::IsSelectable( const SvLBoxEntry
* pEntry
)
3631 SvViewDataEntry
* pViewDataNewCur
= pView
->GetViewDataEntry(const_cast<SvLBoxEntry
*>(pEntry
));
3632 return (pViewDataNewCur
== 0) || pViewDataNewCur
->IsSelectable();