xref: /AOO41X/main/svtools/source/contnr/svtreebx.cxx (revision cc80331f322734fc3d26de82a10eec7c9f65f9c7)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26 
27 #define _SVTREEBX_CXX
28 #include <vcl/svapp.hxx>
29 #ifndef GCC
30 #endif
31 
32 class TabBar;
33 
34 // #102891# -----------------------
35 
36 #include <svtools/svlbox.hxx>
37 #include <svtools/svlbitm.hxx>
38 #include <svtools/svtreebx.hxx>
39 #include <tools/diagnose_ex.h>
40 #include <svimpbox.hxx>
41 #include <unotools/accessiblestatesethelper.hxx>
42 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
43 #include <com/sun/star/awt/XWindowPeer.hpp>
44 
45 
46 using namespace ::com::sun::star::accessibility;
47 
48 /*
49     Bugs/ToDo
50 
51     - Berechnung Rectangle beim Inplace-Editing (Bug bei manchen Fonts)
52     - SetSpaceBetweenEntries: Offset wird in SetEntryHeight nicht
53       beruecksichtigt
54 */
55 
56 #define TREEFLAG_FIXEDHEIGHT        0x0010
57 
58 
DBG_NAME(SvTreeListBox)59 DBG_NAME(SvTreeListBox)
60 
61 #define SV_LBOX_DEFAULT_INDENT_PIXEL 20
62 
63 SvTreeListBox::SvTreeListBox( Window* pParent, WinBits nWinStyle )
64     : SvLBox( pParent, nWinStyle )
65 {
66     DBG_CTOR(SvTreeListBox,0);
67     InitTreeView();
68 
69     SetSublistOpenWithLeftRight();
70 }
71 
SvTreeListBox(Window * pParent,const ResId & rResId)72 SvTreeListBox::SvTreeListBox( Window* pParent , const ResId& rResId )
73     : SvLBox( pParent,rResId )
74 {
75     DBG_CTOR(SvTreeListBox,0);
76 
77     InitTreeView();
78     Resize();
79 
80     SetSublistOpenWithLeftRight();
81 }
82 
InitTreeView()83 void SvTreeListBox::InitTreeView()
84 {
85     DBG_CHKTHIS(SvTreeListBox,0);
86     pCheckButtonData = NULL;
87     pEdEntry = NULL;
88     pEdItem = NULL;
89     nEntryHeight = 0;
90     pEdCtrl = NULL;
91     nFirstSelTab = 0;
92     nLastSelTab = 0;
93     nFocusWidth = -1;
94     nAllItemAccRoleType = 0;
95 
96     Link* pLink = new Link( LINK(this,SvTreeListBox, DefaultCompare) );
97     pLBoxImpl->m_pLink = pLink;
98 
99     nTreeFlags = TREEFLAG_RECALCTABS;
100     nIndent = SV_LBOX_DEFAULT_INDENT_PIXEL;
101     nEntryHeightOffs = SV_ENTRYHEIGHTOFFS_PIXEL;
102     pImp = new SvImpLBox( this, GetModel(), GetStyle() );
103 
104     aContextBmpMode = SVLISTENTRYFLAG_EXPANDED;
105     nContextBmpWidthMax = 0;
106     SetFont( GetFont() );
107     SetSpaceBetweenEntries( 0 );
108     SetLineColor();
109     InitSettings( sal_True, sal_True, sal_True );
110     ImplInitStyle();
111     SetTabs();
112 }
113 
114 
~SvTreeListBox()115 SvTreeListBox::~SvTreeListBox()
116 {
117     DBG_DTOR(SvTreeListBox,0);
118     pImp->CallEventListeners( VCLEVENT_OBJECT_DYING );
119     delete pImp;
120     delete pLBoxImpl->m_pLink;
121     ClearTabList();
122 }
123 
SetExtendedWinBits(ExtendedWinBits _nBits)124 void SvTreeListBox::SetExtendedWinBits( ExtendedWinBits _nBits )
125 {
126     pImp->SetExtendedWindowBits( _nBits );
127 }
128 
GetExtendedWinBits() const129 ExtendedWinBits SvTreeListBox::GetExtendedWinBits() const
130 {
131     return pImp->GetExtendedWindowBits();
132 }
133 
SetModel(SvLBoxTreeList * pNewModel)134 void SvTreeListBox::SetModel( SvLBoxTreeList* pNewModel )
135 {
136     DBG_CHKTHIS(SvTreeListBox,0);
137     pImp->SetModel( pNewModel );
138     SvLBox::SetModel( pNewModel );
139 }
140 
DisconnectFromModel()141 void SvTreeListBox::DisconnectFromModel()
142 {
143     DBG_CHKTHIS(SvTreeListBox,0);
144     SvLBox::DisconnectFromModel();
145     pImp->SetModel( GetModel() );
146 }
147 
148 
IsA()149 sal_uInt16 SvTreeListBox::IsA()
150 {
151     DBG_CHKTHIS(SvTreeListBox,0);
152     return SV_LISTBOX_ID_TREEBOX;
153 }
154 
SetSublistOpenWithReturn(sal_Bool b)155 void SvTreeListBox::SetSublistOpenWithReturn( sal_Bool b )
156 {
157     pImp->bSubLstOpRet = b;
158 }
159 
IsSublistOpenWithReturn() const160 sal_Bool SvTreeListBox::IsSublistOpenWithReturn() const
161 {
162     return pImp->bSubLstOpRet;
163 }
164 
SetSublistOpenWithLeftRight(sal_Bool b)165 void SvTreeListBox::SetSublistOpenWithLeftRight( sal_Bool b )
166 {
167     pImp->bSubLstOpLR = b;
168 }
169 
IsSublistOpenWithLeftRight() const170 sal_Bool SvTreeListBox::IsSublistOpenWithLeftRight() const
171 {
172     return pImp->bSubLstOpLR;
173 }
174 
Resize()175 void SvTreeListBox::Resize()
176 {
177     DBG_CHKTHIS(SvTreeListBox,0);
178     if( IsEditingActive() )
179         EndEditing( sal_True );
180     SvLBox::Resize();
181     pImp->Resize();
182     nFocusWidth = -1;
183     pImp->ShowCursor( sal_False );
184     pImp->ShowCursor( sal_True );
185 }
186 
187 /* Faelle:
188 
189    A) Entries haben Bitmaps
190        0. Keine Buttons
191        1. Node-Buttons (optional auch an Root-Items)
192        2. Node-Buttons (optional auch an Root-Items) + CheckButton
193        3. CheckButton
194    B) Entries haben keine Bitmaps  (->ueber WindowBits wg. D&D !!!!!!)
195        0. Keine Buttons
196        1. Node-Buttons (optional auch an Root-Items)
197        2. Node-Buttons (optional auch an Root-Items) + CheckButton
198        3. CheckButton
199 */
200 
201 #define NO_BUTTONS              0
202 #define NODE_BUTTONS            1
203 #define NODE_AND_CHECK_BUTTONS  2
204 #define CHECK_BUTTONS           3
205 
206 #define TABFLAGS_TEXT (SV_LBOXTAB_DYNAMIC |        \
207                        SV_LBOXTAB_ADJUST_LEFT |    \
208                        SV_LBOXTAB_EDITABLE |       \
209                        SV_LBOXTAB_SHOW_SELECTION)
210 
211 #define TABFLAGS_CONTEXTBMP (SV_LBOXTAB_DYNAMIC | SV_LBOXTAB_ADJUST_CENTER)
212 
213 #define TABFLAGS_CHECKBTN (SV_LBOXTAB_DYNAMIC |        \
214                            SV_LBOXTAB_ADJUST_CENTER |  \
215                            SV_LBOXTAB_PUSHABLE)
216 
217 #define TAB_STARTPOS    2
218 
219 // bei Aenderungen GetTextOffset beruecksichtigen
SetTabs()220 void SvTreeListBox::SetTabs()
221 {
222     DBG_CHKTHIS(SvTreeListBox,0);
223     if( IsEditingActive() )
224         EndEditing( sal_True );
225     nTreeFlags &= (~TREEFLAG_RECALCTABS);
226     nFocusWidth = -1;
227     const WinBits nStyle( GetStyle() );
228     sal_Bool bHasButtons = (nStyle & WB_HASBUTTONS)!=0;
229     sal_Bool bHasButtonsAtRoot = (nStyle & (WB_HASLINESATROOT |
230                                               WB_HASBUTTONSATROOT))!=0;
231     long nStartPos = TAB_STARTPOS;
232     long nNodeWidthPixel = GetExpandedNodeBmp().GetSizePixel().Width();
233 
234     long nCheckWidth = 0;
235     if( nTreeFlags & TREEFLAG_CHKBTN )
236         nCheckWidth = pCheckButtonData->aBmps[0].GetSizePixel().Width();
237     long nCheckWidthDIV2 = nCheckWidth / 2;
238 
239     long nContextWidth = nContextBmpWidthMax;
240     long nContextWidthDIV2 = nContextWidth / 2;
241 
242     ClearTabList();
243 
244     int nCase = NO_BUTTONS;
245     if( !(nTreeFlags & TREEFLAG_CHKBTN) )
246     {
247         if( bHasButtons )
248             nCase = NODE_BUTTONS;
249     }
250     else
251     {
252         if( bHasButtons )
253             nCase = NODE_AND_CHECK_BUTTONS;
254          else
255             nCase = CHECK_BUTTONS;
256     }
257 
258     switch( nCase )
259     {
260         case NO_BUTTONS :
261             nStartPos += nContextWidthDIV2;  // wg. Zentrierung
262             AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
263             nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
264             // Abstand setzen nur wenn Bitmaps da
265             if( nContextBmpWidthMax )
266                 nStartPos += 5; // Abstand Context-Bmp - Text
267             AddTab( nStartPos, TABFLAGS_TEXT );
268             break;
269 
270         case NODE_BUTTONS :
271             if( bHasButtonsAtRoot )
272                 nStartPos += ( nIndent + (nNodeWidthPixel/2) );
273             else
274                 nStartPos += nContextWidthDIV2;
275             AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
276             nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
277             // Abstand setzen nur wenn Bitmaps da
278             if( nContextBmpWidthMax )
279                 nStartPos += 5; // Abstand Context-Bmp - Text
280             AddTab( nStartPos, TABFLAGS_TEXT );
281             break;
282 
283         case NODE_AND_CHECK_BUTTONS :
284             if( bHasButtonsAtRoot )
285                 nStartPos += ( nIndent + nNodeWidthPixel );
286             else
287                 nStartPos += nCheckWidthDIV2;
288             AddTab( nStartPos, TABFLAGS_CHECKBTN );
289             nStartPos += nCheckWidthDIV2;  // rechter Rand des CheckButtons
290             nStartPos += 3;  // Abstand CheckButton Context-Bmp
291             nStartPos += nContextWidthDIV2;  // Mitte der Context-Bmp
292             AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
293             nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
294             // Abstand setzen nur wenn Bitmaps da
295             if( nContextBmpWidthMax )
296                 nStartPos += 5; // Abstand Context-Bmp - Text
297             AddTab( nStartPos, TABFLAGS_TEXT );
298             break;
299 
300         case CHECK_BUTTONS :
301             nStartPos += nCheckWidthDIV2;
302             AddTab( nStartPos, TABFLAGS_CHECKBTN );
303             nStartPos += nCheckWidthDIV2;  // rechter Rand CheckButton
304             nStartPos += 3;  // Abstand CheckButton Context-Bmp
305             nStartPos += nContextWidthDIV2;  // Mitte der Context-Bmp
306             AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
307             nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
308             // Abstand setzen nur wenn Bitmaps da
309             if( nContextBmpWidthMax )
310                 nStartPos += 5; // Abstand Context-Bmp - Text
311             AddTab( nStartPos, TABFLAGS_TEXT );
312             break;
313     }
314     pImp->NotifyTabsChanged();
315 }
316 
InitEntry(SvLBoxEntry * pEntry,const XubString & aStr,const Image & aCollEntryBmp,const Image & aExpEntryBmp,SvLBoxButtonKind eButtonKind)317 void SvTreeListBox::InitEntry( SvLBoxEntry* pEntry,
318   const XubString& aStr, const Image& aCollEntryBmp, const Image& aExpEntryBmp,
319   SvLBoxButtonKind eButtonKind)
320 {
321     DBG_CHKTHIS(SvTreeListBox,0);
322     SvLBoxButton* pButton;
323     SvLBoxString* pString;
324     SvLBoxContextBmp* pContextBmp;
325 
326     if( nTreeFlags & TREEFLAG_CHKBTN )
327     {
328         pButton= new SvLBoxButton( pEntry,eButtonKind,0,pCheckButtonData );
329         pEntry->AddItem( pButton );
330     }
331 
332     pContextBmp= new SvLBoxContextBmp( pEntry,0, aCollEntryBmp,aExpEntryBmp,
333                                      aContextBmpMode );
334     pEntry->AddItem( pContextBmp );
335 
336     pString = new SvLBoxString( pEntry, 0, aStr );
337     pEntry->AddItem( pString );
338 }
339 
GetEntryText(SvLBoxEntry * pEntry) const340 String SvTreeListBox::GetEntryText(SvLBoxEntry* pEntry) const
341 {
342     DBG_CHKTHIS(SvTreeListBox,0);
343     DBG_ASSERT( pEntry, "SvTreeListBox::GetEntryText(): no entry" );
344     SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
345     DBG_ASSERT( pEntry, "SvTreeListBox::GetEntryText(): item not found" );
346     return pItem->GetText();
347 }
348 
GetEntryAltText(SvLBoxEntry *) const349 String  SvTreeListBox::GetEntryAltText( SvLBoxEntry* ) const
350 {
351     String tmp;
352     return tmp;
353 }
GetEntryLongDescription(SvLBoxEntry *) const354 String SvTreeListBox::GetEntryLongDescription( SvLBoxEntry* ) const
355 {
356     String tmp;
357     return tmp;
358 }
359 
SearchEntryTextWithHeadTitle(SvLBoxEntry * pEntry)360 String SvTreeListBox::SearchEntryTextWithHeadTitle( SvLBoxEntry* pEntry )
361 {
362     DBG_CHKTHIS(SvTreeListBox,0);
363     DBG_ASSERT( pEntry, "SvTreeListBox::SearchEntryText(): no entry" );
364     String sRet;
365 
366     sal_uInt16 nCount = pEntry->ItemCount();
367     sal_uInt16 nCur = 0;
368     sal_uInt16 nHeaderCur = 0;
369     SvLBoxItem* pItem;
370     while( nCur < nCount )
371     {
372         // MT: SV_ITEM_ID_EXTENDRLBOXSTRING / GetExtendText() was in use in IA2 cws, but only used in sc: ScSolverOptionsString. Needed?
373         pItem = pEntry->GetItem( nCur );
374         if ( (pItem->IsA() == SV_ITEM_ID_LBOXSTRING /* || pItem->IsA() == SV_ITEM_ID_EXTENDRLBOXSTRING */ ) &&
375              static_cast<SvLBoxString*>( pItem )->GetText().Len() > 0 )
376         {
377 
378             //want to the column header
379             if( headString.Len() > 0)
380             {
381                 xub_StrLen nEnd = headString.Search( sal_Unicode( '\t' ) );
382                 if( nEnd == STRING_NOTFOUND )
383                 {
384                     if(sRet.Len()>0)
385                     {
386                         sRet += ',';
387                     }
388                     if(headString.Len()>0)
389                     {
390                         sRet += headString ;
391                         sRet += ':' ;
392                     }
393                 }
394                 else
395                 {
396                     String  aString=headString.GetToken(nHeaderCur, sal_Unicode( '\t' ) );
397                     if(sRet.Len()>0)
398                     {
399                         sRet += ',';
400                     }
401                     if( aString.Len() > 0)
402                     {
403                         sRet += aString ;
404                         sRet += ':' ;
405                     }
406                     nHeaderCur++;
407                 }
408                 // if (pItem->IsA() == SV_ITEM_ID_LBOXSTRING)
409                     sRet += static_cast<SvLBoxString*>( pItem )->GetText();
410                 // else
411                 //  sRet += static_cast<SvLBoxString*>( pItem )->GetExtendText();
412             }
413             else
414             {
415                 // if (pItem->IsA() == SV_ITEM_ID_LBOXSTRING)
416                     sRet += static_cast<SvLBoxString*>( pItem )->GetText();
417                 // else
418                 //  sRet += static_cast<SvLBoxString*>( pItem )->GetExtendText();
419                 sRet += ',';
420             }
421             //end want to the column header
422         }
423         nCur++;
424     }
425 
426     if (sRet.Len() > 0)
427         sRet = sRet.Erase(sRet.Len() - 1);
428     return sRet;
429 }
SearchEntryText(SvLBoxEntry * pEntry) const430 String SvTreeListBox::SearchEntryText( SvLBoxEntry* pEntry ) const
431 {
432     DBG_CHKTHIS(SvTreeListBox,0);
433     DBG_ASSERT( pEntry, "SvTreeListBox::SearchEntryText(): no entry" );
434     String sRet;
435     sal_uInt16 nCount = pEntry->ItemCount();
436     sal_uInt16 nCur = 0;
437     SvLBoxItem* pItem;
438     while( nCur < nCount )
439     {
440         pItem = pEntry->GetItem( nCur );
441         if ( pItem->IsA() == SV_ITEM_ID_LBOXSTRING &&
442              static_cast<SvLBoxString*>( pItem )->GetText().Len() > 0 )
443         {
444             sRet = static_cast<SvLBoxString*>( pItem )->GetText();
445             break;
446         }
447         nCur++;
448     }
449     return sRet;
450 }
451 
GetExpandedEntryBmp(SvLBoxEntry * pEntry,BmpColorMode _eMode) const452 const Image& SvTreeListBox::GetExpandedEntryBmp(SvLBoxEntry* pEntry, BmpColorMode _eMode) const
453 {
454     DBG_CHKTHIS(SvTreeListBox,0);
455     DBG_ASSERT(pEntry,"Entry?");
456     SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
457     DBG_ASSERT(pItem,"GetContextBmp:Item not found");
458     return pItem->GetBitmap2( _eMode );
459 }
460 
GetCollapsedEntryBmp(SvLBoxEntry * pEntry,BmpColorMode _eMode) const461 const Image& SvTreeListBox::GetCollapsedEntryBmp( SvLBoxEntry* pEntry, BmpColorMode _eMode ) const
462 {
463     DBG_CHKTHIS(SvTreeListBox,0);
464     DBG_ASSERT(pEntry,"Entry?");
465     SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
466     DBG_ASSERT(pItem,"GetContextBmp:Item not found");
467     return pItem->GetBitmap1( _eMode );
468 }
469 
IMPL_LINK_INLINE_START(SvTreeListBox,CheckButtonClick,SvLBoxButtonData *,pData)470 IMPL_LINK_INLINE_START( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData )
471 {
472     DBG_CHKTHIS(SvTreeListBox,0);
473     pHdlEntry = pData->GetActEntry();
474     CheckButtonHdl();
475     return 0;
476 }
IMPL_LINK_INLINE_END(SvTreeListBox,CheckButtonClick,SvLBoxButtonData *,pData)477 IMPL_LINK_INLINE_END( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData )
478 
479 SvLBoxEntry* SvTreeListBox::InsertEntry( const XubString& aText,SvLBoxEntry* pParent,
480                                      sal_Bool bChildsOnDemand, sal_uLong nPos, void* pUser,
481                                      SvLBoxButtonKind eButtonKind )
482 {
483     DBG_CHKTHIS(SvTreeListBox,0);
484     nTreeFlags |= TREEFLAG_MANINS;
485 
486     const Image& rDefExpBmp = pImp->GetDefaultEntryExpBmp( );
487     const Image& rDefColBmp = pImp->GetDefaultEntryColBmp( );
488 
489     aCurInsertedExpBmp = rDefExpBmp;
490     aCurInsertedColBmp = rDefColBmp;
491 
492     SvLBoxEntry* pEntry = CreateEntry();
493     pEntry->SetUserData( pUser );
494     InitEntry( pEntry, aText, rDefColBmp, rDefExpBmp, eButtonKind );
495     pEntry->EnableChildsOnDemand( bChildsOnDemand );
496 
497     // Add the HC versions of the default images
498     SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
499     if( pBmpItem )
500     {
501         pBmpItem->SetBitmap1( pImp->GetDefaultEntryColBmp( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
502         pBmpItem->SetBitmap2( pImp->GetDefaultEntryExpBmp( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
503     }
504 
505     if( !pParent )
506         SvLBox::Insert( pEntry, nPos );
507     else
508         SvLBox::Insert( pEntry, pParent, nPos );
509 
510     aPrevInsertedExpBmp = rDefExpBmp;
511     aPrevInsertedColBmp = rDefColBmp;
512 
513     nTreeFlags &= (~TREEFLAG_MANINS);
514 
515     return pEntry;
516 }
517 
InsertEntry(const XubString & aText,const Image & aExpEntryBmp,const Image & aCollEntryBmp,SvLBoxEntry * pParent,sal_Bool bChildsOnDemand,sal_uLong nPos,void * pUser,SvLBoxButtonKind eButtonKind)518 SvLBoxEntry* SvTreeListBox::InsertEntry( const XubString& aText,
519     const Image& aExpEntryBmp, const Image& aCollEntryBmp,
520     SvLBoxEntry* pParent, sal_Bool bChildsOnDemand, sal_uLong nPos, void* pUser,
521     SvLBoxButtonKind eButtonKind )
522 {
523     DBG_CHKTHIS(SvTreeListBox,0);
524     nTreeFlags |= TREEFLAG_MANINS;
525 
526     aCurInsertedExpBmp = aExpEntryBmp;
527     aCurInsertedColBmp = aCollEntryBmp;
528 
529     SvLBoxEntry* pEntry = CreateEntry();
530     pEntry->SetUserData( pUser );
531     InitEntry( pEntry, aText, aCollEntryBmp, aExpEntryBmp, eButtonKind );
532 
533     pEntry->EnableChildsOnDemand( bChildsOnDemand );
534 
535     if( !pParent )
536         SvLBox::Insert( pEntry, nPos );
537     else
538         SvLBox::Insert( pEntry, pParent, nPos );
539 
540     aPrevInsertedExpBmp = aExpEntryBmp;
541     aPrevInsertedColBmp = aCollEntryBmp;
542 
543     nTreeFlags &= (~TREEFLAG_MANINS);
544 
545     return pEntry;
546 }
547 
SetEntryText(SvLBoxEntry * pEntry,const XubString & aStr)548 void SvTreeListBox::SetEntryText( SvLBoxEntry* pEntry, const XubString& aStr)
549 {
550     DBG_CHKTHIS(SvTreeListBox,0);
551     SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
552     DBG_ASSERT(pItem,"SetText:Item not found");
553     pItem->SetText( pEntry, aStr );
554     pItem->InitViewData( this, pEntry, 0 );
555     GetModel()->InvalidateEntry( pEntry );
556 }
557 
SetExpandedEntryBmp(SvLBoxEntry * pEntry,const Image & aBmp,BmpColorMode _eMode)558 void SvTreeListBox::SetExpandedEntryBmp( SvLBoxEntry* pEntry, const Image& aBmp, BmpColorMode _eMode )
559 {
560     DBG_CHKTHIS(SvTreeListBox,0);
561     SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
562 
563     DBG_ASSERT(pItem,"SetExpBmp:Item not found");
564     pItem->SetBitmap2( aBmp, _eMode );
565 
566     GetModel()->InvalidateEntry( pEntry );
567     SetEntryHeight( pEntry );
568     Size aSize = aBmp.GetSizePixel();
569     // #97680# ---------------
570     short nWidth = pImp->UpdateContextBmpWidthVector( pEntry, (short)aSize.Width() );
571     if( nWidth > nContextBmpWidthMax )
572     {
573         nContextBmpWidthMax = nWidth;
574         SetTabs();
575     }
576 }
577 
SetCollapsedEntryBmp(SvLBoxEntry * pEntry,const Image & aBmp,BmpColorMode _eMode)578 void SvTreeListBox::SetCollapsedEntryBmp(SvLBoxEntry* pEntry,const Image& aBmp, BmpColorMode _eMode )
579 {
580     DBG_CHKTHIS(SvTreeListBox,0);
581     SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
582 
583     DBG_ASSERT(pItem,"SetExpBmp:Item not found");
584     pItem->SetBitmap1( aBmp, _eMode );
585 
586     GetModel()->InvalidateEntry( pEntry );
587     SetEntryHeight( pEntry );
588     Size aSize = aBmp.GetSizePixel();
589     // #97680# -----------
590     short nWidth = pImp->UpdateContextBmpWidthVector( pEntry, (short)aSize.Width() );
591     if( nWidth > nContextBmpWidthMax )
592     {
593         nContextBmpWidthMax = nWidth;
594         SetTabs();
595     }
596 }
597 
ImpEntryInserted(SvLBoxEntry * pEntry)598 void SvTreeListBox::ImpEntryInserted( SvLBoxEntry* pEntry )
599 {
600     DBG_CHKTHIS(SvTreeListBox,0);
601 
602     SvLBoxEntry* pParent = (SvLBoxEntry*)pModel->GetParent( pEntry );
603     if( pParent )
604     {
605         sal_uInt16 nFlags = pParent->GetFlags();
606         nFlags &= ~SV_ENTRYFLAG_NO_NODEBMP;
607         pParent->SetFlags( nFlags );
608     }
609 
610     if(!((nTreeFlags & TREEFLAG_MANINS) &&
611          (aPrevInsertedExpBmp == aCurInsertedExpBmp)  &&
612          (aPrevInsertedColBmp == aCurInsertedColBmp) ))
613     {
614         Size aSize = GetCollapsedEntryBmp( pEntry ).GetSizePixel();
615         if( aSize.Width() > nContextBmpWidthMax )
616         {
617             nContextBmpWidthMax = (short)aSize.Width();
618             nTreeFlags |= TREEFLAG_RECALCTABS;
619         }
620         aSize = GetExpandedEntryBmp( pEntry ).GetSizePixel();
621         if( aSize.Width() > nContextBmpWidthMax )
622         {
623             nContextBmpWidthMax = (short)aSize.Width();
624             nTreeFlags |= TREEFLAG_RECALCTABS;
625         }
626     }
627     SetEntryHeight( (SvLBoxEntry*)pEntry );
628 }
629 
630 
631 
SetCheckButtonState(SvLBoxEntry * pEntry,SvButtonState eState)632 void SvTreeListBox::SetCheckButtonState( SvLBoxEntry* pEntry, SvButtonState eState)
633 {
634     DBG_CHKTHIS(SvTreeListBox,0);
635     if( nTreeFlags & TREEFLAG_CHKBTN )
636     {
637         SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
638         if(!(pItem && pItem->CheckModification()))
639             return ;
640         switch( eState )
641         {
642             case SV_BUTTON_CHECKED:
643                 pItem->SetStateChecked();
644                 break;
645 
646             case SV_BUTTON_UNCHECKED:
647                 pItem->SetStateUnchecked();
648                 break;
649 
650             case SV_BUTTON_TRISTATE:
651                 pItem->SetStateTristate();
652                 break;
653         }
654         InvalidateEntry( pEntry );
655     }
656 }
657 
GetCheckButtonState(SvLBoxEntry * pEntry) const658 SvButtonState SvTreeListBox::GetCheckButtonState( SvLBoxEntry* pEntry ) const
659 {
660     DBG_CHKTHIS(SvTreeListBox,0);
661     SvButtonState eState = SV_BUTTON_UNCHECKED;
662     if( nTreeFlags & TREEFLAG_CHKBTN )
663     {
664         SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
665         if(!pItem)
666             return SV_BUTTON_TRISTATE;
667         sal_uInt16 nButtonFlags = pItem->GetButtonFlags();
668         eState = pCheckButtonData->ConvertToButtonState( nButtonFlags );
669     }
670     return eState;
671 }
672 
CheckButtonHdl()673 void SvTreeListBox::CheckButtonHdl()
674 {
675     DBG_CHKTHIS(SvTreeListBox,0);
676     aCheckButtonHdl.Call( this );
677     if ( pCheckButtonData )
678         pImp->CallEventListeners( VCLEVENT_CHECKBOX_TOGGLE, (void*)pCheckButtonData->GetActEntry() );
679 }
680 
681 // *********************************************************************
682 // *********************************************************************
683 
684 //
685 //  TODO: Momentan werden die Daten so geklont, dass sie dem
686 //  Standard-TreeView-Format entsprechen. Hier sollte eigentlich
687 //  das Model als Referenz dienen. Dies fuehrt dazu, dass
688 //  SvLBoxEntry::Clone _nicht_ gerufen wird, sondern nur dessen
689 //  Basisklasse SvListEntry
690 //
691 
CloneEntry(SvLBoxEntry * pSource)692 SvLBoxEntry* SvTreeListBox::CloneEntry( SvLBoxEntry* pSource )
693 {
694     DBG_CHKTHIS(SvTreeListBox,0);
695     XubString aStr;
696     Image aCollEntryBmp;
697     Image aExpEntryBmp;
698     SvLBoxButtonKind eButtonKind = SvLBoxButtonKind_enabledCheckbox;
699 
700     SvLBoxString* pStringItem = (SvLBoxString*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
701     if( pStringItem )
702         aStr = pStringItem->GetText();
703     SvLBoxContextBmp* pBmpItem = (SvLBoxContextBmp*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
704     if( pBmpItem )
705     {
706         aCollEntryBmp = pBmpItem->GetBitmap1( BMP_COLOR_NORMAL );
707         aExpEntryBmp  = pBmpItem->GetBitmap2( BMP_COLOR_NORMAL );
708     }
709     SvLBoxButton* pButtonItem = (SvLBoxButton*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
710     if( pButtonItem )
711         eButtonKind = pButtonItem->GetKind();
712     SvLBoxEntry* pClone = CreateEntry();
713     InitEntry( pClone, aStr, aCollEntryBmp, aExpEntryBmp, eButtonKind );
714     pClone->SvListEntry::Clone( pSource );
715     pClone->EnableChildsOnDemand( pSource->HasChildsOnDemand() );
716     pClone->SetUserData( pSource->GetUserData() );
717 
718     if ( pBmpItem )
719     {
720         SvLBoxContextBmp* pCloneBitmap = static_cast< SvLBoxContextBmp* >( pClone->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
721         if ( pCloneBitmap )
722         {
723             pCloneBitmap->SetBitmap1( pBmpItem->GetBitmap1( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
724             pCloneBitmap->SetBitmap2( pBmpItem->GetBitmap2( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
725         }
726     }
727 
728     return pClone;
729 }
730 
731 // *********************************************************************
732 // *********************************************************************
733 
734 
ShowExpandBitmapOnCursor(sal_Bool bYes)735 void SvTreeListBox::ShowExpandBitmapOnCursor( sal_Bool bYes )
736 {
737     DBG_CHKTHIS(SvTreeListBox,0);
738     if( bYes )
739         aContextBmpMode = SVLISTENTRYFLAG_FOCUSED;
740     else
741         aContextBmpMode = SVLISTENTRYFLAG_EXPANDED;
742 }
743 
SetIndent(short nNewIndent)744 void SvTreeListBox::SetIndent( short nNewIndent )
745 {
746     DBG_CHKTHIS(SvTreeListBox,0);
747     nIndent = nNewIndent;
748     SetTabs();
749     if( IsUpdateMode() )
750         Invalidate();
751 }
752 
GetDefaultExpandedEntryBmp(BmpColorMode _eMode) const753 const Image& SvTreeListBox::GetDefaultExpandedEntryBmp( BmpColorMode _eMode ) const
754 {
755     return pImp->GetDefaultEntryExpBmp( _eMode );
756 }
757 
GetDefaultCollapsedEntryBmp(BmpColorMode _eMode) const758 const Image& SvTreeListBox::GetDefaultCollapsedEntryBmp( BmpColorMode _eMode ) const
759 {
760     return pImp->GetDefaultEntryColBmp( _eMode );
761 }
762 
SetDefaultExpandedEntryBmp(const Image & aBmp,BmpColorMode _eMode)763 void SvTreeListBox::SetDefaultExpandedEntryBmp( const Image& aBmp, BmpColorMode _eMode )
764 {
765     DBG_CHKTHIS(SvTreeListBox,0);
766     Size aSize = aBmp.GetSizePixel();
767     if( aSize.Width() > nContextBmpWidthMax )
768         nContextBmpWidthMax = (short)aSize.Width();
769     SetTabs();
770 
771     pImp->SetDefaultEntryExpBmp( aBmp, _eMode );
772 }
773 
SetDefaultCollapsedEntryBmp(const Image & aBmp,BmpColorMode _eMode)774 void SvTreeListBox::SetDefaultCollapsedEntryBmp( const Image& aBmp, BmpColorMode _eMode )
775 {
776     DBG_CHKTHIS(SvTreeListBox,0);
777     Size aSize = aBmp.GetSizePixel();
778     if( aSize.Width() > nContextBmpWidthMax )
779         nContextBmpWidthMax = (short)aSize.Width();
780     SetTabs();
781 
782     pImp->SetDefaultEntryColBmp( aBmp, _eMode );
783 }
784 
EnableCheckButton(SvLBoxButtonData * pData)785 void SvTreeListBox::EnableCheckButton( SvLBoxButtonData* pData )
786 {
787     DBG_CHKTHIS(SvTreeListBox,0);
788     DBG_ASSERT(!GetEntryCount(),"EnableCheckButton: Entry count != 0");
789     if( !pData )
790         nTreeFlags &= (~TREEFLAG_CHKBTN);
791     else
792     {
793         SetCheckButtonData( pData );
794         nTreeFlags |= TREEFLAG_CHKBTN;
795         pData->SetLink( LINK(this, SvTreeListBox, CheckButtonClick));
796     }
797 
798     SetTabs();
799     if( IsUpdateMode() )
800         Invalidate();
801 }
802 
SetCheckButtonData(SvLBoxButtonData * pData)803 void SvTreeListBox::SetCheckButtonData( SvLBoxButtonData* pData )
804 {
805     DBG_CHKTHIS(SvTreeListBox,0);
806     if ( pData )
807         pCheckButtonData = pData;
808 }
809 
GetDefaultExpandedNodeImage(BmpColorMode _eMode)810 const Image& SvTreeListBox::GetDefaultExpandedNodeImage( BmpColorMode _eMode )
811 {
812     return SvImpLBox::GetDefaultExpandedNodeImage( _eMode );
813 }
814 
GetDefaultCollapsedNodeImage(BmpColorMode _eMode)815 const Image& SvTreeListBox::GetDefaultCollapsedNodeImage( BmpColorMode _eMode )
816 {
817     return SvImpLBox::GetDefaultCollapsedNodeImage( _eMode );
818 }
819 
SetNodeBitmaps(const Image & rCollapsedNodeBmp,const Image & rExpandedNodeBmp,BmpColorMode _eMode)820 void SvTreeListBox::SetNodeBitmaps( const Image& rCollapsedNodeBmp, const Image& rExpandedNodeBmp, BmpColorMode _eMode )
821 {
822     DBG_CHKTHIS(SvTreeListBox,0);
823     SetExpandedNodeBmp( rExpandedNodeBmp, _eMode );
824     SetCollapsedNodeBmp( rCollapsedNodeBmp, _eMode );
825     SetTabs();
826 }
827 
SetDontKnowNodeBitmap(const Image & rDontKnowBmp,BmpColorMode _eMode)828 void SvTreeListBox::SetDontKnowNodeBitmap( const Image& rDontKnowBmp, BmpColorMode _eMode )
829 {
830     pImp->SetDontKnowNodeBmp( rDontKnowBmp, _eMode );
831 }
832 
EditingEntry(SvLBoxEntry *,Selection &)833 sal_Bool SvTreeListBox::EditingEntry( SvLBoxEntry*, Selection& )
834 {
835     DBG_CHKTHIS(SvTreeListBox,0);
836     return sal_True;
837 }
838 
EditedEntry(SvLBoxEntry *,const XubString &)839 sal_Bool SvTreeListBox::EditedEntry( SvLBoxEntry* /*pEntry*/,const XubString& /*rNewText*/)
840 {
841     DBG_CHKTHIS(SvTreeListBox,0);
842     return sal_True;
843 }
844 
EnableInplaceEditing(sal_Bool bOn)845 void SvTreeListBox::EnableInplaceEditing( sal_Bool bOn )
846 {
847     DBG_CHKTHIS(SvTreeListBox,0);
848     SvLBox::EnableInplaceEditing( bOn );
849 }
850 
KeyInput(const KeyEvent & rKEvt)851 void SvTreeListBox::KeyInput( const KeyEvent& rKEvt )
852 {
853     DBG_CHKTHIS(SvTreeListBox,0);
854     // unter OS/2 bekommen wir auch beim Editieren Key-Up/Down
855     if( IsEditingActive() )
856         return;
857 
858     nImpFlags |= SVLBOX_IS_TRAVELSELECT;
859 
860 #ifdef OVDEBUG
861     sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
862     switch ( nCode )
863     {
864         case KEY_F1:
865         {
866             SvLBoxEntry* pEntry = First();
867             pEntry = NextVisible( pEntry );
868             SetEntryText( pEntry, "SetEntryText" );
869             Sound::Beep();
870         }
871         break;
872     }
873 #endif
874 
875     if( !pImp->KeyInput( rKEvt ) )
876         SvLBox::KeyInput( rKEvt );
877 
878     nImpFlags &= ~SVLBOX_IS_TRAVELSELECT;
879 }
880 
RequestingChilds(SvLBoxEntry * pParent)881 void SvTreeListBox::RequestingChilds( SvLBoxEntry* pParent )
882 {
883     DBG_CHKTHIS(SvTreeListBox,0);
884     if( !pParent->HasChilds() )
885         InsertEntry( String::CreateFromAscii("<dummy>"), pParent, sal_False, LIST_APPEND );
886 }
887 
GetFocus()888 void SvTreeListBox::GetFocus()
889 {
890     DBG_CHKTHIS(SvTreeListBox,0);
891     //Solution:If there is no item in the tree,draw focus.
892     if( !SvLBox::First())
893     {
894         Invalidate();
895     }
896     pImp->GetFocus();
897     SvLBox::GetFocus();
898 
899     SvLBoxEntry* pEntry = FirstSelected();
900     if ( !pEntry )
901     {
902         pEntry = pImp->GetCurrentEntry();
903     }
904     if (pImp->pCursor)
905     {
906         if (pEntry != pImp->pCursor)
907             pEntry = pImp->pCursor;
908     }
909     if ( pEntry )
910         pImp->CallEventListeners( VCLEVENT_LISTBOX_TREEFOCUS, pEntry );
911 
912 }
913 
LoseFocus()914 void SvTreeListBox::LoseFocus()
915 {
916     DBG_CHKTHIS(SvTreeListBox,0);
917     //Solution:If there is no item in the tree,delete visual focus.
918     if( !SvLBox::First())
919     {
920         Invalidate();
921     }
922     pImp->LoseFocus();
923     SvLBox::LoseFocus();
924 }
925 
ModelHasCleared()926 void SvTreeListBox::ModelHasCleared()
927 {
928     DBG_CHKTHIS(SvTreeListBox,0);
929     pImp->pCursor = 0; //sonst Absturz beim Inplace-Editieren im GetFocus
930     delete pEdCtrl;
931     pEdCtrl = NULL;
932     pImp->Clear();
933     nFocusWidth = -1;
934 
935     nContextBmpWidthMax = 0;
936     SetDefaultExpandedEntryBmp( GetDefaultExpandedEntryBmp() );
937     SetDefaultCollapsedEntryBmp( GetDefaultCollapsedEntryBmp() );
938 
939     if( !(nTreeFlags & TREEFLAG_FIXEDHEIGHT ))
940         nEntryHeight = 0;
941     AdjustEntryHeight( GetFont() );
942     AdjustEntryHeight( GetDefaultExpandedEntryBmp() );
943     AdjustEntryHeight( GetDefaultCollapsedEntryBmp() );
944 
945     SvLBox::ModelHasCleared();
946 //  if( IsUpdateMode() )
947 //      Invalidate();
948 }
949 
ShowTargetEmphasis(SvLBoxEntry * pEntry,sal_Bool)950 void SvTreeListBox::ShowTargetEmphasis( SvLBoxEntry* pEntry, sal_Bool /* bShow  */ )
951 {
952     DBG_CHKTHIS(SvTreeListBox,0);
953     pImp->PaintDDCursor( pEntry );
954 }
955 
ScrollOutputArea(short nDeltaEntries)956 void SvTreeListBox::ScrollOutputArea( short nDeltaEntries )
957 {
958     DBG_CHKTHIS(SvTreeListBox,0);
959     if( !nDeltaEntries || !pImp->aVerSBar.IsVisible() )
960         return;
961 
962     long nThumb = pImp->aVerSBar.GetThumbPos();
963     long nMax = pImp->aVerSBar.GetRange().Max();
964 
965     NotifyBeginScroll();
966     if( nDeltaEntries < 0 )
967     {
968         // das Fenster nach oben verschieben
969         nDeltaEntries *= -1;
970         long nVis = pImp->aVerSBar.GetVisibleSize();
971         long nTemp = nThumb + nVis;
972         if( nDeltaEntries > (nMax - nTemp) )
973             nDeltaEntries = (short)(nMax - nTemp);
974         pImp->PageDown( (sal_uInt16)nDeltaEntries );
975     }
976     else
977     {
978         if( nDeltaEntries > nThumb )
979             nDeltaEntries = (short)nThumb;
980         pImp->PageUp( (sal_uInt16)nDeltaEntries );
981     }
982     pImp->SyncVerThumb();
983     NotifyEndScroll();
984 }
985 
SetSelectionMode(SelectionMode eSelectMode)986 void SvTreeListBox::SetSelectionMode( SelectionMode eSelectMode )
987 {
988     DBG_CHKTHIS(SvTreeListBox,0);
989     SvLBox::SetSelectionMode( eSelectMode );
990     pImp->SetSelectionMode( eSelectMode );
991 }
992 
SetDragDropMode(DragDropMode nDDMode)993 void SvTreeListBox::SetDragDropMode( DragDropMode nDDMode )
994 {
995     DBG_CHKTHIS(SvTreeListBox,0);
996     SvLBox::SetDragDropMode( nDDMode );
997     pImp->SetDragDropMode( nDDMode );
998 }
999 
GetHeightOffset(const Image & rBmp,Size & aSizeLogic)1000 short SvTreeListBox::GetHeightOffset(const Image& rBmp, Size& aSizeLogic )
1001 {
1002     DBG_CHKTHIS(SvTreeListBox,0);
1003     short nOffset = 0;
1004     aSizeLogic = rBmp.GetSizePixel();
1005     if( GetEntryHeight() > aSizeLogic.Height() )
1006         nOffset = ( GetEntryHeight() - (short)aSizeLogic.Height()) / 2;
1007     return nOffset;
1008 }
1009 
GetHeightOffset(const Font &,Size & aSizeLogic)1010 short SvTreeListBox::GetHeightOffset(const Font& /* rFont */, Size& aSizeLogic )
1011 {
1012     DBG_CHKTHIS(SvTreeListBox,0);
1013     short nOffset = 0;
1014     aSizeLogic = Size(GetTextWidth('X'), GetTextHeight());
1015     if( GetEntryHeight() > aSizeLogic.Height() )
1016         nOffset = ( GetEntryHeight() - (short)aSizeLogic.Height()) / 2;
1017     return nOffset;
1018 }
1019 
SetEntryHeight(SvLBoxEntry * pEntry)1020 void SvTreeListBox::SetEntryHeight( SvLBoxEntry* pEntry )
1021 {
1022     DBG_CHKTHIS(SvTreeListBox,0);
1023     short nHeight, nHeightMax=0;
1024     sal_uInt16 nCount = pEntry->ItemCount();
1025     sal_uInt16 nCur = 0;
1026     SvViewDataEntry* pViewData = GetViewDataEntry( pEntry );
1027     while( nCur < nCount )
1028     {
1029         SvLBoxItem* pItem = pEntry->GetItem( nCur );
1030         nHeight = (short)(pItem->GetSize( pViewData, nCur ).Height());
1031         if( nHeight > nHeightMax )
1032             nHeightMax = nHeight;
1033         nCur++;
1034     }
1035 
1036     if( nHeightMax > nEntryHeight )
1037     {
1038         nEntryHeight = nHeightMax;
1039         SvLBox::SetFont( GetFont() );
1040         pImp->SetEntryHeight( nHeightMax );
1041     }
1042 }
1043 
SetEntryHeight(short nHeight,sal_Bool bAlways)1044 void SvTreeListBox::SetEntryHeight( short nHeight, sal_Bool bAlways )
1045 {
1046     DBG_CHKTHIS(SvTreeListBox,0);
1047 
1048     if( bAlways || nHeight > nEntryHeight )
1049     {
1050         nEntryHeight = nHeight;
1051         if( nEntryHeight )
1052             nTreeFlags |= TREEFLAG_FIXEDHEIGHT;
1053         else
1054             nTreeFlags &= ~TREEFLAG_FIXEDHEIGHT;
1055         SvLBox::SetFont( GetFont() );
1056         pImp->SetEntryHeight( nHeight );
1057     }
1058 }
1059 
1060 
AdjustEntryHeight(const Image & rBmp)1061 void SvTreeListBox::AdjustEntryHeight( const Image& rBmp )
1062 {
1063     DBG_CHKTHIS(SvTreeListBox,0);
1064     Size aSize;
1065     GetHeightOffset( rBmp, aSize );
1066     if( aSize.Height() > nEntryHeight )
1067     {
1068         nEntryHeight = (short)aSize.Height() + nEntryHeightOffs;
1069         pImp->SetEntryHeight( nEntryHeight );
1070     }
1071 }
1072 
AdjustEntryHeight(const Font & rFont)1073 void SvTreeListBox::AdjustEntryHeight( const Font& rFont )
1074 {
1075     DBG_CHKTHIS(SvTreeListBox,0);
1076     Size aSize;
1077     GetHeightOffset( rFont, aSize );
1078     if( aSize.Height()  >  nEntryHeight )
1079     {
1080         nEntryHeight = (short)aSize.Height() + nEntryHeightOffs;
1081         pImp->SetEntryHeight( nEntryHeight );
1082     }
1083 }
1084 
Expand(SvLBoxEntry * pParent)1085 sal_Bool SvTreeListBox::Expand( SvLBoxEntry* pParent )
1086 {
1087     DBG_CHKTHIS(SvTreeListBox,0);
1088     pHdlEntry = pParent;
1089     sal_Bool bExpanded = sal_False;
1090     sal_uInt16 nFlags;
1091 
1092     if( pParent->HasChildsOnDemand() )
1093         RequestingChilds( pParent );
1094     if( pParent->HasChilds() )
1095     {
1096         nImpFlags |= SVLBOX_IS_EXPANDING;
1097         if( ExpandingHdl() )
1098         {
1099             bExpanded = sal_True;
1100             SvListView::Expand( pParent );
1101             pImp->EntryExpanded( pParent );
1102             pHdlEntry = pParent;
1103             ExpandedHdl();
1104         }
1105         nFlags = pParent->GetFlags();
1106         nFlags &= ~SV_ENTRYFLAG_NO_NODEBMP;
1107         nFlags |= SV_ENTRYFLAG_HAD_CHILDREN;
1108         pParent->SetFlags( nFlags );
1109     }
1110     else
1111     {
1112         nFlags = pParent->GetFlags();
1113         nFlags |= SV_ENTRYFLAG_NO_NODEBMP;
1114         pParent->SetFlags( nFlags );
1115         GetModel()->InvalidateEntry( pParent ); // neu zeichnen
1116     }
1117 
1118     // --> OD 2009-04-01 #i92103#
1119     if ( bExpanded )
1120     {
1121         pImp->CallEventListeners( VCLEVENT_ITEM_EXPANDED, pParent );
1122     }
1123     // <--
1124 
1125     return bExpanded;
1126 }
1127 
Collapse(SvLBoxEntry * pParent)1128 sal_Bool SvTreeListBox::Collapse( SvLBoxEntry* pParent )
1129 {
1130     DBG_CHKTHIS(SvTreeListBox,0);
1131     nImpFlags &= ~SVLBOX_IS_EXPANDING;
1132     pHdlEntry = pParent;
1133     sal_Bool bCollapsed = sal_False;
1134 
1135     if( ExpandingHdl() )
1136     {
1137         bCollapsed = sal_True;
1138         pImp->CollapsingEntry( pParent );
1139         SvListView::Collapse( pParent );
1140         pImp->EntryCollapsed( pParent );
1141         pHdlEntry = pParent;
1142         ExpandedHdl();
1143     }
1144 
1145     // --> OD 2009-04-01 #i92103#
1146     if ( bCollapsed )
1147     {
1148         pImp->CallEventListeners( VCLEVENT_ITEM_COLLAPSED, pParent );
1149     }
1150     // <--
1151 
1152     return bCollapsed;
1153 }
1154 
Select(SvLBoxEntry * pEntry,sal_Bool bSelect)1155 sal_Bool SvTreeListBox::Select( SvLBoxEntry* pEntry, sal_Bool bSelect )
1156 {
1157     DBG_CHKTHIS(SvTreeListBox,0);
1158     DBG_ASSERT(pEntry,"Select: Null-Ptr");
1159     sal_Bool bRetVal = SvListView::Select( pEntry, bSelect );
1160     DBG_ASSERT(IsSelected(pEntry)==bSelect,"Select failed");
1161     if( bRetVal )
1162     {
1163         pImp->EntrySelected( pEntry, bSelect );
1164         pHdlEntry = pEntry;
1165         if( bSelect )
1166         {
1167             SelectHdl();
1168             // pImp->CallEventListeners( VCLEVENT_LISTBOX_SELECT, pEntry );
1169             CallEventListeners( VCLEVENT_LISTBOX_TREESELECT, pEntry);
1170         }
1171         else
1172             DeselectHdl();
1173     }
1174     return bRetVal;
1175 }
1176 
SelectChilds(SvLBoxEntry * pParent,sal_Bool bSelect)1177 sal_uLong SvTreeListBox::SelectChilds( SvLBoxEntry* pParent, sal_Bool bSelect )
1178 {
1179     DBG_CHKTHIS(SvTreeListBox,0);
1180     pImp->DestroyAnchor();
1181     sal_uLong nRet = 0;
1182     if( !pParent->HasChilds() )
1183         return 0;
1184     sal_uInt16 nRefDepth = pModel->GetDepth( pParent );
1185     SvLBoxEntry* pChild = FirstChild( pParent );
1186     do {
1187         nRet++;
1188         Select( pChild, bSelect );
1189         pChild = Next( pChild );
1190     } while( pChild && pModel->GetDepth( pChild ) > nRefDepth );
1191     return nRet;
1192 }
1193 
SelectAll(sal_Bool bSelect,sal_Bool)1194 void SvTreeListBox::SelectAll( sal_Bool bSelect, sal_Bool )
1195 {
1196     DBG_CHKTHIS(SvTreeListBox,0);
1197     pImp->SelAllDestrAnch(
1198         bSelect,
1199         sal_True,       // Anker loeschen,
1200         sal_True );     // auch bei SINGLE_SELECTION den Cursor deselektieren
1201 }
1202 
ModelHasInsertedTree(SvListEntry * pEntry)1203 void SvTreeListBox::ModelHasInsertedTree( SvListEntry* pEntry )
1204 {
1205     DBG_CHKTHIS(SvTreeListBox,0);
1206     sal_uInt16 nRefDepth = pModel->GetDepth( (SvLBoxEntry*)pEntry );
1207     SvLBoxEntry* pTmp = (SvLBoxEntry*)pEntry;
1208     do
1209     {
1210         ImpEntryInserted( pTmp );
1211         pTmp = Next( pTmp );
1212     } while( pTmp && nRefDepth < pModel->GetDepth( pTmp ) );
1213     pImp->TreeInserted( (SvLBoxEntry*)pEntry );
1214 }
1215 
ModelHasInserted(SvListEntry * pEntry)1216 void SvTreeListBox::ModelHasInserted( SvListEntry* pEntry )
1217 {
1218     DBG_CHKTHIS(SvTreeListBox,0);
1219     ImpEntryInserted( (SvLBoxEntry*)pEntry );
1220     pImp->EntryInserted( (SvLBoxEntry*)pEntry );
1221 }
1222 
ModelIsMoving(SvListEntry * pSource,SvListEntry *,sal_uLong)1223 void SvTreeListBox::ModelIsMoving(SvListEntry* pSource,
1224                                         SvListEntry* /* pTargetParent */,
1225                                         sal_uLong /* nChildPos */ )
1226 {
1227     DBG_CHKTHIS(SvTreeListBox,0);
1228     pImp->MovingEntry( (SvLBoxEntry*)pSource );
1229 }
1230 
ModelHasMoved(SvListEntry * pSource)1231 void SvTreeListBox::ModelHasMoved( SvListEntry* pSource )
1232 {
1233     DBG_CHKTHIS(SvTreeListBox,0);
1234     pImp->EntryMoved( (SvLBoxEntry*)pSource );
1235 }
1236 
ModelIsRemoving(SvListEntry * pEntry)1237 void SvTreeListBox::ModelIsRemoving( SvListEntry* pEntry )
1238 {
1239     DBG_CHKTHIS(SvTreeListBox,0);
1240     if(pEdEntry == pEntry)
1241         pEdEntry = NULL;
1242 
1243     pImp->RemovingEntry( (SvLBoxEntry*)pEntry );
1244     NotifyRemoving( (SvLBoxEntry*)pEntry );
1245 }
1246 
ModelHasRemoved(SvListEntry * pEntry)1247 void SvTreeListBox::ModelHasRemoved( SvListEntry* pEntry  )
1248 {
1249     DBG_CHKTHIS(SvTreeListBox,0);
1250     if ( pEntry == pHdlEntry)
1251         pHdlEntry = NULL;
1252     pImp->EntryRemoved();
1253 }
1254 
SetCollapsedNodeBmp(const Image & rBmp,BmpColorMode _eMode)1255 void SvTreeListBox::SetCollapsedNodeBmp( const Image& rBmp, BmpColorMode _eMode )
1256 {
1257     DBG_CHKTHIS(SvTreeListBox,0);
1258     AdjustEntryHeight( rBmp );
1259     pImp->SetCollapsedNodeBmp( rBmp, _eMode );
1260 }
1261 
SetExpandedNodeBmp(const Image & rBmp,BmpColorMode _eMode)1262 void SvTreeListBox::SetExpandedNodeBmp( const Image& rBmp, BmpColorMode _eMode )
1263 {
1264     DBG_CHKTHIS(SvTreeListBox,0);
1265     AdjustEntryHeight( rBmp );
1266     pImp->SetExpandedNodeBmp( rBmp, _eMode );
1267 }
1268 
1269 
SetFont(const Font & rFont)1270 void SvTreeListBox::SetFont( const Font& rFont )
1271 {
1272     DBG_CHKTHIS(SvTreeListBox,0);
1273     Font aTempFont( rFont );
1274     aTempFont.SetTransparent( sal_True );
1275     Control::SetFont( aTempFont );
1276     AdjustEntryHeight( aTempFont );
1277     // immer Invalidieren, sonst fallen wir
1278     // bei SetEntryHeight auf die Nase
1279     RecalcViewData();
1280 }
1281 
1282 
Paint(const Rectangle & rRect)1283 void SvTreeListBox::Paint( const Rectangle& rRect )
1284 {
1285     DBG_CHKTHIS(SvTreeListBox,0);
1286     SvLBox::Paint( rRect );
1287     if( nTreeFlags & TREEFLAG_RECALCTABS )
1288         SetTabs();
1289     pImp->Paint( rRect );
1290     //Solution:Add visual focus draw
1291     if( !SvLBox::First() )
1292     {
1293         if( HasFocus() )
1294         {
1295             long tempHeight = GetTextHeight();
1296             Rectangle tempRect(
1297                                 Point(0,0),Size(GetSizePixel().Width(),tempHeight)
1298                                );
1299             ShowFocus(tempRect);
1300         }
1301 
1302         else{
1303             HideFocus();
1304         }
1305     }
1306 }
1307 
MouseButtonDown(const MouseEvent & rMEvt)1308 void SvTreeListBox::MouseButtonDown( const MouseEvent& rMEvt )
1309 {
1310     DBG_CHKTHIS(SvTreeListBox,0);
1311     pImp->MouseButtonDown( rMEvt );
1312 }
1313 
MouseButtonUp(const MouseEvent & rMEvt)1314 void SvTreeListBox::MouseButtonUp( const MouseEvent& rMEvt )
1315 {
1316     DBG_CHKTHIS(SvTreeListBox,0);
1317     pImp->MouseButtonUp( rMEvt );
1318 }
1319 
MouseMove(const MouseEvent & rMEvt)1320 void SvTreeListBox::MouseMove( const MouseEvent& rMEvt )
1321 {
1322     DBG_CHKTHIS(SvTreeListBox,0);
1323     pImp->MouseMove( rMEvt );
1324 }
1325 
1326 
SetUpdateMode(sal_Bool bUpdate)1327 void SvTreeListBox::SetUpdateMode( sal_Bool bUpdate )
1328 {
1329     DBG_CHKTHIS(SvTreeListBox,0);
1330     pImp->SetUpdateMode( bUpdate );
1331 }
1332 
SetUpdateModeFast(sal_Bool bUpdate)1333 void SvTreeListBox::SetUpdateModeFast( sal_Bool bUpdate )
1334 {
1335     DBG_CHKTHIS(SvTreeListBox,0);
1336     pImp->SetUpdateModeFast( bUpdate );
1337 }
1338 
SetSpaceBetweenEntries(short nOffsLogic)1339 void SvTreeListBox::SetSpaceBetweenEntries( short nOffsLogic )
1340 {
1341     DBG_CHKTHIS(SvTreeListBox,0);
1342     if( nOffsLogic != nEntryHeightOffs )
1343     {
1344         nEntryHeight = nEntryHeight - nEntryHeightOffs;
1345         nEntryHeightOffs = (short)nOffsLogic;
1346         nEntryHeight = nEntryHeight + nOffsLogic;
1347         AdjustEntryHeight( GetFont() );
1348         RecalcViewData();
1349         pImp->SetEntryHeight( nEntryHeight );
1350     }
1351 }
1352 
SetCursor(SvLBoxEntry * pEntry,sal_Bool bForceNoSelect)1353 void SvTreeListBox::SetCursor( SvLBoxEntry* pEntry, sal_Bool bForceNoSelect )
1354 {
1355     DBG_CHKTHIS(SvTreeListBox,0);
1356     pImp->SetCursor(pEntry, bForceNoSelect);
1357 }
1358 
SetCurEntry(SvLBoxEntry * pEntry)1359 void SvTreeListBox::SetCurEntry( SvLBoxEntry* pEntry )
1360 {
1361     DBG_CHKTHIS(SvTreeListBox,0);
1362     pImp->SetCurEntry( pEntry );
1363 }
1364 
GetCollapsedNodeBmp(BmpColorMode _eMode) const1365 Image SvTreeListBox::GetCollapsedNodeBmp( BmpColorMode _eMode ) const
1366 {
1367     return pImp->GetCollapsedNodeBmp( _eMode );
1368 }
1369 
GetExpandedNodeBmp(BmpColorMode _eMode) const1370 Image SvTreeListBox::GetExpandedNodeBmp( BmpColorMode _eMode ) const
1371 {
1372     return pImp->GetExpandedNodeBmp( _eMode );
1373 }
1374 
GetEntryPosition(SvLBoxEntry * pEntry) const1375 Point SvTreeListBox::GetEntryPosition( SvLBoxEntry* pEntry ) const
1376 {
1377     return pImp->GetEntryPosition( pEntry );
1378 }
1379 
ShowEntry(SvLBoxEntry * pEntry)1380 void SvTreeListBox::ShowEntry( SvLBoxEntry* pEntry )
1381 {
1382     MakeVisible( pEntry );
1383 }
1384 
MakeVisible(SvLBoxEntry * pEntry)1385 void SvTreeListBox::MakeVisible( SvLBoxEntry* pEntry )
1386 {
1387     pImp->MakeVisible(pEntry);
1388 }
1389 
MakeVisible(SvLBoxEntry * pEntry,sal_Bool bMoveToTop)1390 void SvTreeListBox::MakeVisible( SvLBoxEntry* pEntry, sal_Bool bMoveToTop )
1391 {
1392     pImp->MakeVisible( pEntry, bMoveToTop );
1393 }
1394 
ModelHasEntryInvalidated(SvListEntry * pEntry)1395 void SvTreeListBox::ModelHasEntryInvalidated( SvListEntry* pEntry )
1396 {
1397     DBG_CHKTHIS(SvTreeListBox,0);
1398     // die einzelnen Items des Entries reinitialisieren
1399     SvLBox::ModelHasEntryInvalidated( pEntry );
1400     // repainten
1401     pImp->InvalidateEntry( (SvLBoxEntry*)pEntry );
1402 }
1403 
EditItemText(SvLBoxEntry * pEntry,SvLBoxString * pItem,const Selection & rSelection)1404 void SvTreeListBox::EditItemText( SvLBoxEntry* pEntry, SvLBoxString* pItem,
1405     const Selection& rSelection )
1406 {
1407     DBG_CHKTHIS(SvTreeListBox,0);
1408     DBG_ASSERT(pEntry&&pItem,"EditItemText: Bad params");
1409     if( IsSelected( pEntry ))
1410     {
1411         pImp->ShowCursor( sal_False );
1412         SvListView::Select( pEntry, sal_False );
1413         PaintEntry( pEntry );
1414         SvListView::Select( pEntry, sal_True );
1415         pImp->ShowCursor( sal_True );
1416     }
1417     pEdEntry = pEntry;
1418     pEdItem = pItem;
1419     SvLBoxTab* pTab = GetTab( pEntry, pItem );
1420     DBG_ASSERT(pTab,"EditItemText:Tab not found");
1421 
1422     Size aItemSize( pItem->GetSize(this, pEntry) );
1423     Point aPos = GetEntryPosition( pEntry );
1424     aPos.Y() += ( nEntryHeight - aItemSize.Height() ) / 2;
1425     aPos.X() = GetTabPos( pEntry, pTab );
1426     long nOutputWidth = pImp->GetOutputSize().Width();
1427     Size aSize( nOutputWidth - aPos.X(), aItemSize.Height() );
1428     sal_uInt16 nPos = aTabs.GetPos( pTab );
1429     if( nPos+1 < aTabs.Count() )
1430     {
1431         SvLBoxTab* pRightTab = (SvLBoxTab*)aTabs.GetObject( nPos + 1 );
1432         long nRight = GetTabPos( pEntry, pRightTab );
1433         if( nRight <= nOutputWidth )
1434             aSize.Width() = nRight - aPos.X();
1435     }
1436     Point aOrigin( GetMapMode().GetOrigin() );
1437     aPos += aOrigin; // in Win-Koord umrechnen
1438     aSize.Width() -= aOrigin.X();
1439     Rectangle aRect( aPos, aSize );
1440 #ifdef OS2
1441     // Platz lassen fuer WB_BORDER
1442     aRect.Left() -= 2;
1443     aRect.Top() -= 3;
1444     aRect.Bottom() += 3;
1445 #endif
1446     EditText( pItem->GetText(), aRect, rSelection );
1447 }
1448 
CancelEditing()1449 void SvTreeListBox::CancelEditing()
1450 {
1451     DBG_CHKTHIS(SvTreeListBox,0);
1452     SvLBox::CancelTextEditing();
1453 }
1454 
EditEntry(SvLBoxEntry * pEntry)1455 void SvTreeListBox::EditEntry( SvLBoxEntry* pEntry )
1456 {
1457     pImp->aEditClickPos = Point( -1, -1 );
1458     ImplEditEntry( pEntry );
1459 }
1460 
ImplEditEntry(SvLBoxEntry * pEntry)1461 void SvTreeListBox::ImplEditEntry( SvLBoxEntry* pEntry )
1462 {
1463     DBG_CHKTHIS(SvTreeListBox,0);
1464     if( IsEditingActive() )
1465         EndEditing();
1466     if( !pEntry )
1467         pEntry = GetCurEntry();
1468     if( pEntry )
1469     {
1470         long nClickX = pImp->aEditClickPos.X();
1471         bool bIsMouseTriggered = nClickX >= 0;
1472 
1473         SvLBoxString* pItem = NULL;
1474         sal_uInt16 nCount = pEntry->ItemCount();
1475         for( sal_uInt16 i = 0 ; i < nCount ; i++ )
1476         {
1477             SvLBoxItem* pTmpItem = pEntry->GetItem( i );
1478             if( pTmpItem->IsA() != SV_ITEM_ID_LBOXSTRING )
1479                 continue;
1480 
1481             SvLBoxTab* pTab = GetTab( pEntry, pTmpItem );
1482             long nTabPos = pTab->GetPos();
1483             long nNextTabPos = -1;
1484             if( i < nCount - 1 )
1485             {
1486                 SvLBoxItem* pNextItem = pEntry->GetItem( i + 1 );
1487                 SvLBoxTab* pNextTab = GetTab( pEntry, pNextItem );
1488                 nNextTabPos = pNextTab->GetPos();
1489             }
1490 
1491             if( pTab && pTab->IsEditable() )
1492             {
1493                 if( !bIsMouseTriggered || (nClickX > nTabPos && (nNextTabPos == -1 || nClickX < nNextTabPos ) ) )
1494                 {
1495                     pItem = static_cast<SvLBoxString*>( pTmpItem );
1496                     break;
1497                 }
1498             }
1499         }
1500 
1501         Selection aSel( SELECTION_MIN, SELECTION_MAX );
1502         if( pItem && EditingEntry( pEntry, aSel ) )
1503         {
1504             SelectAll( sal_False );
1505             MakeVisible( pEntry );
1506             EditItemText( pEntry, pItem, aSel );
1507         }
1508     }
1509 }
1510 
AreChildrenTransient() const1511 sal_Bool SvTreeListBox::AreChildrenTransient() const
1512 {
1513     return pImp->AreChildrenTransient();
1514 }
1515 
SetChildrenNotTransient()1516 void SvTreeListBox::SetChildrenNotTransient()
1517 {
1518     pImp->SetChildrenNotTransient();
1519 }
1520 
EditedText(const XubString & rStr)1521 void SvTreeListBox::EditedText( const XubString& rStr )
1522 
1523 {
1524     DBG_CHKTHIS(SvTreeListBox,0);
1525     if(pEdEntry) // we have to check if this entry is null that means that it is removed while editing
1526     {
1527         Point aPos = GetEntryPosition( pEdEntry );
1528         if( EditedEntry( pEdEntry, rStr ) )
1529         {
1530             ((SvLBoxString*)pEdItem)->SetText( pEdEntry, rStr );
1531             pModel->InvalidateEntry( pEdEntry );
1532         }
1533         //if( GetSelectionMode() == SINGLE_SELECTION )
1534         //{
1535         if( GetSelectionCount() == 0 )
1536             Select( pEdEntry );
1537         if( GetSelectionMode() == MULTIPLE_SELECTION && !GetCurEntry() )
1538             SetCurEntry( pEdEntry );
1539         //}
1540     }
1541 }
1542 
EditingRequest(SvLBoxEntry * pEntry,SvLBoxItem * pItem,const Point &)1543 void SvTreeListBox::EditingRequest( SvLBoxEntry* pEntry, SvLBoxItem* pItem,
1544                                     const Point& )
1545 {
1546     DBG_CHKTHIS(SvTreeListBox,0);
1547     if( IsEditingActive() )
1548         EndEditing();
1549     if( pItem->IsA() == SV_ITEM_ID_LBOXSTRING )
1550     {
1551         Selection aSel( SELECTION_MIN, SELECTION_MAX );
1552         if( EditingEntry( pEntry, aSel ) )
1553         {
1554             SelectAll( sal_False );
1555             EditItemText( pEntry, (SvLBoxString*)pItem, aSel );
1556         }
1557     }
1558 }
1559 
1560 
1561 
GetDropTarget(const Point & rPos)1562 SvLBoxEntry* SvTreeListBox::GetDropTarget( const Point& rPos )
1563 {
1564     DBG_CHKTHIS(SvTreeListBox,0);
1565     // Scrollen
1566     if( rPos.Y() < 12 )
1567     {
1568         SvLBox::ImplShowTargetEmphasis( SvLBox::pTargetEntry, sal_False );
1569         ScrollOutputArea( +1 );
1570     }
1571     else
1572     {
1573         Size aSize( pImp->GetOutputSize() );
1574         if( rPos.Y() > aSize.Height() - 12 )
1575         {
1576             SvLBox::ImplShowTargetEmphasis( SvLBox::pTargetEntry, sal_False );
1577             ScrollOutputArea( -1 );
1578         }
1579     }
1580 
1581     SvLBoxEntry* pTarget = pImp->GetEntry( rPos );
1582     // bei Droppen in leere Flaeche -> den letzten Eintrag nehmen
1583     if( !pTarget )
1584         return (SvLBoxEntry*)LastVisible();
1585     else if( (GetDragDropMode() & SV_DRAGDROP_ENABLE_TOP) &&
1586              pTarget == First() && rPos.Y() < 6 )
1587         return 0;
1588 
1589     return pTarget;
1590 }
1591 
1592 
GetEntry(const Point & rPos,sal_Bool bHit) const1593 SvLBoxEntry* SvTreeListBox::GetEntry( const Point& rPos, sal_Bool bHit ) const
1594 {
1595     DBG_CHKTHIS(SvTreeListBox,0);
1596     SvLBoxEntry* pEntry = pImp->GetEntry( rPos );
1597     if( pEntry && bHit )
1598     {
1599         long nLine = pImp->GetEntryLine( pEntry );
1600         if( !(pImp->EntryReallyHit( pEntry, rPos, nLine)) )
1601             return 0;
1602     }
1603     return pEntry;
1604 }
1605 
GetCurEntry() const1606 SvLBoxEntry* SvTreeListBox::GetCurEntry() const
1607 {
1608     DBG_CHKTHIS(SvTreeListBox,0);
1609     return pImp->GetCurEntry();
1610 }
1611 
ImplInitStyle()1612 void SvTreeListBox::ImplInitStyle()
1613 {
1614     DBG_CHKTHIS(SvTreeListBox,0);
1615 
1616     const WinBits nWindowStyle = GetStyle();
1617 
1618     nTreeFlags |= TREEFLAG_RECALCTABS;
1619     if( nWindowStyle & WB_SORT )
1620     {
1621         GetModel()->SetSortMode( SortAscending );
1622         GetModel()->SetCompareHdl( LINK(this,SvTreeListBox,DefaultCompare));
1623     }
1624     else
1625     {
1626         GetModel()->SetSortMode( SortNone );
1627         GetModel()->SetCompareHdl( Link() );
1628     }
1629     pImp->SetStyle( nWindowStyle );
1630     pImp->Resize();
1631     Invalidate();
1632 }
1633 
PaintEntry(SvLBoxEntry * pEntry)1634 void SvTreeListBox::PaintEntry( SvLBoxEntry* pEntry )
1635 {
1636     DBG_CHKTHIS(SvTreeListBox,0);
1637     DBG_ASSERT(pEntry,"PaintEntry:No Entry");
1638     if( pEntry )
1639         pImp->PaintEntry( pEntry );
1640 }
1641 
InvalidateEntry(SvLBoxEntry * pEntry)1642 void SvTreeListBox::InvalidateEntry( SvLBoxEntry* pEntry )
1643 {
1644     DBG_CHKTHIS(SvTreeListBox,0);
1645     DBG_ASSERT(pEntry,"InvalidateEntry:No Entry");
1646     if( pEntry )
1647     {
1648         GetModel()->InvalidateEntry( pEntry );
1649     //  pImp->InvalidateEntry( pEntry );
1650     }
1651 }
1652 
1653 
PaintEntry(SvLBoxEntry * pEntry,long nLine,sal_uInt16 nTabFlags)1654 long SvTreeListBox::PaintEntry(SvLBoxEntry* pEntry,long nLine,sal_uInt16 nTabFlags)
1655 {
1656     return PaintEntry1(pEntry,nLine,nTabFlags);
1657 }
1658 
1659 #define SV_TAB_BORDER 8
1660 
PaintEntry1(SvLBoxEntry * pEntry,long nLine,sal_uInt16 nTabFlags,sal_Bool bHasClipRegion)1661 long SvTreeListBox::PaintEntry1(SvLBoxEntry* pEntry,long nLine,sal_uInt16 nTabFlags,
1662     sal_Bool bHasClipRegion )
1663 {
1664     DBG_CHKTHIS(SvTreeListBox,0);
1665 
1666     Rectangle aRect; // multi purpose
1667 
1668     sal_Bool bHorSBar = pImp->HasHorScrollBar();
1669     PreparePaint( pEntry );
1670 
1671     // #97680# ------------------
1672     pImp->UpdateContextBmpWidthMax( pEntry );
1673 
1674     if( nTreeFlags & TREEFLAG_RECALCTABS )
1675         SetTabs();
1676 
1677     short nTempEntryHeight = GetEntryHeight();
1678     long nWidth = pImp->GetOutputSize().Width();
1679 
1680     // wurde innerhalb des PreparePaints die horizontale ScrollBar
1681     // angeschaltet? Wenn ja, muss die ClipRegion neu gesetzt werden
1682     if( !bHorSBar && pImp->HasHorScrollBar() )
1683         SetClipRegion( Region(pImp->GetClipRegionRect()) );
1684 
1685     Point aEntryPos( GetMapMode().GetOrigin() );
1686     aEntryPos.X() *= -1; // Umrechnung Dokumentkoord.
1687     long nMaxRight = nWidth + aEntryPos.X() - 1;
1688 
1689     Color aBackupTextColor( GetTextColor() );
1690     Font aBackupFont( GetFont() );
1691     Color aBackupColor = GetFillColor();
1692 
1693     bool bCurFontIsSel = false;
1694     sal_Bool bInUse = pEntry->HasInUseEmphasis();
1695     // wenn eine ClipRegion von aussen gesetzt wird, dann
1696     // diese nicht zuruecksetzen
1697     const WinBits nWindowStyle = GetStyle();
1698     const sal_Bool bResetClipRegion = !bHasClipRegion;
1699     const sal_Bool bHideSelection = ((nWindowStyle & WB_HIDESELECTION) && !HasFocus())!=0;
1700     const StyleSettings& rSettings = GetSettings().GetStyleSettings();
1701 
1702     Font aHighlightFont( GetFont() );
1703     const Color aHighlightTextColor( rSettings.GetHighlightTextColor() );
1704     aHighlightFont.SetColor( aHighlightTextColor );
1705 
1706     Size aRectSize( 0, nTempEntryHeight );
1707 
1708     if( !bHasClipRegion && nWindowStyle & WB_HSCROLL )
1709     {
1710         SetClipRegion( Region(pImp->GetClipRegionRect()) );
1711         bHasClipRegion = sal_True;
1712     }
1713 
1714     SvViewDataEntry* pViewDataEntry = GetViewDataEntry( pEntry );
1715 
1716     sal_uInt16 nTabCount = aTabs.Count();
1717     sal_uInt16 nItemCount = pEntry->ItemCount();
1718     sal_uInt16 nCurTab = 0;
1719     sal_uInt16 nCurItem = 0;
1720 
1721     while( nCurTab < nTabCount && nCurItem < nItemCount )
1722     {
1723         SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( nCurTab );
1724         sal_uInt16 nNextTab = nCurTab + 1;
1725         SvLBoxTab* pNextTab = nNextTab < nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextTab) : 0;
1726         SvLBoxItem* pItem = nCurItem < nItemCount ? pEntry->GetItem(nCurItem) : 0;
1727 
1728         sal_uInt16 nFlags = pTab->nFlags;
1729         Size aSize( pItem->GetSize( pViewDataEntry, nCurItem ));
1730         long nTabPos = GetTabPos( pEntry, pTab );
1731 
1732         long nNextTabPos;
1733         if( pNextTab )
1734             nNextTabPos = GetTabPos( pEntry, pNextTab );
1735         else
1736         {
1737             nNextTabPos = nMaxRight;
1738             if( nTabPos > nMaxRight )
1739                 nNextTabPos += 50;
1740         }
1741 
1742         long nX;
1743         if( pTab->nFlags & SV_LBOXTAB_ADJUST_RIGHT )
1744             //verhindern, das rechter Rand von der Tabtrennung abgeschnitten wird
1745             nX = nTabPos + pTab->CalcOffset(aSize.Width(), (nNextTabPos-SV_TAB_BORDER-1) -nTabPos);
1746         else
1747             nX = nTabPos + pTab->CalcOffset(aSize.Width(), nNextTabPos-nTabPos);
1748 
1749         if( nFlags & nTabFlags )
1750         {
1751             if( !bHasClipRegion && nX + aSize.Width() >= nMaxRight )
1752             {
1753                 SetClipRegion( Region(pImp->GetClipRegionRect()) );
1754                 bHasClipRegion = sal_True;
1755             }
1756             aEntryPos.X() = nX;
1757             aEntryPos.Y() = nLine;
1758 
1759             // Hintergrund-Muster & Farbe bestimmen
1760 
1761             Wallpaper aWallpaper = GetBackground();
1762 
1763             int bSelTab = nFlags & SV_LBOXTAB_SHOW_SELECTION;
1764             sal_uInt16 nItemType = pItem->IsA();
1765 
1766             if ( pViewDataEntry->IsSelected() && bSelTab && !pViewDataEntry->IsCursored() )
1767             {
1768                 Color aNewWallColor = rSettings.GetHighlightColor();
1769                 if ( !bInUse || nItemType != SV_ITEM_ID_LBOXCONTEXTBMP )
1770                 {
1771                     // if the face color is bright then the deactive color is also bright
1772                     // -> so you can't see any deactive selection
1773                     if ( bHideSelection && !rSettings.GetFaceColor().IsBright() &&
1774                          aWallpaper.GetColor().IsBright() != rSettings.GetDeactiveColor().IsBright() )
1775                         aNewWallColor = rSettings.GetDeactiveColor();
1776                     // set font color to highlight
1777                     if ( !bCurFontIsSel )
1778                     {
1779                         SetTextColor( aHighlightTextColor );
1780                         SetFont( aHighlightFont );
1781                         bCurFontIsSel = true;
1782                     }
1783                 }
1784                 aWallpaper.SetColor( aNewWallColor );
1785             }
1786             else  // keine Selektion
1787             {
1788                 if( bInUse && nItemType == SV_ITEM_ID_LBOXCONTEXTBMP )
1789                     aWallpaper.SetColor( rSettings.GetFieldColor() );
1790                 else if( bCurFontIsSel )
1791                 {
1792                     bCurFontIsSel = false;
1793                     SetTextColor( aBackupTextColor );
1794                     SetFont( aBackupFont );
1795                 }
1796             }
1797 
1798             // Hintergrund zeichnen
1799             if( !(nTreeFlags & TREEFLAG_USESEL))
1800             {
1801                 // nur den Bereich zeichnen, den das Item einnimmt
1802                 aRectSize.Width() = aSize.Width();
1803                 aRect.SetPos( aEntryPos );
1804                 aRect.SetSize( aRectSize );
1805             }
1806             else
1807             {
1808                 // vom aktuellen bis zum naechsten Tab zeichnen
1809                 if( nCurTab != 0 )
1810                     aRect.Left() = nTabPos;
1811                 else
1812                     // beim nullten Tab immer ab Spalte 0 zeichnen
1813                     // (sonst Probleme bei Tabs mit Zentrierung)
1814                     aRect.Left() = 0;
1815                 aRect.Top() = nLine;
1816                 aRect.Bottom() = nLine + nTempEntryHeight - 1;
1817                 if( pNextTab )
1818                 {
1819                     long nRight;
1820                     nRight = GetTabPos(pEntry,pNextTab)-1;
1821                     if( nRight > nMaxRight )
1822                         nRight = nMaxRight;
1823                     aRect.Right() = nRight;
1824                 }
1825                 else
1826                     aRect.Right() = nMaxRight;
1827             }
1828             // bei anwenderdefinierter Selektion, die bei einer Tabposition
1829             // groesser 0 beginnt den Hintergrund des 0.ten Items nicht
1830             // fuellen, da sonst z.B. TablistBoxen mit Linien nicht
1831             // realisiert werden koennen.
1832             if( !(nCurTab==0 && (nTreeFlags & TREEFLAG_USESEL) && nFirstSelTab) )
1833             {
1834                 SetFillColor( aWallpaper.GetColor() );
1835                 // Bei kleinen hor. Resizes tritt dieser Fall auf
1836                 if( aRect.Left() < aRect.Right() )
1837                     DrawRect( aRect );
1838             }
1839             // Item zeichnen
1840             // vertikal zentrieren
1841             aEntryPos.Y() += ( nTempEntryHeight - aSize.Height() ) / 2;
1842             pItem->Paint( aEntryPos, *this, pViewDataEntry->GetFlags(), pEntry );
1843 
1844             // Trennungslinie zwischen Tabs
1845             if( pNextTab && pItem->IsA() == SV_ITEM_ID_LBOXSTRING &&
1846                 // nicht am rechten Fensterrand!
1847                 aRect.Right() < nMaxRight )
1848             {
1849                 aRect.Left() = aRect.Right() - SV_TAB_BORDER;
1850                 DrawRect( aRect );
1851             }
1852 
1853             SetFillColor( aBackupColor );
1854         }
1855         nCurItem++;
1856         nCurTab++;
1857     }
1858     if( pViewDataEntry->IsCursored() && !HasFocus() )
1859     {
1860         // Cursor-Emphasis
1861         SetFillColor();
1862         Color aOldLineColor = GetLineColor();
1863         SetLineColor( Color( COL_BLACK ) );
1864         aRect = GetFocusRect( pEntry, nLine );
1865         aRect.Top()++;
1866         aRect.Bottom()--;
1867         DrawRect( aRect );
1868         SetLineColor( aOldLineColor );
1869         SetFillColor( aBackupColor );
1870     }
1871 
1872     if( bCurFontIsSel )
1873     {
1874         SetTextColor( aBackupTextColor );
1875         SetFont( aBackupFont );
1876     }
1877 
1878     sal_uInt16 nFirstDynTabPos;
1879     SvLBoxTab* pFirstDynamicTab = GetFirstDynamicTab( nFirstDynTabPos );
1880     long nDynTabPos = GetTabPos( pEntry, pFirstDynamicTab );
1881     nDynTabPos += pImp->nNodeBmpTabDistance;
1882     nDynTabPos += pImp->nNodeBmpWidth / 2;
1883     nDynTabPos += 4; // 4 Pixel Reserve, damit die Node-Bitmap
1884                      // nicht zu nah am naechsten Tab steht
1885 
1886     if( (!(pEntry->GetFlags() & SV_ENTRYFLAG_NO_NODEBMP)) &&
1887         (nWindowStyle & WB_HASBUTTONS) && pFirstDynamicTab &&
1888         ( pEntry->HasChilds() || pEntry->HasChildsOnDemand() ) )
1889     {
1890         // ersten festen Tab suchen, und pruefen ob die Node-Bitmap
1891         // in ihn hineinragt
1892         sal_uInt16 nNextTab = nFirstDynTabPos;
1893         SvLBoxTab* pNextTab;
1894         do
1895         {
1896             nNextTab++;
1897             pNextTab = nNextTab < nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextTab) : 0;
1898         } while( pNextTab && pNextTab->IsDynamic() );
1899 
1900         if( !pNextTab || (GetTabPos( pEntry, pNextTab ) > nDynTabPos) )
1901         {
1902             if((nWindowStyle & WB_HASBUTTONSATROOT) || pModel->GetDepth(pEntry) > 0)
1903             {
1904                 Point aPos( GetTabPos(pEntry,pFirstDynamicTab), nLine );
1905                 aPos.X() += pImp->nNodeBmpTabDistance;
1906 
1907                 const Image* pImg = 0;
1908                 BmpColorMode eBitmapMode = BMP_COLOR_NORMAL;
1909                 if ( GetSettings().GetStyleSettings().GetHighContrastMode() )
1910                     eBitmapMode = BMP_COLOR_HIGHCONTRAST;
1911 
1912                 if( IsExpanded(pEntry) )
1913                     pImg = &pImp->GetExpandedNodeBmp( eBitmapMode );
1914                 else
1915                 {
1916                     if( (!pEntry->HasChilds()) && pEntry->HasChildsOnDemand() &&
1917                         (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) &&
1918                         pImp->GetDontKnowNodeBmp().GetSizePixel().Width() )
1919                         pImg = &pImp->GetDontKnowNodeBmp( eBitmapMode );
1920                     else
1921                         pImg = &pImp->GetCollapsedNodeBmp( eBitmapMode );
1922                 }
1923                 aPos.Y() += (nTempEntryHeight - pImg->GetSizePixel().Height()) / 2;
1924 
1925                 sal_uInt16 nStyle = 0;
1926                 if ( !IsEnabled() )
1927                     nStyle |= IMAGE_DRAW_DISABLE;
1928 
1929                 //native
1930                 sal_Bool bNativeOK = sal_False;
1931                 if ( IsNativeControlSupported( CTRL_LISTNODE, PART_ENTIRE_CONTROL) )
1932                 {
1933                     ImplControlValue    aControlValue;
1934                     Rectangle           aCtrlRegion( aPos,  pImg->GetSizePixel() );
1935                     ControlState        nState = 0;
1936 
1937                     if ( IsEnabled() )  nState |= CTRL_STATE_ENABLED;
1938 
1939                     if ( IsExpanded(pEntry) )
1940                         aControlValue.setTristateVal( BUTTONVALUE_ON );//expanded node
1941                     else
1942                     {
1943                         if( (!pEntry->HasChilds()) && pEntry->HasChildsOnDemand() &&
1944                             (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) &&
1945                             pImp->GetDontKnowNodeBmp().GetSizePixel().Width() )
1946                             aControlValue.setTristateVal( BUTTONVALUE_DONTKNOW );//dont know
1947                         else
1948                             aControlValue.setTristateVal( BUTTONVALUE_OFF );//collapsed node
1949                     }
1950 
1951                     bNativeOK = DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL,
1952                                             aCtrlRegion, nState, aControlValue, rtl::OUString() );
1953                 }
1954 
1955                 if( !bNativeOK) {
1956                 //non native
1957                     DrawImage( aPos, *pImg ,nStyle);
1958                 }
1959             }
1960         }
1961     }
1962 
1963 
1964     if( bHasClipRegion && bResetClipRegion )
1965         SetClipRegion();
1966     return 0; // nRowLen;
1967 }
1968 
PreparePaint(SvLBoxEntry *)1969 void SvTreeListBox::PreparePaint( SvLBoxEntry* )
1970 {
1971 }
1972 
GetFocusRect(SvLBoxEntry * pEntry,long nLine)1973 Rectangle SvTreeListBox::GetFocusRect( SvLBoxEntry* pEntry, long nLine )
1974 {
1975     DBG_CHKTHIS(SvTreeListBox,0);
1976     Size aSize;
1977     Rectangle aRect;
1978     aRect.Top() = nLine;
1979     aSize.Height() = GetEntryHeight();
1980 
1981     long nRealWidth = pImp->GetOutputSize().Width();
1982     nRealWidth -= GetMapMode().GetOrigin().X();
1983 
1984     sal_uInt16 nCurTab;
1985     SvLBoxTab* pTab = GetFirstTab( SV_LBOXTAB_SHOW_SELECTION, nCurTab );
1986     long nTabPos = 0;
1987     if( pTab )
1988         nTabPos = GetTabPos( pEntry, pTab );
1989     long nNextTabPos;
1990     if( pTab && nCurTab < aTabs.Count() - 1 )
1991     {
1992         SvLBoxTab* pNextTab = (SvLBoxTab*)aTabs.GetObject( nCurTab + 1 );
1993         nNextTabPos = GetTabPos( pEntry, pNextTab );
1994     }
1995     else
1996     {
1997         nNextTabPos = nRealWidth;
1998         if( nTabPos > nRealWidth )
1999             nNextTabPos += 50;
2000     }
2001 
2002     sal_Bool bUserSelection = (sal_Bool)( nTreeFlags & TREEFLAG_USESEL ) != 0;
2003     if( !bUserSelection )
2004     {
2005         if( pTab && nCurTab < pEntry->ItemCount() )
2006         {
2007             SvLBoxItem* pItem = pEntry->GetItem( nCurTab );
2008             aSize.Width() = pItem->GetSize( this, pEntry ).Width();
2009             if( !aSize.Width() )
2010                 aSize.Width() = 15;
2011             long nX = nTabPos; //GetTabPos( pEntry, pTab );
2012             // Ausrichtung
2013             nX += pTab->CalcOffset( aSize.Width(), nNextTabPos - nTabPos );
2014             aRect.Left() = nX;
2015             // damit erster & letzter Buchstabe nicht angeknabbert werden
2016             aRect.SetSize( aSize );
2017             if( aRect.Left() > 0 )
2018                 aRect.Left()--;
2019             aRect.Right()++;
2020         }
2021     }
2022     else
2023     {
2024         // wenn erster SelTab != 0, dann muessen wir auch rechnen
2025         if( nFocusWidth == -1 || nFirstSelTab )
2026         {
2027             sal_uInt16 nLastTab;
2028             SvLBoxTab* pLastTab = GetLastTab(SV_LBOXTAB_SHOW_SELECTION,nLastTab);
2029             nLastTab++;
2030             if( nLastTab < aTabs.Count() ) // gibts noch einen ?
2031                 pLastTab = (SvLBoxTab*)aTabs.GetObject( nLastTab );
2032             else
2033                 pLastTab = 0;  // ueber gesamte Breite selektieren
2034             aSize.Width() = pLastTab ? pLastTab->GetPos() : 0x0fffffff;
2035             nFocusWidth = (short)aSize.Width();
2036             if( pTab )
2037                 nFocusWidth = nFocusWidth - (short)nTabPos; //pTab->GetPos();
2038         }
2039         else
2040         {
2041             aSize.Width() = nFocusWidth;
2042             if( pTab )
2043             {
2044                 if( nCurTab )
2045                     aSize.Width() += nTabPos;
2046                 else
2047                     aSize.Width() += pTab->GetPos(); // Tab0 immer ab ganz links
2048             }
2049         }
2050         // wenn Sel. beim nullten Tab anfaengt, dann ab Spalte 0 sel. zeichnen
2051         if( nCurTab != 0 )
2052         {
2053             aRect.Left() = nTabPos;
2054             aSize.Width() -= nTabPos;
2055         }
2056         aRect.SetSize( aSize );
2057     }
2058     // rechten Rand anpassen wg. Clipping
2059     if( aRect.Right() >= nRealWidth )
2060     {
2061         aRect.Right() = nRealWidth-1;
2062         nFocusWidth = (short)aRect.GetWidth();
2063     }
2064     return aRect;
2065 }
2066 
2067 
GetTabPos(SvLBoxEntry * pEntry,SvLBoxTab * pTab)2068 long SvTreeListBox::GetTabPos( SvLBoxEntry* pEntry, SvLBoxTab* pTab)
2069 {
2070     DBG_CHKTHIS(SvTreeListBox,0);
2071     DBG_ASSERT(pTab,"No Tab");
2072     long nPos = pTab->GetPos();
2073     if( pTab->IsDynamic() )
2074     {
2075         sal_uInt16 nDepth = pModel->GetDepth( pEntry );
2076         nDepth = nDepth * (sal_uInt16)nIndent;
2077         nPos += (long)nDepth;
2078     }
2079     return nPos;
2080 }
2081 
GetItem_Impl(SvLBoxEntry * pEntry,long nX,SvLBoxTab ** ppTab,sal_uInt16 nEmptyWidth)2082 SvLBoxItem* SvTreeListBox::GetItem_Impl( SvLBoxEntry* pEntry, long nX,
2083     SvLBoxTab** ppTab, sal_uInt16 nEmptyWidth )
2084 {
2085     DBG_CHKTHIS(SvTreeListBox,0);
2086     SvLBoxItem* pItemClicked = 0;
2087     sal_uInt16 nTabCount = aTabs.Count();
2088     sal_uInt16 nItemCount = pEntry->ItemCount();
2089     SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(0);
2090     SvLBoxItem* pItem = pEntry->GetItem(0);
2091     sal_uInt16 nNextItem = 1;
2092     nX -= GetMapMode().GetOrigin().X();
2093     long nRealWidth = pImp->GetOutputSize().Width();
2094     nRealWidth -= GetMapMode().GetOrigin().X();
2095 
2096     while( 1 )
2097     {
2098         SvLBoxTab* pNextTab=nNextItem<nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextItem) : 0;
2099         long nStart = GetTabPos( pEntry, pTab );
2100 
2101         long nNextTabPos;
2102         if( pNextTab )
2103             nNextTabPos = GetTabPos( pEntry, pNextTab );
2104         else
2105         {
2106             nNextTabPos = nRealWidth;
2107             if( nStart > nRealWidth )
2108                 nNextTabPos += 50;
2109         }
2110 
2111         Size aItemSize( pItem->GetSize(this, pEntry));
2112         nStart += pTab->CalcOffset( aItemSize.Width(), nNextTabPos - nStart );
2113         long nLen = aItemSize.Width();
2114         if( pNextTab )
2115         {
2116             long nTabWidth = GetTabPos( pEntry, pNextTab ) - nStart;
2117             if( nTabWidth < nLen )
2118                 nLen = nTabWidth;
2119         }
2120 
2121         if( !nLen )
2122             nLen = nEmptyWidth;
2123 
2124         if( nX >= nStart && nX < (nStart+nLen ) )
2125         {
2126             pItemClicked = pItem;
2127             if( ppTab )
2128             {
2129                 *ppTab = pTab;
2130                 break;
2131             }
2132         }
2133         if( nNextItem >= nItemCount || nNextItem >= nTabCount)
2134             break;
2135         pTab = (SvLBoxTab*)aTabs.GetObject( nNextItem );
2136         pItem = pEntry->GetItem( nNextItem );
2137         nNextItem++;
2138     }
2139     return pItemClicked;
2140 }
2141 
GetItem(SvLBoxEntry * pEntry,long nX,SvLBoxTab ** ppTab)2142 SvLBoxItem* SvTreeListBox::GetItem(SvLBoxEntry* pEntry,long nX,SvLBoxTab** ppTab)
2143 {
2144     return GetItem_Impl( pEntry, nX, ppTab, 0 );
2145 }
2146 
GetItem(SvLBoxEntry * pEntry,long nX)2147 SvLBoxItem* SvTreeListBox::GetItem(SvLBoxEntry* pEntry,long nX )
2148 {
2149     DBG_CHKTHIS(SvTreeListBox,0);
2150     SvLBoxTab* pDummyTab;
2151     return GetItem_Impl( pEntry, nX, &pDummyTab, 0 );
2152 }
2153 
GetFirstDynamicItem(SvLBoxEntry * pEntry)2154 SvLBoxItem* SvTreeListBox::GetFirstDynamicItem( SvLBoxEntry* pEntry )
2155 {
2156     DBG_CHKTHIS(SvTreeListBox,0);
2157 
2158     SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(0);
2159     SvLBoxItem* pItem = pEntry->GetItem(0);
2160     sal_uInt16 nTabCount = aTabs.Count();
2161 
2162     sal_uInt16 nNext = 1;
2163     while ( !pTab->IsDynamic() && nNext < nTabCount )
2164     {
2165         pItem = pEntry->GetItem( nNext );
2166         pTab = (SvLBoxTab*)aTabs.GetObject( nNext );
2167         nNext++;
2168     }
2169     return pItem;
2170 }
2171 
AddTab(long nTabPos,sal_uInt16 nFlags,void * pUserData)2172 void SvTreeListBox::AddTab(long nTabPos,sal_uInt16 nFlags,void* pUserData )
2173 {
2174     DBG_CHKTHIS(SvTreeListBox,0);
2175     nFocusWidth = -1;
2176     SvLBoxTab* pTab = new SvLBoxTab( nTabPos, nFlags );
2177     pTab->SetUserData( pUserData );
2178     aTabs.Insert( pTab, aTabs.Count() );
2179     if( nTreeFlags & TREEFLAG_USESEL )
2180     {
2181         sal_uInt16 nPos = aTabs.Count() - 1;
2182         if( nPos >= nFirstSelTab && nPos <= nLastSelTab )
2183             pTab->nFlags |= SV_LBOXTAB_SHOW_SELECTION;
2184         else
2185             // String-Items werden normalerweise immer selektiert
2186             // deshalb explizit ausschalten
2187             pTab->nFlags &= ~SV_LBOXTAB_SHOW_SELECTION;
2188     }
2189 }
2190 
2191 
2192 
GetFirstDynamicTab(sal_uInt16 & rPos) const2193 SvLBoxTab* SvTreeListBox::GetFirstDynamicTab( sal_uInt16& rPos ) const
2194 {
2195     DBG_CHKTHIS(SvTreeListBox,0);
2196     sal_uInt16 nCurTab = 0;
2197     sal_uInt16 nTabCount = aTabs.Count();
2198     while( nCurTab < nTabCount )
2199     {
2200         SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(nCurTab);
2201         if( pTab->nFlags & SV_LBOXTAB_DYNAMIC )
2202         {
2203             rPos = nCurTab;
2204             return pTab;
2205         }
2206         nCurTab++;
2207     }
2208     return 0;
2209 }
2210 
GetFirstDynamicTab() const2211 SvLBoxTab* SvTreeListBox::GetFirstDynamicTab() const
2212 {
2213     sal_uInt16 nDummy;
2214     return GetFirstDynamicTab( nDummy );
2215 }
2216 
GetTab(SvLBoxEntry * pEntry,SvLBoxItem * pItem) const2217 SvLBoxTab* SvTreeListBox::GetTab( SvLBoxEntry* pEntry, SvLBoxItem* pItem) const
2218 {
2219     DBG_CHKTHIS(SvTreeListBox,0);
2220     sal_uInt16 nPos = pEntry->GetPos( pItem );
2221     return (SvLBoxTab*)aTabs.GetObject( nPos );
2222 }
2223 
ClearTabList()2224 void SvTreeListBox::ClearTabList()
2225 {
2226     DBG_CHKTHIS(SvTreeListBox,0);
2227     sal_uInt16 nTabCount = aTabs.Count();
2228     while( nTabCount )
2229     {
2230         nTabCount--;
2231         SvLBoxTab* pDelTab = (SvLBoxTab*)aTabs.GetObject( nTabCount );
2232         delete pDelTab;
2233     }
2234     aTabs.Remove(0,aTabs.Count());
2235 }
2236 
2237 
GetOutputSizePixel() const2238 Size SvTreeListBox::GetOutputSizePixel() const
2239 {
2240     DBG_CHKTHIS(SvTreeListBox,0);
2241     Size aSize = pImp->GetOutputSize();
2242     return aSize;
2243 }
2244 
NotifyBeginScroll()2245 void SvTreeListBox::NotifyBeginScroll()
2246 {
2247     DBG_CHKTHIS(SvTreeListBox,0);
2248 }
2249 
NotifyEndScroll()2250 void SvTreeListBox::NotifyEndScroll()
2251 {
2252     DBG_CHKTHIS(SvTreeListBox,0);
2253 }
2254 
NotifyScrolling(long)2255 void SvTreeListBox::NotifyScrolling( long )
2256 {
2257     DBG_CHKTHIS(SvTreeListBox,0);
2258 }
2259 
NotifyScrolled()2260 void SvTreeListBox::NotifyScrolled()
2261 {
2262     DBG_CHKTHIS(SvTreeListBox,0);
2263     aScrolledHdl.Call( this );
2264 }
2265 
NotifyInvalidating()2266 void SvTreeListBox::NotifyInvalidating()
2267 {
2268     DBG_CHKTHIS(SvTreeListBox,0);
2269 }
2270 
Invalidate(sal_uInt16 nInvalidateFlags)2271 void SvTreeListBox::Invalidate( sal_uInt16 nInvalidateFlags )
2272 {
2273     DBG_CHKTHIS(SvTreeListBox,0);
2274     if( nFocusWidth == -1 )
2275         // damit Control nicht nach dem Paint ein falsches FocusRect anzeigt
2276         pImp->RecalcFocusRect();
2277     NotifyInvalidating();
2278     SvLBox::Invalidate( nInvalidateFlags );
2279     pImp->Invalidate();
2280 }
2281 
Invalidate(const Rectangle & rRect,sal_uInt16 nInvalidateFlags)2282 void SvTreeListBox::Invalidate( const Rectangle& rRect, sal_uInt16 nInvalidateFlags )
2283 {
2284     DBG_CHKTHIS(SvTreeListBox,0);
2285     if( nFocusWidth == -1 )
2286         // damit Control nicht nach dem Paint ein falsches FocusRect anzeigt
2287         pImp->RecalcFocusRect();
2288     NotifyInvalidating();
2289     SvLBox::Invalidate( rRect, nInvalidateFlags );
2290 }
2291 
2292 
SetHighlightRange(sal_uInt16 nStart,sal_uInt16 nEnd)2293 void SvTreeListBox::SetHighlightRange( sal_uInt16 nStart, sal_uInt16 nEnd)
2294 {
2295     DBG_CHKTHIS(SvTreeListBox,0);
2296 
2297     sal_uInt16 nTemp;
2298     nTreeFlags |= TREEFLAG_USESEL;
2299     if( nStart > nEnd )
2300     {
2301         nTemp = nStart;
2302         nStart = nEnd;
2303         nEnd = nTemp;
2304     }
2305     // alle Tabs markieren, die im Bereich liegen
2306     nTreeFlags |= TREEFLAG_RECALCTABS;
2307     nFirstSelTab = nStart;
2308     nLastSelTab = nEnd;
2309     pImp->RecalcFocusRect();
2310 }
2311 
RemoveHighlightRange()2312 void SvTreeListBox::RemoveHighlightRange()
2313 {
2314     DBG_CHKTHIS(SvTreeListBox,0);
2315     nTreeFlags &= (~TREEFLAG_USESEL);
2316     if( IsUpdateMode() )
2317         Invalidate();
2318 }
2319 
GetAscInsertionPos(SvLBoxEntry *,SvLBoxEntry *)2320 sal_uLong SvTreeListBox::GetAscInsertionPos(SvLBoxEntry*,SvLBoxEntry*)
2321 {
2322     return LIST_APPEND;
2323 }
2324 
GetDescInsertionPos(SvLBoxEntry *,SvLBoxEntry *)2325 sal_uLong SvTreeListBox::GetDescInsertionPos(SvLBoxEntry*,SvLBoxEntry*)
2326 {
2327     DBG_CHKTHIS(SvTreeListBox,0);
2328     return LIST_APPEND;
2329 }
2330 
GetDragRegion() const2331 Region SvTreeListBox::GetDragRegion() const
2332 {
2333     DBG_CHKTHIS(SvTreeListBox,0);
2334     Rectangle aRect;
2335     SvLBoxEntry* pEntry = GetCurEntry();
2336     if( pEntry )
2337     {
2338         Point aPos = GetEntryPosition( pEntry );
2339         aRect = ((SvTreeListBox*)this)->GetFocusRect( pEntry, aPos.Y() );
2340     }
2341     Region aRegion( aRect );
2342     return aRegion;
2343 }
2344 
2345 
Command(const CommandEvent & rCEvt)2346 void SvTreeListBox::Command( const CommandEvent& rCEvt )
2347 {
2348     DBG_CHKTHIS(SvTreeListBox,0);
2349     // FIXME gnumake2 resync to DEV300_m84
2350     pImp->Command( rCEvt );
2351 }
2352 
2353 
RemoveParentKeepChilds(SvLBoxEntry * pParent)2354 void SvTreeListBox::RemoveParentKeepChilds( SvLBoxEntry* pParent )
2355 {
2356     DBG_CHKTHIS(SvTreeListBox,0);
2357     DBG_ASSERT(pParent,"RemoveParentKeepChilds:No Parent");
2358     SvLBoxEntry* pNewParent = GetParent( pParent );
2359     if( pParent->HasChilds())
2360     {
2361         SvLBoxEntry* pChild = FirstChild( pParent );
2362         while( pChild )
2363         {
2364             pModel->Move( pChild, pNewParent, LIST_APPEND );
2365             pChild = FirstChild( pParent );
2366         }
2367     }
2368     pModel->Remove( pParent );
2369 }
2370 
GetFirstTab(sal_uInt16 nFlagMask,sal_uInt16 & rPos)2371 SvLBoxTab* SvTreeListBox::GetFirstTab( sal_uInt16 nFlagMask, sal_uInt16& rPos )
2372 {
2373     sal_uInt16 nTabCount = aTabs.Count();
2374     for( sal_uInt16 nPos = 0; nPos < nTabCount; nPos++ )
2375     {
2376         SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( nPos );
2377         if( (pTab->nFlags & nFlagMask) )
2378         {
2379             rPos = nPos;
2380             return pTab;
2381         }
2382     }
2383     rPos = 0xffff;
2384     return 0;
2385 }
2386 
GetLastTab(sal_uInt16 nFlagMask,sal_uInt16 & rTabPos)2387 SvLBoxTab* SvTreeListBox::GetLastTab( sal_uInt16 nFlagMask, sal_uInt16& rTabPos )
2388 {
2389     short nTabCount = (short)aTabs.Count();
2390     if( nTabCount )
2391     {
2392         for( short nPos = nTabCount-1; nPos >= 0; nPos-- )
2393         {
2394             SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( (sal_uInt16)nPos );
2395             if( (pTab->nFlags & nFlagMask) )
2396             {
2397                 rTabPos = (sal_uInt16)nPos;
2398                 return pTab;
2399             }
2400         }
2401     }
2402     rTabPos = 0xffff;
2403     return 0;
2404 }
2405 
SetAddMode(sal_Bool bAdd)2406 void SvTreeListBox::SetAddMode( sal_Bool bAdd )
2407 {
2408     pImp->SetAddMode( bAdd );
2409 }
2410 
IsAddMode() const2411 sal_Bool SvTreeListBox::IsAddMode() const
2412 {
2413     return pImp->IsAddMode();
2414 }
2415 
RequestHelp(const HelpEvent & rHEvt)2416 void SvTreeListBox::RequestHelp( const HelpEvent& rHEvt )
2417 {
2418     if( !pImp->RequestHelp( rHEvt ) )
2419         SvLBox::RequestHelp( rHEvt );
2420 }
2421 
CursorMoved(SvLBoxEntry *)2422 void SvTreeListBox::CursorMoved( SvLBoxEntry* )
2423 {
2424 }
2425 
IMPL_LINK(SvTreeListBox,DefaultCompare,SvSortData *,pData)2426 IMPL_LINK( SvTreeListBox, DefaultCompare, SvSortData*, pData )
2427 {
2428     SvLBoxEntry* pLeft = (SvLBoxEntry*)(pData->pLeft );
2429     SvLBoxEntry* pRight = (SvLBoxEntry*)(pData->pRight );
2430     String aLeft( ((SvLBoxString*)(pLeft->GetFirstItem(SV_ITEM_ID_LBOXSTRING)))->GetText());
2431     String aRight( ((SvLBoxString*)(pRight->GetFirstItem(SV_ITEM_ID_LBOXSTRING)))->GetText());
2432     // #102891# ----------------
2433     pImp->UpdateIntlWrapper();
2434     return pImp->pIntlWrapper->getCaseCollator()->compareString( aLeft, aRight );
2435 }
2436 
ModelNotification(sal_uInt16 nActionId,SvListEntry * pEntry1,SvListEntry * pEntry2,sal_uLong nPos)2437 void SvTreeListBox::ModelNotification( sal_uInt16 nActionId, SvListEntry* pEntry1,
2438                         SvListEntry* pEntry2, sal_uLong nPos )
2439 {
2440     if( nActionId == LISTACTION_CLEARING )
2441         CancelTextEditing();
2442 
2443     SvLBox::ModelNotification( nActionId, pEntry1, pEntry2, nPos );
2444     switch( nActionId )
2445     {
2446         case LISTACTION_INSERTED:
2447         {
2448             SvLBoxEntry* pEntry( dynamic_cast< SvLBoxEntry* >( pEntry1 ) );
2449             ENSURE_OR_BREAK( pEntry, "SvTreeListBox::ModelNotification: invalid entry!" );
2450             SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
2451             if ( !pBmpItem )
2452                 break;
2453             const Image& rBitmap1( pBmpItem->GetBitmap1() );
2454             const Image& rBitmap2( pBmpItem->GetBitmap2() );
2455             short nMaxWidth = short( Max( rBitmap1.GetSizePixel().Width(), rBitmap2.GetSizePixel().Width() ) );
2456             nMaxWidth = pImp->UpdateContextBmpWidthVector( pEntry, nMaxWidth );
2457             if( nMaxWidth > nContextBmpWidthMax )
2458             {
2459                 nContextBmpWidthMax = nMaxWidth;
2460                 SetTabs();
2461             }
2462         }
2463         break;
2464 
2465         case LISTACTION_RESORTING:
2466             SetUpdateMode( sal_False );
2467             break;
2468 
2469         case LISTACTION_RESORTED:
2470             // nach Sortierung den ersten Eintrag anzeigen, dabei die
2471             // Selektion erhalten.
2472             MakeVisible( (SvLBoxEntry*)pModel->First(), sal_True );
2473             SetUpdateMode( sal_True );
2474             break;
2475 
2476         case LISTACTION_CLEARED:
2477             if( IsUpdateMode() )
2478                 Update();
2479             break;
2480     }
2481 }
2482 
2483 // bei Aenderungen SetTabs beruecksichtigen
GetTextOffset() const2484 long SvTreeListBox::GetTextOffset() const
2485 {
2486     DBG_CHKTHIS(SvTreeListBox,0);
2487     const WinBits nWindowStyle = GetStyle();
2488     sal_Bool bHasButtons = (nWindowStyle & WB_HASBUTTONS)!=0;
2489     sal_Bool bHasButtonsAtRoot = (nWindowStyle & (WB_HASLINESATROOT |
2490                                               WB_HASBUTTONSATROOT))!=0;
2491     long nStartPos = TAB_STARTPOS;
2492     long nNodeWidthPixel = GetExpandedNodeBmp().GetSizePixel().Width();
2493 
2494     long nCheckWidth = 0;
2495     if( nTreeFlags & TREEFLAG_CHKBTN )
2496         nCheckWidth = pCheckButtonData->aBmps[0].GetSizePixel().Width();
2497     long nCheckWidthDIV2 = nCheckWidth / 2;
2498 
2499     long nContextWidth = nContextBmpWidthMax;
2500     long nContextWidthDIV2 = nContextWidth / 2;
2501 
2502     int nCase = NO_BUTTONS;
2503     if( !(nTreeFlags & TREEFLAG_CHKBTN) )
2504     {
2505         if( bHasButtons )
2506             nCase = NODE_BUTTONS;
2507     }
2508     else
2509     {
2510         if( bHasButtons )
2511             nCase = NODE_AND_CHECK_BUTTONS;
2512          else
2513             nCase = CHECK_BUTTONS;
2514     }
2515 
2516     switch( nCase )
2517     {
2518         case NO_BUTTONS :
2519             nStartPos += nContextWidthDIV2;  // wg. Zentrierung
2520             nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
2521             if( nContextBmpWidthMax )
2522                 nStartPos += 5; // Abstand Context-Bmp - Text
2523             break;
2524 
2525         case NODE_BUTTONS :
2526             if( bHasButtonsAtRoot )
2527                 nStartPos += ( nIndent + (nNodeWidthPixel/2) );
2528             else
2529                 nStartPos += nContextWidthDIV2;
2530             nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
2531             if( nContextBmpWidthMax )
2532                 nStartPos += 5; // Abstand Context-Bmp - Text
2533             break;
2534 
2535         case NODE_AND_CHECK_BUTTONS :
2536             if( bHasButtonsAtRoot )
2537                 nStartPos += ( nIndent + nNodeWidthPixel );
2538             else
2539                 nStartPos += nCheckWidthDIV2;
2540             nStartPos += nCheckWidthDIV2;  // rechter Rand des CheckButtons
2541             nStartPos += 3;  // Abstand CheckButton Context-Bmp
2542             nStartPos += nContextWidthDIV2;  // Mitte der Context-Bmp
2543             nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
2544             // Abstand setzen nur wenn Bitmaps da
2545             if( nContextBmpWidthMax )
2546                 nStartPos += 5; // Abstand Context-Bmp - Text
2547             break;
2548 
2549         case CHECK_BUTTONS :
2550             nStartPos += nCheckWidthDIV2;
2551             nStartPos += nCheckWidthDIV2;  // rechter Rand CheckButton
2552             nStartPos += 3;  // Abstand CheckButton Context-Bmp
2553             nStartPos += nContextWidthDIV2;  // Mitte der Context-Bmp
2554             nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
2555             if( nContextBmpWidthMax )
2556                 nStartPos += 5; // Abstand Context-Bmp - Text
2557             break;
2558     }
2559     return nStartPos;
2560 }
2561 
EndSelection()2562 void SvTreeListBox::EndSelection()
2563 {
2564     pImp->EndSelection();
2565 }
2566 
IsNodeButton(const Point & rPos) const2567 sal_Bool SvTreeListBox::IsNodeButton( const Point& rPos ) const
2568 {
2569     SvLBoxEntry* pEntry = GetEntry( rPos );
2570     if( pEntry )
2571         return pImp->IsNodeButton( rPos, pEntry );
2572     return sal_False;
2573 }
2574 
RepaintScrollBars() const2575 void SvTreeListBox::RepaintScrollBars() const
2576 {
2577     ((SvTreeListBox*)this)->pImp->RepaintScrollBars();
2578 }
2579 
GetVScroll()2580 ScrollBar *SvTreeListBox::GetVScroll()
2581 {
2582     return &((SvTreeListBox*)this)->pImp->aVerSBar;
2583 }
2584 
GetHScroll()2585 ScrollBar *SvTreeListBox::GetHScroll()
2586 {
2587     return &((SvTreeListBox*)this)->pImp->aHorSBar;
2588 }
2589 
EnableAsyncDrag(sal_Bool b)2590 void SvTreeListBox::EnableAsyncDrag( sal_Bool b )
2591 {
2592     pImp->EnableAsyncDrag( b );
2593 }
2594 
GetFirstEntryInView() const2595 SvLBoxEntry* SvTreeListBox::GetFirstEntryInView() const
2596 {
2597     Point aPos;
2598     return GetEntry( aPos );
2599 }
2600 
GetNextEntryInView(SvLBoxEntry * pEntry) const2601 SvLBoxEntry* SvTreeListBox::GetNextEntryInView(SvLBoxEntry* pEntry ) const
2602 {
2603     SvLBoxEntry* pNext = (SvLBoxEntry*)NextVisible( pEntry );
2604     if( pNext )
2605     {
2606         Point aPos( GetEntryPosition(pNext) );
2607         const Size& rSize = pImp->GetOutputSize();
2608         if( aPos.Y() < 0 || aPos.Y() >= rSize.Height() )
2609             return 0;
2610     }
2611     return pNext;
2612 }
2613 
ShowFocusRect(const SvLBoxEntry * pEntry)2614 void SvTreeListBox::ShowFocusRect( const SvLBoxEntry* pEntry )
2615 {
2616     pImp->ShowFocusRect( pEntry );
2617 }
2618 
SetTabBar(TabBar * pTabBar)2619 void SvTreeListBox::SetTabBar( TabBar* pTabBar )
2620 {
2621     pImp->SetTabBar( pTabBar );
2622 }
2623 
DataChanged(const DataChangedEvent & rDCEvt)2624 void SvTreeListBox::DataChanged( const DataChangedEvent& rDCEvt )
2625 {
2626     if( (rDCEvt.GetType()==DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
2627     {
2628         nEntryHeight = 0;   // _together_ with sal_True of 1. par (bFont) of InitSettings() a zero-height
2629                             //  forces complete recalc of heights!
2630         InitSettings( sal_True, sal_True, sal_True );
2631         Invalidate();
2632     }
2633     else
2634         Control::DataChanged( rDCEvt );
2635 }
2636 
StateChanged(StateChangedType i_nStateChange)2637 void SvTreeListBox::StateChanged( StateChangedType i_nStateChange )
2638 {
2639     SvLBox::StateChanged( i_nStateChange );
2640     if ( i_nStateChange == STATE_CHANGE_STYLE )
2641         ImplInitStyle();
2642 }
2643 
InitSettings(sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground)2644 void SvTreeListBox::InitSettings(sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground)
2645 {
2646     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2647     if( bFont )
2648     {
2649         Font aFont;
2650         aFont = rStyleSettings.GetFieldFont();
2651         aFont.SetColor( rStyleSettings.GetWindowTextColor() );
2652         SetPointFont( aFont );
2653         AdjustEntryHeight( aFont );
2654         RecalcViewData();
2655     }
2656 
2657     if( bForeground || bFont )
2658     {
2659         SetTextColor( rStyleSettings.GetFieldTextColor() );
2660         SetTextFillColor();
2661     }
2662 
2663     if( bBackground )
2664         SetBackground( rStyleSettings.GetFieldColor() );
2665 
2666     // always try to re-create default-SvLBoxButtonData
2667     if( pCheckButtonData && pCheckButtonData->HasDefaultImages() )
2668         pCheckButtonData->SetDefaultImages( this );
2669 }
2670 
IsCellFocusEnabled() const2671 sal_Bool SvTreeListBox::IsCellFocusEnabled() const
2672 {
2673     return pImp->IsCellFocusEnabled();
2674 }
2675 
SetCurrentTabPos(sal_uInt16 _nNewPos)2676 bool SvTreeListBox::SetCurrentTabPos( sal_uInt16 _nNewPos )
2677 {
2678     return pImp->SetCurrentTabPos( _nNewPos );
2679 }
2680 
GetCurrentTabPos() const2681 sal_uInt16 SvTreeListBox::GetCurrentTabPos() const
2682 {
2683     return pImp->GetCurrentTabPos();
2684 }
2685 
InitStartEntry()2686 void SvTreeListBox::InitStartEntry()
2687 {
2688     if( !pImp->pStartEntry )
2689         pImp->pStartEntry = GetModel()->First();
2690 }
2691 
CancelPendingEdit()2692 void SvTreeListBox::CancelPendingEdit()
2693 {
2694     if( pImp )
2695         pImp->CancelPendingEdit();
2696 }
2697 
CreateContextMenu(void)2698 PopupMenu* SvTreeListBox::CreateContextMenu( void )
2699 {
2700     return NULL;
2701 }
2702 
ExcecuteContextMenuAction(sal_uInt16)2703 void SvTreeListBox::ExcecuteContextMenuAction( sal_uInt16 )
2704 {
2705     DBG_WARNING( "SvTreeListBox::ExcecuteContextMenuAction(): now there's happening nothing!" );
2706 }
2707 
EnableContextMenuHandling(void)2708 void SvTreeListBox::EnableContextMenuHandling( void )
2709 {
2710     DBG_ASSERT( pImp, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" );
2711 
2712     pImp->bContextMenuHandling = sal_True;
2713 }
2714 
EnableContextMenuHandling(sal_Bool b)2715 void SvTreeListBox::EnableContextMenuHandling( sal_Bool b )
2716 {
2717     DBG_ASSERT( pImp, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" );
2718 
2719     pImp->bContextMenuHandling = b;
2720 }
2721 
IsContextMenuHandlingEnabled(void) const2722 sal_Bool SvTreeListBox::IsContextMenuHandlingEnabled( void ) const
2723 {
2724     DBG_ASSERT( pImp, "-SvTreeListBox::IsContextMenuHandlingEnabled(): No implementation!" );
2725 
2726     return pImp->bContextMenuHandling;
2727 }
2728 
EnableList(bool _bEnable)2729 void SvTreeListBox::EnableList( bool _bEnable )
2730 {
2731     // call base class method
2732     Window::Enable( _bEnable != false );
2733     // then paint immediately
2734     Paint( Rectangle( Point(), GetSizePixel() ) );
2735 }
2736 
CreateAccessible()2737 ::com::sun::star::uno::Reference< XAccessible > SvTreeListBox::CreateAccessible()
2738 {
2739     Window* pParent = GetAccessibleParentWindow();
2740     DBG_ASSERT( pParent, "SvTreeListBox::CreateAccessible - accessible parent not found" );
2741 
2742     ::com::sun::star::uno::Reference< XAccessible > xAccessible;
2743     if ( pParent )
2744     {
2745         ::com::sun::star::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible();
2746         if ( xAccParent.is() )
2747         {
2748             // need to be done here to get the vclxwindow later on in the accessbile
2749             ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xTemp(GetComponentInterface());
2750             xAccessible = pImp->m_aFactoryAccess.getFactory().createAccessibleTreeListBox( *this, xAccParent );
2751         }
2752     }
2753     return xAccessible;
2754 }
2755 
FillAccessibleEntryStateSet(SvLBoxEntry * pEntry,::utl::AccessibleStateSetHelper & rStateSet) const2756 void SvTreeListBox::FillAccessibleEntryStateSet( SvLBoxEntry* pEntry, ::utl::AccessibleStateSetHelper& rStateSet ) const
2757 {
2758     DBG_ASSERT( pEntry, "SvTreeListBox::FillAccessibleEntryStateSet: invalid entry" );
2759 
2760     if ( pEntry )
2761     {
2762         if ( pEntry->HasChildsOnDemand() || pEntry->HasChilds() )
2763         {
2764             rStateSet.AddState( AccessibleStateType::EXPANDABLE );
2765             if ( IsExpanded( pEntry ) )
2766                 rStateSet.AddState( (sal_Int16)AccessibleStateType::EXPANDED );
2767         }
2768 
2769         if ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED )
2770             rStateSet.AddState( AccessibleStateType::CHECKED );
2771         if ( IsEntryVisible( pEntry ) )
2772             rStateSet.AddState( AccessibleStateType::VISIBLE );
2773         if ( IsSelected( pEntry ) )
2774             rStateSet.AddState( AccessibleStateType::SELECTED );
2775         if ( IsEnabled() )
2776         {
2777             rStateSet.AddState( AccessibleStateType::ENABLED );
2778             rStateSet.AddState( AccessibleStateType::FOCUSABLE );
2779             rStateSet.AddState( AccessibleStateType::SELECTABLE );
2780             SvViewDataEntry* pViewDataNewCur = 0;
2781             pViewDataNewCur = GetViewDataEntry(pEntry);
2782             if( pViewDataNewCur && pViewDataNewCur->HasFocus() )
2783                 rStateSet.AddState( AccessibleStateType::FOCUSED );
2784         }
2785     }
2786 }
2787 
GetBoundingRect(SvLBoxEntry * pEntry)2788 Rectangle SvTreeListBox::GetBoundingRect( SvLBoxEntry* pEntry )
2789 {
2790     Point aPos = GetEntryPosition( pEntry );
2791     Rectangle aRect = GetFocusRect( pEntry, aPos.Y() );
2792     return aRect;
2793 }
2794 
EnableCellFocus()2795 void SvTreeListBox::EnableCellFocus()
2796 {
2797     pImp->EnableCellFocus();
2798 }
2799 
CallImplEventListeners(sal_uLong nEvent,void * pData)2800 void SvTreeListBox::CallImplEventListeners(sal_uLong nEvent, void* pData)
2801 {
2802     CallEventListeners(nEvent, pData);
2803 }
2804 
FillAccessibleStateSet(::utl::AccessibleStateSetHelper & rStateSet) const2805 void SvTreeListBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& rStateSet ) const
2806 {
2807       SvLBox::FillAccessibleStateSet( rStateSet );
2808 }
2809 
2810