xref: /aoo41x/main/svtools/source/contnr/svimpbox.cxx (revision 2bfcd321)
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 #include <vcl/svapp.hxx>
27 #include <vcl/salnativewidgets.hxx>
28 #include <vcl/help.hxx>
29 #include <svtools/tabbar.hxx>
30 
31 #include <stack>
32 
33 #define _SVTREEBX_CXX
34 #include <svtools/svtreebx.hxx>
35 #include <svtools/svlbox.hxx>
36 #include <svimpbox.hxx>
37 #include <rtl/instance.hxx>
38 #include <svtools/svtdata.hxx>
39 #include <tools/wintypes.hxx>
40 #include <svtools/svtools.hrc>
41 #include <comphelper/processfactory.hxx>
42 
43 #define NODE_BMP_TABDIST_NOTVALID 	-2000000
44 #define FIRST_ENTRY_TAB				1
45 
46 // #i27063# (pl), #i32300# (pb) never access VCL after DeInitVCL - also no destructors
47 Image*	SvImpLBox::s_pDefCollapsed		= NULL;
48 Image*	SvImpLBox::s_pDefExpanded		= NULL;
49 Image*	SvImpLBox::s_pDefCollapsedHC	= NULL;
50 Image*	SvImpLBox::s_pDefExpandedHC		= NULL;
51 sal_Int32 SvImpLBox::s_nImageRefCount	= 0;
52 
53 SvImpLBox::SvImpLBox( SvTreeListBox* pLBView, SvLBoxTreeList* pLBTree, WinBits nWinStyle) :
54 
55 	pTabBar( NULL ),
56 	aVerSBar( pLBView, WB_DRAG | WB_VSCROLL ),
57 	aHorSBar( pLBView, WB_DRAG | WB_HSCROLL ),
58 	aScrBarBox( pLBView ),
59 	aOutputSize( 0, 0 ),
60 	aSelEng( pLBView, (FunctionSet*)0 ),
61 	aFctSet( this, &aSelEng, pLBView ),
62     nExtendedWinBits( 0 ),
63     bAreChildrenTransient( sal_True ),
64 	pIntlWrapper( NULL ) // #102891# -----------------------
65 {
66 	osl_incrementInterlockedCount(&s_nImageRefCount);
67 	pView = pLBView;
68 	pTree = pLBTree;
69 	aSelEng.SetFunctionSet( (FunctionSet*)&aFctSet );
70 	aSelEng.ExpandSelectionOnMouseMove( sal_False );
71 	SetStyle( nWinStyle );
72 	SetSelectionMode( SINGLE_SELECTION );
73 	SetDragDropMode( 0 );
74 
75 	aVerSBar.SetScrollHdl( LINK( this, SvImpLBox, ScrollUpDownHdl ) );
76 	aHorSBar.SetScrollHdl( LINK( this, SvImpLBox, ScrollLeftRightHdl ) );
77 	aHorSBar.SetEndScrollHdl( LINK( this, SvImpLBox, EndScrollHdl ) );
78 	aVerSBar.SetEndScrollHdl( LINK( this, SvImpLBox, EndScrollHdl ) );
79 	aVerSBar.SetRange( Range(0,0) );
80 	aVerSBar.Hide();
81 	aHorSBar.SetRange( Range(0,0) );
82 	aHorSBar.SetPageSize( 24 ); // Pixel
83 	aHorSBar.SetLineSize( 8 ); // Pixel
84 
85 	nHorSBarHeight = (short)aHorSBar.GetSizePixel().Height();
86 	nVerSBarWidth = (short)aVerSBar.GetSizePixel().Width();
87 
88 	pStartEntry	= 0;
89 	pCursor 			= 0;
90 	pAnchor				= 0;
91 	nVisibleCount  		= 0; 	// Anzahl Daten-Zeilen im Control
92 	nNodeBmpTabDistance = NODE_BMP_TABDIST_NOTVALID;
93 	nYoffsNodeBmp 		= 0;
94 	nNodeBmpWidth		= 0;
95 
96 	bAsyncBeginDrag		= sal_False;
97 	aAsyncBeginDragTimer.SetTimeout( 0 );
98 	aAsyncBeginDragTimer.SetTimeoutHdl( LINK(this,SvImpLBox,BeginDragHdl));
99 	// Button-Animation in Listbox
100 	pActiveButton = 0;
101 	pActiveEntry = 0;
102 	pActiveTab = 0;
103 
104 	nFlags = 0;
105 	nCurTabPos = FIRST_ENTRY_TAB;
106 
107 	aEditTimer.SetTimeout( 800 );
108 	aEditTimer.SetTimeoutHdl( LINK(this,SvImpLBox,EditTimerCall) );
109 
110 	nMostRight = -1;
111 	pMostRightEntry = 0;
112 	nCurUserEvent = 0xffffffff;
113 
114 	bUpdateMode = sal_True;
115 	bInVScrollHdl = sal_False;
116 	nFlags |= F_FILLING;
117 
118 	bSubLstOpRet = bSubLstOpLR = bContextMenuHandling = bIsCellFocusEnabled = sal_False;
119 }
120 
121 SvImpLBox::~SvImpLBox()
122 {
123 	aEditTimer.Stop();
124 	StopUserEvent();
125 
126 	// #102891# ---------------------
127 	if( pIntlWrapper )
128 		delete pIntlWrapper;
129 	if ( osl_decrementInterlockedCount(&s_nImageRefCount) == 0 )
130 	{
131 		DELETEZ(s_pDefCollapsed);
132 		DELETEZ(s_pDefExpanded);
133 		DELETEZ(s_pDefCollapsedHC);
134 		DELETEZ(s_pDefExpandedHC);
135 	}
136 }
137 
138 // #102891# --------------------
139 void SvImpLBox::UpdateIntlWrapper()
140 {
141 	const ::com::sun::star::lang::Locale & aNewLocale = Application::GetSettings().GetLocale();
142 	if( !pIntlWrapper )
143 		pIntlWrapper = new IntlWrapper( ::comphelper::getProcessServiceFactory(), aNewLocale );
144 	else
145 	{
146 		const ::com::sun::star::lang::Locale &aLocale = pIntlWrapper->getLocale();
147 		if( aLocale.Language != aNewLocale.Language || // different Locale from the older one
148 			aLocale.Country != aNewLocale.Country ||
149 			aLocale.Variant != aNewLocale.Variant )
150 		{
151 			delete pIntlWrapper;
152 			pIntlWrapper = new IntlWrapper( ::comphelper::getProcessServiceFactory(), aNewLocale );
153 		}
154 	}
155 }
156 
157 // #97680# ----------------------
158 short SvImpLBox::UpdateContextBmpWidthVector( SvLBoxEntry* pEntry, short nWidth )
159 {
160 	DBG_ASSERT( pView->pModel, "View and Model aren't valid!" );
161 
162 	sal_uInt16 nDepth = pView->pModel->GetDepth( pEntry );
163 	// initialize vector if necessary
164 	std::vector< short >::size_type nSize = aContextBmpWidthVector.size();
165 	while ( nDepth > nSize )
166 	{
167 		aContextBmpWidthVector.resize( nSize + 1 );
168 		aContextBmpWidthVector.at( nSize ) = nWidth;
169 		++nSize;
170 	}
171 	if( aContextBmpWidthVector.size() == nDepth )
172 	{
173 		aContextBmpWidthVector.resize( nDepth + 1 );
174 		aContextBmpWidthVector.at( nDepth ) = 0;
175 	}
176 	short nContextBmpWidth = aContextBmpWidthVector[ nDepth ];
177 	if( nContextBmpWidth < nWidth )
178 	{
179 		aContextBmpWidthVector.at( nDepth ) = nWidth;
180 		return nWidth;
181 	}
182 	else
183 		return nContextBmpWidth;
184 }
185 
186 void SvImpLBox::UpdateContextBmpWidthVectorFromMovedEntry( SvLBoxEntry* pEntry )
187 {
188 	DBG_ASSERT( pEntry, "Moved Entry is invalid!" );
189 
190 	SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
191 	short nExpWidth = (short)pBmpItem->GetBitmap1().GetSizePixel().Width();
192 	short nColWidth = (short)pBmpItem->GetBitmap2().GetSizePixel().Width();
193 	short nMax = Max(nExpWidth, nColWidth);
194 	UpdateContextBmpWidthVector( pEntry, nMax );
195 
196 	if( pEntry->HasChilds() ) // recursive call, whether expanded or not
197 	{
198 		SvLBoxEntry* pChild = pView->FirstChild( pEntry );
199 		DBG_ASSERT( pChild, "The first child is invalid!" );
200 		do
201 		{
202 			UpdateContextBmpWidthVectorFromMovedEntry( pChild );
203 			pChild = pView->Next( pChild );
204 		} while ( pChild );
205 	}
206 }
207 
208 void SvImpLBox::UpdateContextBmpWidthMax( SvLBoxEntry* pEntry )
209 {
210 	sal_uInt16 nDepth = pView->pModel->GetDepth( pEntry );
211 	if( aContextBmpWidthVector.size() < 1 )
212 		return;
213 	short nWidth = aContextBmpWidthVector[ nDepth ];
214 	if( nWidth != pView->nContextBmpWidthMax ) {
215 		pView->nContextBmpWidthMax = nWidth;
216 		nFlags |= F_IGNORE_CHANGED_TABS;
217 		pView->SetTabs();
218 		nFlags &= ~F_IGNORE_CHANGED_TABS;
219 	}
220 }
221 
222 void SvImpLBox::CalcCellFocusRect( SvLBoxEntry* pEntry, Rectangle& rRect )
223 {
224 	if ( pEntry && bIsCellFocusEnabled )
225 	{
226 		if ( nCurTabPos > FIRST_ENTRY_TAB )
227 		{
228 			SvLBoxItem* pItem = pCursor->GetItem( nCurTabPos );
229 			rRect.Left() = pView->GetTab( pCursor, pItem )->GetPos();
230 		}
231         if ( pCursor->ItemCount() > ( nCurTabPos + 1 ) )
232         {
233             SvLBoxItem* pNextItem = pCursor->GetItem( nCurTabPos + 1 );
234             long nRight = pView->GetTab( pCursor, pNextItem )->GetPos() - 1;
235             if ( nRight < rRect.Right() )
236                 rRect.Right() = nRight;
237         }
238 	}
239 }
240 
241 void SvImpLBox::SetStyle( WinBits i_nWinStyle )
242 {
243 	m_nStyle = i_nWinStyle;
244 	if ( ( m_nStyle & WB_SIMPLEMODE) && ( aSelEng.GetSelectionMode() == MULTIPLE_SELECTION ) )
245 		aSelEng.AddAlways( sal_True );
246 }
247 
248 void SvImpLBox::SetExtendedWindowBits( ExtendedWinBits _nBits )
249 {
250 	nExtendedWinBits = _nBits;
251 }
252 
253 // Das Model darf hier nicht mehr angefasst werden
254 void SvImpLBox::Clear()
255 {
256 	StopUserEvent();
257 	pStartEntry	= 0;
258 	pAnchor = 0;
259 
260 	pActiveButton = 0;
261 	pActiveEntry = 0;
262 	pActiveTab = 0;
263 
264 	nMostRight = -1;
265 	pMostRightEntry = 0;
266 
267 	// Der Cursor darf hier nicht mehr angefasst werden!
268 	if( pCursor )
269 	{
270 		if( pView->HasFocus() )
271 			pView->HideFocus();
272 		pCursor = 0;
273 	}
274 	aVerSBar.Hide();
275 	aVerSBar.SetThumbPos( 0 );
276 	Range aRange( 0, 0 );
277 	aVerSBar.SetRange( aRange );
278 	aOutputSize = pView->Control::GetOutputSizePixel();
279 	nFlags &= ~(F_VER_SBARSIZE_WITH_HBAR | F_HOR_SBARSIZE_WITH_VBAR );
280 	if( pTabBar )
281 	{
282 		aOutputSize.Height() -= nHorSBarHeight;
283 		nFlags |= F_VER_SBARSIZE_WITH_HBAR;
284 	}
285 	if( !pTabBar )
286 		aHorSBar.Hide();
287 	aHorSBar.SetThumbPos( 0 );
288 	MapMode aMapMode( pView->GetMapMode());
289 	aMapMode.SetOrigin( Point(0,0) );
290 	pView->Control::SetMapMode( aMapMode );
291 	aHorSBar.SetRange( aRange );
292 	aHorSBar.SetSizePixel(Size(aOutputSize.Width(),nHorSBarHeight));
293 	pView->SetClipRegion();
294 	if( GetUpdateMode() )
295 		pView->Invalidate( GetVisibleArea() );
296 	nFlags |= F_FILLING;
297 	if( !aHorSBar.IsVisible() && !aVerSBar.IsVisible() )
298 		aScrBarBox.Hide();
299 
300 	// #97680# ---------
301 	aContextBmpWidthVector.clear();
302 
303 //IAccessibility2 Implementation 2009-----
304 	CallEventListeners( VCLEVENT_LISTBOX_ITEMREMOVED, NULL );
305 //-----IAccessibility2 Implementation 2009
306 }
307 
308 // *********************************************************************
309 // Painten, Navigieren, Scrollen
310 // *********************************************************************
311 
312 IMPL_LINK_INLINE_START( SvImpLBox, EndScrollHdl, ScrollBar *, EMPTYARG )
313 {
314 	if( nFlags & F_ENDSCROLL_SET_VIS_SIZE )
315 	{
316 		aVerSBar.SetVisibleSize( nNextVerVisSize );
317 		nFlags &= ~F_ENDSCROLL_SET_VIS_SIZE;
318 	}
319 	EndScroll();
320 	return 0;
321 }
322 IMPL_LINK_INLINE_END( SvImpLBox, EndScrollHdl, ScrollBar *, pScrollBar )
323 
324 
325 // Handler vertikale ScrollBar
326 
327 IMPL_LINK( SvImpLBox, ScrollUpDownHdl, ScrollBar *, pScrollBar )
328 {
329 	DBG_ASSERT(!bInVScrollHdl,"Scroll-Handler ueberholt sich!");
330 	long nDelta = pScrollBar->GetDelta();
331 	if( !nDelta )
332 		return 0;
333 
334 	nFlags &= (~F_FILLING);
335 
336 	bInVScrollHdl = sal_True;
337 
338 	if( pView->IsEditingActive() )
339 	{
340 		pView->EndEditing( sal_True ); // Cancel
341 		pView->Update();
342 	}
343 	BeginScroll();
344 
345 	if( nDelta > 0 )
346 	{
347 		if( nDelta == 1 )
348 			CursorDown();
349 		else
350 			PageDown( (sal_uInt16) nDelta );
351 	}
352 	else
353 	{
354 		nDelta *= (-1);
355 		if( nDelta == 1 )
356 			CursorUp();
357 		else
358 			PageUp( (sal_uInt16) nDelta );
359 	}
360 	bInVScrollHdl = sal_False;
361 	return 0;
362 }
363 
364 
365 void SvImpLBox::CursorDown()
366 {
367 	SvLBoxEntry* pNextFirstToDraw = (SvLBoxEntry*)(pView->NextVisible( pStartEntry));
368 	if( pNextFirstToDraw )
369 	{
370 		nFlags &= (~F_FILLING);
371 		pView->NotifyScrolling( -1 );
372 		ShowCursor( sal_False );
373 		pView->Update();
374 		pStartEntry = pNextFirstToDraw;
375 		Rectangle aArea( GetVisibleArea() );
376 		pView->Scroll( 0, -(pView->GetEntryHeight()), aArea, SCROLL_NOCHILDREN );
377 		pView->Update();
378 		ShowCursor( sal_True );
379 		pView->NotifyScrolled();
380 	}
381 }
382 
383 void SvImpLBox::CursorUp()
384 {
385 	SvLBoxEntry* pPrevFirstToDraw = (SvLBoxEntry*)(pView->PrevVisible( pStartEntry));
386 	if( pPrevFirstToDraw )
387 	{
388 		nFlags &= (~F_FILLING);
389 		long nEntryHeight = pView->GetEntryHeight();
390 		pView->NotifyScrolling( 1 );
391 		ShowCursor( sal_False );
392 		pView->Update();
393 		pStartEntry = pPrevFirstToDraw;
394 		Rectangle aArea( GetVisibleArea() );
395 		aArea.Bottom() -= nEntryHeight;
396 		pView->Scroll( 0, nEntryHeight, aArea, SCROLL_NOCHILDREN );
397 		pView->Update();
398 		ShowCursor( sal_True );
399 		pView->NotifyScrolled();
400 	}
401 }
402 
403 void SvImpLBox::PageDown( sal_uInt16 nDelta )
404 {
405 	sal_uInt16 nRealDelta = nDelta;
406 
407 	if( !nDelta )
408 		return;
409 
410 	SvLBoxEntry* pNext;
411 	pNext = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, nRealDelta ));
412 	if( (sal_uLong)pNext == (sal_uLong)pStartEntry )
413 		return;
414 
415 	ShowCursor( sal_False );
416 
417 	nFlags &= (~F_FILLING);
418 	pView->Update();
419 	pStartEntry = pNext;
420 
421 	if( nRealDelta >= nVisibleCount )
422 	{
423 		pView->Invalidate( GetVisibleArea() );
424 		pView->Update();
425 	}
426 	else
427 	{
428 		long nScroll = nRealDelta * (-1);
429 		pView->NotifyScrolling( nScroll );
430 		Rectangle aArea( GetVisibleArea() );
431 		nScroll = pView->GetEntryHeight()*nRealDelta;
432 		nScroll = -nScroll;
433 		pView->Update();
434 		pView->Scroll( 0, nScroll, aArea, SCROLL_NOCHILDREN );
435 		pView->Update();
436 		pView->NotifyScrolled();
437 	}
438 
439 	ShowCursor( sal_True );
440 }
441 
442 void SvImpLBox::PageUp( sal_uInt16 nDelta )
443 {
444 	sal_uInt16 nRealDelta = nDelta;
445 	if( !nDelta )
446 		return;
447 
448 	SvLBoxEntry* pPrev = (SvLBoxEntry*)(pView->PrevVisible( pStartEntry, nRealDelta ));
449 	if( (sal_uLong)pPrev == (sal_uLong)pStartEntry )
450 		return;
451 
452 	nFlags &= (~F_FILLING);
453 	ShowCursor( sal_False );
454 
455 	pView->Update();
456 	pStartEntry = pPrev;
457 	if( nRealDelta >= nVisibleCount )
458 	{
459 		pView->Invalidate( GetVisibleArea() );
460 		pView->Update();
461 	}
462 	else
463 	{
464 		long nEntryHeight = pView->GetEntryHeight();
465 		pView->NotifyScrolling( (long)nRealDelta );
466 		Rectangle aArea( GetVisibleArea() );
467 		pView->Update();
468 		pView->Scroll( 0, nEntryHeight*nRealDelta, aArea, SCROLL_NOCHILDREN );
469 		pView->Update();
470 		pView->NotifyScrolled();
471 	}
472 
473 	ShowCursor( sal_True );
474 }
475 
476 void SvImpLBox::KeyUp( sal_Bool bPageUp, sal_Bool bNotifyScroll )
477 {
478 	if( !aVerSBar.IsVisible() )
479 		return;
480 
481 	long nDelta;
482 	if( bPageUp )
483 		nDelta = aVerSBar.GetPageSize();
484 	else
485 		nDelta = 1;
486 
487 	long nThumbPos = aVerSBar.GetThumbPos();
488 
489 	if( nThumbPos < nDelta )
490 		nDelta = nThumbPos;
491 
492 	if( nDelta <= 0 )
493 		return;
494 
495 	nFlags &= (~F_FILLING);
496 	if( bNotifyScroll )
497 		BeginScroll();
498 
499 	aVerSBar.SetThumbPos( nThumbPos - nDelta );
500 	if( bPageUp )
501 		PageUp( (short)nDelta );
502 	else
503 		CursorUp();
504 
505 	if( bNotifyScroll )
506 		EndScroll();
507 }
508 
509 
510 void SvImpLBox::KeyDown( sal_Bool bPageDown, sal_Bool bNotifyScroll )
511 {
512 	if( !aVerSBar.IsVisible() )
513 		return;
514 
515 	long nDelta;
516 	if( bPageDown )
517 		nDelta = aVerSBar.GetPageSize();
518 	else
519 		nDelta = 1;
520 
521 	long nThumbPos = aVerSBar.GetThumbPos();
522 	long nVisibleSize = aVerSBar.GetVisibleSize();
523 	long nRange = aVerSBar.GetRange().Len();
524 
525 	long nTmp = nThumbPos+nVisibleSize;
526 	while( (nDelta > 0) && (nTmp+nDelta) >= nRange )
527 		nDelta--;
528 
529 	if( nDelta <= 0 )
530 		return;
531 
532 	nFlags &= (~F_FILLING);
533 	if( bNotifyScroll )
534 		BeginScroll();
535 
536 	aVerSBar.SetThumbPos( nThumbPos+nDelta );
537 	if( bPageDown )
538 		PageDown( (short)nDelta );
539 	else
540 		CursorDown();
541 
542 	if( bNotifyScroll )
543 		EndScroll();
544 }
545 
546 
547 
548 void SvImpLBox::InvalidateEntriesFrom( long nY ) const
549 {
550 	if( !(nFlags & F_IN_PAINT ))
551 	{
552 		Rectangle aRect( GetVisibleArea() );
553 		aRect.Top() = nY;
554 		pView->Invalidate( aRect );
555 	}
556 }
557 
558 void SvImpLBox::InvalidateEntry( long nY ) const
559 {
560 	if( !(nFlags & F_IN_PAINT ))
561 	{
562 		Rectangle aRect( GetVisibleArea() );
563 		long nMaxBottom = aRect.Bottom();
564 		aRect.Top() = nY;
565 		aRect.Bottom() = nY; aRect.Bottom() += pView->GetEntryHeight();
566 		if( aRect.Top() > nMaxBottom )
567 			return;
568 		if( aRect.Bottom() > nMaxBottom )
569 			aRect.Bottom() = nMaxBottom;
570 		pView->Invalidate( aRect );
571 	}
572 }
573 
574 void SvImpLBox::InvalidateEntry( SvLBoxEntry* pEntry )
575 {
576 	if( GetUpdateMode() )
577 	{
578 		long nPrev = nMostRight;
579 		SetMostRight( pEntry );
580 		if( nPrev < nMostRight )
581 			ShowVerSBar();
582 	}
583 	if( !(nFlags & F_IN_PAINT ))
584 	{
585 		sal_Bool bHasFocusRect = sal_False;
586 		if( pEntry==pCursor && pView->HasFocus() )
587 		{
588 			bHasFocusRect = sal_True;
589 			ShowCursor( sal_False );
590 		}
591 		InvalidateEntry( GetEntryLine( pEntry ) );
592 		if( bHasFocusRect )
593 			ShowCursor( sal_True );
594 	}
595 }
596 
597 
598 void SvImpLBox::RecalcFocusRect()
599 {
600 	if( pView->HasFocus() && pCursor )
601 	{
602 		pView->HideFocus();
603 		long nY = GetEntryLine( pCursor );
604 		Rectangle aRect = pView->GetFocusRect( pCursor, nY );
605 		CalcCellFocusRect( pCursor, aRect );
606 		Region aOldClip( pView->GetClipRegion());
607 		Region aClipRegion( GetClipRegionRect() );
608 		pView->SetClipRegion( aClipRegion );
609 		pView->ShowFocus( aRect );
610 		pView->SetClipRegion( aOldClip );
611 	}
612 }
613 
614 //
615 //  Setzt Cursor. Passt bei SingleSelection die Selektion an
616 //
617 
618 void SvImpLBox::SetCursor( SvLBoxEntry* pEntry, sal_Bool bForceNoSelect )
619 {
620 	SvViewDataEntry* pViewDataNewCur = 0;
621 	if( pEntry )
622 		pViewDataNewCur= pView->GetViewDataEntry(pEntry);
623 	if( pEntry &&
624 		pEntry == pCursor &&
625 		pViewDataNewCur->HasFocus() &&
626 		pViewDataNewCur->IsSelected())
627 	{
628 		return;
629 	}
630 
631 	// if this cursor is not selectable, find first visible that is and use it
632 	while( pEntry && pViewDataNewCur && !pViewDataNewCur->IsSelectable() )
633 	{
634 		pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
635 		pViewDataNewCur = pEntry ? pView->GetViewDataEntry(pEntry) : 0;
636 	}
637 
638 	SvLBoxEntry* pOldCursor = pCursor;
639 	if( pCursor && pEntry != pCursor )
640 	{
641 		pView->SetEntryFocus( pCursor, sal_False );
642 		if( bSimpleTravel )
643 			pView->Select( pCursor, sal_False );
644 		pView->HideFocus();
645 	}
646 	pCursor = pEntry;
647 	if( pCursor )
648 	{
649 		pViewDataNewCur->SetFocus( sal_True );
650 		if(!bForceNoSelect && bSimpleTravel && !(nFlags & F_DESEL_ALL) && GetUpdateMode())
651 		{
652 			pView->Select( pCursor, sal_True );
653 			//IAccessibility2 Implementation 2009-----
654 			CallEventListeners( VCLEVENT_LISTBOX_TREEFOCUS, pCursor );
655 			//-----IAccessibility2 Implementation 2009
656 		}
657 		// Mehrfachselektion: Im Cursor-Move selektieren, wenn
658 		// nicht im Add-Mode (Ctrl-F8)
659 		else if( GetUpdateMode() &&
660 				 pView->GetSelectionMode() == MULTIPLE_SELECTION &&
661 				 !(nFlags & F_DESEL_ALL) && !aSelEng.IsAddMode() &&
662 				 !bForceNoSelect )
663 		{
664 			pView->Select( pCursor, sal_True );
665 			//IAccessibility2 Implementation 2009-----
666 			CallEventListeners( VCLEVENT_LISTBOX_TREEFOCUS, pCursor );
667 			//-----IAccessibility2 Implementation 2009
668 		}
669 		else
670 		{
671 			ShowCursor( sal_True );
672 			//IAccessibility2 Implementation 2009-----
673 			if (bForceNoSelect && GetUpdateMode())
674 			{
675 				CallEventListeners( VCLEVENT_LISTBOX_TREEFOCUS, pCursor);
676 			}
677 			//-----IAccessibility2 Implementation 2009
678 		}
679 
680 		if( pAnchor )
681 		{
682 			DBG_ASSERT(aSelEng.GetSelectionMode() != SINGLE_SELECTION,"Mode?");
683 			SetAnchorSelection( pOldCursor, pCursor );
684 		}
685 	}
686 	nFlags &= (~F_DESEL_ALL);
687 
688     pView->OnCurrentEntryChanged();
689 }
690 
691 void SvImpLBox::ShowCursor( sal_Bool bShow )
692 {
693 	if( !bShow || !pCursor || !pView->HasFocus() )
694 	{
695 		Region aOldClip( pView->GetClipRegion());
696 		Region aClipRegion( GetClipRegionRect() );
697 		pView->SetClipRegion( aClipRegion );
698 		pView->HideFocus();
699 		pView->SetClipRegion( aOldClip );
700 	}
701 	else
702 	{
703 		long nY = GetEntryLine( pCursor );
704 		Rectangle aRect = pView->GetFocusRect( pCursor, nY );
705 		CalcCellFocusRect( pCursor, aRect );
706 		Region aOldClip( pView->GetClipRegion());
707 		Region aClipRegion( GetClipRegionRect() );
708 		pView->SetClipRegion( aClipRegion );
709 		pView->ShowFocus( aRect );
710 		pView->SetClipRegion( aOldClip );
711 	}
712 }
713 
714 
715 
716 void SvImpLBox::UpdateAll( sal_Bool bInvalidateCompleteView,
717 	sal_Bool bUpdateVerScrollBar )
718 {
719 	if( bUpdateVerScrollBar )
720 		FindMostRight(0);
721 	aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1 ) );
722 	SyncVerThumb();
723 	FillView();
724 	ShowVerSBar();
725 	if( bSimpleTravel && pCursor && pView->HasFocus() )
726 		pView->Select( pCursor, sal_True );
727 	ShowCursor( sal_True );
728 	if( bInvalidateCompleteView )
729 		pView->Invalidate();
730 	else
731 		pView->Invalidate( GetVisibleArea() );
732 }
733 
734 IMPL_LINK_INLINE_START( SvImpLBox, ScrollLeftRightHdl, ScrollBar *, pScrollBar )
735 {
736 	long nDelta = pScrollBar->GetDelta();
737 	if( nDelta )
738 	{
739 		if( pView->IsEditingActive() )
740 		{
741 			pView->EndEditing( sal_True ); // Cancel
742 			pView->Update();
743 		}
744 		pView->nFocusWidth = -1;
745 		KeyLeftRight( nDelta );
746 	}
747 	return 0;
748 }
749 IMPL_LINK_INLINE_END( SvImpLBox, ScrollLeftRightHdl, ScrollBar *, pScrollBar )
750 
751 void SvImpLBox::KeyLeftRight( long nDelta )
752 {
753 	if( !(nFlags & F_IN_RESIZE) )
754 		pView->Update();
755 	BeginScroll();
756 	nFlags &= (~F_FILLING);
757 	pView->NotifyScrolling( 0 ); // 0 == horizontales Scrolling
758 	ShowCursor( sal_False );
759 
760 	// neuen Origin berechnen
761 	long nPos = aHorSBar.GetThumbPos();
762 	Point aOrigin( -nPos, 0 );
763 
764 	MapMode aMapMode( pView->GetMapMode() );
765 	aMapMode.SetOrigin( aOrigin );
766 	pView->SetMapMode( aMapMode );
767 
768 	if( !(nFlags & F_IN_RESIZE) )
769 	{
770 		Rectangle aRect( GetVisibleArea() );
771 		pView->Scroll( -nDelta, 0, aRect, SCROLL_NOCHILDREN );
772 	}
773 	else
774 		pView->Invalidate();
775 	RecalcFocusRect();
776 	ShowCursor( sal_True );
777 	pView->NotifyScrolled();
778 }
779 
780 
781 // gibt letzten Eintrag zurueck, wenn Position unter
782 // dem letzten Eintrag ist
783 SvLBoxEntry* SvImpLBox::GetClickedEntry( const Point& rPoint ) const
784 {
785     DBG_ASSERT( pView->GetModel(), "SvImpLBox::GetClickedEntry: how can this ever happen? Please tell me (frank.schoenheit@sun.com) how to reproduce!" );
786     if ( !pView->GetModel() )
787         // this is quite impossible. Nevertheless, stack traces from the crash reporter
788         // suggest it isn't. Okay, make it safe, and wait for somebody to reproduce it
789         // reliably :-\ ....
790         // #122359# / 2005-05-23 / frank.schoenheit@sun.com
791         return NULL;
792     if( pView->GetEntryCount() == 0 || !pStartEntry || !pView->GetEntryHeight())
793 		return 0;
794 
795 	sal_uInt16 nClickedEntry = (sal_uInt16)(rPoint.Y() / pView->GetEntryHeight() );
796 	sal_uInt16 nTemp = nClickedEntry;
797 	SvLBoxEntry* pEntry = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, nTemp ));
798 	return pEntry;
799 }
800 
801 //
802 //  prueft, ob der Eintrag "richtig" getroffen wurde
803 //  (Focusrect+ ContextBitmap bei TreeListBox)
804 //
805 sal_Bool SvImpLBox::EntryReallyHit(SvLBoxEntry* pEntry,const Point& rPosPixel,long nLine)
806 {
807 	sal_Bool bRet;
808 	// bei "besonderen" Entries (mit CheckButtons usw.) sind wir
809 	// nicht so pingelig
810 	if( pEntry->ItemCount() >= 3 )
811 		return sal_True;
812 
813 	Rectangle aRect( pView->GetFocusRect( pEntry, nLine ));
814 	aRect.Right() = GetOutputSize().Width() - pView->GetMapMode().GetOrigin().X();
815 	if( pView->IsA() == SV_LISTBOX_ID_TREEBOX )
816 	{
817 		SvLBoxContextBmp* pBmp = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
818 		aRect.Left() -= pBmp->GetSize(pView,pEntry).Width();
819 		aRect.Left() -= 4; // etwas Speilraum lassen
820 	}
821 	Point aPos( rPosPixel );
822 	aPos -= pView->GetMapMode().GetOrigin();
823 	if( aRect.IsInside( aPos ) )
824 		bRet = sal_True;
825 	else
826 		bRet = sal_False;
827 	return bRet;
828 }
829 
830 
831 // gibt 0 zurueck, wenn Position unter dem letzten Eintrag ist
832 SvLBoxEntry* SvImpLBox::GetEntry( const Point& rPoint ) const
833 {
834 	if( (pView->GetEntryCount() == 0) || !pStartEntry ||
835         (rPoint.Y() > aOutputSize.Height())
836         || !pView->GetEntryHeight())
837 		return 0;
838 
839 	sal_uInt16 nClickedEntry = (sal_uInt16)(rPoint.Y() / pView->GetEntryHeight() );
840 	sal_uInt16 nTemp = nClickedEntry;
841 	SvLBoxEntry* pEntry = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, nTemp ));
842 	if( nTemp != nClickedEntry )
843 		pEntry = 0;
844 	return pEntry;
845 }
846 
847 
848 SvLBoxEntry* SvImpLBox::MakePointVisible(const Point& rPoint,sal_Bool bNotifyScroll)
849 {
850 	if( !pCursor )
851 		return 0;
852 	long nY = rPoint.Y();
853 	SvLBoxEntry* pEntry = 0;
854 	long nMax = aOutputSize.Height();
855 	if( nY < 0 || nY >= nMax ) // aOutputSize.Height() )
856 	{
857 		if( nY < 0 )
858 			pEntry = (SvLBoxEntry*)(pView->PrevVisible( pCursor ));
859 		else
860 			pEntry = (SvLBoxEntry*)(pView->NextVisible( pCursor ));
861 
862 		if( pEntry && pEntry != pCursor )
863 			pView->SetEntryFocus( pCursor, sal_False );
864 
865 		if( nY < 0 )
866 			KeyUp( sal_False, bNotifyScroll );
867 		else
868 			KeyDown( sal_False, bNotifyScroll );
869 	}
870 	else
871 	{
872 		pEntry = GetClickedEntry( rPoint );
873 		if( !pEntry )
874 		{
875 			sal_uInt16 nSteps = 0xFFFF;
876 			// LastVisible ist noch nicht implementiert!
877 			pEntry = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, nSteps ));
878 		}
879 		if( pEntry )
880 		{
881 			if( pEntry != pCursor &&
882 				 aSelEng.GetSelectionMode() == SINGLE_SELECTION
883 			)
884 				pView->Select( pCursor, sal_False );
885 		}
886 	}
887 	return pEntry;
888 }
889 
890 Rectangle SvImpLBox::GetClipRegionRect() const
891 {
892 	Point aOrigin( pView->GetMapMode().GetOrigin() );
893 	aOrigin.X() *= -1; // Umrechnung Dokumentkoord.
894 	Rectangle aClipRect( aOrigin, aOutputSize );
895 	aClipRect.Bottom()++;
896 	return aClipRect;
897 }
898 
899 
900 void SvImpLBox::Paint( const Rectangle& rRect )
901 {
902 	if( !pView->GetVisibleCount() )
903 		return;
904 
905 	nFlags |= F_IN_PAINT;
906 
907 	if( nFlags & F_FILLING )
908 	{
909 		SvLBoxEntry* pFirst = pView->First();
910 		if( pFirst != pStartEntry )
911 		{
912 			ShowCursor( sal_False );
913 			pStartEntry = pView->First();
914 			aVerSBar.SetThumbPos( 0 );
915 			StopUserEvent();
916 			ShowCursor( sal_True );
917 			nCurUserEvent = Application::PostUserEvent(LINK(this,SvImpLBox,MyUserEvent),(void*)1);
918 			return;
919 		}
920 	}
921 
922 	if( !pStartEntry )
923 	{
924 		pStartEntry = pView->First();
925 	}
926 
927 #ifdef XX_OV
928 	sal_uLong nXAbsPos = (sal_uInt16)pTree->GetAbsPos( pStartEntry );
929 	sal_uLong nXVisPos = pView->GetVisiblePos( pStartEntry );
930 	SvLBoxString* pXStr = (SvLBoxString*)pStartEntry->GetFirstItem( SV_ITEM_ID_LBOXSTRING);
931 #endif
932 
933 
934 
935 	if( nNodeBmpTabDistance == NODE_BMP_TABDIST_NOTVALID )
936 		SetNodeBmpTabDistance();
937 
938 	long nRectHeight = rRect.GetHeight();
939 	long nEntryHeight = pView->GetEntryHeight();
940 
941 	// Bereich der zu zeichnenden Entries berechnen
942 	sal_uInt16 nStartLine = (sal_uInt16)( rRect.Top() / nEntryHeight );
943 	sal_uInt16 nCount = (sal_uInt16)( nRectHeight / nEntryHeight );
944 		nCount += 2; // keine Zeile vergessen
945 
946 	long nY = nStartLine * nEntryHeight;
947 	SvLBoxEntry* pEntry = pStartEntry;
948 	while( nStartLine && pEntry )
949 	{
950 		pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
951 		nStartLine--;
952 	}
953 
954 	Region aClipRegion( GetClipRegionRect() );
955 
956 	// erst die Linien Zeichnen, dann clippen!
957 	pView->SetClipRegion();
958 	if( m_nStyle & ( WB_HASLINES | WB_HASLINESATROOT ) )
959 		DrawNet();
960 
961 	pView->SetClipRegion( aClipRegion );
962 
963 	for( sal_uInt16 n=0; n< nCount && pEntry; n++ )
964 	{
965 		/*long nMaxRight=*/
966 		pView->PaintEntry1( pEntry, nY, 0xffff, sal_True );
967 		nY += nEntryHeight;
968 		pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
969 	}
970 
971     if ( !pCursor && ( ( nExtendedWinBits & EWB_NO_AUTO_CURENTRY ) == 0 ) )
972 	{
973         // do not select if multiselection or explicit set
974         sal_Bool bNotSelect = ( aSelEng.GetSelectionMode() == MULTIPLE_SELECTION )
975                 || ( ( m_nStyle & WB_NOINITIALSELECTION ) == WB_NOINITIALSELECTION );
976         SetCursor( pStartEntry, bNotSelect );
977 	}
978 
979     nFlags &= (~F_DESEL_ALL);
980 	pView->SetClipRegion();
981 	Rectangle aRect;
982 	if( !(nFlags & F_PAINTED) )
983 	{
984 		nFlags |= F_PAINTED;
985 		RepaintScrollBars();
986 	}
987 	nFlags &= (~F_IN_PAINT);
988 }
989 
990 void SvImpLBox::MakeVisible( SvLBoxEntry* pEntry, sal_Bool bMoveToTop )
991 {
992 	if( !pEntry )
993 		return;
994 
995 	sal_Bool bInView = IsEntryInView( pEntry );
996 
997 	if( bInView && (!bMoveToTop || pStartEntry == pEntry) )
998 		return;  // ist schon sichtbar
999 
1000 	if( pStartEntry || (m_nStyle & WB_FORCE_MAKEVISIBLE) )
1001 		nFlags &= (~F_FILLING);
1002 	if( !bInView )
1003 	{
1004 		if( !pView->IsEntryVisible(pEntry) )  // Parent(s) zugeklappt ?
1005 		{
1006 			SvLBoxEntry* pParent = pView->GetParent( pEntry );
1007 			while( pParent )
1008 			{
1009 				if( !pView->IsExpanded( pParent ) )
1010 				{
1011                     #ifdef DBG_UTIL
1012                     sal_Bool bRet =
1013                     #endif
1014 					    pView->Expand( pParent );
1015 					DBG_ASSERT(bRet,"Not expanded!");
1016 				}
1017 				pParent = pView->GetParent( pParent );
1018 			}
1019 			// Passen Childs der Parents in View oder muessen wir scrollen ?
1020 			if( IsEntryInView( pEntry ) && !bMoveToTop )
1021 				return;  // Scrollen nicht noetig -> tschuess
1022 		}
1023 	}
1024 
1025 	pStartEntry = pEntry;
1026 	ShowCursor( sal_False );
1027 	FillView();
1028 	aVerSBar.SetThumbPos( (long)(pView->GetVisiblePos( pStartEntry )) );
1029 	ShowCursor( sal_True );
1030 	pView->Invalidate();
1031 }
1032 
1033 
1034 void SvImpLBox::RepaintSelectionItems()
1035 {
1036 	if( !pView->GetVisibleCount() )
1037 		return;
1038 
1039 	if( !pStartEntry )
1040 		pStartEntry = pView->First();
1041 
1042 	if( nNodeBmpTabDistance == NODE_BMP_TABDIST_NOTVALID )
1043 		SetNodeBmpTabDistance();
1044 
1045 	ShowCursor( sal_False );
1046 
1047 	long nEntryHeight = pView->GetEntryHeight();
1048 
1049 	sal_uLong nCount = nVisibleCount;
1050 	long nY = 0;
1051 	SvLBoxEntry* pEntry = pStartEntry;
1052 	for( sal_uLong n=0; n< nCount && pEntry; n++ )
1053 	{
1054 		pView->PaintEntry1( pEntry, nY, 0xffff ); //wg. ItemsetBrowser SV_LBOXTAB_SHOW_SELECTION );
1055 		nY += nEntryHeight;
1056 		pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
1057 	}
1058 
1059 	ShowCursor( sal_True );
1060 }
1061 
1062 
1063 void SvImpLBox::DrawNet()
1064 {
1065 	if( pView->GetVisibleCount() < 2 && !pStartEntry->HasChildsOnDemand() &&
1066 		!pStartEntry->HasChilds() )
1067 		return;
1068 
1069     //for platforms who don't have nets, DrawNativeControl does nothing and return true
1070     //so that SvImpLBox::DrawNet() doesn't draw anything too
1071  	if(pView->IsNativeControlSupported( CTRL_LISTNET, PART_ENTIRE_CONTROL)) {
1072         ImplControlValue	aControlValue;
1073         Point  aTemp(0,0);   // temporary needed for g++ 3.3.5
1074         Rectangle aCtrlRegion( aTemp, Size( 0, 0 ) );
1075         ControlState		nState = CTRL_STATE_ENABLED;
1076         if( pView->DrawNativeControl( CTRL_LISTNET, PART_ENTIRE_CONTROL,
1077                                       aCtrlRegion, nState, aControlValue, rtl::OUString() ) )
1078         {
1079             return;
1080         }
1081 
1082     }
1083 
1084 	long nEntryHeight = pView->GetEntryHeight();
1085 	long nEntryHeightDIV2 = nEntryHeight / 2;
1086 	if( nEntryHeightDIV2 && !(nEntryHeight & 0x0001))
1087 		nEntryHeightDIV2--;
1088 
1089 	SvLBoxEntry* pChild;
1090 	SvLBoxEntry* pEntry = pStartEntry;
1091 
1092 	SvLBoxTab* pFirstDynamicTab = pView->GetFirstDynamicTab();
1093 	while( pTree->GetDepth( pEntry ) > 0 )
1094 		pEntry = pView->GetParent( pEntry );
1095 	sal_uInt16 nOffs = (sal_uInt16)(pView->GetVisiblePos( pStartEntry ) -
1096 							pView->GetVisiblePos( pEntry ));
1097 	long nY = 0;
1098 	nY -= ( nOffs * nEntryHeight );
1099 
1100 	DBG_ASSERT(pFirstDynamicTab,"No Tree!");
1101 
1102 	Color aOldLineColor = pView->GetLineColor();
1103 	const StyleSettings& rStyleSettings = pView->GetSettings().GetStyleSettings();
1104 	Color aCol= rStyleSettings.GetFaceColor();
1105 
1106 	if( aCol.IsRGBEqual( pView->GetBackground().GetColor()) )
1107 		aCol = rStyleSettings.GetShadowColor();
1108 	pView->SetLineColor( aCol );
1109 	Point aPos1, aPos2;
1110 	sal_uInt16 nDistance;
1111 	sal_uLong nMax = nVisibleCount + nOffs + 1;
1112 
1113 	const Image& rExpandedNodeBitmap = GetExpandedNodeBmp();
1114 
1115 	for( sal_uLong n=0; n< nMax && pEntry; n++ )
1116 	{
1117 		if( pView->IsExpanded(pEntry) )
1118 		{
1119 			aPos1.X() = pView->GetTabPos(pEntry, pFirstDynamicTab);
1120 			// wenn keine ContextBitmap, dann etwas nach rechts
1121 			// unter den ersten Text (Node.Bmp ebenfalls
1122 			if( !pView->nContextBmpWidthMax )
1123 				aPos1.X() += rExpandedNodeBitmap.GetSizePixel().Width() / 2;
1124 
1125 			aPos1.Y() = nY;
1126 			aPos1.Y() += nEntryHeightDIV2;
1127 
1128 			pChild = pView->FirstChild( pEntry );
1129 			DBG_ASSERT(pChild,"Child?");
1130 			pChild = pTree->LastSibling( pChild );
1131 			nDistance = (sal_uInt16)(pView->GetVisiblePos(pChild) -
1132 								 pView->GetVisiblePos(pEntry));
1133 			aPos2 = aPos1;
1134 			aPos2.Y() += nDistance * nEntryHeight;
1135 			pView->DrawLine( aPos1, aPos2 );
1136 		}
1137 		// Sichtbar im Control ?
1138 		if( n>= nOffs && ((m_nStyle & WB_HASLINESATROOT) || !pTree->IsAtRootDepth(pEntry)))
1139 		{
1140 			// kann aPos1 recyclet werden ?
1141 			if( !pView->IsExpanded(pEntry) )
1142 			{
1143 				// njet
1144 				aPos1.X() = pView->GetTabPos(pEntry, pFirstDynamicTab);
1145 				// wenn keine ContextBitmap, dann etwas nach rechts
1146 				// unter den ersten Text (Node.Bmp ebenfalls
1147 				if( !pView->nContextBmpWidthMax )
1148 					aPos1.X() += rExpandedNodeBitmap.GetSizePixel().Width() / 2;
1149 				aPos1.Y() = nY;
1150 				aPos1.Y() += nEntryHeightDIV2;
1151 				aPos2.X() = aPos1.X();
1152 			}
1153 			aPos2.Y() = aPos1.Y();
1154 			aPos2.X() -= pView->GetIndent();
1155 			pView->DrawLine( aPos1, aPos2 );
1156 		}
1157 		nY += nEntryHeight;
1158 		pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
1159 	}
1160 	if( m_nStyle & WB_HASLINESATROOT )
1161 	{
1162 		pEntry = pView->First();
1163 		aPos1.X() = pView->GetTabPos( pEntry, pFirstDynamicTab);
1164 		// wenn keine ContextBitmap, dann etwas nach rechts
1165 		// unter den ersten Text (Node.Bmp ebenfalls
1166 		if( !pView->nContextBmpWidthMax )
1167 			aPos1.X() += rExpandedNodeBitmap.GetSizePixel().Width() / 2;
1168 		aPos1.X() -=  pView->GetIndent();
1169 		aPos1.Y() = GetEntryLine( pEntry );
1170 		aPos1.Y() += nEntryHeightDIV2;
1171 		pChild = pTree->LastSibling( pEntry );
1172 		aPos2.X() = aPos1.X();
1173 		aPos2.Y() = GetEntryLine( pChild );
1174 		aPos2.Y() += nEntryHeightDIV2;
1175 		pView->DrawLine( aPos1, aPos2 );
1176 	}
1177 	pView->SetLineColor( aOldLineColor );
1178 }
1179 
1180 
1181 static long GetOptSize( TabBar* pTabBar )
1182 {
1183 	return pTabBar->CalcWindowSizePixel().Width();
1184 }
1185 
1186 void SvImpLBox::PositionScrollBars( Size& rSize, sal_uInt16 nMask )
1187 {
1188 	long nOverlap = 0;
1189 
1190 	Size aVerSize( nVerSBarWidth, rSize.Height() );
1191 	Size aHorSize( rSize.Width(), nHorSBarHeight );
1192 	long nTabBarWidth = 0;
1193 	if( pTabBar )
1194 	{
1195 		nTabBarWidth = GetOptSize( pTabBar );
1196 		long nMaxWidth = (rSize.Width() * 700) / 1000;
1197 		if( nTabBarWidth > nMaxWidth )
1198 		{
1199 			nTabBarWidth = nMaxWidth;
1200 			pTabBar->SetStyle( pTabBar->GetStyle() | WB_MINSCROLL );
1201 		}
1202 		else
1203 		{
1204 			WinBits nStyle = pTabBar->GetStyle();
1205 			nStyle &= ~(WB_MINSCROLL);
1206 			pTabBar->SetStyle( nStyle );
1207 		}
1208 		aHorSize.Width() -= nTabBarWidth;
1209 		Size aTabSize( pTabBar->GetSizePixel() );
1210 		aTabSize.Width() = nTabBarWidth;
1211 		pTabBar->SetSizePixel( aTabSize );
1212 	}
1213 	if( nMask & 0x0001 )
1214 		aHorSize.Width() -= nVerSBarWidth;
1215 	if( nMask & 0x0002 )
1216 		aVerSize.Height() -= nHorSBarHeight;
1217 
1218 	aVerSize.Height() += 2 * nOverlap;
1219 	Point aVerPos( rSize.Width() - aVerSize.Width() + nOverlap, -nOverlap );
1220 	aVerSBar.SetPosSizePixel( aVerPos, aVerSize );
1221 
1222 	aHorSize.Width() += 2 * nOverlap;
1223 	Point aHorPos( -nOverlap, rSize.Height() - aHorSize.Height() + nOverlap );
1224 	if( pTabBar )
1225 		pTabBar->SetPosPixel( aHorPos );
1226 	aHorPos.X() += nTabBarWidth;
1227 	aHorSBar.SetPosSizePixel( aHorPos, aHorSize );
1228 
1229 	if( nMask & 0x0001 )
1230 		rSize.Width() = aVerPos.X();
1231 	if( nMask & 0x0002 )
1232 		rSize.Height() = aHorPos.Y();
1233 	if( pTabBar )
1234 		pTabBar->Show();
1235 
1236 	if( (nMask & (0x0001|0x0002)) == (0x0001|0x0002) )
1237 		aScrBarBox.Show();
1238 	else
1239 		aScrBarBox.Hide();
1240 
1241 }
1242 
1243 // nResult: Bit0 == VerSBar Bit1 == HorSBar
1244 sal_uInt16 SvImpLBox::AdjustScrollBars( Size& rSize )
1245 {
1246 	long nEntryHeight = pView->GetEntryHeight();
1247 	if( !nEntryHeight )
1248 		return 0;
1249 
1250 	sal_uInt16 nResult = 0;
1251 
1252 	Size aOSize( pView->Control::GetOutputSizePixel() );
1253 
1254     const WinBits nWindowStyle = pView->GetStyle();
1255 	sal_Bool bVerSBar = ( nWindowStyle & WB_VSCROLL ) != 0;
1256 	sal_Bool bHorBar = sal_False;
1257 	long nMaxRight = aOSize.Width(); //GetOutputSize().Width();
1258 	Point aOrigin( pView->GetMapMode().GetOrigin() );
1259 	aOrigin.X() *= -1;
1260 	nMaxRight += aOrigin.X() - 1;
1261 	long nVis = nMostRight - aOrigin.X();
1262 	if( pTabBar || (
1263 		(nWindowStyle & WB_HSCROLL) &&
1264 		(nVis < nMostRight || nMaxRight < nMostRight) ))
1265 		bHorBar = sal_True;
1266 
1267 	// Anzahl aller nicht eingeklappten Eintraege
1268 	sal_uLong nTotalCount = pView->GetVisibleCount();
1269 
1270 	// Anzahl in der View sichtbarer Eintraege
1271 	nVisibleCount = aOSize.Height() / nEntryHeight;
1272 
1273 	// muessen wir eine vertikale Scrollbar einblenden?
1274     if( bVerSBar || nTotalCount > nVisibleCount )
1275 	{
1276 		nResult = 1;
1277 		nFlags |= F_HOR_SBARSIZE_WITH_VBAR;
1278 		nMaxRight -= nVerSBarWidth;
1279 		if( !bHorBar )
1280 		{
1281 			if( (nWindowStyle & WB_HSCROLL) &&
1282 				(nVis < nMostRight || nMaxRight < nMostRight) )
1283 				bHorBar = sal_True;
1284 		}
1285 	}
1286 
1287 	// muessen wir eine horizontale Scrollbar einblenden?
1288 	if( bHorBar )
1289 	{
1290 		nResult |= 0x0002;
1291 		// die Anzahl der in der View sichtbaren Eintraege
1292 		// muss neu berechnet werden, da die horizontale
1293 		// ScrollBar eingeblendet wird
1294 		nVisibleCount =  (aOSize.Height() - nHorSBarHeight) / nEntryHeight;
1295 		// eventuell brauchen wir jetzt doch eine vertikale ScrollBar
1296 		if( !(nResult & 0x0001) &&
1297             ((nTotalCount > nVisibleCount) || bVerSBar) )
1298 		{
1299 			nResult = 3;
1300 			nFlags |= F_VER_SBARSIZE_WITH_HBAR;
1301 		}
1302 	}
1303 
1304 	PositionScrollBars( aOSize, nResult );
1305 
1306 	// Range, VisibleRange usw. anpassen
1307 
1308 	// Output-Size aktualisieren, falls wir scrollen muessen
1309 	Rectangle aRect;
1310 	aRect.SetSize( aOSize );
1311 	aSelEng.SetVisibleArea( aRect );
1312 
1313 	// Vertikale ScrollBar
1314 	long nTemp = (long)nVisibleCount;
1315 	nTemp--;
1316 	if( nTemp != aVerSBar.GetVisibleSize() )
1317 	{
1318 		if( !bInVScrollHdl )
1319 		{
1320 			aVerSBar.SetPageSize( nTemp - 1 );
1321 			aVerSBar.SetVisibleSize( nTemp );
1322 		}
1323 		else
1324 		{
1325 			nFlags |= F_ENDSCROLL_SET_VIS_SIZE;
1326 			nNextVerVisSize = nTemp;
1327 		}
1328 	}
1329 
1330 	// Horizontale ScrollBar
1331 	nTemp = aHorSBar.GetThumbPos();
1332 	aHorSBar.SetVisibleSize( aOSize.Width() );
1333 	long nNewThumbPos = aHorSBar.GetThumbPos();
1334 	Range aRange( aHorSBar.GetRange() );
1335 	if( aRange.Max() < nMostRight+25 )
1336 	{
1337 		aRange.Max() = nMostRight+25;
1338 		aHorSBar.SetRange( aRange );
1339 	}
1340 
1341 	if( nTemp != nNewThumbPos )
1342 	{
1343 		nTemp = nNewThumbPos - nTemp;
1344 		if( pView->IsEditingActive() )
1345 		{
1346 			pView->EndEditing( sal_True ); // Cancel
1347 			pView->Update();
1348 		}
1349 		pView->nFocusWidth = -1;
1350 		KeyLeftRight( nTemp );
1351 	}
1352 
1353 	if( nResult & 0x0001 )
1354 		aVerSBar.Show();
1355 	else
1356 		aVerSBar.Hide();
1357 
1358 	if( nResult & 0x0002 )
1359 		aHorSBar.Show();
1360 	else
1361 	{
1362 		if( !pTabBar )
1363 			aHorSBar.Hide();
1364 	}
1365 	rSize = aOSize;
1366 	return nResult;
1367 }
1368 
1369 void SvImpLBox::InitScrollBarBox()
1370 {
1371 	aScrBarBox.SetSizePixel( Size(nVerSBarWidth, nHorSBarHeight) );
1372 	Size aSize( pView->Control::GetOutputSizePixel() );
1373 	aScrBarBox.SetPosPixel( Point(aSize.Width()-nVerSBarWidth, aSize.Height()-nHorSBarHeight));
1374 }
1375 
1376 void SvImpLBox::Resize()
1377 {
1378 	Size aSize( pView->Control::GetOutputSizePixel());
1379 	if( aSize.Width() <= 0 || aSize.Height() <= 0 )
1380 		return;
1381 	nFlags |= F_IN_RESIZE;
1382 	InitScrollBarBox();
1383 
1384 	if( pView->GetEntryHeight())
1385 	{
1386 		AdjustScrollBars( aOutputSize );
1387 		FillView();
1388 	}
1389 	// !!!HACK, da in Floating- & Docking-Windows nach Resizes
1390 	// die Scrollbars nicht richtig, bzw. ueberhaupt nicht gezeichnet werden
1391 	if( aHorSBar.IsVisible())
1392 		aHorSBar.Invalidate();
1393 	if( aVerSBar.IsVisible())
1394 		aVerSBar.Invalidate();
1395 	nFlags &= (~(F_IN_RESIZE | F_PAINTED));
1396 }
1397 
1398 void SvImpLBox::FillView()
1399 {
1400 	if( !pStartEntry )
1401 	{
1402 		sal_uInt16 nVisibleViewCount = (sal_uInt16)(pView->GetVisibleCount());
1403 		sal_uInt16 nTempThumb = (sal_uInt16)aVerSBar.GetThumbPos();
1404 		if( nTempThumb >= nVisibleViewCount )
1405 			nTempThumb = nVisibleViewCount - 1;
1406 		pStartEntry = (SvLBoxEntry*)(pView->GetEntryAtVisPos(nTempThumb));
1407 	}
1408 	if( pStartEntry )
1409 	{
1410 		sal_uInt16 nLast = (sal_uInt16)(pView->GetVisiblePos( (SvLBoxEntry*)(pView->LastVisible())));
1411 		sal_uInt16 nThumb = (sal_uInt16)(pView->GetVisiblePos( pStartEntry ));
1412 		sal_uInt16 nCurDispEntries = nLast-nThumb+1;
1413 		if( nCurDispEntries <  nVisibleCount )
1414 		{
1415 			ShowCursor( sal_False );
1416 			// Fenster fuellen, indem der Thumb schrittweise
1417 			// nach oben bewegt wird
1418 			sal_Bool bFound = sal_False;
1419 			SvLBoxEntry* pTemp = pStartEntry;
1420 			while( nCurDispEntries < nVisibleCount && pTemp )
1421 			{
1422 				pTemp = (SvLBoxEntry*)(pView->PrevVisible(pStartEntry));
1423 				if( pTemp )
1424 				{
1425 					nThumb--;
1426 					pStartEntry = pTemp;
1427 					nCurDispEntries++;
1428 					bFound = sal_True;
1429 				}
1430 			}
1431 			if( bFound )
1432 			{
1433 				aVerSBar.SetThumbPos( nThumb );
1434 				ShowCursor( sal_True );	// Focusrect neu berechnen
1435 				pView->Invalidate();
1436 			}
1437 		}
1438 	}
1439 }
1440 
1441 
1442 
1443 
1444 void SvImpLBox::ShowVerSBar()
1445 {
1446 	sal_Bool bVerBar = ( pView->GetStyle() & WB_VSCROLL ) != 0;
1447 	sal_uLong nVis = 0;
1448 	if( !bVerBar )
1449 		nVis = pView->GetVisibleCount();
1450 	if( bVerBar || (nVisibleCount && nVis > (sal_uLong)(nVisibleCount-1)) )
1451 	{
1452 		if( !aVerSBar.IsVisible() )
1453 		{
1454 			pView->nFocusWidth = -1;
1455 			AdjustScrollBars( aOutputSize );
1456 			if( GetUpdateMode() )
1457 				aVerSBar.Update();
1458 		}
1459 	}
1460 	else
1461 	{
1462 		if( aVerSBar.IsVisible() )
1463 		{
1464 			pView->nFocusWidth = -1;
1465 			AdjustScrollBars( aOutputSize );
1466 		}
1467 	}
1468 
1469 	long nMaxRight = GetOutputSize().Width();
1470 	Point aPos( pView->GetMapMode().GetOrigin() );
1471 	aPos.X() *= -1; // Umrechnung Dokumentkoord.
1472 	nMaxRight = nMaxRight + aPos.X() - 1;
1473 	if( nMaxRight < nMostRight  )
1474 	{
1475 		if( !aHorSBar.IsVisible() )
1476 		{
1477 			pView->nFocusWidth = -1;
1478 			AdjustScrollBars( aOutputSize );
1479 			if( GetUpdateMode() )
1480 				aHorSBar.Update();
1481 		}
1482 		else
1483 		{
1484 			Range aRange( aHorSBar.GetRange() );
1485 			if( aRange.Max() < nMostRight+25 )
1486 			{
1487 				aRange.Max() = nMostRight+25;
1488 				aHorSBar.SetRange( aRange );
1489 			}
1490 			else
1491 			{
1492 				pView->nFocusWidth = -1;
1493 				AdjustScrollBars( aOutputSize );
1494 			}
1495 		}
1496 	}
1497 	else
1498 	{
1499 		if( aHorSBar.IsVisible() )
1500 		{
1501 			pView->nFocusWidth = -1;
1502 			AdjustScrollBars( aOutputSize );
1503 		}
1504 	}
1505 }
1506 
1507 
1508 void SvImpLBox::SyncVerThumb()
1509 {
1510 	if( pStartEntry )
1511 	{
1512 		long nEntryPos = pView->GetVisiblePos( pStartEntry );
1513 		aVerSBar.SetThumbPos( nEntryPos );
1514 	}
1515 	else
1516 		aVerSBar.SetThumbPos( 0 );
1517 }
1518 
1519 sal_Bool SvImpLBox::IsEntryInView( SvLBoxEntry* pEntry ) const
1520 {
1521 	// Parent eingeklappt
1522 	if( !pView->IsEntryVisible(pEntry) )
1523 		return sal_False;
1524 	long nY = GetEntryLine( pEntry );
1525 	if( nY < 0 )
1526 		return sal_False;
1527 	long nMax = nVisibleCount * pView->GetEntryHeight();
1528 	if( nY >= nMax )
1529 		return sal_False;
1530 	return sal_True;
1531 }
1532 
1533 
1534 long SvImpLBox::GetEntryLine( SvLBoxEntry* pEntry ) const
1535 {
1536 	if(!pStartEntry )
1537 		return -1; // unsichtbare Position
1538 
1539 	long nFirstVisPos = pView->GetVisiblePos( pStartEntry );
1540 	long nEntryVisPos = pView->GetVisiblePos( pEntry );
1541 	nFirstVisPos = nEntryVisPos - nFirstVisPos;
1542 	nFirstVisPos *= pView->GetEntryHeight();
1543 	return nFirstVisPos;
1544 }
1545 
1546 void SvImpLBox::SetEntryHeight( short /* nHeight */ )
1547 {
1548 	SetNodeBmpYOffset( GetExpandedNodeBmp() );
1549 	SetNodeBmpYOffset( GetCollapsedNodeBmp() );
1550 	if(!pView->HasViewData()) // stehen wir im Clear?
1551 	{
1552 		Size aSize = pView->Control::GetOutputSizePixel();
1553 		AdjustScrollBars( aSize );
1554 	}
1555 	else
1556 	{
1557 		Resize();
1558 		if( GetUpdateMode() )
1559 			pView->Invalidate();
1560 	}
1561 }
1562 
1563 
1564 
1565 // ***********************************************************************
1566 // Callback-Functions
1567 // ***********************************************************************
1568 
1569 void SvImpLBox::IndentChanged( short /* nIndentPixel */ ) {}
1570 
1571 void SvImpLBox::EntryExpanded( SvLBoxEntry* pEntry )
1572 {
1573 	// SelAllDestrAnch( sal_False, sal_True ); //DeselectAll();
1574 	if( GetUpdateMode() )
1575 	{
1576 		ShowCursor( sal_False );
1577 		long nY = GetEntryLine( pEntry );
1578 		if( IsLineVisible(nY) )
1579 		{
1580 			InvalidateEntriesFrom( nY );
1581 			FindMostRight( pEntry, 0  );
1582 		}
1583 		aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1 ) );
1584 		// falls vor dem Thumb expandiert wurde, muss
1585 		// die Thumb-Position korrigiert werden.
1586 		SyncVerThumb();
1587 		ShowVerSBar();
1588 		ShowCursor( sal_True );
1589 	}
1590 }
1591 
1592 void SvImpLBox::EntryCollapsed( SvLBoxEntry* pEntry )
1593 {
1594 	if( !pView->IsEntryVisible( pEntry ) )
1595 		return;
1596 
1597 	ShowCursor( sal_False );
1598 
1599 	if( !pMostRightEntry || pTree->IsChild( pEntry,pMostRightEntry ) )
1600 	{
1601 		FindMostRight(0);
1602 	}
1603 
1604 	if( pStartEntry )
1605 	{
1606 		long nOldThumbPos   = aVerSBar.GetThumbPos();
1607 		sal_uLong nVisList      = pView->GetVisibleCount();
1608 		aVerSBar.SetRange( Range(0, nVisList-1) );
1609 		long nNewThumbPos   = aVerSBar.GetThumbPos();
1610 		if( nNewThumbPos != nOldThumbPos  )
1611 		{
1612 			pStartEntry = pView->First();
1613 			sal_uInt16 nDistance = (sal_uInt16)nNewThumbPos;
1614 			if( nDistance )
1615 				pStartEntry = (SvLBoxEntry*)(pView->NextVisible( pStartEntry,
1616 														nDistance));
1617 			if( GetUpdateMode() )
1618 				pView->Invalidate();
1619 		}
1620 		else
1621 			SyncVerThumb();
1622 		ShowVerSBar();
1623 	}
1624 	// wurde Cursor eingeklappt ?
1625 	if( pTree->IsChild( pEntry, pCursor ) )
1626 		SetCursor( pEntry );
1627 	if( GetUpdateMode() )
1628 		ShowVerSBar();
1629 	ShowCursor( sal_True );
1630 	if( GetUpdateMode() && pCursor )
1631 		pView->Select( pCursor, sal_True );
1632 }
1633 
1634 void SvImpLBox::CollapsingEntry( SvLBoxEntry* pEntry )
1635 {
1636 	if( !pView->IsEntryVisible( pEntry ) || !pStartEntry )
1637 		return;
1638 
1639 	SelAllDestrAnch( sal_False, sal_True ); // deselectall
1640 
1641 	// ist der eingeklappte Parent sichtbar ?
1642 	long nY = GetEntryLine( pEntry );
1643 	if( IsLineVisible(nY) )
1644 	{
1645 		if( GetUpdateMode() )
1646 			InvalidateEntriesFrom( nY );
1647 	}
1648 	else
1649 	{
1650 		if( pTree->IsChild(pEntry, pStartEntry) )
1651 		{
1652 			pStartEntry = pEntry;
1653 			if( GetUpdateMode() )
1654 				pView->Invalidate();
1655 		}
1656 	}
1657 }
1658 
1659 
1660 void SvImpLBox::SetNodeBmpYOffset( const Image& rBmp )
1661 {
1662 	Size aSize;
1663 	nYoffsNodeBmp = pView->GetHeightOffset( rBmp, aSize );
1664 	nNodeBmpWidth = aSize.Width();
1665 }
1666 
1667 void SvImpLBox::SetNodeBmpTabDistance()
1668 {
1669 	nNodeBmpTabDistance = -pView->GetIndent();
1670 	if( pView->nContextBmpWidthMax )
1671 	{
1672 		// nur, wenn der erste dynamische Tab zentriert ist
1673 		// (setze ich momentan voraus)
1674 		Size aSize = GetExpandedNodeBmp().GetSizePixel();
1675 		nNodeBmpTabDistance -= aSize.Width() / 2;
1676 	}
1677 }
1678 
1679 //
1680 // korrigiert bei SingleSelection den Cursor
1681 //
1682 void SvImpLBox::EntrySelected( SvLBoxEntry* pEntry, sal_Bool bSelect )
1683 {
1684 	if( nFlags & F_IGNORE_SELECT )
1685 		return;
1686 
1687 	/*
1688 	if( (m_nStyle & WB_HIDESELECTION) && pEntry && !pView->HasFocus() )
1689 	{
1690 		SvViewData* pViewData = pView->GetViewData( pEntry );
1691 		pViewData->SetCursored( bSelect );
1692 	}
1693 	*/
1694 
1695 	nFlags &= (~F_DESEL_ALL);
1696 	if( bSelect &&
1697 		aSelEng.GetSelectionMode() == SINGLE_SELECTION &&
1698 		pEntry != pCursor )
1699 	{
1700 		SetCursor( pEntry );
1701 		DBG_ASSERT(pView->GetSelectionCount()==1,"selection count?");
1702 	}
1703 
1704 	if( GetUpdateMode() && pView->IsEntryVisible(pEntry) )
1705 	{
1706 		long nY = GetEntryLine( pEntry );
1707 		if( IsLineVisible( nY ) )
1708 		{
1709 			ShowCursor( sal_False );
1710 			pView->PaintEntry1( pEntry, nY, 0xffff ); // wg. ItemsetBrowser SV_LBOXTAB_SHOW_SELECTION );
1711 			ShowCursor( sal_True );
1712 		}
1713 	}
1714 }
1715 
1716 
1717 void SvImpLBox::RemovingEntry( SvLBoxEntry* pEntry )
1718 {
1719 	//IAccessibility2 Implementation 2009-----
1720 	CallEventListeners( VCLEVENT_LISTBOX_ITEMREMOVED , pEntry );
1721 	//-----IAccessibility2 Implementation 2009
1722 
1723 	DestroyAnchor();
1724 
1725 	if( !pView->IsEntryVisible( pEntry ) )
1726 	{
1727 		// wenn Parent eingeklappt, dann tschuess
1728 		nFlags |= F_REMOVED_ENTRY_INVISIBLE;
1729 		return;
1730 	}
1731 
1732 	if( pEntry == pMostRightEntry || (
1733 		pEntry->HasChilds() && pView->IsExpanded(pEntry) &&
1734 		pTree->IsChild(pEntry, pMostRightEntry)))
1735 	{
1736 		nFlags |= F_REMOVED_RECALC_MOST_RIGHT;
1737 	}
1738 
1739 	SvLBoxEntry* pOldStartEntry = pStartEntry;
1740 
1741 	SvLBoxEntry* pParent = (SvLBoxEntry*)(pView->GetModel()->GetParent(pEntry));
1742 
1743 	if( pParent && pView->GetModel()->GetChildList(pParent)->Count() == 1 )
1744 	{
1745 		DBG_ASSERT( pView->IsExpanded( pParent ), "Parent not expanded");
1746 		pParent->SetFlags( pParent->GetFlags() | SV_ENTRYFLAG_NO_NODEBMP);
1747 		InvalidateEntry( pParent );
1748 	}
1749 
1750 	if( pCursor && pTree->IsChild( pEntry, pCursor) )
1751 		pCursor = pEntry;
1752 	if( pStartEntry && pTree->IsChild(pEntry,pStartEntry) )
1753 		pStartEntry = pEntry;
1754 
1755 	SvLBoxEntry* pTemp;
1756 	if( pCursor && pCursor == pEntry )
1757 	{
1758 		if( bSimpleTravel )
1759 			pView->Select( pCursor, sal_False );
1760 		ShowCursor( sal_False );	// Focus-Rect weg
1761 		// NextSibling, weil auch Childs des Cursors geloescht werden
1762 		pTemp = pView->NextSibling( pCursor );
1763 		if( !pTemp )
1764 			pTemp = (SvLBoxEntry*)(pView->PrevVisible( pCursor ));
1765 
1766 		SetCursor( pTemp, sal_True );
1767 	}
1768 	if( pStartEntry && pStartEntry == pEntry )
1769 	{
1770 		pTemp = pView->NextSibling( pStartEntry );
1771 		if( !pTemp )
1772 			pTemp = (SvLBoxEntry*)(pView->PrevVisible( pStartEntry ));
1773 		pStartEntry = pTemp;
1774 	}
1775 	if( GetUpdateMode())
1776 	{
1777 		// wenns der letzte ist, muss invalidiert werden, damit die Linien
1778 		// richtig gezeichnet (in diesem Fall geloescht) werden.
1779 		if( pStartEntry && (pStartEntry != pOldStartEntry || pEntry == (SvLBoxEntry*)pView->GetModel()->Last()) )
1780 		{
1781 			aVerSBar.SetThumbPos( pView->GetVisiblePos( pStartEntry ));
1782 			pView->Invalidate( GetVisibleArea() );
1783 		}
1784 		else
1785 			InvalidateEntriesFrom( GetEntryLine( pEntry ) );
1786 	}
1787 }
1788 
1789 void SvImpLBox::EntryRemoved()
1790 {
1791 	if( nFlags & F_REMOVED_ENTRY_INVISIBLE )
1792 	{
1793 		nFlags &= (~F_REMOVED_ENTRY_INVISIBLE);
1794 		return;
1795 	}
1796 	if( !pStartEntry )
1797 		pStartEntry = pTree->First();
1798 	if( !pCursor )
1799 		SetCursor( pStartEntry, sal_True );
1800 
1801 	if( pCursor && (bSimpleTravel || !pView->GetSelectionCount() ))
1802 		pView->Select( pCursor, sal_True );
1803 
1804 	if( GetUpdateMode())
1805 	{
1806 		if( nFlags & F_REMOVED_RECALC_MOST_RIGHT )
1807 			FindMostRight(0);
1808 		aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1 ) );
1809 		FillView();
1810 		if( pStartEntry )
1811 			// falls ueber dem Thumb geloescht wurde
1812 			aVerSBar.SetThumbPos( pView->GetVisiblePos( pStartEntry) );
1813 
1814 		ShowVerSBar();
1815 		if( pCursor && pView->HasFocus() && !pView->IsSelected(pCursor) )
1816 		{
1817 			if( pView->GetSelectionCount() )
1818 			{
1819 				// ist ein benachbarter Eintrag selektiert?
1820 				SvLBoxEntry* pNextCursor = (SvLBoxEntry*)pView->PrevVisible( pCursor );
1821 				if( !pNextCursor || !pView->IsSelected( pNextCursor ))
1822 					pNextCursor = (SvLBoxEntry*)pView->NextVisible( pCursor );
1823 				if( !pNextCursor || !pView->IsSelected( pNextCursor ))
1824 					// kein Nachbar selektiert: Ersten selektierten nehmen
1825 					pNextCursor = pView->FirstSelected();
1826 				SetCursor( pNextCursor );
1827 				MakeVisible( pCursor );
1828 			}
1829 			else
1830 				pView->Select( pCursor, sal_True );
1831 		}
1832 		ShowCursor( sal_True );
1833 	}
1834 	nFlags &= (~F_REMOVED_RECALC_MOST_RIGHT);
1835 }
1836 
1837 
1838 void SvImpLBox::MovingEntry( SvLBoxEntry* pEntry )
1839 {
1840 	int bDeselAll = nFlags & F_DESEL_ALL;
1841 	SelAllDestrAnch( sal_False, sal_True );  // DeselectAll();
1842 	if( !bDeselAll )
1843 		nFlags &= (~F_DESEL_ALL);
1844 
1845 	if( pEntry == pCursor )
1846 		ShowCursor( sal_False );
1847 	if( IsEntryInView( pEntry ) )
1848 		pView->Invalidate();
1849 	if( pEntry == pStartEntry )
1850 	{
1851 		SvLBoxEntry* pNew = 0;
1852 		if( !pEntry->HasChilds() )
1853 		{
1854 			pNew = (SvLBoxEntry*)(pView->NextVisible( pStartEntry ));
1855 			if( !pNew )
1856 				pNew = (SvLBoxEntry*)(pView->PrevVisible( pStartEntry ));
1857 		}
1858 		else
1859 		{
1860 			pNew = pTree->NextSibling( pEntry );
1861 			if( !pNew )
1862 				pNew = pTree->PrevSibling( pEntry );
1863 		}
1864 		pStartEntry = pNew;
1865 	}
1866 }
1867 
1868 void SvImpLBox::EntryMoved( SvLBoxEntry* pEntry )
1869 {
1870 	// #97680# --------------
1871 	UpdateContextBmpWidthVectorFromMovedEntry( pEntry );
1872 
1873     if ( !pStartEntry )
1874         // this might happen if the only entry in the view is moved to its very same position
1875         // #i97346#
1876         pStartEntry = pView->First();
1877 
1878 	aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1));
1879 	sal_uInt16 nFirstPos = (sal_uInt16)pTree->GetAbsPos( pStartEntry );
1880 	sal_uInt16 nNewPos = (sal_uInt16)pTree->GetAbsPos( pEntry );
1881 	FindMostRight(0);
1882 	if( nNewPos < nFirstPos ) //!!!Notloesung
1883 		pStartEntry = pEntry;
1884 	// #97702# ---------------
1885 	SyncVerThumb();
1886 	if( pEntry == pCursor )
1887 	{
1888 		if( pView->IsEntryVisible( pCursor ) )
1889 			ShowCursor( sal_True );
1890 		else
1891 		{
1892 			SvLBoxEntry* pParent = pEntry;
1893 			do {
1894 				pParent = pTree->GetParent( pParent );
1895 			}
1896 			while( !pView->IsEntryVisible( pParent ) );
1897 			SetCursor( pParent );
1898 		}
1899 	}
1900 	if( IsEntryInView( pEntry ) )
1901 		pView->Invalidate();
1902 }
1903 
1904 
1905 
1906 void SvImpLBox::EntryInserted( SvLBoxEntry* pEntry )
1907 {
1908 	if( GetUpdateMode() )
1909 	{
1910 		SvLBoxEntry* pParent = (SvLBoxEntry*)pTree->GetParent(pEntry);
1911 		if( pParent && pTree->GetChildList(pParent)->Count() == 1 )
1912 			// Pluszeichen zeichnen
1913 			pTree->InvalidateEntry( pParent );
1914 
1915 		if( !pView->IsEntryVisible( pEntry ) )
1916 			return;
1917 		int bDeselAll = nFlags & F_DESEL_ALL;
1918 		if( bDeselAll )
1919 			SelAllDestrAnch( sal_False, sal_True );
1920 		else
1921 			DestroyAnchor();
1922 		//	nFlags &= (~F_DESEL_ALL);
1923 //		ShowCursor( sal_False ); // falls sich Cursor nach unten verschiebt
1924 		long nY = GetEntryLine( pEntry );
1925 		sal_Bool bEntryVisible = IsLineVisible( nY );
1926 		if( bEntryVisible )
1927 		{
1928 			ShowCursor( sal_False ); // falls sich Cursor nach unten verschiebt
1929 			nY -= pView->GetEntryHeight(); // wg. Linien
1930 			InvalidateEntriesFrom( nY );
1931 		}
1932 		else if( pStartEntry && nY < GetEntryLine(pStartEntry) )
1933 		{
1934 			// pruefen, ob die View komplett gefuellt ist. Wenn
1935 			// nicht, dann pStartEntry und den Cursor anpassen
1936 			// (automatisches scrollen)
1937 			sal_uInt16 nLast = (sal_uInt16)(pView->GetVisiblePos( (SvLBoxEntry*)(pView->LastVisible())));
1938 			sal_uInt16 nThumb = (sal_uInt16)(pView->GetVisiblePos( pStartEntry ));
1939 			sal_uInt16 nCurDispEntries = nLast-nThumb+1;
1940 			if( nCurDispEntries < nVisibleCount )
1941 			{
1942 				// beim naechsten Paint-Event setzen
1943 				pStartEntry = 0;
1944 				SetCursor( 0 );
1945 				pView->Invalidate();
1946 			}
1947 		}
1948 		else if( !pStartEntry )
1949 			pView->Invalidate();
1950 
1951 		// die Linien invalidieren
1952 		/*
1953 		if( (bEntryVisible || bPrevEntryVisible) &&
1954 			(m_nStyle & ( WB_HASLINES | WB_HASLINESATROOT )) )
1955 		{
1956 			SvLBoxTab* pTab = pView->GetFirstDynamicTab();
1957 			if( pTab )
1958 			{
1959 				long nDX = pView->GetTabPos( pEntry, pTab );
1960 				Point aTmpPoint;
1961 				Size aSize( nDX, nY );
1962 				Rectangle aRect( aTmpPoint, aSize );
1963 				pView->Invalidate( aRect );
1964 			}
1965 		}
1966 		*/
1967 
1968 		SetMostRight( pEntry );
1969 		aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1));
1970 		SyncVerThumb(); // falls vor Thumb eingefuegt wurde
1971 		ShowVerSBar();
1972 		ShowCursor( sal_True );
1973 		if( pStartEntry != pView->First() && (nFlags & F_FILLING) )
1974 			pView->Update();
1975 	}
1976 }
1977 
1978 
1979 
1980 // ********************************************************************
1981 // Eventhandler
1982 // ********************************************************************
1983 
1984 
1985 // ****** Steuerung der Controlanimation
1986 
1987 sal_Bool SvImpLBox::ButtonDownCheckCtrl(const MouseEvent& rMEvt, SvLBoxEntry* pEntry,
1988 								   long nY	)
1989 {
1990 	SvLBoxItem* pItem = pView->GetItem(pEntry,rMEvt.GetPosPixel().X(),&pActiveTab);
1991 	if( pItem && (pItem->IsA()==SV_ITEM_ID_LBOXBUTTON))
1992 	{
1993 		pActiveButton = (SvLBoxButton*)pItem;
1994 		pActiveEntry = pEntry;
1995 		if( pCursor == pActiveEntry )
1996 			pView->HideFocus();
1997 		pView->CaptureMouse();
1998 		pActiveButton->SetStateHilighted( sal_True );
1999 		pView->PaintEntry1( pActiveEntry, nY,
2000 					SV_LBOXTAB_PUSHABLE | SV_LBOXTAB_ADJUST_CENTER |
2001 					SV_LBOXTAB_ADJUST_RIGHT );
2002 		return sal_True;
2003 	}
2004 	else
2005 		pActiveButton = 0;
2006 	return sal_False;
2007 }
2008 
2009 sal_Bool SvImpLBox::MouseMoveCheckCtrl( const MouseEvent& rMEvt, SvLBoxEntry* pEntry)
2010 {
2011 	if( pActiveButton )
2012 	{
2013 		long nY;
2014 		long nMouseX = rMEvt.GetPosPixel().X();
2015 		if( pEntry == pActiveEntry &&
2016 			 pView->GetItem(pActiveEntry, nMouseX) == pActiveButton )
2017 		{
2018 			if( !pActiveButton->IsStateHilighted() )
2019 			{
2020 				pActiveButton->SetStateHilighted(sal_True );
2021 				nY = GetEntryLine( pActiveEntry );
2022 				pView->PaintEntry1( pActiveEntry, nY,
2023 					SV_LBOXTAB_PUSHABLE | SV_LBOXTAB_ADJUST_CENTER |
2024 					SV_LBOXTAB_ADJUST_RIGHT );
2025 			}
2026 		}
2027 		else
2028 		{
2029 			if( pActiveButton->IsStateHilighted() )
2030 			{
2031 				pActiveButton->SetStateHilighted(sal_False );
2032 				nY = GetEntryLine( pActiveEntry );
2033 				pView->PaintEntry1( pActiveEntry, nY, SV_LBOXTAB_PUSHABLE );
2034 			}
2035 		}
2036 		return sal_True;
2037 	}
2038 	return sal_False;
2039 }
2040 
2041 sal_Bool SvImpLBox::ButtonUpCheckCtrl( const MouseEvent& rMEvt )
2042 {
2043 	if( pActiveButton )
2044 	{
2045 		pView->ReleaseMouse();
2046 		SvLBoxEntry* pEntry = GetClickedEntry( rMEvt.GetPosPixel() );
2047 		long nY = GetEntryLine( pActiveEntry );
2048 		pActiveButton->SetStateHilighted( sal_False );
2049 		long nMouseX = rMEvt.GetPosPixel().X();
2050 		if( pEntry == pActiveEntry &&
2051 			 pView->GetItem( pActiveEntry, nMouseX ) == pActiveButton )
2052 			pActiveButton->ClickHdl( pView, pActiveEntry );
2053 		pView->PaintEntry1( pActiveEntry, nY,
2054 					SV_LBOXTAB_PUSHABLE | SV_LBOXTAB_ADJUST_CENTER |
2055 					SV_LBOXTAB_ADJUST_RIGHT );
2056 		if( pCursor == pActiveEntry )
2057 			ShowCursor( sal_True );
2058 		pActiveButton = 0;
2059 		pActiveEntry = 0;
2060 		pActiveTab = 0;
2061 		return sal_True;
2062 	}
2063 	return sal_False;
2064 }
2065 
2066 // ******* Steuerung Plus/Minus-Button zum Expandieren/Kollabieren
2067 
2068 // sal_False == kein Expand/Collapse-Button getroffen
2069 sal_Bool SvImpLBox::IsNodeButton( const Point& rPosPixel, SvLBoxEntry* pEntry ) const
2070 {
2071 	if( !pEntry->HasChilds() && !pEntry->HasChildsOnDemand() )
2072 		return sal_False;
2073 
2074 	SvLBoxTab* pFirstDynamicTab = pView->GetFirstDynamicTab();
2075 	if( !pFirstDynamicTab )
2076 		return sal_False;
2077 
2078 	long nMouseX = rPosPixel.X();
2079 	// in Doc-Koords umrechnen
2080 	Point aOrigin( pView->GetMapMode().GetOrigin() );
2081 	nMouseX -= aOrigin.X();
2082 
2083 	long nX = pView->GetTabPos( pEntry, pFirstDynamicTab);
2084 	nX += nNodeBmpTabDistance;
2085 	if( nMouseX < nX )
2086 		return sal_False;
2087 	nX += nNodeBmpWidth;
2088 	if( nMouseX > nX )
2089 		return sal_False;
2090 	return sal_True;
2091 }
2092 
2093 // sal_False == hit no node button
2094 sal_Bool SvImpLBox::ButtonDownCheckExpand( const MouseEvent& rMEvt, SvLBoxEntry* pEntry, long /* nY */ )
2095 {
2096 	sal_Bool bRet = sal_False;
2097 
2098 	if ( pView->IsEditingActive() && pEntry == pView->pEdEntry )
2099 		// inplace editing -> nothing to do
2100 		bRet = sal_True;
2101 	else if ( IsNodeButton( rMEvt.GetPosPixel(), pEntry ) )
2102 	{
2103 		if ( pView->IsExpanded( pEntry ) )
2104 		{
2105 			pView->EndEditing( sal_True );
2106 			pView->Collapse( pEntry );
2107 		}
2108 		else
2109 		{
2110 			// you can expand an entry, which is in editing
2111 			pView->Expand( pEntry );
2112 		}
2113 		bRet = sal_True;
2114 	}
2115 
2116 	return bRet;
2117 }
2118 
2119 void SvImpLBox::MouseButtonDown( const MouseEvent& rMEvt )
2120 {
2121 	if ( !rMEvt.IsLeft() && !rMEvt.IsRight())
2122 		return;
2123 
2124 #ifdef OS2
2125 	// unter OS/2 kommt zwischen MouseButtonDown und
2126 	// MouseButtonUp ein MouseMove
2127 	nFlags |= F_IGNORE_NEXT_MOUSEMOVE;
2128 #endif
2129 	aEditTimer.Stop();
2130 	Point aPos( rMEvt.GetPosPixel());
2131 
2132 	if( aPos.X() > aOutputSize.Width() || aPos.Y() > aOutputSize.Height() )
2133 		return;
2134 
2135 	SvLBoxEntry* pEntry = GetEntry( aPos );
2136 	if ( pEntry != pCursor )
2137 		// new entry selected -> reset current tab position to first tab
2138 		nCurTabPos = FIRST_ENTRY_TAB;
2139 	nFlags &= (~F_FILLING);
2140 	pView->GrabFocus();
2141 	// #120417# the entry can still be invalid!
2142     if( !pEntry || !pView->GetViewData( pEntry ))
2143 		return;
2144 
2145 	long nY = GetEntryLine( pEntry );
2146 	// Node-Button?
2147 	if( ButtonDownCheckExpand( rMEvt, pEntry, nY ) )
2148 		return;
2149 
2150 	if( !EntryReallyHit(pEntry,aPos,nY))
2151 		return;
2152 
2153 	SvLBoxItem* pXItem = pView->GetItem( pEntry, aPos.X() );
2154 	if( pXItem )
2155 	{
2156 		SvLBoxTab* pXTab = pView->GetTab( pEntry, pXItem );
2157 		if ( !rMEvt.IsMod1() && !rMEvt.IsMod2() && rMEvt.IsLeft() && pXTab->IsEditable()
2158 			&& pEntry == pView->FirstSelected() && NULL == pView->NextSelected( pEntry ) )
2159 				// #i8234# FirstSelected() and NextSelected() ensures, that inplace editing is only triggered, when only one entry is selected
2160 			nFlags |= F_START_EDITTIMER;
2161 		if ( !pView->IsSelected( pEntry ) )
2162 			nFlags &= ~F_START_EDITTIMER;
2163 	}
2164 
2165 
2166 	if( (rMEvt.GetClicks() % 2) == 0 )
2167 	{
2168 		nFlags &= (~F_START_EDITTIMER);
2169 		pView->pHdlEntry = pEntry;
2170 		if( pView->DoubleClickHdl() )
2171 		{
2172 			// falls im Handler der Eintrag geloescht wurde
2173 			pEntry = GetClickedEntry( aPos );
2174 			if( !pEntry )
2175 				return;
2176 			if( pEntry != pView->pHdlEntry )
2177 			{
2178 				// neu selektieren & tschuess
2179 				if( !bSimpleTravel && !aSelEng.IsAlwaysAdding())
2180 					SelAllDestrAnch( sal_False, sal_True ); // DeselectAll();
2181 				SetCursor( pEntry );
2182 
2183 				return;
2184 			}
2185 			if( pEntry->HasChilds() || pEntry->HasChildsOnDemand() )
2186 			{
2187 				if( pView->IsExpanded(pEntry) )
2188 					pView->Collapse( pEntry );
2189 				else
2190 					pView->Expand( pEntry );
2191 				if( pEntry == pCursor )  // nur wenn Entryitem angeklickt wurde
2192 										  // (Nodebutton ist kein Entryitem!)
2193 					pView->Select( pCursor, sal_True );
2194 				return;
2195 			}
2196 		}
2197 	}
2198 	else
2199 	{
2200 		// CheckButton? (TreeListBox: Check + Info)
2201 		if( ButtonDownCheckCtrl(rMEvt, pEntry, nY) == sal_True)
2202 			return;
2203 		// Inplace-Editing?
2204 #if 0
2205 		if( rMEvt.IsMod2() && pView->IsInplaceEditingEnabled() )
2206 		{
2207 			SvLBoxItem* pItem = pView->GetItem( pEntry, aPos.X() );
2208 			if( pItem )
2209 				pView->EditingRequest( pEntry, pItem, aPos );
2210 			return;
2211 		}
2212 #endif
2213 	}
2214     if ( aSelEng.GetSelectionMode() != NO_SELECTION )
2215 	    aSelEng.SelMouseButtonDown( rMEvt );
2216 }
2217 
2218 void SvImpLBox::MouseButtonUp( const MouseEvent& rMEvt)
2219 {
2220 #ifdef OS2
2221 	nFlags &= (~F_IGNORE_NEXT_MOUSEMOVE);
2222 #endif
2223 	if ( !ButtonUpCheckCtrl( rMEvt ) && ( aSelEng.GetSelectionMode() != NO_SELECTION ) )
2224 		aSelEng.SelMouseButtonUp( rMEvt );
2225 	EndScroll();
2226 	if( nFlags & F_START_EDITTIMER )
2227 	{
2228 		nFlags &= (~F_START_EDITTIMER);
2229 		aEditClickPos = rMEvt.GetPosPixel();
2230 		aEditTimer.Start();
2231 	}
2232 
2233 	return;
2234 }
2235 
2236 void SvImpLBox::MouseMove( const MouseEvent& rMEvt)
2237 {
2238 #ifdef OS2
2239 	if( nFlags & F_IGNORE_NEXT_MOUSEMOVE )
2240 	{
2241 		nFlags &= (~F_IGNORE_NEXT_MOUSEMOVE);
2242 		return;
2243 	}
2244 #endif
2245 	SvLBoxEntry* pEntry = GetClickedEntry( rMEvt.GetPosPixel() );
2246 	if ( !MouseMoveCheckCtrl( rMEvt, pEntry ) && ( aSelEng.GetSelectionMode() != NO_SELECTION ) )
2247 		aSelEng.SelMouseMove( rMEvt );
2248 	return;
2249 }
2250 
2251 sal_Bool SvImpLBox::KeyInput( const KeyEvent& rKEvt)
2252 {
2253 	aEditTimer.Stop();
2254 	const KeyCode&	rKeyCode = rKEvt.GetKeyCode();
2255 
2256 	if( rKeyCode.IsMod2() )
2257 		return sal_False; // Alt-Taste nicht auswerten
2258 
2259 	nFlags &= (~F_FILLING);
2260 
2261 	if( !pCursor )
2262 		pCursor = pStartEntry;
2263 	if( !pCursor )
2264 		return sal_False;
2265 
2266 	sal_Bool bKeyUsed = sal_True;
2267 
2268 	sal_uInt16  nDelta = (sal_uInt16)aVerSBar.GetPageSize();
2269 	sal_uInt16  aCode = rKeyCode.GetCode();
2270 
2271 	sal_Bool    bShift = rKeyCode.IsShift();
2272 	sal_Bool    bMod1 = rKeyCode.IsMod1();
2273 
2274 	SvLBoxEntry* pNewCursor;
2275 
2276     const WinBits nWindowStyle = pView->GetStyle();
2277 	switch( aCode )
2278 	{
2279 		case KEY_UP:
2280 			if( !IsEntryInView( pCursor ) )
2281 				MakeVisible( pCursor );
2282 
2283 			pNewCursor = pCursor;
2284 			do
2285 			{
2286 				pNewCursor = (SvLBoxEntry*)(pView->PrevVisible( pNewCursor ));
2287 			} while( pNewCursor && !IsSelectable(pNewCursor) );
2288 
2289 			if ( pNewCursor )
2290 				// new entry selected -> reset current tab position to first tab
2291 				nCurTabPos = FIRST_ENTRY_TAB;
2292 			// if there is no next entry, take the current one
2293 			// this ensures that in case of _one_ entry in the list, this entry is selected when pressing
2294 			// the cursor key
2295 			// 06.09.20001 - 83416 - fs@openoffice.org
2296 			if ( !pNewCursor && pCursor )
2297 				pNewCursor = pCursor;
2298 
2299 			if( pNewCursor )
2300 			{
2301 				aSelEng.CursorPosChanging( bShift, bMod1 );
2302 				SetCursor( pNewCursor, bMod1 );		// no selection, when Ctrl is on
2303 				if( !IsEntryInView( pNewCursor ) )
2304 					KeyUp( sal_False );
2305 			}
2306 			break;
2307 
2308 		case KEY_DOWN:
2309 			if( !IsEntryInView( pCursor ) )
2310 				MakeVisible( pCursor );
2311 
2312 			pNewCursor = pCursor;
2313 			do
2314 			{
2315 				pNewCursor = (SvLBoxEntry*)(pView->NextVisible( pNewCursor ));
2316 			} while( pNewCursor && !IsSelectable(pNewCursor) );
2317 
2318 			if ( pNewCursor )
2319 				// new entry selected -> reset current tab position to first tab
2320 				nCurTabPos = FIRST_ENTRY_TAB;
2321 
2322 			// if there is no next entry, take the current one
2323 			// this ensures that in case of _one_ entry in the list, this entry is selected when pressing
2324 			// the cursor key
2325 			// 06.09.20001 - 83416 - frank.schoenheit@sun.com
2326 			if ( !pNewCursor && pCursor )
2327 				pNewCursor = pCursor;
2328 
2329 			if( pNewCursor )
2330 			{
2331 				aSelEng.CursorPosChanging( bShift, bMod1 );
2332 				if( IsEntryInView( pNewCursor ) )
2333 					SetCursor( pNewCursor, bMod1 );	// no selection, when Ctrl is on
2334 				else
2335 				{
2336 					if( pCursor )
2337 						pView->Select( pCursor, sal_False );
2338 					KeyDown( sal_False );
2339 					SetCursor( pNewCursor, bMod1 );	// no selection, when Ctrl is on
2340 				}
2341 			}
2342 			else
2343 				KeyDown( sal_False ); // weil ScrollBar-Range evtl. noch
2344 								  // scrollen erlaubt
2345 			break;
2346 
2347 		case KEY_RIGHT:
2348 		{
2349 			if( bSubLstOpLR && IsNowExpandable() )
2350 				pView->Expand( pCursor );
2351             else if ( bIsCellFocusEnabled && pCursor )
2352             {
2353                 if ( nCurTabPos < ( pView->TabCount() - 1 /*!2*/ ) )
2354                 {
2355                     ++nCurTabPos;
2356                     ShowCursor( sal_True );
2357                     CallEventListeners( VCLEVENT_LISTBOX_SELECT, pCursor );
2358                 }
2359             }
2360 			else if( nWindowStyle & WB_HSCROLL )
2361 			{
2362 				long	nThumb = aHorSBar.GetThumbPos();
2363 				nThumb += aHorSBar.GetLineSize();
2364 				long	nOldThumb = aHorSBar.GetThumbPos();
2365 				aHorSBar.SetThumbPos( nThumb );
2366 				nThumb = nOldThumb;
2367 				nThumb -= aHorSBar.GetThumbPos();
2368 				nThumb *= -1;
2369 				if( nThumb )
2370 				{
2371 					KeyLeftRight( nThumb );
2372 					EndScroll();
2373 				}
2374 			}
2375 			else
2376 				bKeyUsed = sal_False;
2377 			break;
2378 		}
2379 
2380 		case KEY_LEFT:
2381 		{
2382             //IAccessibility2 Implementation 2009-----
2383             // if ( bIsCellFocusEnabled )
2384             if ( bIsCellFocusEnabled && pCursor )
2385 			//-----IAccessibility2 Implementation 2009
2386             {
2387                 if ( nCurTabPos > FIRST_ENTRY_TAB )
2388                 {
2389                     --nCurTabPos;
2390                     ShowCursor( sal_True );
2391                     CallEventListeners( VCLEVENT_LISTBOX_SELECT, pCursor );
2392                 }
2393             }
2394             else if ( nWindowStyle & WB_HSCROLL )
2395 			{
2396 				long	nThumb = aHorSBar.GetThumbPos();
2397 				nThumb -= aHorSBar.GetLineSize();
2398 				long	nOldThumb = aHorSBar.GetThumbPos();
2399 				aHorSBar.SetThumbPos( nThumb );
2400 				nThumb = nOldThumb;
2401 				nThumb -= aHorSBar.GetThumbPos();
2402 				if( nThumb )
2403 				{
2404 					KeyLeftRight( -nThumb );
2405 					EndScroll();
2406 				}
2407 				else if( bSubLstOpLR )
2408 				{
2409 					if( IsExpandable() && pView->IsExpanded( pCursor ) )
2410 						pView->Collapse( pCursor );
2411 					else
2412 					{
2413 						pNewCursor = pView->GetParent( pCursor );
2414 						if( pNewCursor )
2415 							SetCursor( pNewCursor );
2416 					}
2417 				}
2418 			}
2419 			else if( bSubLstOpLR && IsExpandable() )
2420 				pView->Collapse( pCursor );
2421 			else
2422 				bKeyUsed = sal_False;
2423 			break;
2424 		}
2425 
2426 		case KEY_PAGEUP:
2427 			if( !bMod1 )
2428 			{
2429 				pNewCursor = (SvLBoxEntry*)(pView->PrevVisible( pCursor, nDelta ));
2430 
2431 				while( nDelta && pNewCursor && !IsSelectable(pNewCursor) )
2432 				{
2433 					pNewCursor = (SvLBoxEntry*)(pView->NextVisible( pNewCursor ));
2434 					nDelta--;
2435 				}
2436 
2437 				if( nDelta )
2438 				{
2439 					DBG_ASSERT(pNewCursor&&(sal_uLong)pNewCursor!=(sal_uLong)pCursor,"Cursor?");
2440 					aSelEng.CursorPosChanging( bShift, bMod1 );
2441 					if( IsEntryInView( pNewCursor ) )
2442 						SetCursor( pNewCursor );
2443 					else
2444 					{
2445 						SetCursor( pNewCursor );
2446 						KeyUp( sal_True );
2447 					}
2448 				}
2449 			}
2450 			else
2451 				bKeyUsed = sal_False;
2452 			break;
2453 
2454 		case KEY_PAGEDOWN:
2455 			if( !bMod1 )
2456 			{
2457 				pNewCursor= (SvLBoxEntry*)(pView->NextVisible( pCursor, nDelta ));
2458 
2459 				while( nDelta && pNewCursor && !IsSelectable(pNewCursor) )
2460 				{
2461 					pNewCursor = (SvLBoxEntry*)(pView->PrevVisible( pNewCursor ));
2462 					nDelta--;
2463 				}
2464 
2465 				if( nDelta )
2466 				{
2467 					DBG_ASSERT(pNewCursor&&(sal_uLong)pNewCursor!=(sal_uLong)pCursor,"Cursor?");
2468 					aSelEng.CursorPosChanging( bShift, bMod1 );
2469 					if( IsEntryInView( pNewCursor ) )
2470 						SetCursor( pNewCursor );
2471 					else
2472 					{
2473 						SetCursor( pNewCursor );
2474 						KeyDown( sal_True );
2475 					}
2476 				}
2477 				else
2478 					KeyDown( sal_False ); // siehe KEY_DOWN
2479 			}
2480 			else
2481 				bKeyUsed = sal_False;
2482 			break;
2483 
2484 		case KEY_SPACE:
2485             if ( pView->GetSelectionMode() != NO_SELECTION )
2486             {
2487 			    if ( bMod1 )
2488 			    {
2489 				    if ( pView->GetSelectionMode() == MULTIPLE_SELECTION && !bShift )
2490 					    // toggle selection
2491 					    pView->Select( pCursor, !pView->IsSelected( pCursor ) );
2492 			    }
2493 			    else if ( !bShift /*&& !bMod1*/ )
2494 			    {
2495 				    if ( aSelEng.IsAddMode() )
2496                     {
2497 					    // toggle selection
2498 					    pView->Select( pCursor, !pView->IsSelected( pCursor ) );
2499                     }
2500 				    else if ( !pView->IsSelected( pCursor ) )
2501 				    {
2502 					    SelAllDestrAnch( sal_False );
2503 					    pView->Select( pCursor, sal_True );
2504 				    }
2505                     else
2506 				        bKeyUsed = sal_False;
2507 			    }
2508                 else
2509 				    bKeyUsed = sal_False;
2510             }
2511 			else
2512 				bKeyUsed = sal_False;
2513 			break;
2514 
2515 		case KEY_RETURN:
2516 			if( bSubLstOpRet && IsExpandable() )
2517 			{
2518 				if( pView->IsExpanded( pCursor ) )
2519 					pView->Collapse( pCursor );
2520 				else
2521 					pView->Expand( pCursor );
2522 			}
2523 			else
2524 				bKeyUsed = sal_False;
2525 			break;
2526 
2527 		case KEY_F2:
2528 			if( !bShift && !bMod1 )
2529 			{
2530 				aEditClickPos = Point( -1, -1 );
2531 				EditTimerCall( 0 );
2532 			}
2533 			else
2534 				bKeyUsed = sal_False;
2535 			break;
2536 
2537 		case KEY_F8:
2538 			if( bShift && pView->GetSelectionMode()==MULTIPLE_SELECTION &&
2539 				!(m_nStyle & WB_SIMPLEMODE))
2540 			{
2541 				if( aSelEng.IsAlwaysAdding() )
2542 					aSelEng.AddAlways( sal_False );
2543 				else
2544 					aSelEng.AddAlways( sal_True );
2545 			}
2546 			else
2547 				bKeyUsed = sal_False;
2548 			break;
2549 
2550 
2551 #ifdef OV_DEBUG
2552 		case KEY_F9:
2553 			MakeVisible( pCursor );
2554 			break;
2555 		case KEY_F10:
2556 			pView->RemoveSelection();
2557 			break;
2558 		case KEY_DELETE:
2559 			pView->RemoveEntry( pCursor );
2560 			break;
2561 #endif
2562 
2563 		case KEY_ADD:
2564 			if( pCursor )
2565 			{
2566 				if( !pView->IsExpanded(pCursor))
2567 					pView->Expand( pCursor );
2568 				if( bMod1 )
2569 				{
2570 					sal_uInt16 nRefDepth = pTree->GetDepth( pCursor );
2571 					SvLBoxEntry* pCur = pTree->Next( pCursor );
2572 					while( pCur && pTree->GetDepth(pCur) > nRefDepth )
2573 					{
2574 						if( pCur->HasChilds() && !pView->IsExpanded(pCur))
2575 							pView->Expand( pCur );
2576 						pCur = pTree->Next( pCur );
2577 					}
2578 				}
2579 			}
2580 			else
2581 				bKeyUsed = sal_False;
2582 			break;
2583 
2584 		case KEY_A:
2585 			if( bMod1 )
2586 				SelAllDestrAnch( sal_True );
2587 			else
2588 				bKeyUsed = sal_False;
2589 			break;
2590 
2591 		case KEY_SUBTRACT:
2592 			if( pCursor )
2593 			{
2594 				if( pView->IsExpanded(pCursor))
2595 					pView->Collapse( pCursor );
2596 				if( bMod1 )
2597 				{
2598 					// bis zur Root alle Parents einklappen
2599 					SvLBoxEntry* pParentToCollapse = (SvLBoxEntry*)pTree->GetRootLevelParent(pCursor);
2600 					if( pParentToCollapse )
2601 					{
2602 						sal_uInt16 nRefDepth;
2603 						// Sonderbehandlung Explorer: Befindet sich auf der
2604 						// Root nur ein Eintrag,dann den Root-Entry nicht
2605 						// einklappen
2606 						if( pTree->GetChildList(0)->Count() < 2 )
2607 						{
2608 							nRefDepth = 1;
2609 							pParentToCollapse = pCursor;
2610 							while( pTree->GetParent(pParentToCollapse) &&
2611 								   pTree->GetDepth( pTree->GetParent(pParentToCollapse)) > 0)
2612 							{
2613 								pParentToCollapse = pTree->GetParent(pParentToCollapse);
2614 							}
2615 						}
2616 						else
2617 							nRefDepth = 0;
2618 
2619 						if( pView->IsExpanded(pParentToCollapse) )
2620 							pView->Collapse( pParentToCollapse );
2621 						SvLBoxEntry* pCur = pTree->Next( pParentToCollapse );
2622 						while( pCur && pTree->GetDepth(pCur) > nRefDepth )
2623 						{
2624 							if( pCur->HasChilds() && pView->IsExpanded(pCur) )
2625 								pView->Collapse( pCur );
2626 							pCur = pTree->Next( pCur );
2627 						}
2628 					}
2629 				}
2630 			}
2631 			else
2632 				bKeyUsed = sal_False;
2633 			break;
2634 
2635 		case KEY_DIVIDE :
2636 			if( bMod1 )
2637 				SelAllDestrAnch( sal_True );
2638 			else
2639 				bKeyUsed = sal_False;
2640 			break;
2641 
2642 		case KEY_COMMA :
2643 			if( bMod1 )
2644 				SelAllDestrAnch( sal_False );
2645 			else
2646 				bKeyUsed = sal_False;
2647 			break;
2648 
2649 		case KEY_HOME :
2650 			pNewCursor = pView->GetModel()->First();
2651 
2652 			while( pNewCursor && !IsSelectable(pNewCursor) )
2653 			{
2654 				pNewCursor = (SvLBoxEntry*)(pView->NextVisible( pNewCursor ));
2655 			}
2656 
2657 			if( pNewCursor && pNewCursor != pCursor )
2658 			{
2659 //				SelAllDestrAnch( sal_False );
2660 				aSelEng.CursorPosChanging( bShift, bMod1 );
2661 				SetCursor( pNewCursor );
2662 				if( !IsEntryInView( pNewCursor ) )
2663 					MakeVisible( pNewCursor );
2664 			}
2665 			else
2666 				bKeyUsed = sal_False;
2667 			break;
2668 
2669 		case KEY_END :
2670 			pNewCursor = pView->GetModel()->Last();
2671 
2672 			while( pNewCursor && !IsSelectable(pNewCursor) )
2673 			{
2674 				pNewCursor = (SvLBoxEntry*)(pView->PrevVisible( pNewCursor ));
2675 			}
2676 
2677 			if( pNewCursor && pNewCursor != pCursor)
2678 			{
2679 //				SelAllDestrAnch( sal_False );
2680 				aSelEng.CursorPosChanging( bShift, bMod1 );
2681 				SetCursor( pNewCursor );
2682 				if( !IsEntryInView( pNewCursor ) )
2683 					MakeVisible( pNewCursor );
2684 			}
2685 			else
2686 				bKeyUsed = sal_False;
2687 			break;
2688 
2689 		case KEY_ESCAPE:
2690 		case KEY_TAB:
2691 		case KEY_DELETE:
2692 		case KEY_BACKSPACE:
2693 			// #105907# must not be handled because this quits dialogs and does other magic things...
2694 			// if there are other single keys which should not be handled, they can be added here
2695 			bKeyUsed = sal_False;
2696 			break;
2697 
2698 		default:
2699             // is there any reason why we should eat the events here? The only place where this is called
2700             // is from SvTreeListBox::KeyInput. If we set bKeyUsed to sal_True here, then the key input
2701             // is just silenced. However, we want SvLBox::KeyInput to get a chance, to do the QuickSelection
2702             // handling.
2703             // (The old code here which intentionally set bKeyUsed to sal_True said this was because of "quick search"
2704             // handling, but actually there was no quick search handling anymore. We just re-implemented it.)
2705             // #i31275# / 2009-06-16 / frank.schoenheit@sun.com
2706 			bKeyUsed = sal_False;
2707             break;
2708 	}
2709 	return bKeyUsed;
2710 }
2711 
2712 void __EXPORT SvImpLBox::GetFocus()
2713 {
2714 	if( pCursor )
2715 	{
2716 		pView->SetEntryFocus( pCursor, sal_True );
2717 		ShowCursor( sal_True );
2718 // auskommentiert wg. deselectall
2719 //		if( bSimpleTravel && !pView->IsSelected(pCursor) )
2720 //			pView->Select( pCursor, sal_True );
2721 	}
2722 	if( m_nStyle & WB_HIDESELECTION )
2723 	{
2724 		SvLBoxEntry* pEntry = pView->FirstSelected();
2725 		while( pEntry )
2726 		{
2727 			InvalidateEntry( pEntry );
2728 			pEntry = pView->NextSelected( pEntry );
2729 		}
2730 		/*
2731 		SvLBoxEntry* pEntry = pView->GetModel()->First();
2732 		while( pEntry )
2733 		{
2734 			SvViewData* pViewData = pView->GetViewData( pEntry );
2735 			if( pViewData->IsCursored() )
2736 			{
2737 				pViewData->SetCursored( sal_False );
2738 				InvalidateEntry( pEntry );
2739 			}
2740 			pEntry = pView->GetModel()->Next( pEntry );
2741 		}
2742 		*/
2743 
2744 
2745 	}
2746 }
2747 
2748 void __EXPORT SvImpLBox::LoseFocus()
2749 {
2750 	aEditTimer.Stop();
2751 	if( pCursor )
2752 		pView->SetEntryFocus( pCursor,sal_False );
2753 	ShowCursor( sal_False );
2754 
2755 	if( m_nStyle & WB_HIDESELECTION )
2756 	{
2757 		SvLBoxEntry* pEntry = pView->FirstSelected();
2758 		while( pEntry )
2759 		{
2760 			//SvViewData* pViewData = pView->GetViewData( pEntry );
2761 			//pViewData->SetCursored( sal_True );
2762 			InvalidateEntry( pEntry );
2763 			pEntry = pView->NextSelected( pEntry );
2764 		}
2765 	}
2766 }
2767 
2768 
2769 // ********************************************************************
2770 // SelectionEngine
2771 // ********************************************************************
2772 
2773 inline void SvImpLBox::SelectEntry( SvLBoxEntry* pEntry, sal_Bool bSelect )
2774 {
2775 	pView->Select( pEntry, bSelect );
2776 }
2777 
2778 __EXPORT ImpLBSelEng::ImpLBSelEng( SvImpLBox* pImpl, SelectionEngine* pSEng,
2779 	SvTreeListBox* pV )
2780 {
2781 	pImp = pImpl;
2782 	pSelEng = pSEng;
2783 	pView = pV;
2784 }
2785 
2786 __EXPORT ImpLBSelEng::~ImpLBSelEng()
2787 {
2788 }
2789 
2790 void __EXPORT ImpLBSelEng::BeginDrag()
2791 {
2792 	pImp->BeginDrag();
2793 }
2794 
2795 /*
2796 void __EXPORT ImpLBSelEng::EndDrag( const Point& )
2797 {
2798 }
2799 */
2800 
2801 void __EXPORT ImpLBSelEng::CreateAnchor()
2802 {
2803 	pImp->pAnchor = pImp->pCursor;
2804 }
2805 
2806 void __EXPORT ImpLBSelEng::DestroyAnchor()
2807 {
2808 	pImp->pAnchor = 0;
2809 }
2810 
2811 /*
2812 void __EXPORT ImpLBSelEng::CreateCursor()
2813 {
2814 	pImp->pAnchor = 0;
2815 }
2816 */
2817 
2818 
2819 sal_Bool __EXPORT ImpLBSelEng::SetCursorAtPoint(const Point& rPoint, sal_Bool bDontSelectAtCursor)
2820 {
2821 	SvLBoxEntry* pNewCursor = pImp->MakePointVisible( rPoint );
2822 	if( pNewCursor != pImp->pCursor  )
2823 		pImp->BeginScroll();
2824 
2825 	if( pNewCursor )
2826 	{
2827 		// bei SimpleTravel wird in SetCursor selektiert und
2828 		// der Select-Handler gerufen
2829 		//if( !bDontSelectAtCursor && !pImp->bSimpleTravel )
2830 		//	pImp->SelectEntry( pNewCursor, sal_True );
2831 		pImp->SetCursor( pNewCursor, bDontSelectAtCursor );
2832 		return sal_True;
2833 	}
2834 	return sal_False;
2835 }
2836 
2837 sal_Bool __EXPORT ImpLBSelEng::IsSelectionAtPoint( const Point& rPoint )
2838 {
2839 	SvLBoxEntry* pEntry = pImp->MakePointVisible( rPoint );
2840 	if( pEntry )
2841 		return pView->IsSelected(pEntry);
2842 	return sal_False;
2843 }
2844 
2845 void __EXPORT ImpLBSelEng::DeselectAtPoint( const Point& rPoint )
2846 {
2847 	SvLBoxEntry* pEntry = pImp->MakePointVisible( rPoint );
2848 	if( !pEntry )
2849 		return;
2850 	pImp->SelectEntry( pEntry, sal_False );
2851 }
2852 
2853 /*
2854 void __EXPORT ImpLBSelEng::SelectAtPoint( const Point& rPoint )
2855 {
2856 	SvLBoxEntry* pEntry = pImp->MakePointVisible( rPoint );
2857 	if( !pEntry )
2858 		return;
2859 	pImp->SelectEntry( pEntry, sal_True );
2860 }
2861 */
2862 
2863 void __EXPORT ImpLBSelEng::DeselectAll()
2864 {
2865 	pImp->SelAllDestrAnch( sal_False, sal_False ); // SelectionEngine nicht resetten!
2866 	pImp->nFlags &= (~F_DESEL_ALL);
2867 }
2868 
2869 // ***********************************************************************
2870 // Selektion
2871 // ***********************************************************************
2872 
2873 void SvImpLBox::SetAnchorSelection(SvLBoxEntry* pOldCursor,SvLBoxEntry* pNewCursor)
2874 {
2875 	SvLBoxEntry* pEntry;
2876 	sal_uLong nAnchorVisPos = pView->GetVisiblePos( pAnchor );
2877 	sal_uLong nOldVisPos = pView->GetVisiblePos( pOldCursor );
2878 	sal_uLong nNewVisPos = pView->GetVisiblePos( pNewCursor );
2879 
2880 	if( nOldVisPos > nAnchorVisPos ||
2881 		( nAnchorVisPos==nOldVisPos && nNewVisPos > nAnchorVisPos) )
2882 	{
2883 		if( nNewVisPos > nOldVisPos )
2884 		{
2885 			pEntry = pOldCursor;
2886 			while( pEntry && pEntry != pNewCursor )
2887 			{
2888 				pView->Select( pEntry, sal_True );
2889 				pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
2890 			}
2891 			if( pEntry )
2892 				pView->Select( pEntry, sal_True );
2893 			return;
2894 		}
2895 
2896 		if( nNewVisPos < nAnchorVisPos )
2897 		{
2898 			pEntry = pAnchor;
2899 			while( pEntry && pEntry != pOldCursor )
2900 			{
2901 				pView->Select( pEntry, sal_False );
2902 				pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
2903 			}
2904 			if( pEntry )
2905 				pView->Select( pEntry, sal_False );
2906 
2907 			pEntry = pNewCursor;
2908 			while( pEntry && pEntry != pAnchor )
2909 			{
2910 				pView->Select( pEntry, sal_True );
2911 				pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
2912 			}
2913 			if( pEntry )
2914 				pView->Select( pEntry, sal_True );
2915 			return;
2916 		}
2917 
2918 		if( nNewVisPos < nOldVisPos )
2919 		{
2920 			pEntry = pNewCursor;
2921 			pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
2922 			while( pEntry && pEntry != pOldCursor )
2923 			{
2924 				pView->Select( pEntry, sal_False );
2925 				pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
2926 			}
2927 			if( pEntry )
2928 				pView->Select( pEntry, sal_False );
2929 			return;
2930 		}
2931 	}
2932 	else
2933 	{
2934 		if( nNewVisPos < nOldVisPos )  // Vergroessern der Selektion
2935 		{
2936 			pEntry = pNewCursor;
2937 			while( pEntry && pEntry != pOldCursor )
2938 			{
2939 				pView->Select( pEntry, sal_True );
2940 				pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
2941 			}
2942 			if( pEntry )
2943 				pView->Select( pEntry, sal_True );
2944 			return;
2945 		}
2946 
2947 		if( nNewVisPos > nAnchorVisPos )
2948 		{
2949 			pEntry = pOldCursor;
2950 			while( pEntry && pEntry != pAnchor )
2951 			{
2952 				pView->Select( pEntry, sal_False );
2953 				pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
2954 			}
2955 			if( pEntry )
2956 				pView->Select( pEntry, sal_False );
2957 			pEntry = pAnchor;
2958 			while( pEntry && pEntry != pNewCursor )
2959 			{
2960 				pView->Select( pEntry, sal_True );
2961 				pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
2962 			}
2963 			if( pEntry )
2964 				pView->Select( pEntry, sal_True );
2965 			return;
2966 		}
2967 
2968 		if( nNewVisPos > nOldVisPos )
2969 		{
2970 			pEntry = pOldCursor;
2971 			while( pEntry && pEntry != pNewCursor )
2972 			{
2973 				pView->Select( pEntry, sal_False );
2974 				pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry ));
2975 			}
2976 			return;
2977 		}
2978 	}
2979 }
2980 
2981 void SvImpLBox::SelAllDestrAnch( sal_Bool bSelect, sal_Bool bDestroyAnchor,
2982 	sal_Bool bSingleSelToo )
2983 {
2984 	SvLBoxEntry* pEntry;
2985 	nFlags &= (~F_DESEL_ALL);
2986 	if( bSelect && bSimpleTravel )
2987 	{
2988 		if( pCursor && !pView->IsSelected( pCursor ))
2989 		{
2990 			pView->Select( pCursor, sal_True );
2991 		}
2992 		return;
2993 	}
2994 	if( !bSelect && pView->GetSelectionCount() == 0 )
2995 	{
2996 		if( bSimpleTravel && ( !GetUpdateMode() || !pCursor) )
2997 			nFlags |= F_DESEL_ALL;
2998 		return;
2999 	}
3000 	if( bSelect && pView->GetSelectionCount() == pView->GetEntryCount())
3001 		return;
3002 	if( !bSingleSelToo && bSimpleTravel )
3003 		return;
3004 
3005 	if( !bSelect && pView->GetSelectionCount()==1 && pCursor &&
3006 		pView->IsSelected( pCursor ))
3007 	{
3008 		pView->Select( pCursor, sal_False );
3009 		if( bDestroyAnchor )
3010 			DestroyAnchor(); // Anker loeschen & SelectionEngine zuruecksetzen
3011 		else
3012 			pAnchor = 0; // internen Anker immer loeschen
3013 		return;
3014 	}
3015 
3016 	if( bSimpleTravel && !pCursor && !GetUpdateMode() )
3017 		nFlags |= F_DESEL_ALL;
3018 
3019 	ShowCursor( sal_False );
3020 	sal_Bool bUpdate = GetUpdateMode();
3021 
3022 	nFlags |= F_IGNORE_SELECT; // EntryInserted soll nix tun
3023 	pEntry = pTree->First();
3024 	while( pEntry )
3025 	{
3026 		if( pView->Select( pEntry, bSelect ) )
3027 		{
3028 			if( bUpdate && pView->IsEntryVisible(pEntry) )
3029 			{
3030 				long nY = GetEntryLine( pEntry );
3031 				if( IsLineVisible( nY ) )
3032 					pView->PaintEntry1( pEntry, nY, 0xffff ); // wg. ItemsetBrowser SV_LBOXTAB_SHOW_SELECTION );
3033 			}
3034 		}
3035 		pEntry = pTree->Next( pEntry );
3036 	}
3037 	nFlags &= ~F_IGNORE_SELECT;
3038 
3039 	if( bDestroyAnchor )
3040 		DestroyAnchor(); // Anker loeschen & SelectionEngine zuruecksetzen
3041 	else
3042 		pAnchor = 0; // internen Anker immer loeschen
3043 	ShowCursor( sal_True );
3044 }
3045 
3046 void SvImpLBox::SetSelectionMode( SelectionMode eSelMode  )
3047 {
3048 	aSelEng.SetSelectionMode( eSelMode);
3049 	if( eSelMode == SINGLE_SELECTION )
3050 		bSimpleTravel = sal_True;
3051 	else
3052 		bSimpleTravel = sal_False;
3053 	if( (m_nStyle & WB_SIMPLEMODE) && (eSelMode == MULTIPLE_SELECTION) )
3054 		aSelEng.AddAlways( sal_True );
3055 }
3056 
3057 // ***********************************************************************
3058 // Drag & Drop
3059 // ***********************************************************************
3060 
3061 void SvImpLBox::SetDragDropMode( DragDropMode eDDMode )
3062 {
3063 	if( eDDMode && eDDMode != SV_DRAGDROP_APP_DROP )
3064 	{
3065 		aSelEng.ExpandSelectionOnMouseMove( sal_False );
3066 		aSelEng.EnableDrag( sal_True );
3067 	}
3068 	else
3069 	{
3070 		aSelEng.ExpandSelectionOnMouseMove( sal_True );
3071 		aSelEng.EnableDrag( sal_False );
3072 	}
3073 }
3074 
3075 void SvImpLBox::BeginDrag()
3076 {
3077 	nFlags &= (~F_FILLING);
3078 	if( !bAsyncBeginDrag )
3079 	{
3080 		BeginScroll();
3081 		pView->StartDrag( 0, aSelEng.GetMousePosPixel() );
3082 		EndScroll();
3083 	}
3084 	else
3085 	{
3086 		aAsyncBeginDragPos = aSelEng.GetMousePosPixel();
3087 		aAsyncBeginDragTimer.Start();
3088 	}
3089 }
3090 
3091 IMPL_LINK( SvImpLBox, BeginDragHdl, void*, EMPTYARG )
3092 {
3093 	pView->StartDrag( 0, aAsyncBeginDragPos );
3094 	return 0;
3095 }
3096 
3097 void SvImpLBox::PaintDDCursor( SvLBoxEntry* pInsertionPos )
3098 {
3099 	long nY;
3100 	if( pInsertionPos )
3101 	{
3102 		nY = GetEntryLine( pInsertionPos );
3103 		nY += pView->GetEntryHeight();
3104 	}
3105 	else
3106 		nY = 1;
3107 	RasterOp eOldOp = pView->GetRasterOp();
3108 	pView->SetRasterOp( ROP_INVERT );
3109 	Color aOldLineColor = pView->GetLineColor();
3110 	pView->SetLineColor( Color( COL_BLACK ) );
3111 	pView->DrawLine( Point( 0, nY ), Point( aOutputSize.Width(), nY ) );
3112 	pView->SetLineColor( aOldLineColor );
3113 	pView->SetRasterOp( eOldOp );
3114 }
3115 /* -----------------26.08.2003 12:52-----------------
3116     Delete all sub menues of a PopupMenu, recursively
3117  --------------------------------------------------*/
3118 void lcl_DeleteSubPopups(PopupMenu* pPopup)
3119 {
3120     for(sal_uInt16 i = 0; i < pPopup->GetItemCount(); i++)
3121     {
3122         PopupMenu* pSubPopup = pPopup->GetPopupMenu( pPopup->GetItemId( i ));
3123         if(pSubPopup)
3124 		{
3125             lcl_DeleteSubPopups(pSubPopup);
3126 			delete pSubPopup;
3127 		}
3128     }
3129 }
3130 
3131 void SvImpLBox::Command( const CommandEvent& rCEvt )
3132 {
3133 	sal_uInt16				nCommand = rCEvt.GetCommand();
3134 
3135     if( nCommand == COMMAND_CONTEXTMENU )
3136         aEditTimer.Stop();
3137 
3138 	// Rollmaus-Event?
3139 	if( ( ( nCommand == COMMAND_WHEEL ) || ( nCommand == COMMAND_STARTAUTOSCROLL ) || ( nCommand == COMMAND_AUTOSCROLL ) )
3140 		&& pView->HandleScrollCommand( rCEvt, &aHorSBar, &aVerSBar ) )
3141 			return;
3142 
3143 	if( bContextMenuHandling && nCommand == COMMAND_CONTEXTMENU )
3144 	{
3145 		Point	aPopupPos;
3146 		sal_Bool	bClickedIsFreePlace = sal_False;
3147 		std::stack<SvLBoxEntry*> aSelRestore;
3148 
3149 		if( rCEvt.IsMouseEvent() )
3150 		{	// change selection, if mouse pos doesn't fit to selection
3151 
3152 			aPopupPos = rCEvt.GetMousePosPixel();
3153 
3154 			SvLBoxEntry*	pClickedEntry = GetEntry( aPopupPos );
3155 			if( pClickedEntry )
3156 			{	// mouse in non empty area
3157 				sal_Bool				bClickedIsSelected = sal_False;
3158 
3159 				// collect the currently selected entries
3160 				SvLBoxEntry*		pSelected = pView->FirstSelected();
3161 				while( pSelected )
3162 				{
3163 					bClickedIsSelected |= ( pClickedEntry == pSelected );
3164 					pSelected = pView->NextSelected( pSelected );
3165 				}
3166 
3167 				// if the entry which the user clicked at is not selected
3168 				if( !bClickedIsSelected )
3169 				{	// deselect all other and select the clicked one
3170 					pView->SelectAll( sal_False );
3171 					pView->SetCursor( pClickedEntry );
3172 				}
3173 			}
3174 			else if( aSelEng.GetSelectionMode() == SINGLE_SELECTION )
3175 			{//modified by BerryJia for fixing Bug102739 2002-9-9 17:00(Beijing Time)
3176 				bClickedIsFreePlace = sal_True;
3177 				sal_Int32				nSelectedEntries = pView->GetSelectionCount();
3178 				SvLBoxEntry*		pSelected = pView->FirstSelected();
3179 				for(sal_uInt16 nSel = 0; nSel < nSelectedEntries; nSel++ )
3180 				{
3181 					aSelRestore.push(pSelected);
3182 					pSelected = pView->NextSelected( pSelected );
3183 				}
3184 				pView->SelectAll( sal_False );
3185 			}
3186 			else
3187 			{	// deselect all
3188 				pView->SelectAll( sal_False );
3189 			}
3190 
3191 
3192 		}
3193 		else
3194 		{	// key event (or at least no mouse event)
3195 			sal_Int32	nSelectionCount = pView->GetSelectionCount();
3196 
3197 			if( nSelectionCount )
3198 			{	// now allways take first visible as base for positioning the menu
3199 				SvLBoxEntry*	pSelected = pView->FirstSelected();
3200 				while( pSelected )
3201 				{
3202 					if( IsEntryInView( pSelected ) )
3203 						break;
3204 
3205 					pSelected = pView->NextSelected( pSelected );
3206 				}
3207 
3208 				if( !pSelected )
3209 				{
3210 					// no one was visible
3211 					pSelected = pView->FirstSelected();
3212 					pView->MakeVisible( pSelected );
3213 				}
3214 
3215 				aPopupPos = pView->GetFocusRect( pSelected, pView->GetEntryPosition( pSelected ).Y() ).Center();
3216 			}
3217 			else
3218 				aPopupPos = Point( 0, 0 );
3219 		}
3220 
3221 		PopupMenu*	pPopup = pView->CreateContextMenu();
3222 
3223 		if( pPopup )
3224 		{
3225 			// do action for selected entry in popup menu
3226             sal_uInt16 nMenuAction = pPopup->Execute( pView, aPopupPos );
3227             if ( nMenuAction )
3228 			    pView->ExcecuteContextMenuAction( nMenuAction );
3229             lcl_DeleteSubPopups(pPopup);
3230             delete pPopup;
3231 		}
3232 		//added by BerryJia for fixing Bug102739 2002-9-9 17:00(Beijing Time)
3233 		if( bClickedIsFreePlace )
3234 		{
3235 			while(!aSelRestore.empty())
3236 			{
3237 				SvLBoxEntry* pEntry = aSelRestore.top();
3238 				//#i19717# the entry is maybe already deleted
3239 				bool bFound = false;
3240 				for(sal_uLong nEntry = 0; nEntry < pView->GetEntryCount(); nEntry++)
3241 					if(pEntry == pView->GetEntry(nEntry))
3242 					{
3243 						bFound = true;
3244 						break;
3245 					}
3246 				if(bFound)
3247 					SetCurEntry( pEntry );
3248 				aSelRestore.pop();
3249 			}
3250 		}
3251 	}
3252 #ifndef NOCOMMAND
3253 	else
3254 	{
3255 		const Point& rPos = rCEvt.GetMousePosPixel();
3256 		if( rPos.X() < aOutputSize.Width() && rPos.Y() < aOutputSize.Height() )
3257 			aSelEng.Command( rCEvt );
3258 	}
3259 #endif
3260 }
3261 
3262 void SvImpLBox::BeginScroll()
3263 {
3264 	if( !(nFlags & F_IN_SCROLLING))
3265 	{
3266 		pView->NotifyBeginScroll();
3267 		nFlags |= F_IN_SCROLLING;
3268 	}
3269 }
3270 
3271 void SvImpLBox::EndScroll()
3272 {
3273 	if( nFlags & F_IN_SCROLLING)
3274 	{
3275 		pView->NotifyEndScroll();
3276 		nFlags &= (~F_IN_SCROLLING);
3277 	}
3278 }
3279 
3280 
3281 Rectangle SvImpLBox::GetVisibleArea() const
3282 {
3283 	Point aPos( pView->GetMapMode().GetOrigin() );
3284 	aPos.X() *= -1;
3285 	Rectangle aRect( aPos, aOutputSize );
3286 	return aRect;
3287 }
3288 
3289 void SvImpLBox::Invalidate()
3290 {
3291 	pView->SetClipRegion();
3292 }
3293 
3294 void SvImpLBox::SetCurEntry( SvLBoxEntry* pEntry )
3295 {
3296 	if  (  ( aSelEng.GetSelectionMode() != SINGLE_SELECTION )
3297         && ( aSelEng.GetSelectionMode() != NO_SELECTION )
3298         )
3299 		SelAllDestrAnch( sal_False, sal_True, sal_False );
3300     if ( pEntry )
3301 	    MakeVisible( pEntry );
3302 	SetCursor( pEntry );
3303     if ( pEntry && ( aSelEng.GetSelectionMode() != NO_SELECTION ) )
3304 		pView->Select( pEntry, sal_True );
3305 }
3306 
3307 IMPL_LINK( SvImpLBox, EditTimerCall, Timer *, EMPTYARG )
3308 {
3309 	if( pView->IsInplaceEditingEnabled() )
3310 	{
3311 		sal_Bool bIsMouseTriggered = aEditClickPos.X() >= 0;
3312 		if ( bIsMouseTriggered )
3313 		{
3314 			Point aCurrentMousePos = pView->GetPointerPosPixel();
3315 			if	(	( abs( aCurrentMousePos.X() - aEditClickPos.X() ) > 5 )
3316 				||	( abs( aCurrentMousePos.Y() - aEditClickPos.Y() ) > 5 )
3317 				)
3318 			{
3319 				return 0L;
3320 			}
3321 		}
3322 
3323 		SvLBoxEntry* pEntry = GetCurEntry();
3324 		if( pEntry )
3325 		{
3326 			ShowCursor( sal_False );
3327 			pView->ImplEditEntry( pEntry );
3328 			ShowCursor( sal_True );
3329 		}
3330 	}
3331 	return 0;
3332 }
3333 
3334 sal_Bool SvImpLBox::RequestHelp( const HelpEvent& rHEvt )
3335 {
3336 	if( rHEvt.GetMode() & HELPMODE_QUICK )
3337 	{
3338 		Point aPos( pView->ScreenToOutputPixel( rHEvt.GetMousePosPixel() ));
3339 		if( !GetVisibleArea().IsInside( aPos ))
3340 			return sal_False;
3341 
3342 		SvLBoxEntry* pEntry = GetEntry( aPos );
3343 		if( pEntry )
3344 		{
3345 			// Rechteck des Textes berechnen
3346 			SvLBoxTab* pTab;
3347 			SvLBoxString* pItem = (SvLBoxString*)(pView->GetItem( pEntry, aPos.X(), &pTab ));
3348 			if( !pItem || pItem->IsA() != SV_ITEM_ID_LBOXSTRING )
3349 				return sal_False;
3350 
3351 			aPos = GetEntryPosition( pEntry );
3352 			aPos.X() = pView->GetTabPos( pEntry, pTab ); //pTab->GetPos();
3353 			Size aSize( pItem->GetSize( pView, pEntry ) );
3354 			SvLBoxTab* pNextTab = NextTab( pTab );
3355 			sal_Bool bItemClipped = sal_False;
3356 			// wurde das Item von seinem rechten Nachbarn abgeschnitten?
3357 			if( pNextTab && pView->GetTabPos(pEntry,pNextTab) < aPos.X()+aSize.Width() )
3358 			{
3359 				aSize.Width() = pNextTab->GetPos() - pTab->GetPos();
3360 				bItemClipped = sal_True;
3361 			}
3362 			Rectangle aItemRect( aPos, aSize );
3363 
3364 			Rectangle aViewRect( GetVisibleArea() );
3365 
3366 			if( bItemClipped || !aViewRect.IsInside( aItemRect ) )
3367 			{
3368 				// rechten Item-Rand am View-Rand clippen
3369 				//if( aItemRect.Right() > aViewRect.Right() )
3370 				//	aItemRect.Right() = aViewRect.Right();
3371 
3372 				Point aPt = pView->OutputToScreenPixel( aItemRect.TopLeft() );
3373 				aItemRect.Left()   = aPt.X();
3374 				aItemRect.Top()    = aPt.Y();
3375 				aPt = pView->OutputToScreenPixel( aItemRect.BottomRight() );
3376 				aItemRect.Right()  = aPt.X();
3377 				aItemRect.Bottom() = aPt.Y();
3378 
3379 				Help::ShowQuickHelp( pView, aItemRect,
3380 									 pItem->GetText(), QUICKHELP_LEFT | QUICKHELP_VCENTER );
3381 				return sal_True;
3382 			}
3383 		}
3384 	}
3385 	return sal_False;
3386 }
3387 
3388 SvLBoxTab* SvImpLBox::NextTab( SvLBoxTab* pTab )
3389 {
3390 	sal_uInt16 nTabCount = pView->TabCount();
3391 	if( nTabCount <= 1 )
3392 		return 0;
3393 	for( sal_uInt16 nTab=0; nTab < (nTabCount-1); nTab++)
3394 	{
3395 		if( pView->aTabs[nTab]==pTab )
3396 			return (SvLBoxTab*)(pView->aTabs[nTab+1]);
3397 	}
3398 	return 0;
3399 }
3400 
3401 void SvImpLBox::EndSelection()
3402 {
3403 	DestroyAnchor();
3404 	nFlags &=  ~F_START_EDITTIMER;
3405 }
3406 
3407 void SvImpLBox::RepaintScrollBars()
3408 {
3409 }
3410 
3411 void SvImpLBox::SetUpdateMode( sal_Bool bMode )
3412 {
3413 	if( bUpdateMode != bMode )
3414 	{
3415 		bUpdateMode = bMode;
3416 		if( bUpdateMode )
3417 			UpdateAll( sal_False );
3418 	}
3419 }
3420 
3421 void SvImpLBox::SetUpdateModeFast( sal_Bool bMode )
3422 {
3423 	if( bUpdateMode != bMode )
3424 	{
3425 		bUpdateMode = bMode;
3426 		if( bUpdateMode )
3427 			UpdateAll( sal_False, sal_False );
3428 	}
3429 }
3430 
3431 
3432 sal_Bool SvImpLBox::SetMostRight( SvLBoxEntry* pEntry )
3433 {
3434 	if( pView->nTreeFlags & TREEFLAG_RECALCTABS )
3435 	{
3436 		nFlags |= F_IGNORE_CHANGED_TABS;
3437 		pView->SetTabs();
3438 		nFlags &= ~F_IGNORE_CHANGED_TABS;
3439 	}
3440 
3441 	sal_uInt16 nLastTab = pView->aTabs.Count() - 1;
3442 	sal_uInt16 nLastItem = pEntry->ItemCount() - 1;
3443 	if( nLastTab != USHRT_MAX && nLastItem != USHRT_MAX )
3444 	{
3445 		if( nLastItem < nLastTab )
3446 			nLastTab = nLastItem;
3447 
3448 		SvLBoxTab* pTab = (SvLBoxTab*)pView->aTabs[ nLastTab ];
3449 		SvLBoxItem* pItem = pEntry->GetItem( nLastTab );
3450 
3451 		long nTabPos = pView->GetTabPos( pEntry, pTab );
3452 
3453 		long nMaxRight = GetOutputSize().Width();
3454 		Point aPos( pView->GetMapMode().GetOrigin() );
3455 		aPos.X() *= -1; // Umrechnung Dokumentkoord.
3456 		nMaxRight = nMaxRight + aPos.X() - 1;
3457 
3458 		long nNextTab = nTabPos < nMaxRight ? nMaxRight : nMaxRight + 50;
3459 		long nTabWidth = nNextTab - nTabPos + 1;
3460 		long nItemSize = pItem->GetSize(pView,pEntry).Width();
3461 		long nOffset = pTab->CalcOffset( nItemSize, nTabWidth );
3462 
3463 		long nRight = nTabPos + nOffset + nItemSize;
3464 		if( nRight > nMostRight )
3465 		{
3466 			nMostRight = nRight;
3467 			pMostRightEntry = pEntry;
3468 			return sal_True;
3469 		}
3470 	}
3471 	return sal_False;
3472 }
3473 
3474 void SvImpLBox::FindMostRight( SvLBoxEntry* pEntryToIgnore )
3475 {
3476 	nMostRight = -1;
3477 	pMostRightEntry = 0;
3478 	if( !pView->GetModel() )
3479 		return;
3480 
3481 	SvLBoxEntry* pEntry = (SvLBoxEntry*)pView->FirstVisible();
3482 	while( pEntry )
3483 	{
3484 		if( pEntry != pEntryToIgnore )
3485 			SetMostRight( pEntry );
3486 		pEntry = (SvLBoxEntry*)pView->NextVisible( pEntry );
3487 	}
3488 }
3489 
3490 void SvImpLBox::FindMostRight( SvLBoxEntry* pParent, SvLBoxEntry* pEntryToIgnore )
3491 {
3492 	if( !pParent )
3493 		FindMostRight( pEntryToIgnore );
3494 	else
3495 		FindMostRight_Impl( pParent, pEntryToIgnore  );
3496 }
3497 
3498 void SvImpLBox::FindMostRight_Impl( SvLBoxEntry* pParent, SvLBoxEntry* pEntryToIgnore )
3499 {
3500 	SvTreeEntryList* pList = pTree->GetChildList( pParent );
3501 
3502 	if( !pList )
3503 		return;
3504 
3505 	sal_uLong nCount = pList->Count();
3506 	for( sal_uLong nCur = 0; nCur < nCount; nCur++ )
3507 	{
3508 		SvLBoxEntry* pChild = (SvLBoxEntry*)pList->GetObject( nCur );
3509 		if( pChild != pEntryToIgnore )
3510 		{
3511 			SetMostRight( pChild );
3512 			if( pChild->HasChilds() && pView->IsExpanded( pChild ))
3513 				FindMostRight_Impl( pChild, pEntryToIgnore );
3514 		}
3515 	}
3516 }
3517 
3518 void SvImpLBox::NotifyTabsChanged()
3519 {
3520 	if( GetUpdateMode() && !(nFlags & F_IGNORE_CHANGED_TABS ) &&
3521 		nCurUserEvent == 0xffffffff )
3522 	{
3523 		nCurUserEvent = Application::PostUserEvent(LINK(this,SvImpLBox,MyUserEvent),(void*)0);
3524 	}
3525 }
3526 
3527 IMPL_LINK(SvImpLBox,MyUserEvent,void*, pArg )
3528 {
3529 	nCurUserEvent = 0xffffffff;
3530 	if( !pArg )
3531 	{
3532 		pView->Invalidate();
3533 		pView->Update();
3534 	}
3535 	else
3536 	{
3537 		FindMostRight( 0 );
3538 		ShowVerSBar();
3539 		pView->Invalidate( GetVisibleArea() );
3540 	}
3541 	return 0;
3542 }
3543 
3544 
3545 void SvImpLBox::StopUserEvent()
3546 {
3547 	if( nCurUserEvent != 0xffffffff )
3548 	{
3549 		Application::RemoveUserEvent( nCurUserEvent );
3550 		nCurUserEvent = 0xffffffff;
3551 	}
3552 }
3553 
3554 void SvImpLBox::ShowFocusRect( const SvLBoxEntry* pEntry )
3555 {
3556 	if( pEntry )
3557 	{
3558 		long nY = GetEntryLine( (SvLBoxEntry*)pEntry );
3559 		Rectangle aRect = pView->GetFocusRect( (SvLBoxEntry*)pEntry, nY );
3560 		Region aOldClip( pView->GetClipRegion());
3561 		Region aClipRegion( GetClipRegionRect() );
3562 		pView->SetClipRegion( aClipRegion );
3563 		pView->ShowFocus( aRect );
3564 		pView->SetClipRegion( aOldClip );
3565 
3566 	}
3567 	else
3568 	{
3569 		pView->HideFocus();
3570 	}
3571 }
3572 
3573 void SvImpLBox::SetTabBar( TabBar* _pTabBar )
3574 {
3575 	pTabBar = _pTabBar;
3576 }
3577 
3578 void SvImpLBox::CancelPendingEdit()
3579 {
3580 	if( aEditTimer.IsActive() )
3581 		aEditTimer.Stop();
3582 	nFlags &= ~F_START_EDITTIMER;
3583 }
3584 
3585 // -----------------------------------------------------------------------
3586 void SvImpLBox::implInitDefaultNodeImages()
3587 {
3588 	if ( s_pDefCollapsed )
3589 		// assume that all or nothing is initialized
3590 		return;
3591 
3592 	s_pDefCollapsed = new Image( SvtResId( RID_IMG_TREENODE_COLLAPSED ) );
3593 	s_pDefCollapsedHC = new Image( SvtResId( RID_IMG_TREENODE_COLLAPSED_HC ) );
3594 	s_pDefExpanded = new Image( SvtResId( RID_IMG_TREENODE_EXPANDED ) );
3595 	s_pDefExpandedHC = new Image( SvtResId( RID_IMG_TREENODE_EXPANDED_HC ) );
3596 }
3597 
3598 // -----------------------------------------------------------------------
3599 const Image& SvImpLBox::GetDefaultExpandedNodeImage( BmpColorMode _eMode )
3600 {
3601 	implInitDefaultNodeImages();
3602 	return ( BMP_COLOR_NORMAL == _eMode ) ? *s_pDefExpanded : *s_pDefExpandedHC;
3603 }
3604 
3605 // -----------------------------------------------------------------------
3606 const Image& SvImpLBox::GetDefaultCollapsedNodeImage( BmpColorMode _eMode )
3607 {
3608 	implInitDefaultNodeImages();
3609 	return ( BMP_COLOR_NORMAL == _eMode ) ? *s_pDefCollapsed : *s_pDefCollapsedHC;
3610 }
3611 
3612 // -----------------------------------------------------------------------
3613 void SvImpLBox::CallEventListeners( sal_uLong nEvent, void* pData )
3614 {
3615 	if ( pView )
3616 		pView->CallImplEventListeners( nEvent, pData);
3617 }
3618 
3619 // -----------------------------------------------------------------------
3620 
3621 bool SvImpLBox::SetCurrentTabPos( sal_uInt16 _nNewPos )
3622 {
3623 	bool bRet = false;
3624 
3625 	if ( pView && _nNewPos < ( pView->TabCount() - 2 ) )
3626 	{
3627 		nCurTabPos = _nNewPos;
3628 		ShowCursor( sal_True );
3629 		bRet = true;
3630 	}
3631 
3632 	return bRet;
3633 }
3634 
3635 // -----------------------------------------------------------------------
3636 
3637 bool SvImpLBox::IsSelectable( const SvLBoxEntry* pEntry )
3638 {
3639 	if( pEntry )
3640 	{
3641 		SvViewDataEntry* pViewDataNewCur = pView->GetViewDataEntry(const_cast<SvLBoxEntry*>(pEntry));
3642 		return (pViewDataNewCur == 0) || pViewDataNewCur->IsSelectable();
3643 	}
3644 	else
3645 	{
3646 		return false;
3647 	}
3648 }
3649 
3650