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