LibreOffice Module vcl (master)  1
svimpbox.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <vcl/svapp.hxx>
21 #include <vcl/salnativewidgets.hxx>
22 #include <vcl/help.hxx>
23 #include <vcl/settings.hxx>
24 #include <vcl/commandevent.hxx>
25 
26 #include <cstdlib>
27 #include <memory>
28 #include <stack>
29 
30 #include <vcl/treelistbox.hxx>
31 #include <vcl/svlbitm.hxx>
32 #include <tools/wintypes.hxx>
33 #include <bitmaps.hlst>
34 #include <svimpbox.hxx>
36 #include <comphelper/string.hxx>
38 #include <tools/debug.hxx>
39 
40 #include <vcl/treelistentry.hxx>
41 #include <vcl/viewdataentry.hxx>
42 
43 // #i27063# (pl), #i32300# (pb) never access VCL after DeInitVCL - also no destructors
46 oslInterlockedCount SvImpLBox::s_nImageRefCount = 0;
47 
48 SvImpLBox::SvImpLBox( SvTreeListBox* pLBView, SvTreeList* pLBTree, WinBits nWinStyle)
49  : m_aHorSBar(VclPtr<ScrollBar>::Create(pLBView, WB_DRAG | WB_HSCROLL))
50  , m_aScrBarBox(VclPtr<ScrollBarBox>::Create(pLBView))
51  , m_aFctSet(this, pLBView)
52  , m_bAreChildrenTransient(true)
53  , mbForceMakeVisible (false)
54  , m_aVerSBar(VclPtr<ScrollBar>::Create(pLBView, WB_DRAG | WB_VSCROLL))
55  , m_aOutputSize(0, 0)
56  , mbNoAutoCurEntry(false)
57  , m_aSelEng(pLBView, nullptr)
58  , m_nNextVerVisSize(0)
59 {
60  osl_atomic_increment(&s_nImageRefCount);
61  m_pView = pLBView;
62  m_pTree = pLBTree;
63  m_aSelEng.SetFunctionSet( static_cast<FunctionSet*>(&m_aFctSet) );
65  SetStyle( nWinStyle );
68 
69  m_aVerSBar->SetScrollHdl( LINK( this, SvImpLBox, ScrollUpDownHdl ) );
70  m_aHorSBar->SetScrollHdl( LINK( this, SvImpLBox, ScrollLeftRightHdl ) );
71  m_aHorSBar->SetEndScrollHdl( LINK( this, SvImpLBox, EndScrollHdl ) );
72  m_aVerSBar->SetEndScrollHdl( LINK( this, SvImpLBox, EndScrollHdl ) );
73  m_aVerSBar->SetRange( Range(0,0) );
74  m_aVerSBar->Hide();
75  m_aHorSBar->SetRange( Range(0,0) );
76  m_aHorSBar->SetPageSize( 24 ); // pixels
77  m_aHorSBar->SetLineSize( 8 ); // pixels
78 
79  m_nHorSBarHeight = static_cast<short>(m_aHorSBar->GetSizePixel().Height());
80  m_nVerSBarWidth = static_cast<short>(m_aVerSBar->GetSizePixel().Width());
81 
82  m_pStartEntry = nullptr;
83  m_pCursor = nullptr;
84  m_pAnchor = nullptr;
85  m_nVisibleCount = 0; // number of rows of data in control
87  m_nNodeBmpWidth = 0;
88 
89  m_bAsyncBeginDrag = false;
92  // button animation in listbox
93  m_pActiveButton = nullptr;
94  m_pActiveEntry = nullptr;
95  m_pActiveTab = nullptr;
96 
99 
101  m_aEditIdle.SetInvokeHandler( LINK(this,SvImpLBox,EditTimerCall) );
102 
103  m_nMostRight = -1;
104  m_pMostRightEntry = nullptr;
105  m_nCurUserEvent = nullptr;
106 
107  m_bUpdateMode = true;
108  m_bInVScrollHdl = false;
110 
112  m_bSubLstOpDblClick = true;
113 }
114 
116 {
117  m_aEditIdle.Stop();
118  StopUserEvent();
119 
120  if ( osl_atomic_decrement(&s_nImageRefCount) == 0 )
121  {
124  }
128 }
129 
131 {
132  const css::lang::Locale& rNewLocale = Application::GetSettings().GetLanguageTag().getLocale();
133 
134  if( m_pStringSorter )
135  {
136  // different Locale from the older one, drop it and force recreate
137  const css::lang::Locale &aLocale = m_pStringSorter->getLocale();
138  if( aLocale.Language != rNewLocale.Language ||
139  aLocale.Country != rNewLocale.Country ||
140  aLocale.Variant != rNewLocale.Variant )
141  m_pStringSorter.reset();
142  }
143 
144  if( !m_pStringSorter )
145  {
148  rNewLocale));
149  }
150 }
151 
152 short SvImpLBox::UpdateContextBmpWidthVector( SvTreeListEntry const * pEntry, short nWidth )
153 {
154  DBG_ASSERT( m_pView->pModel, "View and Model aren't valid!" );
155 
156  sal_uInt16 nDepth = m_pView->pModel->GetDepth( pEntry );
157  // initialize vector if necessary
158  std::vector< short >::size_type nSize = m_aContextBmpWidthVector.size();
159  while ( nDepth > nSize )
160  {
161  m_aContextBmpWidthVector.resize( nSize + 1 );
162  m_aContextBmpWidthVector.at( nSize ) = nWidth;
163  ++nSize;
164  }
165  if( m_aContextBmpWidthVector.size() == nDepth )
166  {
167  m_aContextBmpWidthVector.resize( nDepth + 1 );
168  m_aContextBmpWidthVector.at( nDepth ) = 0;
169  }
170  short nContextBmpWidth = m_aContextBmpWidthVector[ nDepth ];
171  if( nContextBmpWidth < nWidth )
172  {
173  m_aContextBmpWidthVector.at( nDepth ) = nWidth;
174  return nWidth;
175  }
176  else
177  return nContextBmpWidth;
178 }
179 
181 {
182  DBG_ASSERT( pEntry, "Moved Entry is invalid!" );
183 
184  SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem(SvLBoxItemType::ContextBmp) );
185  short nExpWidth = static_cast<short>(pBmpItem->GetBitmap1().GetSizePixel().Width());
186  short nColWidth = static_cast<short>(pBmpItem->GetBitmap2().GetSizePixel().Width());
187  short nMax = std::max(nExpWidth, nColWidth);
188  UpdateContextBmpWidthVector( pEntry, nMax );
189 
190  if( pEntry->HasChildren() ) // recursive call, whether expanded or not
191  {
192  SvTreeListEntry* pChild = m_pView->FirstChild( pEntry );
193  DBG_ASSERT( pChild, "The first child is invalid!" );
194  do
195  {
197  pChild = m_pView->Next( pChild );
198  } while ( pChild );
199  }
200 }
201 
203 {
204  sal_uInt16 nDepth = m_pView->pModel->GetDepth( pEntry );
205  if( m_aContextBmpWidthVector.empty() )
206  return;
207  short nWidth = m_aContextBmpWidthVector[ nDepth ];
208  if( nWidth != m_pView->nContextBmpWidthMax ) {
209  m_pView->nContextBmpWidthMax = nWidth;
211  m_pView->SetTabs();
213  }
214 }
215 
217 {
218  if ( !(pEntry && m_bIsCellFocusEnabled) )
219  return;
220 
222  {
224  rRect.SetLeft( m_pView->GetTab( m_pCursor, &rItem )->GetPos() );
225  }
226  if (m_pCursor->ItemCount() > static_cast<size_t>(m_nCurTabPos+1))
227  {
228  SvLBoxItem& rNextItem = m_pCursor->GetItem( m_nCurTabPos + 1 );
229  long nRight = m_pView->GetTab( m_pCursor, &rNextItem )->GetPos() - 1;
230  if ( nRight < rRect.Right() )
231  rRect.SetRight( nRight );
232  }
233 }
234 
235 void SvImpLBox::SetStyle( WinBits i_nWinStyle )
236 {
237  m_nStyle = i_nWinStyle;
239  m_aSelEng.AddAlways( true );
240 }
241 
243 {
244  mbNoAutoCurEntry = b;
245 }
246 
247 // don't touch the model any more
249 {
250  StopUserEvent();
251  m_pStartEntry = nullptr;
252  m_pAnchor = nullptr;
253 
254  m_pActiveButton = nullptr;
255  m_pActiveEntry = nullptr;
256  m_pActiveTab = nullptr;
257 
258  m_nMostRight = -1;
259  m_pMostRightEntry = nullptr;
260 
261  // don't touch the cursor any more
262  if( m_pCursor )
263  {
264  if( m_pView->HasFocus() )
265  m_pView->HideFocus();
266  m_pCursor = nullptr;
267  }
268  m_aVerSBar->Hide();
269  m_aVerSBar->SetThumbPos( 0 );
270  Range aRange( 0, 0 );
271  m_aVerSBar->SetRange( aRange );
272  m_aOutputSize = m_pView->Control::GetOutputSizePixel();
273  m_aHorSBar->Hide();
274  m_aHorSBar->SetThumbPos( 0 );
275  MapMode aMapMode( m_pView->GetMapMode());
276  aMapMode.SetOrigin( Point(0,0) );
277  m_pView->Control::SetMapMode( aMapMode );
278  m_aHorSBar->SetRange( aRange );
281  if( GetUpdateMode() )
284  if( !m_aHorSBar->IsVisible() && !m_aVerSBar->IsVisible() )
285  m_aScrBarBox->Hide();
286 
287  m_aContextBmpWidthVector.clear();
288 
290 }
291 
292 // *********************************************************************
293 // Paint, navigate, scroll
294 // *********************************************************************
295 
296 IMPL_LINK_NOARG(SvImpLBox, EndScrollHdl, ScrollBar*, void)
297 {
298  if( m_nFlags & LBoxFlags::EndScrollSetVisSize )
299  {
300  m_aVerSBar->SetVisibleSize( m_nNextVerVisSize );
301  m_nFlags &= ~LBoxFlags::EndScrollSetVisSize;
302  }
303  EndScroll();
304 }
305 
306 // handler for vertical scrollbar
307 
308 IMPL_LINK( SvImpLBox, ScrollUpDownHdl, ScrollBar *, pScrollBar, void )
309 {
310  DBG_ASSERT(!m_bInVScrollHdl,"Scroll handler out-paces itself!");
311  long nDelta = pScrollBar->GetDelta();
312  if( !nDelta )
313  return;
314 
315  m_nFlags &= ~LBoxFlags::Filling;
316 
317  m_bInVScrollHdl = true;
318 
319  if( m_pView->IsEditingActive() )
320  {
321  m_pView->EndEditing( true ); // Cancel
322  m_pView->Update();
323  }
324  BeginScroll();
325 
326  if( nDelta > 0 )
327  {
328  if( nDelta == 1 )
329  CursorDown();
330  else
331  PageDown( static_cast<sal_uInt16>(nDelta) );
332  }
333  else
334  {
335  nDelta *= -1;
336  if( nDelta == 1 )
337  CursorUp();
338  else
339  PageUp( static_cast<sal_uInt16>(nDelta) );
340  }
341  m_bInVScrollHdl = false;
342 }
343 
344 
346 {
347  if (!m_pStartEntry)
348  return;
349 
350  SvTreeListEntry* pNextFirstToDraw = m_pView->NextVisible(m_pStartEntry);
351  if( pNextFirstToDraw )
352  {
354  ShowCursor( false );
355  m_pView->Update();
356  m_pStartEntry = pNextFirstToDraw;
357  tools::Rectangle aArea( GetVisibleArea() );
359  m_pView->Update();
360  ShowCursor( true );
362  }
363 }
364 
366 {
367  if (!m_pStartEntry)
368  return;
369 
370  SvTreeListEntry* pPrevFirstToDraw = m_pView->PrevVisible(m_pStartEntry);
371  if( !pPrevFirstToDraw )
372  return;
373 
375  long nEntryHeight = m_pView->GetEntryHeight();
376  ShowCursor( false );
377  m_pView->Update();
378  m_pStartEntry = pPrevFirstToDraw;
379  tools::Rectangle aArea( GetVisibleArea() );
380  aArea.AdjustBottom( -nEntryHeight );
381  m_pView->Scroll( 0, nEntryHeight, aArea, ScrollFlags::NoChildren );
382  m_pView->Update();
383  ShowCursor( true );
385 }
386 
387 void SvImpLBox::PageDown( sal_uInt16 nDelta )
388 {
389  sal_uInt16 nRealDelta = nDelta;
390 
391  if( !nDelta )
392  return;
393 
394  if (!m_pStartEntry)
395  return;
396 
397  SvTreeListEntry* pNext = m_pView->NextVisible(m_pStartEntry, nRealDelta);
398  if( pNext == m_pStartEntry )
399  return;
400 
401  ShowCursor( false );
402 
404  m_pView->Update();
405  m_pStartEntry = pNext;
406 
407  if( nRealDelta >= m_nVisibleCount )
408  {
410  m_pView->Update();
411  }
412  else
413  {
414  tools::Rectangle aArea( GetVisibleArea() );
415  long nScroll = m_pView->GetEntryHeight() * static_cast<long>(nRealDelta);
416  nScroll = -nScroll;
417  m_pView->Update();
418  m_pView->Scroll( 0, nScroll, aArea, ScrollFlags::NoChildren );
419  m_pView->Update();
421  }
422 
423  ShowCursor( true );
424 }
425 
426 void SvImpLBox::PageUp( sal_uInt16 nDelta )
427 {
428  sal_uInt16 nRealDelta = nDelta;
429  if( !nDelta )
430  return;
431 
432  if (!m_pStartEntry)
433  return;
434 
435  SvTreeListEntry* pPrev = m_pView->PrevVisible(m_pStartEntry, nRealDelta);
436  if( pPrev == m_pStartEntry )
437  return;
438 
440  ShowCursor( false );
441 
442  m_pView->Update();
443  m_pStartEntry = pPrev;
444  if( nRealDelta >= m_nVisibleCount )
445  {
447  m_pView->Update();
448  }
449  else
450  {
451  long nEntryHeight = m_pView->GetEntryHeight();
452  tools::Rectangle aArea( GetVisibleArea() );
453  m_pView->Update();
454  m_pView->Scroll( 0, nEntryHeight*nRealDelta, aArea, ScrollFlags::NoChildren );
455  m_pView->Update();
457  }
458 
459  ShowCursor( true );
460 }
461 
462 void SvImpLBox::KeyUp( bool bPageUp )
463 {
464  if( !m_aVerSBar->IsVisible() )
465  return;
466 
467  long nDelta;
468  if( bPageUp )
469  nDelta = m_aVerSBar->GetPageSize();
470  else
471  nDelta = 1;
472 
473  long nThumbPos = m_aVerSBar->GetThumbPos();
474 
475  if( nThumbPos < nDelta )
476  nDelta = nThumbPos;
477 
478  if( nDelta <= 0 )
479  return;
480 
482  BeginScroll();
483 
484  m_aVerSBar->SetThumbPos( nThumbPos - nDelta );
485  if( bPageUp )
486  PageUp( static_cast<short>(nDelta) );
487  else
488  CursorUp();
489 
490  EndScroll();
491 }
492 
493 
494 void SvImpLBox::KeyDown( bool bPageDown )
495 {
496  if( !m_aVerSBar->IsVisible() )
497  return;
498 
499  long nDelta;
500  if( bPageDown )
501  nDelta = m_aVerSBar->GetPageSize();
502  else
503  nDelta = 1;
504 
505  long nThumbPos = m_aVerSBar->GetThumbPos();
506  long nVisibleSize = m_aVerSBar->GetVisibleSize();
507  long nRange = m_aVerSBar->GetRange().Len();
508 
509  long nTmp = nThumbPos+nVisibleSize;
510  while( (nDelta > 0) && (nTmp+nDelta) >= nRange )
511  nDelta--;
512 
513  if( nDelta <= 0 )
514  return;
515 
517  BeginScroll();
518 
519  m_aVerSBar->SetThumbPos( nThumbPos+nDelta );
520  if( bPageDown )
521  PageDown( static_cast<short>(nDelta) );
522  else
523  CursorDown();
524 
525  EndScroll();
526 }
527 
528 
529 void SvImpLBox::InvalidateEntriesFrom( long nY ) const
530 {
531  if( !(m_nFlags & LBoxFlags::InPaint ))
532  {
533  tools::Rectangle aRect( GetVisibleArea() );
534  aRect.SetTop( nY );
535  m_pView->Invalidate( aRect );
536  }
537 }
538 
539 void SvImpLBox::InvalidateEntry( long nY ) const
540 {
541  if( !(m_nFlags & LBoxFlags::InPaint ))
542  {
543  tools::Rectangle aRect( GetVisibleArea() );
544  long nMaxBottom = aRect.Bottom();
545  aRect.SetTop( nY );
546  aRect.SetBottom( nY ); aRect.AdjustBottom(m_pView->GetEntryHeight() );
547  if( aRect.Top() > nMaxBottom )
548  return;
549  if( aRect.Bottom() > nMaxBottom )
550  aRect.SetBottom( nMaxBottom );
552  // Perform full paint when flicker is to be avoided explicitly.
553  m_pView->Invalidate();
554  else
555  m_pView->Invalidate(aRect);
556  }
557 }
558 
560 {
561  if( GetUpdateMode() )
562  {
563  long nPrev = m_nMostRight;
564  SetMostRight( pEntry );
565  if( nPrev < m_nMostRight )
566  ShowVerSBar();
567  }
568  if( !(m_nFlags & LBoxFlags::InPaint ))
569  {
570  bool bHasFocusRect = false;
571  if( pEntry==m_pCursor && m_pView->HasFocus() )
572  {
573  bHasFocusRect = true;
574  ShowCursor( false );
575  }
576  InvalidateEntry( GetEntryLine( pEntry ) );
577  if( bHasFocusRect )
578  ShowCursor( true );
579  }
580 }
581 
582 
584 {
585  if( m_pView->HasFocus() && m_pCursor )
586  {
587  m_pView->HideFocus();
588  long nY = GetEntryLine( m_pCursor );
590  CalcCellFocusRect( m_pCursor, aRect );
591  vcl::Region aOldClip( m_pView->GetClipRegion());
592  vcl::Region aClipRegion( GetClipRegionRect() );
593  m_pView->SetClipRegion( aClipRegion );
594  m_pView->ShowFocus( aRect );
595  m_pView->SetClipRegion( aOldClip );
596  }
597 }
598 
599 
600 // Sets cursor. When using SingleSelection, the selection is adjusted.
601 
602 
603 void SvImpLBox::SetCursor( SvTreeListEntry* pEntry, bool bForceNoSelect )
604 {
605  SvViewDataEntry* pViewDataNewCur = nullptr;
606  if( pEntry )
607  pViewDataNewCur= m_pView->GetViewDataEntry(pEntry);
608  if( pEntry &&
609  pEntry == m_pCursor &&
610  pViewDataNewCur &&
611  pViewDataNewCur->HasFocus() &&
612  pViewDataNewCur->IsSelected())
613  {
614  return;
615  }
616 
617  // if this cursor is not selectable, find first visible that is and use it
618  while( pEntry && pViewDataNewCur && !pViewDataNewCur->IsSelectable() )
619  {
620  pEntry = m_pView->NextVisible(pEntry);
621  pViewDataNewCur = pEntry ? m_pView->GetViewDataEntry(pEntry) : nullptr;
622  }
623 
624  SvTreeListEntry* pOldCursor = m_pCursor;
625  if( m_pCursor && pEntry != m_pCursor )
626  {
627  m_pView->SetEntryFocus( m_pCursor, false );
628  if( m_bSimpleTravel )
629  m_pView->Select( m_pCursor, false );
630  m_pView->HideFocus();
631  }
632  m_pCursor = pEntry;
633  if( m_pCursor )
634  {
635  if (pViewDataNewCur)
636  pViewDataNewCur->SetFocus( true );
637  if(!bForceNoSelect && m_bSimpleTravel && !(m_nFlags & LBoxFlags::DeselectAll) && GetUpdateMode())
638  {
641  }
642  // multiple selection: select in cursor move if we're not in
643  // Add mode (Ctrl-F8)
644  else if( GetUpdateMode() &&
647  !bForceNoSelect )
648  {
651  }
652  else
653  {
654  ShowCursor( true );
655  if (bForceNoSelect && GetUpdateMode())
656  {
658  }
659  }
660 
661  if( m_pAnchor )
662  {
664  SetAnchorSelection( pOldCursor, m_pCursor );
665  }
666  }
668 
670 }
671 
672 void SvImpLBox::ShowCursor( bool bShow )
673 {
674  if( !bShow || !m_pCursor || !m_pView->HasFocus() )
675  {
676  vcl::Region aOldClip( m_pView->GetClipRegion());
677  vcl::Region aClipRegion( GetClipRegionRect() );
678  m_pView->SetClipRegion( aClipRegion );
679  m_pView->HideFocus();
680  m_pView->SetClipRegion( aOldClip );
681  }
682  else
683  {
684  long nY = GetEntryLine( m_pCursor );
686  CalcCellFocusRect( m_pCursor, aRect );
687  vcl::Region aOldClip( m_pView->GetClipRegion());
688  vcl::Region aClipRegion( GetClipRegionRect() );
689  m_pView->SetClipRegion( aClipRegion );
690  m_pView->ShowFocus( aRect );
691  m_pView->SetClipRegion( aOldClip );
692  }
693 }
694 
695 
696 void SvImpLBox::UpdateAll( bool bInvalidateCompleteView )
697 {
698  FindMostRight(nullptr);
700  SyncVerThumb();
701  FillView();
702  ShowVerSBar();
705  ShowCursor( true );
706  if( bInvalidateCompleteView )
707  m_pView->Invalidate();
708  else
710 }
711 
712 IMPL_LINK( SvImpLBox, ScrollLeftRightHdl, ScrollBar *, pScrollBar, void )
713 {
714  long nDelta = pScrollBar->GetDelta();
715  if( nDelta )
716  {
717  if( m_pView->IsEditingActive() )
718  {
719  m_pView->EndEditing( true ); // Cancel
720  m_pView->Update();
721  }
722  m_pView->nFocusWidth = -1;
723  KeyLeftRight( nDelta );
724  }
725 }
726 
727 void SvImpLBox::KeyLeftRight( long nDelta )
728 {
729  if( !(m_nFlags & LBoxFlags::InResize) )
730  m_pView->Update();
731  BeginScroll();
733  ShowCursor( false );
734 
735  // calculate new origin
736  long nPos = m_aHorSBar->GetThumbPos();
737  Point aOrigin( -nPos, 0 );
738 
739  MapMode aMapMode( m_pView->GetMapMode() );
740  aMapMode.SetOrigin( aOrigin );
741  m_pView->SetMapMode( aMapMode );
742 
743  if( !(m_nFlags & LBoxFlags::InResize) )
744  {
745  tools::Rectangle aRect( GetVisibleArea() );
746  m_pView->Scroll( -nDelta, 0, aRect, ScrollFlags::NoChildren );
747  }
748  else
749  m_pView->Invalidate();
750  RecalcFocusRect();
751  ShowCursor( true );
753 }
754 
755 
756 // returns the last entry if position is just past the last entry
758 {
759  DBG_ASSERT( m_pView->GetModel(), "SvImpLBox::GetClickedEntry: how can this ever happen? Please tell me (frank.schoenheit@sun.com) how to reproduce!" );
760  if ( !m_pView->GetModel() )
761  // this is quite impossible. Nevertheless, stack traces from the crash reporter
762  // suggest it isn't. Okay, make it safe, and wait for somebody to reproduce it
763  // reliably :-\ ...
764  // #122359# / 2005-05-23 / frank.schoenheit@sun.com
765  return nullptr;
767  return nullptr;
768 
769  sal_uInt16 nClickedEntry = static_cast<sal_uInt16>(rPoint.Y() / m_pView->GetEntryHeight() );
770  sal_uInt16 nTemp = nClickedEntry;
772  return pEntry;
773 }
774 
775 
776 // checks if the entry was hit "the right way"
777 // (Focusrect+ ContextBitmap at TreeListBox)
778 
779 bool SvImpLBox::EntryReallyHit(SvTreeListEntry* pEntry, const Point& rPosPixel, long nLine)
780 {
781  bool bRet;
782  // we are not too exact when it comes to "special" entries
783  // (with CheckButtons etc.)
784  if( pEntry->ItemCount() >= 3 )
785  return true;
786 
787  tools::Rectangle aRect( m_pView->GetFocusRect( pEntry, nLine ));
788  aRect.SetRight( GetOutputSize().Width() - m_pView->GetMapMode().GetOrigin().X() );
789 
791  aRect.AdjustLeft( -pBmp->GetWidth(m_pView,pEntry) );
792  aRect.AdjustLeft( -4 ); // a little tolerance
793 
794  Point aPos( rPosPixel );
795  aPos -= m_pView->GetMapMode().GetOrigin();
796  bRet = aRect.IsInside( aPos );
797  return bRet;
798 }
799 
800 
801 // returns 0 if position is just past the last entry
803 {
804  if( (m_pView->GetEntryCount() == 0) || !m_pStartEntry ||
805  (rPoint.Y() > m_aOutputSize.Height())
806  || !m_pView->GetEntryHeight())
807  return nullptr;
808 
809  sal_uInt16 nClickedEntry = static_cast<sal_uInt16>(rPoint.Y() / m_pView->GetEntryHeight() );
810  sal_uInt16 nTemp = nClickedEntry;
812  if( nTemp != nClickedEntry )
813  pEntry = nullptr;
814  return pEntry;
815 }
816 
817 
819 {
820  if( !m_pCursor )
821  return nullptr;
822  long nY = rPoint.Y();
823  SvTreeListEntry* pEntry = nullptr;
824  long nMax = m_aOutputSize.Height();
825  if( nY < 0 || nY >= nMax ) // aOutputSize.Height() )
826  {
827  if( nY < 0 )
828  pEntry = m_pView->PrevVisible(m_pCursor);
829  else
830  pEntry = m_pView->NextVisible(m_pCursor);
831 
832  if( pEntry && pEntry != m_pCursor )
833  m_pView->SetEntryFocus( m_pCursor, false );
834 
835  if( nY < 0 )
836  KeyUp( false );
837  else
838  KeyDown( false );
839  }
840  else
841  {
842  pEntry = GetClickedEntry( rPoint );
843  if( !pEntry )
844  {
845  sal_uInt16 nSteps = 0xFFFF;
846  // TODO: LastVisible is not yet implemented!
847  pEntry = m_pView->NextVisible(m_pStartEntry, nSteps);
848  }
849  if( pEntry )
850  {
851  if( pEntry != m_pCursor &&
853  )
854  m_pView->Select( m_pCursor, false );
855  }
856  }
857  return pEntry;
858 }
859 
861 {
862  Point aOrigin( m_pView->GetMapMode().GetOrigin() );
863  aOrigin.setX( aOrigin.X() * -1 ); // conversion document coordinates
864  tools::Rectangle aClipRect( aOrigin, m_aOutputSize );
865  aClipRect.AdjustBottom( 1 );
866  return aClipRect;
867 }
868 
869 
870 void SvImpLBox::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
871 {
872  if (!m_pView->GetVisibleCount())
873  return;
874 
876 
878  {
879  SvTreeListEntry* pFirst = m_pView->First();
880  if (pFirst != m_pStartEntry)
881  {
882  ShowCursor(false);
884  m_aVerSBar->SetThumbPos( 0 );
885  StopUserEvent();
886  ShowCursor(true);
888  reinterpret_cast<void*>(1));
889  return;
890  }
891  }
892 
893  if (!m_pStartEntry)
894  {
896  }
897 
900 
901  long nRectHeight = rRect.GetHeight();
902  long nEntryHeight = m_pView->GetEntryHeight();
903 
904  // calculate area for the entries we want to draw
905  sal_uInt16 nStartLine = static_cast<sal_uInt16>(rRect.Top() / nEntryHeight);
906  sal_uInt16 nCount = static_cast<sal_uInt16>(nRectHeight / nEntryHeight);
907  nCount += 2; // don't miss a row
908 
909  long nY = nStartLine * nEntryHeight;
910  SvTreeListEntry* pEntry = m_pStartEntry;
911  while (nStartLine && pEntry)
912  {
913  pEntry = m_pView->NextVisible(pEntry);
914  nStartLine--;
915  }
916 
917  vcl::Region aClipRegion(GetClipRegionRect());
918 
919  // first draw the lines, then clip them!
920  rRenderContext.SetClipRegion();
922  DrawNet(rRenderContext);
923 
924  rRenderContext.SetClipRegion(aClipRegion);
925 
926  if (!m_pCursor && !mbNoAutoCurEntry)
927  {
928  // do not select if multiselection or explicit set
929  bool bNotSelect = (m_aSelEng.GetSelectionMode() == SelectionMode::Multiple ) || ((m_nStyle & WB_NOINITIALSELECTION) == WB_NOINITIALSELECTION);
930  SetCursor(m_pStartEntry, bNotSelect);
931  }
932 
933  for(sal_uInt16 n=0; n< nCount && pEntry; n++)
934  {
935  /*long nMaxRight=*/
936  m_pView->PaintEntry1(*pEntry, nY, rRenderContext );
937  nY += nEntryHeight;
938  pEntry = m_pView->NextVisible(pEntry);
939  }
940 
942  rRenderContext.SetClipRegion();
944 }
945 
946 void SvImpLBox::MakeVisible( SvTreeListEntry* pEntry, bool bMoveToTop )
947 {
948  if( !pEntry )
949  return;
950 
951  bool bInView = IsEntryInView( pEntry );
952 
953  if( bInView && (!bMoveToTop || m_pStartEntry == pEntry) )
954  return; // is already visible
955 
958  if( !bInView )
959  {
960  if( !m_pView->IsEntryVisible(pEntry) ) // Parent(s) collapsed?
961  {
962  SvTreeListEntry* pParent = m_pView->GetParent( pEntry );
963  while( pParent )
964  {
965  if( !m_pView->IsExpanded( pParent ) )
966  {
967  bool bRet = m_pView->Expand( pParent );
968  DBG_ASSERT(bRet,"Not expanded!");
969  }
970  pParent = m_pView->GetParent( pParent );
971  }
972  // do the parent's children fit into the view or do we have to scroll?
973  if( IsEntryInView( pEntry ) && !bMoveToTop )
974  return; // no need to scroll
975  }
976  }
977 
978  m_pStartEntry = pEntry;
979  ShowCursor( false );
980  FillView();
981  m_aVerSBar->SetThumbPos( static_cast<long>(m_pView->GetVisiblePos( m_pStartEntry )) );
982  ShowCursor( true );
983  m_pView->Invalidate();
984 }
985 
986 void SvImpLBox::ScrollToAbsPos( long nPos )
987 {
988  if( m_pView->GetVisibleCount() == 0 )
989  return;
990  long nLastEntryPos = m_pView->GetAbsPos( m_pView->Last() );
991 
992  if( nPos < 0 )
993  nPos = 0;
994  else if( nPos > nLastEntryPos )
995  nPos = nLastEntryPos;
996 
997  SvTreeListEntry* pEntry = m_pView->GetEntryAtAbsPos( nPos );
998  if( !pEntry || pEntry == m_pStartEntry )
999  return;
1000 
1003 
1004  if( m_pView->IsEntryVisible(pEntry) )
1005  {
1006  m_pStartEntry = pEntry;
1007  ShowCursor( false );
1008  m_aVerSBar->SetThumbPos( nPos );
1009  ShowCursor( true );
1010  if (GetUpdateMode())
1011  m_pView->Invalidate();
1012  }
1013 }
1014 
1016 {
1019  {
1020  return;
1021  }
1022 
1023  // for platforms that don't have nets, DrawNativeControl does nothing and returns true
1024  // so that SvImpLBox::DrawNet() doesn't draw anything either
1026  {
1027  ImplControlValue aControlValue;
1029  tools::Rectangle(), ControlState::ENABLED, aControlValue, OUString()))
1030  {
1031  return;
1032  }
1033  }
1034 
1035  long nEntryHeight = m_pView->GetEntryHeight();
1036  long nEntryHeightDIV2 = nEntryHeight / 2;
1037  if( nEntryHeightDIV2 && !(nEntryHeight & 0x0001))
1038  nEntryHeightDIV2--;
1039 
1040  SvTreeListEntry* pChild;
1041  SvTreeListEntry* pEntry = m_pStartEntry;
1042 
1043  SvLBoxTab* pFirstDynamicTab = m_pView->GetFirstDynamicTab();
1044  while (m_pTree->GetDepth( pEntry ) > 0)
1045  {
1046  pEntry = m_pView->GetParent(pEntry);
1047  }
1048  sal_uInt16 nOffs = static_cast<sal_uInt16>(m_pView->GetVisiblePos(m_pStartEntry) - m_pView->GetVisiblePos(pEntry));
1049  long nY = 0;
1050  nY -= (nOffs * nEntryHeight);
1051 
1052  DBG_ASSERT(pFirstDynamicTab,"No Tree!");
1053 
1054  rRenderContext.Push(PushFlags::LINECOLOR);
1055 
1056  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
1057  Color aCol = rStyleSettings.GetFaceColor();
1058 
1059  if (aCol.IsRGBEqual(rRenderContext.GetBackground().GetColor()))
1060  aCol = rStyleSettings.GetShadowColor();
1061  rRenderContext.SetLineColor(aCol);
1062  Point aPos1, aPos2;
1063  sal_uInt16 nDistance;
1064  sal_uLong nMax = m_nVisibleCount + nOffs + 1;
1065 
1066  const Image& rExpandedNodeBitmap = GetExpandedNodeBmp();
1067 
1068  for (sal_uLong n=0; n< nMax && pEntry; n++)
1069  {
1070  if (m_pView->IsExpanded(pEntry))
1071  {
1072  aPos1.setX( m_pView->GetTabPos(pEntry, pFirstDynamicTab) );
1073  // if it is not a context bitmap, go a little to the right below the
1074  // first text (node bitmap, too)
1076  aPos1.AdjustX(rExpandedNodeBitmap.GetSizePixel().Width() / 2 );
1077 
1078  aPos1.setY( nY );
1079  aPos1.AdjustY(nEntryHeightDIV2 );
1080 
1081  pChild = m_pView->FirstChild( pEntry );
1082  assert(pChild && "Child?");
1083  pChild = pChild->LastSibling();
1084  nDistance = static_cast<sal_uInt16>(m_pView->GetVisiblePos(pChild) - m_pView->GetVisiblePos(pEntry));
1085  aPos2 = aPos1;
1086  aPos2.AdjustY(nDistance * nEntryHeight );
1087  rRenderContext.DrawLine(aPos1, aPos2);
1088  }
1089  // visible in control?
1090  if (n >= nOffs && ((m_nStyle & WB_HASLINESATROOT) || !m_pTree->IsAtRootDepth(pEntry)))
1091  {
1092  // can we recycle aPos1?
1093  if (!m_pView->IsExpanded(pEntry))
1094  {
1095  // nope
1096  aPos1.setX( m_pView->GetTabPos(pEntry, pFirstDynamicTab) );
1097  // if it is not a context bitmap, go a little to the right below
1098  // the first text (node bitmap, too)
1100  aPos1.AdjustX(rExpandedNodeBitmap.GetSizePixel().Width() / 2 );
1101  aPos1.setY( nY );
1102  aPos1.AdjustY(nEntryHeightDIV2 );
1103  aPos2.setX( aPos1.X() );
1104  }
1105  aPos2.setY( aPos1.Y() );
1106  aPos2.AdjustX( -(m_pView->GetIndent()) );
1107  rRenderContext.DrawLine(aPos1, aPos2);
1108  }
1109  nY += nEntryHeight;
1110  pEntry = m_pView->NextVisible(pEntry);
1111  }
1113  {
1114  pEntry = m_pView->First();
1115  aPos1.setX( m_pView->GetTabPos(pEntry, pFirstDynamicTab) );
1116  // if it is not a context bitmap, go a little to the right below the
1117  // first text (node bitmap, too)
1119  aPos1.AdjustX(rExpandedNodeBitmap.GetSizePixel().Width() / 2 );
1120  aPos1.AdjustX( -(m_pView->GetIndent()) );
1121  aPos1.setY( GetEntryLine( pEntry ) );
1122  aPos1.AdjustY(nEntryHeightDIV2 );
1123  pChild = pEntry->LastSibling();
1124  aPos2.setX( aPos1.X() );
1125  aPos2.setY( GetEntryLine( pChild ) );
1126  aPos2.AdjustY(nEntryHeightDIV2 );
1127  rRenderContext.DrawLine(aPos1, aPos2);
1128  }
1129  rRenderContext.Pop();
1130 }
1131 
1132 void SvImpLBox::PositionScrollBars( Size& rSize, sal_uInt16 nMask )
1133 {
1134  long nOverlap = 0;
1135 
1136  Size aVerSize( m_nVerSBarWidth, rSize.Height() );
1137  Size aHorSize( rSize.Width(), m_nHorSBarHeight );
1138 
1139  if( nMask & 0x0001 )
1140  aHorSize.AdjustWidth( -m_nVerSBarWidth );
1141  if( nMask & 0x0002 )
1142  aVerSize.AdjustHeight( -m_nHorSBarHeight );
1143 
1144  aVerSize.AdjustHeight(2 * nOverlap );
1145  Point aVerPos( rSize.Width() - aVerSize.Width() + nOverlap, -nOverlap );
1146  m_aVerSBar->SetPosSizePixel( aVerPos, aVerSize );
1147 
1148  aHorSize.AdjustWidth(2 * nOverlap );
1149  Point aHorPos( -nOverlap, rSize.Height() - aHorSize.Height() + nOverlap );
1150 
1151  m_aHorSBar->SetPosSizePixel( aHorPos, aHorSize );
1152 
1153  if( nMask & 0x0001 )
1154  rSize.setWidth( aVerPos.X() );
1155  if( nMask & 0x0002 )
1156  rSize.setHeight( aHorPos.Y() );
1157 
1158  if( (nMask & (0x0001|0x0002)) == (0x0001|0x0002) )
1159  m_aScrBarBox->Show();
1160  else
1161  m_aScrBarBox->Hide();
1162 }
1163 
1165 {
1166  long nEntryHeight = m_pView->GetEntryHeight();
1167  if( !nEntryHeight )
1168  return;
1169 
1170  sal_uInt16 nResult = 0;
1171 
1172  Size aOSize( m_pView->Control::GetOutputSizePixel() );
1173 
1174  const WinBits nWindowStyle = m_pView->GetStyle();
1175  bool bVerSBar = ( nWindowStyle & WB_VSCROLL ) != 0;
1176  bool bHorBar = false;
1177  long nMaxRight = aOSize.Width(); //GetOutputSize().Width();
1178  Point aOrigin( m_pView->GetMapMode().GetOrigin() );
1179  aOrigin.setX( aOrigin.X() * -1 );
1180  nMaxRight += aOrigin.X() - 1;
1181  long nVis = m_nMostRight - aOrigin.X();
1182  if( (nWindowStyle & (WB_AUTOHSCROLL|WB_HSCROLL)) &&
1183  (nVis < m_nMostRight || nMaxRight < m_nMostRight) )
1184  {
1185  bHorBar = true;
1186  }
1187 
1188  // number of entries that are not collapsed
1189  sal_uLong nTotalCount = m_pView->GetVisibleCount();
1190 
1191  // number of entries visible within the view
1192  m_nVisibleCount = aOSize.Height() / nEntryHeight;
1193 
1194  // do we need a vertical scrollbar?
1195  if( bVerSBar || nTotalCount > m_nVisibleCount )
1196  {
1197  nResult = 1;
1198  nMaxRight -= m_nVerSBarWidth;
1199  if( !bHorBar )
1200  {
1201  if( (nWindowStyle & (WB_AUTOHSCROLL|WB_HSCROLL)) &&
1202  (nVis < m_nMostRight || nMaxRight < m_nMostRight) )
1203  bHorBar = true;
1204  }
1205  }
1206 
1207  // do we need a horizontal scrollbar?
1208  if( bHorBar )
1209  {
1210  nResult |= 0x0002;
1211  // the number of entries visible within the view has to be recalculated
1212  // because the horizontal scrollbar is now visible.
1213  m_nVisibleCount = (aOSize.Height() - m_nHorSBarHeight) / nEntryHeight;
1214  // we might actually need a vertical scrollbar now
1215  if( !(nResult & 0x0001) &&
1216  ((nTotalCount > m_nVisibleCount) || bVerSBar) )
1217  {
1218  nResult = 3;
1219  }
1220  }
1221 
1222  PositionScrollBars( aOSize, nResult );
1223 
1224  // adapt Range, VisibleRange etc.
1225 
1226  // refresh output size, in case we have to scroll
1227  tools::Rectangle aRect;
1228  aRect.SetSize( aOSize );
1229  m_aSelEng.SetVisibleArea( aRect );
1230 
1231  // vertical scrollbar
1232  long nTemp = static_cast<long>(m_nVisibleCount);
1233  nTemp--;
1234  if( nTemp != m_aVerSBar->GetVisibleSize() )
1235  {
1236  if( !m_bInVScrollHdl )
1237  {
1238  m_aVerSBar->SetPageSize( nTemp - 1 );
1239  m_aVerSBar->SetVisibleSize( nTemp );
1240  }
1241  else
1242  {
1244  m_nNextVerVisSize = nTemp;
1245  }
1246  }
1247 
1248  // horizontal scrollbar
1249  nTemp = m_aHorSBar->GetThumbPos();
1250  m_aHorSBar->SetVisibleSize( aOSize.Width() );
1251  long nNewThumbPos = m_aHorSBar->GetThumbPos();
1252  Range aRange( m_aHorSBar->GetRange() );
1253  if( aRange.Max() < m_nMostRight+25 )
1254  {
1255  aRange.Max() = m_nMostRight+25;
1256  m_aHorSBar->SetRange( aRange );
1257  }
1258 
1259  if( nTemp != nNewThumbPos )
1260  {
1261  nTemp = nNewThumbPos - nTemp;
1262  if( m_pView->IsEditingActive() )
1263  {
1264  m_pView->EndEditing( true ); // Cancel
1265  m_pView->Update();
1266  }
1267  m_pView->nFocusWidth = -1;
1268  KeyLeftRight( nTemp );
1269  }
1270 
1271  if( nResult & 0x0001 )
1272  m_aVerSBar->Show();
1273  else
1274  m_aVerSBar->Hide();
1275 
1276  if( nResult & 0x0002 )
1277  m_aHorSBar->Show();
1278  else
1279  {
1280  m_aHorSBar->Hide();
1281  }
1282  rSize = aOSize;
1283 }
1284 
1286 {
1288  Size aSize( m_pView->Control::GetOutputSizePixel() );
1289  m_aScrBarBox->SetPosPixel( Point(aSize.Width()-m_nVerSBarWidth, aSize.Height()-m_nHorSBarHeight));
1290 }
1291 
1293 {
1294  m_aOutputSize = m_pView->Control::GetOutputSizePixel();
1295  if( m_aOutputSize.Width() <= 0 || m_aOutputSize.Height() <= 0 )
1296  return;
1298  InitScrollBarBox();
1299 
1300  if( m_pView->GetEntryHeight())
1301  {
1303  UpdateAll(false);
1304  }
1305  // HACK, as in floating and docked windows the scrollbars might not be drawn
1306  // correctly/not be drawn at all after resizing!
1307  if( m_aHorSBar->IsVisible())
1309  if( m_aVerSBar->IsVisible())
1312 }
1313 
1315 {
1316  if( !m_pStartEntry )
1317  {
1318  sal_uLong nVisibleViewCount = m_pView->GetVisibleCount();
1319  long nTempThumb = m_aVerSBar->GetThumbPos();
1320  if( nTempThumb < 0 )
1321  nTempThumb = 0;
1322  else if( static_cast<unsigned long>(nTempThumb) >= nVisibleViewCount )
1323  nTempThumb = nVisibleViewCount == 0 ? 0 : nVisibleViewCount - 1;
1324  m_pStartEntry = m_pView->GetEntryAtVisPos(nTempThumb);
1325  }
1326  if( !m_pStartEntry )
1327  return;
1328 
1329  sal_uInt16 nLast = static_cast<sal_uInt16>(m_pView->GetVisiblePos(m_pView->LastVisible()));
1330  sal_uInt16 nThumb = static_cast<sal_uInt16>(m_pView->GetVisiblePos( m_pStartEntry ));
1331  sal_uLong nCurDispEntries = nLast-nThumb+1;
1332  if( nCurDispEntries >= m_nVisibleCount )
1333  return;
1334 
1335  ShowCursor( false );
1336  // fill window by moving the thumb up incrementally
1337  bool bFound = false;
1338  SvTreeListEntry* pTemp = m_pStartEntry;
1339  while( nCurDispEntries < m_nVisibleCount && pTemp )
1340  {
1341  pTemp = m_pView->PrevVisible(m_pStartEntry);
1342  if( pTemp )
1343  {
1344  nThumb--;
1345  m_pStartEntry = pTemp;
1346  nCurDispEntries++;
1347  bFound = true;
1348  }
1349  }
1350  if( bFound )
1351  {
1352  m_aVerSBar->SetThumbPos( nThumb );
1353  ShowCursor( true ); // recalculate focus rectangle
1354  m_pView->Invalidate();
1355  }
1356 }
1357 
1358 
1360 {
1361  bool bVerBar = ( m_pView->GetStyle() & WB_VSCROLL ) != 0;
1362  sal_uLong nVis = 0;
1363  if( !bVerBar )
1364  nVis = m_pView->GetVisibleCount();
1365  if( bVerBar || (m_nVisibleCount && nVis > static_cast<sal_uLong>(m_nVisibleCount-1)) )
1366  {
1367  if( !m_aVerSBar->IsVisible() )
1368  {
1369  m_pView->nFocusWidth = -1;
1371  if( GetUpdateMode() )
1372  m_aVerSBar->Update();
1373  }
1374  }
1375  else
1376  {
1377  if( m_aVerSBar->IsVisible() )
1378  {
1379  m_pView->nFocusWidth = -1;
1381  }
1382  }
1383 
1384  long nMaxRight = GetOutputSize().Width();
1385  Point aPos( m_pView->GetMapMode().GetOrigin() );
1386  aPos.setX( aPos.X() * -1 ); // convert document coordinates
1387  nMaxRight = nMaxRight + aPos.X() - 1;
1388  if( nMaxRight < m_nMostRight )
1389  {
1390  if( !m_aHorSBar->IsVisible() )
1391  {
1392  m_pView->nFocusWidth = -1;
1394  if( GetUpdateMode() )
1395  m_aHorSBar->Update();
1396  }
1397  else
1398  {
1399  Range aRange( m_aHorSBar->GetRange() );
1400  if( aRange.Max() < m_nMostRight+25 )
1401  {
1402  aRange.Max() = m_nMostRight+25;
1403  m_aHorSBar->SetRange( aRange );
1404  }
1405  else
1406  {
1407  m_pView->nFocusWidth = -1;
1409  }
1410  }
1411  }
1412  else
1413  {
1414  if( m_aHorSBar->IsVisible() )
1415  {
1416  m_pView->nFocusWidth = -1;
1418  }
1419  }
1420 }
1421 
1422 
1424 {
1425  if( m_pStartEntry )
1426  {
1427  long nEntryPos = m_pView->GetVisiblePos( m_pStartEntry );
1428  m_aVerSBar->SetThumbPos( nEntryPos );
1429  }
1430  else
1431  m_aVerSBar->SetThumbPos( 0 );
1432 }
1433 
1435 {
1436  // parent collapsed
1437  if( !m_pView->IsEntryVisible(pEntry) )
1438  return false;
1439  long nY = GetEntryLine( pEntry );
1440  if( nY < 0 )
1441  return false;
1442  long nMax = m_nVisibleCount * m_pView->GetEntryHeight();
1443  return nY < nMax;
1444 }
1445 
1446 
1448 {
1449  if(!m_pStartEntry )
1450  return -1; // invisible position
1451 
1452  long nFirstVisPos = m_pView->GetVisiblePos( m_pStartEntry );
1453  long nEntryVisPos = m_pView->GetVisiblePos( pEntry );
1454  nFirstVisPos = nEntryVisPos - nFirstVisPos;
1455  nFirstVisPos *= m_pView->GetEntryHeight();
1456  return nFirstVisPos;
1457 }
1458 
1460 {
1463  if(!m_pView->HasViewData()) // are we within the Clear?
1464  {
1465  Size aSize = m_pView->Control::GetOutputSizePixel();
1466  AdjustScrollBars( aSize );
1467  }
1468  else
1469  {
1470  Resize();
1471  if( GetUpdateMode() )
1472  m_pView->Invalidate();
1473  }
1474 }
1475 
1476 
1477 // ***********************************************************************
1478 // Callback Functions
1479 // ***********************************************************************
1480 
1482 {
1483  // SelAllDestrAnch( false, true ); //DeselectAll();
1484  if( !GetUpdateMode() )
1485  return;
1486 
1487  ShowCursor( false );
1488  long nY = GetEntryLine( pEntry );
1489  if( IsLineVisible(nY) )
1490  {
1491  InvalidateEntriesFrom( nY );
1492  FindMostRight( pEntry, nullptr );
1493  }
1495  // if we expanded before the thumb, the thumb's position has to be
1496  // corrected
1497  SyncVerThumb();
1498  ShowVerSBar();
1499  ShowCursor( true );
1500 }
1501 
1503 {
1504  if( !m_pView->IsEntryVisible( pEntry ) )
1505  return;
1506 
1507  ShowCursor( false );
1508 
1509  if( !m_pMostRightEntry || m_pTree->IsChild( pEntry,m_pMostRightEntry ) )
1510  {
1511  FindMostRight(nullptr);
1512  }
1513 
1514  if( m_pStartEntry )
1515  {
1516  long nOldThumbPos = m_aVerSBar->GetThumbPos();
1517  sal_uLong nVisList = m_pView->GetVisibleCount();
1518  m_aVerSBar->SetRange( Range(0, nVisList-1) );
1519  long nNewThumbPos = m_aVerSBar->GetThumbPos();
1520  if( nNewThumbPos != nOldThumbPos )
1521  {
1523  sal_uInt16 nDistance = static_cast<sal_uInt16>(nNewThumbPos);
1524  if( nDistance )
1526  if( GetUpdateMode() )
1527  m_pView->Invalidate();
1528  }
1529  else
1530  SyncVerThumb();
1531  ShowVerSBar();
1532  }
1533  // has the cursor been collapsed?
1534  if( m_pTree->IsChild( pEntry, m_pCursor ) )
1535  SetCursor( pEntry );
1536  if( GetUpdateMode() )
1537  ShowVerSBar();
1538  ShowCursor( true );
1539  if( GetUpdateMode() && m_pCursor )
1540  m_pView->Select( m_pCursor );
1541 }
1542 
1544 {
1545  if( !m_pView->IsEntryVisible( pEntry ) || !m_pStartEntry )
1546  return;
1547 
1548  SelAllDestrAnch( false ); // deselect all
1549 
1550  // is the collapsed cursor visible?
1551  long nY = GetEntryLine( pEntry );
1552  if( IsLineVisible(nY) )
1553  {
1554  if( GetUpdateMode() )
1555  InvalidateEntriesFrom( nY );
1556  }
1557  else
1558  {
1559  if( m_pTree->IsChild(pEntry, m_pStartEntry) )
1560  {
1561  m_pStartEntry = pEntry;
1562  if( GetUpdateMode() )
1563  m_pView->Invalidate();
1564  }
1565  }
1566 }
1567 
1568 
1570 {
1571  const Size aSize( rBmp.GetSizePixel() );
1572  m_nNodeBmpWidth = aSize.Width();
1573 }
1574 
1576 {
1579  {
1580  // only if the first dynamic tab is centered (we currently assume that)
1581  Size aSize = GetExpandedNodeBmp().GetSizePixel();
1582  m_nNodeBmpTabDistance -= aSize.Width() / 2;
1583  }
1584 }
1585 
1586 
1587 // corrects the cursor when using SingleSelection
1588 
1589 void SvImpLBox::EntrySelected( SvTreeListEntry* pEntry, bool bSelect )
1590 {
1592  return;
1593 
1595  if( bSelect &&
1597  pEntry != m_pCursor )
1598  {
1599  SetCursor( pEntry );
1600  DBG_ASSERT(m_pView->GetSelectionCount()==1,"selection count?");
1601  }
1602 
1603  if( GetUpdateMode() && m_pView->IsEntryVisible(pEntry) )
1604  {
1605  long nY = GetEntryLine( pEntry );
1606  if( IsLineVisible( nY ) )
1607  {
1608  ShowCursor(false);
1609  InvalidateEntry(pEntry);
1610  ShowCursor(true);
1611  }
1612  }
1613 }
1614 
1615 
1617 {
1619 
1620  DestroyAnchor();
1621 
1622  if( !m_pView->IsEntryVisible( pEntry ) )
1623  {
1624  // if parent is collapsed => bye!
1626  return;
1627  }
1628 
1629  if( pEntry == m_pMostRightEntry || (
1630  pEntry->HasChildren() && m_pView->IsExpanded(pEntry) &&
1631  m_pTree->IsChild(pEntry, m_pMostRightEntry)))
1632  {
1634  }
1635 
1636  SvTreeListEntry* pOldStartEntry = m_pStartEntry;
1637 
1638  SvTreeListEntry* pParent = m_pView->GetModel()->GetParent(pEntry);
1639 
1640  if (pParent && m_pView->GetModel()->GetChildList(pParent).size() == 1)
1641  {
1642  DBG_ASSERT( m_pView->IsExpanded( pParent ), "Parent not expanded");
1643  pParent->SetFlags( pParent->GetFlags() | SvTLEntryFlags::NO_NODEBMP);
1644  InvalidateEntry( pParent );
1645  }
1646 
1647  if( m_pCursor && m_pTree->IsChild( pEntry, m_pCursor) )
1648  m_pCursor = pEntry;
1649  if( m_pStartEntry && m_pTree->IsChild(pEntry,m_pStartEntry) )
1650  m_pStartEntry = pEntry;
1651 
1652  SvTreeListEntry* pTemp;
1653  if( m_pCursor && m_pCursor == pEntry )
1654  {
1655  if( m_bSimpleTravel )
1656  m_pView->Select( m_pCursor, false );
1657  ShowCursor( false ); // focus rectangle gone
1658  // NextSibling, because we also delete the children of the cursor
1659  pTemp = m_pCursor->NextSibling();
1660  if( !pTemp )
1661  pTemp = m_pView->PrevVisible(m_pCursor);
1662 
1663  SetCursor( pTemp, true );
1664  }
1665  if( m_pStartEntry && m_pStartEntry == pEntry )
1666  {
1667  pTemp = m_pStartEntry->NextSibling();
1668  if( !pTemp )
1669  pTemp = m_pView->PrevVisible(m_pStartEntry);
1670  m_pStartEntry = pTemp;
1671  }
1672  if( GetUpdateMode())
1673  {
1674  // if it is the last one, we have to invalidate it, so the lines are
1675  // drawn correctly (in this case they're deleted)
1676  if( m_pStartEntry && (m_pStartEntry != pOldStartEntry || pEntry == m_pView->GetModel()->Last()) )
1677  {
1680  }
1681  else
1682  InvalidateEntriesFrom( GetEntryLine( pEntry ) );
1683  }
1684 }
1685 
1687 {
1689  {
1691  return;
1692  }
1693  if( !m_pStartEntry )
1695  if( !m_pCursor )
1696  SetCursor( m_pStartEntry, true );
1697 
1699  m_pView->Select( m_pCursor );
1700 
1701  if( GetUpdateMode())
1702  {
1704  FindMostRight(nullptr);
1706  FillView();
1707  if( m_pStartEntry )
1708  // if something above the thumb was deleted
1710 
1711  ShowVerSBar();
1713  {
1714  if( m_pView->GetSelectionCount() )
1715  {
1716  // is a neighboring entry selected?
1717  SvTreeListEntry* pNextCursor = m_pView->PrevVisible( m_pCursor );
1718  if( !pNextCursor || !m_pView->IsSelected( pNextCursor ))
1719  pNextCursor = m_pView->NextVisible( m_pCursor );
1720  if( !pNextCursor || !m_pView->IsSelected( pNextCursor ))
1721  // no neighbor selected: use first selected
1722  pNextCursor = m_pView->FirstSelected();
1723  SetCursor( pNextCursor );
1725  }
1726  else
1727  m_pView->Select( m_pCursor );
1728  }
1729  ShowCursor( true );
1730  }
1732 }
1733 
1734 
1736 {
1737  bool bDeselAll(m_nFlags & LBoxFlags::DeselectAll);
1738  SelAllDestrAnch( false ); // DeselectAll();
1739  if( !bDeselAll )
1741 
1742  if( pEntry == m_pCursor )
1743  ShowCursor( false );
1744  if( IsEntryInView( pEntry ) )
1745  m_pView->Invalidate();
1746  if( pEntry != m_pStartEntry )
1747  return;
1748 
1749  SvTreeListEntry* pNew = nullptr;
1750  if( !pEntry->HasChildren() )
1751  {
1753  if( !pNew )
1755  }
1756  else
1757  {
1758  pNew = pEntry->NextSibling();
1759  if( !pNew )
1760  pNew = pEntry->PrevSibling();
1761  }
1762  m_pStartEntry = pNew;
1763 }
1764 
1766 {
1768 
1769  if ( !m_pStartEntry )
1770  // this might happen if the only entry in the view is moved to its very same position
1771  // #i97346#
1773 
1775  sal_uInt16 nFirstPos = static_cast<sal_uInt16>(m_pTree->GetAbsPos( m_pStartEntry ));
1776  sal_uInt16 nNewPos = static_cast<sal_uInt16>(m_pTree->GetAbsPos( pEntry ));
1777  FindMostRight(nullptr);
1778  if( nNewPos < nFirstPos ) // HACK!
1779  m_pStartEntry = pEntry;
1780  SyncVerThumb();
1781  if( pEntry == m_pCursor )
1782  {
1783  if( m_pView->IsEntryVisible( m_pCursor ) )
1784  ShowCursor( true );
1785  else
1786  {
1787  SvTreeListEntry* pParent = pEntry;
1788  do {
1789  pParent = m_pTree->GetParent( pParent );
1790  }
1791  while( !m_pView->IsEntryVisible( pParent ) );
1792  SetCursor( pParent );
1793  }
1794  }
1795  if( IsEntryInView( pEntry ) )
1796  m_pView->Invalidate();
1797 }
1798 
1799 
1801 {
1802  if( !GetUpdateMode() )
1803  return;
1804 
1805  SvTreeListEntry* pParent = m_pTree->GetParent(pEntry);
1806  if (pParent && m_pTree->GetChildList(pParent).size() == 1)
1807  // draw plus sign
1808  m_pTree->InvalidateEntry( pParent );
1809 
1810  if( !m_pView->IsEntryVisible( pEntry ) )
1811  return;
1812  bool bDeselAll(m_nFlags & LBoxFlags::DeselectAll);
1813  if( bDeselAll )
1814  SelAllDestrAnch( false );
1815  else
1816  DestroyAnchor();
1817  // nFlags &= (~LBoxFlags::DeselectAll);
1818 // ShowCursor( false ); // if cursor is moved lower
1819  long nY = GetEntryLine( pEntry );
1820  bool bEntryVisible = IsLineVisible( nY );
1821  if( bEntryVisible )
1822  {
1823  ShowCursor( false ); // if cursor is moved lower
1824  nY -= m_pView->GetEntryHeight(); // because of lines
1825  InvalidateEntriesFrom( nY );
1826  }
1827  else if( m_pStartEntry && nY < GetEntryLine(m_pStartEntry) )
1828  {
1829  // Check if the view is filled completely. If not, then adjust
1830  // pStartEntry and the Cursor (automatic scrolling).
1831  sal_uInt16 nLast = static_cast<sal_uInt16>(m_pView->GetVisiblePos(m_pView->LastVisible()));
1832  sal_uInt16 nThumb = static_cast<sal_uInt16>(m_pView->GetVisiblePos( m_pStartEntry ));
1833  sal_uInt16 nCurDispEntries = nLast-nThumb+1;
1834  if( nCurDispEntries < m_nVisibleCount )
1835  {
1836  // set at the next paint event
1837  m_pStartEntry = nullptr;
1838  SetCursor( nullptr );
1839  m_pView->Invalidate();
1840  }
1841  }
1842  else if( !m_pStartEntry )
1843  m_pView->Invalidate();
1844 
1845  SetMostRight( pEntry );
1847  SyncVerThumb(); // if something was inserted before the thumb
1848  ShowVerSBar();
1849  ShowCursor( true );
1851  m_pView->Update();
1852 }
1853 
1854 
1855 // ********************************************************************
1856 // Event handler
1857 // ********************************************************************
1858 
1859 
1860 // ****** Control the control animation
1861 
1863 {
1864  SvLBoxItem* pItem = m_pView->GetItem(pEntry,rMEvt.GetPosPixel().X(),&m_pActiveTab);
1865  if (pItem && pItem->GetType() == SvLBoxItemType::Button)
1866  {
1867  m_pActiveButton = static_cast<SvLBoxButton*>(pItem);
1868  m_pActiveEntry = pEntry;
1869  if( m_pCursor == m_pActiveEntry )
1870  m_pView->HideFocus();
1871  m_pView->CaptureMouse();
1874  return true;
1875  }
1876  else
1877  m_pActiveButton = nullptr;
1878  return false;
1879 }
1880 
1882 {
1883  if( m_pActiveButton )
1884  {
1885  long nMouseX = rMEvt.GetPosPixel().X();
1886  if( pEntry == m_pActiveEntry &&
1888  {
1890  {
1893  }
1894  }
1895  else
1896  {
1898  {
1901  }
1902  }
1903  return true;
1904  }
1905  return false;
1906 }
1907 
1909 {
1910  if( m_pActiveButton )
1911  {
1912  m_pView->ReleaseMouse();
1913  SvTreeListEntry* pEntry = GetClickedEntry( rMEvt.GetPosPixel() );
1915  long nMouseX = rMEvt.GetPosPixel().X();
1916  if (pEntry == m_pActiveEntry && m_pView->GetItem(m_pActiveEntry, nMouseX) == m_pActiveButton)
1919  if (m_pCursor == m_pActiveEntry)
1920  ShowCursor(true);
1921  m_pActiveButton = nullptr;
1922  m_pActiveEntry = nullptr;
1923  m_pActiveTab = nullptr;
1924  return true;
1925  }
1926  return false;
1927 }
1928 
1929 // ******* Control plus/minus button for expanding/collapsing
1930 
1931 // false == no expand/collapse button hit
1932 bool SvImpLBox::IsNodeButton( const Point& rPosPixel, SvTreeListEntry* pEntry ) const
1933 {
1934  if( !pEntry->HasChildren() && !pEntry->HasChildrenOnDemand() )
1935  return false;
1936 
1937  SvLBoxTab* pFirstDynamicTab = m_pView->GetFirstDynamicTab();
1938  if( !pFirstDynamicTab )
1939  return false;
1940 
1941  long nMouseX = rPosPixel.X();
1942  // convert to document coordinates
1943  Point aOrigin( m_pView->GetMapMode().GetOrigin() );
1944  nMouseX -= aOrigin.X();
1945 
1946  long nX = m_pView->GetTabPos( pEntry, pFirstDynamicTab);
1947  nX += m_nNodeBmpTabDistance;
1948  if( nMouseX < nX )
1949  return false;
1950  nX += m_nNodeBmpWidth;
1951  return nMouseX <= nX;
1952 }
1953 
1954 // false == hit no node button
1956 {
1957  bool bRet = false;
1958 
1959  if ( m_pView->IsEditingActive() && pEntry == m_pView->pEdEntry )
1960  // inplace editing -> nothing to do
1961  bRet = true;
1962  else if ( IsNodeButton( rMEvt.GetPosPixel(), pEntry ) )
1963  {
1964  if ( m_pView->IsExpanded( pEntry ) )
1965  {
1966  m_pView->EndEditing( true );
1967  m_pView->Collapse( pEntry );
1968  }
1969  else
1970  {
1971  // you can expand an entry, which is in editing
1972  m_pView->Expand( pEntry );
1973  }
1974  bRet = true;
1975  }
1976 
1977  return bRet;
1978 }
1979 
1981 {
1982  if ( !rMEvt.IsLeft() && !rMEvt.IsRight())
1983  return;
1984 
1985  m_aEditIdle.Stop();
1986  Point aPos( rMEvt.GetPosPixel());
1987 
1988  if( aPos.X() > m_aOutputSize.Width() || aPos.Y() > m_aOutputSize.Height() )
1989  return;
1990 
1991  if( !m_pCursor )
1993  SvTreeListEntry* pEntry = GetEntry( aPos );
1994  if ( pEntry != m_pCursor )
1995  // new entry selected -> reset current tab position to first tab
1998  m_pView->GrabFocus();
1999  //fdo#82270 Grabbing focus can invalidate the entries, re-fetch
2000  pEntry = GetEntry(aPos);
2001  // the entry can still be invalid!
2002  if( !pEntry || !m_pView->GetViewData( pEntry ))
2003  return;
2004 
2005  long nY = GetEntryLine( pEntry );
2006  // Node-Button?
2007  if( ButtonDownCheckExpand( rMEvt, pEntry ) )
2008  return;
2009 
2010  if( !EntryReallyHit(pEntry,aPos,nY))
2011  return;
2012 
2013  SvLBoxItem* pXItem = m_pView->GetItem( pEntry, aPos.X() );
2014  if( pXItem )
2015  {
2016  SvLBoxTab* pXTab = m_pView->GetTab( pEntry, pXItem );
2017  if ( !rMEvt.IsMod1() && !rMEvt.IsMod2() && rMEvt.IsLeft() && pXTab->IsEditable()
2018  && pEntry == m_pView->FirstSelected() && nullptr == m_pView->NextSelected( pEntry ) )
2019  // #i8234# FirstSelected() and NextSelected() ensures, that inplace editing is only triggered, when only one entry is selected
2021  if ( !m_pView->IsSelected( pEntry ) )
2023  }
2024 
2025 
2026  if( (rMEvt.GetClicks() % 2) == 0 )
2027  {
2029  m_pView->pHdlEntry = pEntry;
2030  if( !m_pView->DoubleClickHdl() )
2031  {
2032  // Handler signals nothing to be done anymore, bail out, 'this' may
2033  // even be dead and destroyed.
2034  return;
2035  }
2036  else
2037  {
2038  // if the entry was deleted within the handler
2039  pEntry = GetClickedEntry( aPos );
2040  if( !pEntry )
2041  return;
2042  if( pEntry != m_pView->pHdlEntry )
2043  {
2044  // select anew & bye
2046  SelAllDestrAnch( false ); // DeselectAll();
2047  SetCursor( pEntry );
2048 
2049  return;
2050  }
2051  if( pEntry->HasChildren() || pEntry->HasChildrenOnDemand() )
2052  {
2053  if( m_bSubLstOpDblClick )
2054  {
2055  if( m_pView->IsExpanded(pEntry) )
2056  m_pView->Collapse( pEntry );
2057  else
2058  m_pView->Expand( pEntry );
2059  }
2060  if( pEntry == m_pCursor ) // only if Entryitem was clicked
2061  // (Nodebutton is not an Entryitem!)
2062  m_pView->Select( m_pCursor );
2063  return;
2064  }
2065  }
2066  }
2067  else
2068  {
2069  // CheckButton? (TreeListBox: Check + Info)
2070  if( ButtonDownCheckCtrl(rMEvt, pEntry) )
2071  return;
2072  // Inplace-Editing?
2073  }
2075  m_aSelEng.SelMouseButtonDown( rMEvt );
2076 }
2077 
2079 {
2081  m_aSelEng.SelMouseButtonUp( rMEvt );
2082  EndScroll();
2084  {
2086  m_aEditClickPos = rMEvt.GetPosPixel();
2087  m_aEditIdle.Start();
2088  }
2089 }
2090 
2092 {
2093  SvTreeListEntry* pEntry = GetClickedEntry( rMEvt.GetPosPixel() );
2094  if ( !MouseMoveCheckCtrl( rMEvt, pEntry ) && ( m_aSelEng.GetSelectionMode() != SelectionMode::NONE ) )
2095  m_aSelEng.SelMouseMove( rMEvt );
2096 }
2097 
2099 {
2100  sal_uInt16 nRefDepth = m_pTree->GetDepth(m_pCursor);
2102  while (pCur && m_pTree->GetDepth(pCur) > nRefDepth)
2103  {
2104  if (pCur->HasChildren() && !m_pView->IsExpanded(pCur))
2105  m_pView->Expand(pCur);
2106  pCur = m_pTree->Next(pCur);
2107  }
2108 }
2109 
2110 void SvImpLBox::CollapseTo(SvTreeListEntry* pParentToCollapse)
2111 {
2112  // collapse all parents until we get to the given parent to collapse
2113  if (pParentToCollapse)
2114  {
2115  sal_uInt16 nRefDepth;
2116  // special case explorer: if the root only has a single
2117  // entry, don't collapse the root entry
2118  if (m_pTree->GetChildList(nullptr).size() < 2)
2119  {
2120  nRefDepth = 1;
2121  pParentToCollapse = m_pCursor;
2122  while (m_pTree->GetParent(pParentToCollapse)
2123  && m_pTree->GetDepth(m_pTree->GetParent(pParentToCollapse)) > 0)
2124  {
2125  pParentToCollapse = m_pTree->GetParent(pParentToCollapse);
2126  }
2127  }
2128  else
2129  nRefDepth = m_pTree->GetDepth(pParentToCollapse);
2130 
2131  if (m_pView->IsExpanded(pParentToCollapse))
2132  m_pView->Collapse(pParentToCollapse);
2133  SvTreeListEntry* pCur = m_pTree->Next(pParentToCollapse);
2134  while (pCur && m_pTree->GetDepth(pCur) > nRefDepth)
2135  {
2136  if (pCur->HasChildren() && m_pView->IsExpanded(pCur))
2137  m_pView->Collapse(pCur);
2138  pCur = m_pTree->Next(pCur);
2139  }
2140  }
2141 }
2142 
2143 bool SvImpLBox::KeyInput( const KeyEvent& rKEvt)
2144 {
2145  m_aEditIdle.Stop();
2146  const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
2147 
2148  if( rKeyCode.IsMod2() )
2149  return false; // don't evaluate Alt key
2150 
2152 
2153  if( !m_pCursor )
2155  if( !m_pCursor )
2156  return false;
2157 
2158  bool bKeyUsed = true;
2159 
2160  sal_uInt16 nDelta = static_cast<sal_uInt16>(m_aVerSBar->GetPageSize());
2161  sal_uInt16 aCode = rKeyCode.GetCode();
2162 
2163  bool bShift = rKeyCode.IsShift();
2164  bool bMod1 = rKeyCode.IsMod1();
2165 
2166  SvTreeListEntry* pNewCursor;
2167 
2168  switch( aCode )
2169  {
2170  case KEY_UP:
2171  if( !IsEntryInView( m_pCursor ) )
2173 
2174  pNewCursor = m_pCursor;
2175  do
2176  {
2177  pNewCursor = m_pView->PrevVisible(pNewCursor);
2178  } while( pNewCursor && !IsSelectable(pNewCursor) );
2179 
2180  if ( pNewCursor )
2181  // new entry selected -> reset current tab position to first tab
2183  // if there is no next entry, take the current one
2184  // this ensures that in case of _one_ entry in the list, this entry is selected when pressing
2185  // the cursor key
2186  if (!pNewCursor)
2187  pNewCursor = m_pCursor;
2188 
2189  m_aSelEng.CursorPosChanging( bShift, bMod1 );
2190  SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
2191  if( !IsEntryInView( pNewCursor ) )
2192  KeyUp( false );
2193  break;
2194 
2195  case KEY_DOWN:
2196  if( !IsEntryInView( m_pCursor ) )
2198 
2199  pNewCursor = m_pCursor;
2200  do
2201  {
2202  pNewCursor = m_pView->NextVisible(pNewCursor);
2203  } while( pNewCursor && !IsSelectable(pNewCursor) );
2204 
2205  if ( pNewCursor )
2206  // new entry selected -> reset current tab position to first tab
2208 
2209  // if there is no next entry, take the current one
2210  // this ensures that in case of _one_ entry in the list, this entry is selected when pressing
2211  // the cursor key
2212  // 06.09.20001 - 83416 - frank.schoenheit@sun.com
2213  if ( !pNewCursor && m_pCursor )
2214  pNewCursor = m_pCursor;
2215 
2216  if( pNewCursor )
2217  {
2218  m_aSelEng.CursorPosChanging( bShift, bMod1 );
2219  if( IsEntryInView( pNewCursor ) )
2220  SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
2221  else
2222  {
2223  if( m_pCursor )
2224  m_pView->Select( m_pCursor, false );
2225  KeyDown( false );
2226  SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
2227  }
2228  }
2229  else
2230  KeyDown( false ); // because scrollbar range might still
2231  // allow scrolling
2232  break;
2233 
2234  case KEY_RIGHT:
2235  {
2236  if( m_bSubLstOpLR )
2237  {
2238  // only try to expand if sublist is expandable,
2239  // otherwise ignore the key press
2240  if( IsExpandable() && !m_pView->IsExpanded( m_pCursor ) )
2241  m_pView->Expand( m_pCursor );
2242  }
2243  else if (m_bIsCellFocusEnabled)
2244  {
2245  if ( m_nCurTabPos < ( m_pView->TabCount() - 1 ) )
2246  {
2247  ++m_nCurTabPos;
2248  ShowCursor( true );
2250  }
2251  }
2252  else if (m_aHorSBar->IsVisible())
2253  {
2254  long nThumb = m_aHorSBar->GetThumbPos();
2255  nThumb += m_aHorSBar->GetLineSize();
2256  long nOldThumb = m_aHorSBar->GetThumbPos();
2257  m_aHorSBar->SetThumbPos( nThumb );
2258  nThumb = nOldThumb;
2259  nThumb -= m_aHorSBar->GetThumbPos();
2260  nThumb *= -1;
2261  if( nThumb )
2262  {
2263  KeyLeftRight( nThumb );
2264  EndScroll();
2265  }
2266  }
2267  else
2268  bKeyUsed = false;
2269  break;
2270  }
2271 
2272  case KEY_LEFT:
2273  {
2275  {
2276  if ( m_nCurTabPos > FIRST_ENTRY_TAB )
2277  {
2278  --m_nCurTabPos;
2279  ShowCursor( true );
2281  }
2282  }
2283  else if (m_aHorSBar->IsVisible())
2284  {
2285  long nThumb = m_aHorSBar->GetThumbPos();
2286  nThumb -= m_aHorSBar->GetLineSize();
2287  long nOldThumb = m_aHorSBar->GetThumbPos();
2288  m_aHorSBar->SetThumbPos( nThumb );
2289  nThumb = nOldThumb;
2290  nThumb -= m_aHorSBar->GetThumbPos();
2291  if( nThumb )
2292  {
2293  KeyLeftRight( -nThumb );
2294  EndScroll();
2295  }
2296  else if( m_bSubLstOpLR )
2297  {
2298  if( IsExpandable() && m_pView->IsExpanded( m_pCursor ) )
2300  else
2301  {
2302  pNewCursor = m_pView->GetParent( m_pCursor );
2303  if( pNewCursor )
2304  SetCursor( pNewCursor );
2305  }
2306  }
2307  }
2308  else if( m_bSubLstOpLR )
2309  {
2310  if( IsExpandable() && m_pView->IsExpanded( m_pCursor ) )
2312  else
2313  {
2314  pNewCursor = m_pView->GetParent( m_pCursor );
2315  if( pNewCursor )
2316  SetCursor( pNewCursor );
2317  }
2318  }
2319  else
2320  bKeyUsed = false;
2321  break;
2322  }
2323 
2324  case KEY_PAGEUP:
2325  if( !bMod1 )
2326  {
2327  pNewCursor = m_pView->PrevVisible(m_pCursor, nDelta);
2328 
2329  while( nDelta && pNewCursor && !IsSelectable(pNewCursor) )
2330  {
2331  pNewCursor = m_pView->NextVisible(pNewCursor);
2332  nDelta--;
2333  }
2334 
2335  if( nDelta )
2336  {
2337  DBG_ASSERT(pNewCursor && pNewCursor!=m_pCursor, "Cursor?");
2338  m_aSelEng.CursorPosChanging( bShift, bMod1 );
2339  if( IsEntryInView( pNewCursor ) )
2340  SetCursor( pNewCursor );
2341  else
2342  {
2343  SetCursor( pNewCursor );
2344  KeyUp( true );
2345  }
2346  }
2347  }
2348  else
2349  bKeyUsed = false;
2350  break;
2351 
2352  case KEY_PAGEDOWN:
2353  if( !bMod1 )
2354  {
2355  pNewCursor= m_pView->NextVisible(m_pCursor, nDelta);
2356 
2357  while( nDelta && pNewCursor && !IsSelectable(pNewCursor) )
2358  {
2359  pNewCursor = m_pView->PrevVisible(pNewCursor);
2360  nDelta--;
2361  }
2362 
2363  if( nDelta && pNewCursor )
2364  {
2365  DBG_ASSERT(pNewCursor && pNewCursor!=m_pCursor, "Cursor?");
2366  m_aSelEng.CursorPosChanging( bShift, bMod1 );
2367  if( IsEntryInView( pNewCursor ) )
2368  SetCursor( pNewCursor );
2369  else
2370  {
2371  SetCursor( pNewCursor );
2372  KeyDown( true );
2373  }
2374  }
2375  else
2376  KeyDown( false ); // see also: KEY_DOWN
2377  }
2378  else
2379  bKeyUsed = false;
2380  break;
2381 
2382  case KEY_SPACE:
2384  {
2385  if ( bMod1 )
2386  {
2387  if ( m_pView->GetSelectionMode() == SelectionMode::Multiple && !bShift )
2388  // toggle selection
2390  }
2391  else if ( !bShift /*&& !bMod1*/ )
2392  {
2393  if ( m_aSelEng.IsAddMode() )
2394  {
2395  // toggle selection
2397  }
2398  else if ( !m_pView->IsSelected( m_pCursor ) )
2399  {
2400  SelAllDestrAnch( false );
2401  m_pView->Select( m_pCursor );
2402  }
2403  else
2404  bKeyUsed = false;
2405  }
2406  else
2407  bKeyUsed = false;
2408  }
2409  else
2410  bKeyUsed = false;
2411  break;
2412 
2413  case KEY_RETURN:
2414  if( m_bSubLstOpRet && IsExpandable() )
2415  {
2416  if( m_pView->IsExpanded( m_pCursor ) )
2418  else
2419  m_pView->Expand( m_pCursor );
2420  }
2421  else
2422  bKeyUsed = false;
2423  break;
2424 
2425  case KEY_F2:
2426  if( !bShift && !bMod1 )
2427  {
2428  m_aEditClickPos = Point( -1, -1 );
2429  EditTimerCall( nullptr );
2430  }
2431  else
2432  bKeyUsed = false;
2433  break;
2434 
2435  case KEY_F8:
2436  if( bShift && m_pView->GetSelectionMode()==SelectionMode::Multiple &&
2437  !(m_nStyle & WB_SIMPLEMODE))
2438  {
2439  if( m_aSelEng.IsAlwaysAdding() )
2440  m_aSelEng.AddAlways( false );
2441  else
2442  m_aSelEng.AddAlways( true );
2443  }
2444  else
2445  bKeyUsed = false;
2446  break;
2447 
2448  case KEY_ADD:
2449  if (!m_pView->IsExpanded(m_pCursor))
2451  if (bMod1)
2452  ExpandAll();
2453  break;
2454 
2455  case KEY_A:
2456  if( bMod1 )
2457  SelAllDestrAnch( true );
2458  else
2459  bKeyUsed = false;
2460  break;
2461 
2462  case KEY_SUBTRACT:
2465  if (bMod1)
2467  break;
2468 
2469  case KEY_MULTIPLY:
2470  if( bMod1 )
2471  {
2472  // only try to expand/collapse if sublist is expandable,
2473  // otherwise ignore the key press
2474  if( IsExpandable() )
2475  {
2477  {
2479  ExpandAll();
2480  }
2481  else
2483  }
2484  }
2485  else
2486  bKeyUsed = false;
2487  break;
2488 
2489  case KEY_DIVIDE :
2490  if( bMod1 )
2491  SelAllDestrAnch( true );
2492  else
2493  bKeyUsed = false;
2494  break;
2495 
2496  case KEY_COMMA :
2497  if( bMod1 )
2498  SelAllDestrAnch( false );
2499  else
2500  bKeyUsed = false;
2501  break;
2502 
2503  case KEY_HOME :
2504  pNewCursor = m_pView->GetModel()->First();
2505 
2506  while( pNewCursor && !IsSelectable(pNewCursor) )
2507  {
2508  pNewCursor = m_pView->NextVisible(pNewCursor);
2509  }
2510 
2511  if( pNewCursor && pNewCursor != m_pCursor )
2512  {
2513 // SelAllDestrAnch( false );
2514  m_aSelEng.CursorPosChanging( bShift, bMod1 );
2515  SetCursor( pNewCursor );
2516  if( !IsEntryInView( pNewCursor ) )
2517  MakeVisible( pNewCursor );
2518  }
2519  else
2520  bKeyUsed = false;
2521  break;
2522 
2523  case KEY_END :
2524  pNewCursor = m_pView->GetModel()->Last();
2525 
2526  while( pNewCursor && !IsSelectable(pNewCursor) )
2527  {
2528  pNewCursor = m_pView->PrevVisible(pNewCursor);
2529  }
2530 
2531  if( pNewCursor && pNewCursor != m_pCursor)
2532  {
2533 // SelAllDestrAnch( false );
2534  m_aSelEng.CursorPosChanging( bShift, bMod1 );
2535  SetCursor( pNewCursor );
2536  if( !IsEntryInView( pNewCursor ) )
2537  MakeVisible( pNewCursor );
2538  }
2539  else
2540  bKeyUsed = false;
2541  break;
2542 
2543  case KEY_ESCAPE:
2544  case KEY_TAB:
2545  case KEY_DELETE:
2546  case KEY_BACKSPACE:
2547  // must not be handled because this quits dialogs and does other magic things...
2548  // if there are other single keys which should not be handled, they can be added here
2549  bKeyUsed = false;
2550  break;
2551 
2552  default:
2553  // is there any reason why we should eat the events here? The only place where this is called
2554  // is from SvTreeListBox::KeyInput. If we set bKeyUsed to true here, then the key input
2555  // is just silenced. However, we want SvLBox::KeyInput to get a chance, to do the QuickSelection
2556  // handling.
2557  // (The old code here which intentionally set bKeyUsed to sal_True said this was because of "quick search"
2558  // handling, but actually there was no quick search handling anymore. We just re-implemented it.)
2559  // #i31275# / 2009-06-16 / frank.schoenheit@sun.com
2560  bKeyUsed = false;
2561  break;
2562  }
2563  return bKeyUsed;
2564 }
2565 
2567 {
2568  if( m_pCursor )
2569  {
2570  m_pView->SetEntryFocus( m_pCursor, true );
2571  ShowCursor( true );
2572 // auskommentiert wg. deselectall
2573 // if( bSimpleTravel && !pView->IsSelected(pCursor) )
2574 // pView->Select( pCursor, true );
2575  }
2576  if( m_nStyle & WB_HIDESELECTION )
2577  {
2578  SvTreeListEntry* pEntry = m_pView->FirstSelected();
2579  while( pEntry )
2580  {
2581  InvalidateEntry( pEntry );
2582  pEntry = m_pView->NextSelected( pEntry );
2583  }
2584  }
2585 }
2586 
2588 {
2589  m_aEditIdle.Stop();
2590  if( m_pCursor )
2591  m_pView->SetEntryFocus( m_pCursor,false );
2592  ShowCursor( false );
2593 
2594  if( m_nStyle & WB_HIDESELECTION )
2595  {
2596  SvTreeListEntry* pEntry = m_pView ? m_pView->FirstSelected() : nullptr;
2597  while( pEntry )
2598  {
2599  InvalidateEntry( pEntry );
2600  pEntry = m_pView->NextSelected( pEntry );
2601  }
2602  }
2603 }
2604 
2605 
2606 // ********************************************************************
2607 // SelectionEngine
2608 // ********************************************************************
2609 
2610 void SvImpLBox::SelectEntry( SvTreeListEntry* pEntry, bool bSelect )
2611 {
2612  m_pView->Select( pEntry, bSelect );
2613 }
2614 
2616 {
2617  pImp = pImpl;
2618  pView = pV;
2619 }
2620 
2622 {
2623 }
2624 
2626 {
2627  pImp->BeginDrag();
2628 }
2629 
2631 {
2633 }
2634 
2636 {
2637  pImp->m_pAnchor = nullptr;
2638 }
2639 
2640 void ImpLBSelEng::SetCursorAtPoint(const Point& rPoint, bool bDontSelectAtCursor)
2641 {
2642  SvTreeListEntry* pNewCursor = pImp->MakePointVisible( rPoint );
2643  if( pNewCursor != pImp->m_pCursor )
2644  pImp->BeginScroll();
2645 
2646  if( pNewCursor )
2647  {
2648  // at SimpleTravel, the SetCursor is selected and the select handler is
2649  // called
2650  //if( !bDontSelectAtCursor && !pImp->bSimpleTravel )
2651  // pImp->SelectEntry( pNewCursor, true );
2652  pImp->SetCursor( pNewCursor, bDontSelectAtCursor );
2653  }
2654 }
2655 
2657 {
2658  SvTreeListEntry* pEntry = pImp->MakePointVisible( rPoint );
2659  if( pEntry )
2660  return pView->IsSelected(pEntry);
2661  return false;
2662 }
2663 
2665 {
2666  SvTreeListEntry* pEntry = pImp->MakePointVisible( rPoint );
2667  if( !pEntry )
2668  return;
2669  pImp->SelectEntry( pEntry, false );
2670 }
2671 
2673 {
2674  pImp->SelAllDestrAnch( false, false ); // don't reset SelectionEngine!
2676 }
2677 
2678 // ***********************************************************************
2679 // Selection
2680 // ***********************************************************************
2681 
2683 {
2684  SvTreeListEntry* pEntry;
2685  sal_uLong nAnchorVisPos = m_pView->GetVisiblePos( m_pAnchor );
2686  sal_uLong nOldVisPos = m_pView->GetVisiblePos( pOldCursor );
2687  sal_uLong nNewVisPos = m_pView->GetVisiblePos( pNewCursor );
2688 
2689  if( nOldVisPos > nAnchorVisPos ||
2690  ( nAnchorVisPos==nOldVisPos && nNewVisPos > nAnchorVisPos) )
2691  {
2692  if( nNewVisPos > nOldVisPos )
2693  {
2694  pEntry = pOldCursor;
2695  while( pEntry && pEntry != pNewCursor )
2696  {
2697  m_pView->Select( pEntry );
2698  pEntry = m_pView->NextVisible(pEntry);
2699  }
2700  if( pEntry )
2701  m_pView->Select( pEntry );
2702  return;
2703  }
2704 
2705  if( nNewVisPos < nAnchorVisPos )
2706  {
2707  pEntry = m_pAnchor;
2708  while( pEntry && pEntry != pOldCursor )
2709  {
2710  m_pView->Select( pEntry, false );
2711  pEntry = m_pView->NextVisible(pEntry);
2712  }
2713  if( pEntry )
2714  m_pView->Select( pEntry, false );
2715 
2716  pEntry = pNewCursor;
2717  while( pEntry && pEntry != m_pAnchor )
2718  {
2719  m_pView->Select( pEntry );
2720  pEntry = m_pView->NextVisible(pEntry);
2721  }
2722  if( pEntry )
2723  m_pView->Select( pEntry );
2724  return;
2725  }
2726 
2727  if( nNewVisPos < nOldVisPos )
2728  {
2729  pEntry = m_pView->NextVisible(pNewCursor);
2730  while( pEntry && pEntry != pOldCursor )
2731  {
2732  m_pView->Select( pEntry, false );
2733  pEntry = m_pView->NextVisible(pEntry);
2734  }
2735  if( pEntry )
2736  m_pView->Select( pEntry, false );
2737  return;
2738  }
2739  }
2740  else
2741  {
2742  if( nNewVisPos < nOldVisPos ) // enlarge selection
2743  {
2744  pEntry = pNewCursor;
2745  while( pEntry && pEntry != pOldCursor )
2746  {
2747  m_pView->Select( pEntry );
2748  pEntry = m_pView->NextVisible(pEntry);
2749  }
2750  if( pEntry )
2751  m_pView->Select( pEntry );
2752  return;
2753  }
2754 
2755  if( nNewVisPos > nAnchorVisPos )
2756  {
2757  pEntry = pOldCursor;
2758  while( pEntry && pEntry != m_pAnchor )
2759  {
2760  m_pView->Select( pEntry, false );
2761  pEntry = m_pView->NextVisible(pEntry);
2762  }
2763  if( pEntry )
2764  m_pView->Select( pEntry, false );
2765  pEntry = m_pAnchor;
2766  while( pEntry && pEntry != pNewCursor )
2767  {
2768  m_pView->Select( pEntry );
2769  pEntry = m_pView->NextVisible(pEntry);
2770  }
2771  if( pEntry )
2772  m_pView->Select( pEntry );
2773  return;
2774  }
2775 
2776  if( nNewVisPos > nOldVisPos )
2777  {
2778  pEntry = pOldCursor;
2779  while( pEntry && pEntry != pNewCursor )
2780  {
2781  m_pView->Select( pEntry, false );
2782  pEntry = m_pView->NextVisible(pEntry);
2783  }
2784  return;
2785  }
2786  }
2787 }
2788 
2790  bool bSelect, bool bDestroyAnchor, bool bSingleSelToo )
2791 {
2792  SvTreeListEntry* pEntry;
2794  if( bSelect && m_bSimpleTravel )
2795  {
2796  if( m_pCursor && !m_pView->IsSelected( m_pCursor ))
2797  {
2798  m_pView->Select( m_pCursor );
2799  }
2800  return;
2801  }
2802  if( !bSelect && m_pView->GetSelectionCount() == 0 )
2803  {
2804  if( m_bSimpleTravel && ( !GetUpdateMode() || !m_pCursor) )
2806  return;
2807  }
2808  if( bSelect && m_pView->GetSelectionCount() == m_pView->GetEntryCount())
2809  return;
2810  if( !bSingleSelToo && m_bSimpleTravel )
2811  return;
2812 
2813  if( !bSelect && m_pView->GetSelectionCount()==1 && m_pCursor &&
2815  {
2816  m_pView->Select( m_pCursor, false );
2817  if( bDestroyAnchor )
2818  DestroyAnchor(); // delete anchor & reset SelectionEngine
2819  else
2820  m_pAnchor = nullptr; // always delete internal anchor
2821  return;
2822  }
2823 
2824  if( m_bSimpleTravel && !m_pCursor && !GetUpdateMode() )
2826 
2827  ShowCursor( false );
2828  bool bUpdate = GetUpdateMode();
2829 
2830  m_nFlags |= LBoxFlags::IgnoreSelect; // EntryInserted should not do anything
2831  pEntry = m_pTree->First();
2832  while( pEntry )
2833  {
2834  if( m_pView->Select( pEntry, bSelect ) )
2835  {
2836  if( bUpdate && m_pView->IsEntryVisible(pEntry) )
2837  {
2838  long nY = GetEntryLine( pEntry );
2839  if( IsLineVisible( nY ) )
2840  InvalidateEntry(pEntry);
2841  }
2842  }
2843  pEntry = m_pTree->Next( pEntry );
2844  }
2846 
2847  if( bDestroyAnchor )
2848  DestroyAnchor(); // delete anchor & reset SelectionEngine
2849  else
2850  m_pAnchor = nullptr; // always delete internal anchor
2851  ShowCursor( true );
2852 }
2853 
2855 {
2856  m_aSelEng.SetSelectionMode( eSelMode);
2857  if( eSelMode == SelectionMode::Single )
2858  m_bSimpleTravel = true;
2859  else
2860  m_bSimpleTravel = false;
2861  if( (m_nStyle & WB_SIMPLEMODE) && (eSelMode == SelectionMode::Multiple) )
2862  m_aSelEng.AddAlways( true );
2863 }
2864 
2865 // ***********************************************************************
2866 // Drag & Drop
2867 // ***********************************************************************
2868 
2870 {
2871  if( eDDMode != DragDropMode::NONE && eDDMode != DragDropMode::APP_DROP )
2872  {
2874  m_aSelEng.EnableDrag( true );
2875  }
2876  else
2877  {
2879  m_aSelEng.EnableDrag( false );
2880  }
2881 }
2882 
2884 {
2886  if( !m_bAsyncBeginDrag )
2887  {
2888  BeginScroll();
2890  EndScroll();
2891  }
2892  else
2893  {
2896  }
2897 }
2898 
2899 IMPL_LINK_NOARG(SvImpLBox, BeginDragHdl, Timer *, void)
2900 {
2901  m_pView->StartDrag( 0, m_aAsyncBeginDragPos );
2902 }
2903 
2905 {
2906  if (pEntry)
2907  {
2908 
2909  SvViewDataEntry* pViewData = m_pView->GetViewData(pEntry);
2910  pViewData->SetDragTarget(bShow);
2911 #ifdef MACOSX
2912  // in MacOS we need to draw directly (as we are synchronous) or no invalidation happens
2913  m_pView->PaintEntry1(*pEntry, GetEntryLine(pEntry), *m_pView);
2914 #else
2915  InvalidateEntry(pEntry);
2916 #endif
2917  }
2918 }
2919 
2920 void SvImpLBox::Command( const CommandEvent& rCEvt )
2921 {
2922  CommandEventId nCommand = rCEvt.GetCommand();
2923 
2924  if( nCommand == CommandEventId::ContextMenu )
2925  m_aEditIdle.Stop();
2926 
2927  // scroll mouse event?
2928  if (nCommand == CommandEventId::Wheel ||
2929  nCommand == CommandEventId::StartAutoScroll ||
2930  nCommand == CommandEventId::AutoScroll ||
2931  nCommand == CommandEventId::Gesture)
2932  {
2934  return;
2935  }
2936 
2938  {
2939  Point aPopupPos;
2940  bool bClickedIsFreePlace = false;
2941  std::stack<SvTreeListEntry*> aSelRestore;
2942 
2943  if( rCEvt.IsMouseEvent() )
2944  { // change selection, if mouse position doesn't fit to selection
2945 
2946  aPopupPos = rCEvt.GetMousePosPixel();
2947 
2948  SvTreeListEntry* pClickedEntry = GetEntry( aPopupPos );
2949  if( pClickedEntry )
2950  { // mouse in non empty area
2951  bool bClickedIsSelected = false;
2952 
2953  // collect the currently selected entries
2954  SvTreeListEntry* pSelected = m_pView->FirstSelected();
2955  while( pSelected )
2956  {
2957  bClickedIsSelected |= ( pClickedEntry == pSelected );
2958  pSelected = m_pView->NextSelected( pSelected );
2959  }
2960 
2961  // if the entry which the user clicked at is not selected
2962  if( !bClickedIsSelected )
2963  { // deselect all other and select the clicked one
2964  m_pView->SelectAll( false );
2965  m_pView->SetCursor( pClickedEntry );
2966  }
2967  }
2969  {
2970  bClickedIsFreePlace = true;
2971  sal_Int32 nSelectedEntries = m_pView->GetSelectionCount();
2972  SvTreeListEntry* pSelected = m_pView->FirstSelected();
2973  for(sal_Int32 nSel = 0; nSel < nSelectedEntries; nSel++ )
2974  {
2975  aSelRestore.push(pSelected);
2976  pSelected = m_pView->NextSelected( pSelected );
2977  }
2978  m_pView->SelectAll( false );
2979  }
2980  else
2981  { // deselect all
2982  m_pView->SelectAll( false );
2983  }
2984 
2985 
2986  }
2987  else
2988  { // key event (or at least no mouse event)
2989  sal_Int32 nSelectionCount = m_pView->GetSelectionCount();
2990 
2991  if( nSelectionCount )
2992  { // now always take first visible as base for positioning the menu
2993  SvTreeListEntry* pSelected = m_pView->FirstSelected();
2994  while( pSelected )
2995  {
2996  if( IsEntryInView( pSelected ) )
2997  break;
2998 
2999  pSelected = m_pView->NextSelected( pSelected );
3000  }
3001 
3002  if( !pSelected )
3003  {
3004  // no one was visible
3005  pSelected = m_pView->FirstSelected();
3006  m_pView->MakeVisible( pSelected );
3007  }
3008 
3009  aPopupPos = m_pView->GetFocusRect( pSelected, m_pView->GetEntryPosition( pSelected ).Y() ).Center();
3010  }
3011  else
3012  aPopupPos = Point( 0, 0 );
3013  }
3014 
3015  {
3017  if (pPopup)
3018  {
3019  // do action for selected entry in popup menu
3020  sal_uInt16 nMenuAction = pPopup->Execute( m_pView, aPopupPos );
3021  if ( nMenuAction )
3022  m_pView->ExecuteContextMenuAction( nMenuAction );
3023  pPopup.disposeAndClear();
3024  }
3025  }
3026 
3027  if( bClickedIsFreePlace )
3028  {
3029  while(!aSelRestore.empty())
3030  {
3031  SvTreeListEntry* pEntry = aSelRestore.top();
3032  //#i19717# the entry is maybe already deleted
3033  bool bFound = false;
3034  for(sal_uLong nEntry = 0; nEntry < m_pView->GetEntryCount(); nEntry++)
3035  if(pEntry == m_pView->GetEntry(nEntry))
3036  {
3037  bFound = true;
3038  break;
3039  }
3040  if(bFound)
3041  SetCurEntry( pEntry );
3042  aSelRestore.pop();
3043  }
3044  }
3045  }
3046  else
3047  {
3048  const Point& rPos = rCEvt.GetMousePosPixel();
3049  if( rPos.X() < m_aOutputSize.Width() && rPos.Y() < m_aOutputSize.Height() )
3050  m_aSelEng.Command( rCEvt );
3051  }
3052 }
3053 
3055 {
3057  {
3059  }
3060 }
3061 
3063 {
3065  {
3068  }
3069 }
3070 
3071 
3073 {
3074  Point aPos( m_pView->GetMapMode().GetOrigin() );
3075  aPos.setX( aPos.X() * -1 );
3076  tools::Rectangle aRect( aPos, m_aOutputSize );
3077  return aRect;
3078 }
3079 
3081 {
3083 }
3084 
3086 {
3089  )
3090  SelAllDestrAnch( false );
3091  if ( pEntry )
3092  MakeVisible( pEntry );
3093  SetCursor( pEntry );
3094  if ( pEntry && ( m_aSelEng.GetSelectionMode() != SelectionMode::NONE ) )
3095  m_pView->Select( pEntry );
3096 }
3097 
3098 IMPL_LINK_NOARG(SvImpLBox, EditTimerCall, Timer *, void)
3099 {
3100  if( !m_pView->IsInplaceEditingEnabled() )
3101  return;
3102 
3103  bool bIsMouseTriggered = m_aEditClickPos.X() >= 0;
3104  if ( bIsMouseTriggered )
3105  {
3106  Point aCurrentMousePos = m_pView->GetPointerPosPixel();
3107  if ( ( std::abs( aCurrentMousePos.X() - m_aEditClickPos.X() ) > 5 )
3108  || ( std::abs( aCurrentMousePos.Y() - m_aEditClickPos.Y() ) > 5 )
3109  )
3110  {
3111  return;
3112  }
3113  }
3114 
3115  SvTreeListEntry* pEntry = GetCurEntry();
3116  if( pEntry )
3117  {
3118  ShowCursor( false );
3119  m_pView->ImplEditEntry( pEntry );
3120  ShowCursor( true );
3121  }
3122 }
3123 
3124 bool SvImpLBox::RequestHelp( const HelpEvent& rHEvt )
3125 {
3126  if( rHEvt.GetMode() & HelpEventMode::QUICK )
3127  {
3129  if( !GetVisibleArea().IsInside( aPos ))
3130  return false;
3131 
3132  SvTreeListEntry* pEntry = GetEntry( aPos );
3133  if( pEntry )
3134  {
3135  // recalculate text rectangle
3136  SvLBoxTab* pTab;
3137  SvLBoxItem* pItem = m_pView->GetItem( pEntry, aPos.X(), &pTab );
3138  if (!pItem || pItem->GetType() != SvLBoxItemType::String)
3139  return false;
3140 
3141  aPos = GetEntryPosition( pEntry );
3142  aPos.setX( m_pView->GetTabPos( pEntry, pTab ) ); //pTab->GetPos();
3143  Size aSize(pItem->GetWidth(m_pView, pEntry), pItem->GetHeight(m_pView, pEntry));
3144  SvLBoxTab* pNextTab = NextTab( pTab );
3145  bool bItemClipped = false;
3146  // is the item cut off by its right neighbor?
3147  if( pNextTab && m_pView->GetTabPos(pEntry,pNextTab) < aPos.X()+aSize.Width() )
3148  {
3149  aSize.setWidth( pNextTab->GetPos() - pTab->GetPos() );
3150  bItemClipped = true;
3151  }
3152  tools::Rectangle aItemRect( aPos, aSize );
3153 
3154  tools::Rectangle aViewRect( GetVisibleArea() );
3155 
3156  if( bItemClipped || !aViewRect.IsInside( aItemRect ) )
3157  {
3158  // clip the right edge of the item at the edge of the view
3159  //if( aItemRect.Right() > aViewRect.Right() )
3160  // aItemRect.Right() = aViewRect.Right();
3161 
3162  Point aPt = m_pView->OutputToScreenPixel( aItemRect.TopLeft() );
3163  aItemRect.SetLeft( aPt.X() );
3164  aItemRect.SetTop( aPt.Y() );
3165  aPt = m_pView->OutputToScreenPixel( aItemRect.BottomRight() );
3166  aItemRect.SetRight( aPt.X() );
3167  aItemRect.SetBottom( aPt.Y() );
3168 
3169  Help::ShowQuickHelp( m_pView, aItemRect,
3170  static_cast<SvLBoxString*>(pItem)->GetText(), QuickHelpFlags::Left | QuickHelpFlags::VCenter );
3171  return true;
3172  }
3173  }
3174  }
3175  return false;
3176 }
3177 
3179 {
3180  sal_uInt16 nTabCount = m_pView->TabCount();
3181  if( nTabCount <= 1 )
3182  return nullptr;
3183  for( int nTab=0; nTab < (nTabCount-1); nTab++)
3184  {
3185  if( m_pView->aTabs[nTab].get() == pTab )
3186  return m_pView->aTabs[nTab+1].get();
3187  }
3188  return nullptr;
3189 }
3190 
3192 {
3193  DestroyAnchor();
3195 }
3196 
3197 void SvImpLBox::SetUpdateMode( bool bMode )
3198 {
3199  if( m_bUpdateMode != bMode )
3200  {
3201  m_bUpdateMode = bMode;
3202  if( m_bUpdateMode )
3203  UpdateAll( false );
3204  }
3205 }
3206 
3208 {
3210  {
3212  m_pView->SetTabs();
3214  }
3215 
3216  sal_uInt16 nLastTab = m_pView->aTabs.size() - 1;
3217  sal_uInt16 nLastItem = pEntry->ItemCount() - 1;
3218  if( !m_pView->aTabs.empty() && nLastItem != USHRT_MAX )
3219  {
3220  if( nLastItem < nLastTab )
3221  nLastTab = nLastItem;
3222 
3223  SvLBoxTab* pTab = m_pView->aTabs[ nLastTab ].get();
3224  SvLBoxItem& rItem = pEntry->GetItem( nLastTab );
3225 
3226  long nTabPos = m_pView->GetTabPos( pEntry, pTab );
3227 
3228  long nMaxRight = GetOutputSize().Width();
3229  Point aPos( m_pView->GetMapMode().GetOrigin() );
3230  aPos.setX( aPos.X() * -1 ); // conversion document coordinates
3231  nMaxRight = nMaxRight + aPos.X() - 1;
3232 
3233  long nNextTab = nTabPos < nMaxRight ? nMaxRight : nMaxRight + 50;
3234  long nTabWidth = nNextTab - nTabPos + 1;
3235  auto nItemSize = rItem.GetWidth(m_pView,pEntry);
3236  long nOffset = pTab->CalcOffset( nItemSize, nTabWidth );
3237 
3238  long nRight = nTabPos + nOffset + nItemSize;
3239  if( nRight > m_nMostRight )
3240  {
3241  m_nMostRight = nRight;
3242  m_pMostRightEntry = pEntry;
3243  return true;
3244  }
3245  }
3246  return false;
3247 }
3248 
3249 void SvImpLBox::FindMostRight( SvTreeListEntry const * pEntryToIgnore )
3250 {
3251  m_nMostRight = -1;
3252  m_pMostRightEntry = nullptr;
3253  if( !m_pView->GetModel() )
3254  return;
3255 
3256  SvTreeListEntry* pEntry = m_pView->FirstVisible();
3257  while( pEntry )
3258  {
3259  if( pEntry != pEntryToIgnore )
3260  SetMostRight( pEntry );
3261  pEntry = m_pView->NextVisible( pEntry );
3262  }
3263 }
3264 
3266 {
3267  if( !pParent )
3268  FindMostRight( pEntryToIgnore );
3269  else
3270  FindMostRight_Impl( pParent, pEntryToIgnore );
3271 }
3272 
3274 {
3275  SvTreeListEntries& rList = m_pTree->GetChildList( pParent );
3276 
3277  size_t nCount = rList.size();
3278  for( size_t nCur = 0; nCur < nCount; nCur++ )
3279  {
3280  SvTreeListEntry* pChild = rList[nCur].get();
3281  if( pChild != pEntryToIgnore )
3282  {
3283  SetMostRight( pChild );
3284  if( pChild->HasChildren() && m_pView->IsExpanded( pChild ))
3285  FindMostRight_Impl( pChild, pEntryToIgnore );
3286  }
3287  }
3288 }
3289 
3291 {
3293  m_nCurUserEvent == nullptr )
3294  {
3296  }
3297 }
3298 
3300 {
3302 }
3303 
3304 IMPL_LINK(SvImpLBox, MyUserEvent, void*, pArg, void )
3305 {
3306  m_nCurUserEvent = nullptr;
3307  if( !pArg )
3308  {
3309  m_pView->Invalidate();
3310  m_pView->Update();
3311  }
3312  else
3313  {
3314  FindMostRight( nullptr );
3315  ShowVerSBar();
3316  m_pView->Invalidate( GetVisibleArea() );
3317  }
3318 }
3319 
3320 
3322 {
3323  if( m_nCurUserEvent != nullptr )
3324  {
3326  m_nCurUserEvent = nullptr;
3327  }
3328 }
3329 
3331 {
3332  if( pEntry )
3333  {
3334  long nY = GetEntryLine( const_cast<SvTreeListEntry*>(pEntry) );
3335  tools::Rectangle aRect = m_pView->GetFocusRect( const_cast<SvTreeListEntry*>(pEntry), nY );
3336  vcl::Region aOldClip( m_pView->GetClipRegion());
3337  vcl::Region aClipRegion( GetClipRegionRect() );
3338  m_pView->SetClipRegion( aClipRegion );
3339  m_pView->ShowFocus( aRect );
3340  m_pView->SetClipRegion( aOldClip );
3341 
3342  }
3343  else
3344  {
3345  m_pView->HideFocus();
3346  }
3347 }
3348 
3349 
3351 {
3352  if ( s_pDefCollapsed )
3353  // assume that all or nothing is initialized
3354  return;
3355 
3356  s_pDefCollapsed = new Image(StockImage::Yes, RID_BMP_TREENODE_COLLAPSED);
3357  s_pDefExpanded = new Image(StockImage::Yes, RID_BMP_TREENODE_EXPANDED);
3358 }
3359 
3360 
3362 {
3364  return *s_pDefExpanded;
3365 }
3366 
3367 
3369 {
3371  return *s_pDefCollapsed;
3372 }
3373 
3374 
3375 void SvImpLBox::CallEventListeners( VclEventId nEvent, void* pData )
3376 {
3377  if ( m_pView )
3378  m_pView->CallImplEventListeners( nEvent, pData);
3379 }
3380 
3381 
3382 bool SvImpLBox::SetCurrentTabPos( sal_uInt16 _nNewPos )
3383 {
3384  bool bRet = false;
3385 
3386  if ( m_pView && _nNewPos < ( m_pView->TabCount() - 2 ) )
3387  {
3388  m_nCurTabPos = _nNewPos;
3389  ShowCursor( true );
3390  bRet = true;
3391  }
3392 
3393  return bRet;
3394 }
3395 
3396 
3398 {
3399  if( pEntry )
3400  {
3401  SvViewDataEntry* pViewDataNewCur = m_pView->GetViewDataEntry(pEntry);
3402  return (pViewDataNewCur == nullptr) || pViewDataNewCur->IsSelectable();
3403  }
3404  else
3405  {
3406  return false;
3407  }
3408 }
3409 
3410 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Point TopLeft() const
#define KEY_SUBTRACT
Definition: keycodes.hxx:128
long Width() const
vcl::Region GetClipRegion() const
Size GetSizePixel() const
Definition: Image.cxx:86
#define KEY_F2
Definition: keycodes.hxx:84
void EntryMoved(SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:1765
bool SelMouseButtonDown(const MouseEvent &rMEvt)
Definition: seleng.cxx:115
const Color & GetShadowColor() const
void MovingEntry(SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:1735
bool m_bContextMenuHandling
Definition: svimpbox.hxx:141
void SetCursorAtPoint(const Point &rPoint, bool bDontSelectAtCursor=false) override
Definition: svimpbox.cxx:2640
bool RequestHelp(const HelpEvent &rHEvt)
Definition: svimpbox.cxx:3124
void SelectEntry(SvTreeListEntry *pEntry, bool bSelect)
Definition: svimpbox.cxx:2610
long GetVisibleSize() const
Definition: scrbar.hxx:128
void CaptureMouse()
Definition: mouse.cxx:439
#define KEY_BACKSPACE
Definition: keycodes.hxx:122
const Wallpaper & GetBackground() const
Definition: outdev.hxx:631
void HideFocus()
Definition: window2.cxx:91
SvTreeListEntry * NextSelected(SvTreeListEntry *pEntry) const
Definition: treelist.hxx:260
bool IsSelectable() const
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect)
Definition: svimpbox.cxx:870
bool GetUpdateMode() const
Definition: svimpbox.hxx:332
#define KEY_DELETE
Definition: keycodes.hxx:125
long GetHeight() const
void MouseMove(const MouseEvent &)
Definition: svimpbox.cxx:2091
IMPL_LINK_NOARG(SvImpLBox, EndScrollHdl, ScrollBar *, void)
Definition: svimpbox.cxx:296
Range GetRange() const
Definition: scrbar.hxx:120
void InvalidateEntry(SvTreeListEntry *)
Definition: treelist.cxx:1030
virtual void AdjustScrollBars(Size &rSize)
Definition: svimpbox.cxx:1164
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption)
Request rendering of a particular control and/or part.
sal_uInt16 TabCount() const
void SetSelectionMode(SelectionMode eMode)
Definition: seleng.cxx:62
#define KEY_SPACE
Definition: keycodes.hxx:123
long AdjustWidth(long n)
SvLBoxTab * m_pActiveTab
Definition: svimpbox.hxx:100
long AdjustX(long nHorzMove)
CommandEventId
void SetNoAutoCurEntry(bool b)
Definition: svimpbox.cxx:242
#define KEY_TAB
Definition: keycodes.hxx:121
IMPL_LINK(SvImpLBox, ScrollUpDownHdl, ScrollBar *, pScrollBar, void)
Definition: svimpbox.cxx:308
#define KEY_PAGEDOWN
Definition: keycodes.hxx:117
short m_nHorSBarHeight
Definition: svimpbox.hxx:133
bool IsEntryVisible(SvTreeListEntry *pEntry) const
Definition: treelist.hxx:286
const Image & GetExpandedNodeBmp()
Definition: svimpbox.hxx:370
virtual SvTreeListEntry * GetEntry(const Point &rPos) const
Definition: svimpbox.cxx:802
A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for refer...
Definition: button.hxx:32
long Height() const
#define KEY_PAGEUP
Definition: keycodes.hxx:116
SvTreeList * GetModel() const
SvTreeListEntry * PrevVisible(SvTreeListEntry *pEntry) const
Definition: treelist.hxx:243
bool IsEditingActive() const
SvTLEntryFlags GetFlags() const
Size m_aOutputSize
Definition: svimpbox.hxx:215
virtual void UpdateAll(bool bInvalidateCompleteView)
Definition: svimpbox.cxx:696
void UpdateStringSorter()
Definition: svimpbox.cxx:130
const SvTreeListEntries & GetChildList(SvTreeListEntry *pParent) const
Definition: treelist.cxx:1549
sal_uIntPtr sal_uLong
void SetEntryHeight()
Definition: svimpbox.cxx:1459
void EndScroll()
Definition: svimpbox.cxx:3062
sal_uLong GetEntryCount() const
void disposeAndClear()
Definition: vclptr.hxx:200
void ScrollToAbsPos(long nPos)
Definition: svimpbox.cxx:986
SvLBoxItem * GetItem(SvTreeListEntry *, long nX, SvLBoxTab **ppTab)
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:704
void BeginDrag()
Definition: svimpbox.cxx:2883
const Color & GetFaceColor() const
void SetFlags(SvTLEntryFlags nFlags)
sal_uInt16 GetDepth(const SvTreeListEntry *pEntry) const
Definition: treelist.cxx:102
virtual Size GetSizePixel() const
Definition: window.cxx:2365
void EntryExpanded(SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:1481
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1251
SvLBoxTab * GetFirstDynamicTab() const
void MakeVisible(SvTreeListEntry *pEntry, bool bMoveToTop=false)
Definition: svimpbox.cxx:946
void DrawNet(vcl::RenderContext &rRenderContext)
Definition: svimpbox.cxx:1015
void GetFocus()
Definition: svimpbox.cxx:2566
void PositionScrollBars(Size &rOSize, sal_uInt16 nMask)
Definition: svimpbox.cxx:1132
static Image * s_pDefCollapsed
Definition: svimpbox.hxx:108
SvTreeList * m_pTree
Definition: svimpbox.hxx:95
VclPtr< SvTreeListBox > m_pView
Definition: svimpbox.hxx:210
long GetThumbPos() const
Definition: scrbar.hxx:122
bool IsSelectionAtPoint(const Point &rPoint) override
Definition: svimpbox.cxx:2656
static const Image & GetDefaultCollapsedNodeImage()
Definition: svimpbox.cxx:3368
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
Post a user event to the default window.
Definition: svapp.cxx:996
const MapMode & GetMapMode() const
Definition: outdev.hxx:1674
virtual void StartDrag(sal_Int8 nAction, const Point &rPosPixel) override
sal_uInt16 GetCode() const
Definition: keycod.hxx:53
SelectionMode
Definition: vclenum.hxx:26
void UpdateContextBmpWidthMax(SvTreeListEntry const *pEntry)
Definition: svimpbox.cxx:202
void SetCursor(SvTreeListEntry *pEntry, bool bForceNoSelect=false)
VCL_DLLPRIVATE void PaintEntry1(SvTreeListEntry &, long nLine, vcl::RenderContext &rRenderContext)
sal_uInt16 Execute(vcl::Window *pWindow, const Point &rPopupPos)
Definition: menu.cxx:2767
short nContextBmpWidthMax
WinBits const WB_VSCROLL
SelectionMode GetSelectionMode() const
void StopUserEvent()
Definition: svimpbox.cxx:3321
long GetPos() const
void Command(const CommandEvent &rCEvt)
Definition: seleng.cxx:349
sal_uLong m_nVisibleCount
Definition: svimpbox.hxx:220
virtual bool DoubleClickHdl()
LBoxFlags
Definition: svimpbox.hxx:66
View-dependent data for a tree list entry created in the virtual function SvTreeListBox::CreateViewDa...
Center
bool HandleScrollCommand(const CommandEvent &rCmd, ScrollBar *pHScrl, ScrollBar *pVScrl)
Definition: window2.cxx:609
void EnableDrag(bool bOn)
Definition: seleng.hxx:179
void EntryRemoved()
Definition: svimpbox.cxx:1686
#define KEY_LEFT
Definition: keycodes.hxx:112
void CursorPosChanging(bool bShift, bool bMod1)
Definition: seleng.cxx:67
#define KEY_ADD
Definition: keycodes.hxx:127
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
void SetMapMode()
Definition: map.cxx:655
bool IsExpandable() const
Definition: svimpbox.cxx:3299
HelpEventMode GetMode() const
Definition: event.hxx:192
void SetCurEntry(SvTreeListEntry *)
Definition: svimpbox.cxx:3085
static const Image & GetDefaultExpandedNodeImage()
Definition: svimpbox.cxx:3361
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
SvTreeListEntry * MakePointVisible(const Point &rPoint)
Definition: svimpbox.cxx:818
void SetFocus(bool bFocus)
void Resize()
Definition: svimpbox.cxx:1292
const Image & GetBitmap2() const
Definition: svlbitm.hxx:274
long AdjustBottom(long nVertMoveDelta)
virtual ~SvImpLBox()
Definition: svimpbox.cxx:115
sal_uInt16 m_nCurTabPos
Definition: svimpbox.hxx:134
void InitScrollBarBox()
Definition: svimpbox.cxx:1285
void MakeVisible(SvTreeListEntry *pEntry)
bool mbNoAutoCurEntry
Definition: svimpbox.hxx:218
sal_uLong GetAbsPos(SvTreeListEntry const *pEntry) const
Definition: treelist.hxx:274
bool m_bAsyncBeginDrag
Definition: svimpbox.hxx:137
sal_uInt16 GetClicks() const
Definition: event.hxx:120
bool ButtonDownCheckCtrl(const MouseEvent &rMEvt, SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:1862
int GetHeight(const SvTreeListBox *pView, const SvTreeListEntry *pEntry) const
sal_Int64 WinBits
bool IsStateHilighted() const
Definition: svlbitm.hxx:189
virtual bool IsEntryInView(SvTreeListEntry *pEntry) const
Definition: svimpbox.cxx:1434
void SetEntryFocus(SvTreeListEntry *pEntry, bool bFocus)
Definition: treelist.cxx:1381
void SetAnchorSelection(SvTreeListEntry *pOld, SvTreeListEntry *pNewCursor)
Definition: svimpbox.cxx:2682
long Right() const
void MouseButtonUp(const MouseEvent &)
Definition: svimpbox.cxx:2078
void UpdateContextBmpWidthVectorFromMovedEntry(SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:180
DragDropMode
SvImpLBox(SvTreeListBox *pView, SvTreeList *, WinBits nWinStyle)
Definition: svimpbox.cxx:48
bool EntryReallyHit(SvTreeListEntry *pEntry, const Point &rPos, long nLine)
Definition: svimpbox.cxx:779
SvTreeListEntry * Next(SvTreeListEntry *pEntry, sal_uInt16 *pDepth=nullptr) const
Definition: treelist.cxx:467
VclPtr< ScrollBarBox > m_aScrBarBox
Definition: svimpbox.hxx:103
void setX(long nX)
Idle m_aAsyncBeginDragIdle
Definition: svimpbox.hxx:128
const SvTreeListEntry * GetParent(const SvTreeListEntry *pEntry) const
Definition: treelist.cxx:1563
void SetDragDropMode(DragDropMode eDDMode)
Definition: svimpbox.cxx:2869
SvTreeListEntry * FirstSelected() const
Definition: treelist.hxx:257
WinBits const WB_HSCROLL
bool IsMouseEvent() const
const Point & GetMousePosPixel() const
Definition: seleng.hxx:132
void RecalcFocusRect()
Definition: svimpbox.cxx:583
void Hide()
Definition: window.hxx:932
bool SetCurrentTabPos(sal_uInt16 _nNewPos)
Definition: svimpbox.cxx:3382
SvTreeListEntry * NextSibling() const
VclPtr< SvTreeListBox > pView
Definition: svimpbox.hxx:50
virtual void Start() override
Activates the timer task.
Definition: idle.cxx:34
VclEventId
Definition: vclevent.hxx:41
void InvalidateEntriesFrom(long nY) const
Definition: svimpbox.cxx:529
void EndEditing(bool bCancel=false)
void SetSelectionMode(SelectionMode eSelMode)
Definition: svimpbox.cxx:2854
#define KEY_A
Definition: keycodes.hxx:56
void SelectAll(bool bSelect, bool bPaint=true)
bool ButtonDownCheckExpand(const MouseEvent &, SvTreeListEntry *)
Definition: svimpbox.cxx:1955
bool m_bIsCellFocusEnabled
Definition: svimpbox.hxx:142
static void implInitDefaultNodeImages()
Definition: svimpbox.cxx:3350
WinBits const WB_HASLINESATROOT
long Top() const
const Size & GetOutputSize() const
Definition: svimpbox.hxx:317
virtual bool KeyInput(const KeyEvent &)
Definition: svimpbox.cxx:2143
void setY(long nY)
bool m_bSimpleTravel
Definition: svimpbox.hxx:222
virtual void PageDown(sal_uInt16 nDelta)
Definition: svimpbox.cxx:387
void CallImplEventListeners(VclEventId nEvent, void *pData)
ImplSVEvent * m_nCurUserEvent
Definition: svimpbox.hxx:214
void DrawLine(const Point &rStartPt, const Point &rEndPt)
Definition: line.cxx:88
SvTreeListEntry * GetRootLevelParent(SvTreeListEntry *pEntry) const
Definition: treelist.cxx:1038
virtual void NotifyScrolled()
void MouseButtonDown(const MouseEvent &)
Definition: svimpbox.cxx:1980
short GetEntryHeight() const
virtual tools::Rectangle GetFocusRect(SvTreeListEntry *, long nLine)
const LanguageTag & GetLanguageTag() const
SvTreeListEntry * NextVisible(SvTreeListEntry *pEntry, sal_uInt16 *pDepth=nullptr) const
Definition: treelist.hxx:240
void EntrySelected(SvTreeListEntry *pEntry, bool bSelect)
Definition: svimpbox.cxx:1589
void Update()
Definition: paint.cxx:1276
void DestroyAnchor() override
Definition: svimpbox.cxx:2635
SvTreeListEntry * pHdlEntry
const Point & GetMousePosPixel() const
Definition: event.hxx:191
bool IsChild(const SvTreeListEntry *pParent, const SvTreeListEntry *pChild) const
Definition: treelist.cxx:127
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
Remove user event based on event ID.
Definition: svapp.cxx:1024
void EndSelection()
Definition: svimpbox.cxx:3191
virtual void CursorUp()
Definition: svimpbox.cxx:365
Point BottomRight() const
void CreateAnchor() override
Definition: svimpbox.cxx:2630
void SetLineColor()
void OnCurrentEntryChanged()
bool HasViewData() const
Definition: treelist.cxx:1095
ImpLBSelEng(SvImpLBox *pImp, SvTreeListBox *pView)
Definition: svimpbox.cxx:2615
void CallEventListeners(VclEventId nEvent, void *pData=nullptr)
Definition: svimpbox.cxx:3375
size_t ItemCount() const
void SetTop(long v)
void ExpandSelectionOnMouseMove(bool bExpand=true)
Definition: seleng.hxx:154
long GetLineSize() const
Definition: scrbar.hxx:124
long m_nNextVerVisSize
Definition: svimpbox.hxx:223
sal_uLong GetAbsPos(const SvTreeListEntry *pEntry) const
Definition: treelist.cxx:847
#define DBG_ASSERT(sCon, aError)
const SvTreeListEntry * GetParent(const SvTreeListEntry *pEntry) const
Idle m_aEditIdle
Definition: svimpbox.hxx:147
SvTreeListEntry * PrevSibling() const
bool IsEditable() const
long AdjustY(long nVertMove)
void FindMostRight_Impl(SvTreeListEntry *pParent, SvTreeListEntry *EntryToIgnore)
Definition: svimpbox.cxx:3273
SvTreeListEntry * m_pAnchor
Definition: svimpbox.hxx:96
bool IsMod2() const
Definition: event.hxx:146
long m_nNodeBmpWidth
Definition: svimpbox.hxx:131
void NotifyTabsChanged()
Definition: svimpbox.cxx:3290
virtual void SetTabs()
bool SelMouseMove(const MouseEvent &rMEvt)
Definition: seleng.cxx:294
WinBits const WB_SIMPLEMODE
void SetVisibleSize(long nNewSize)
Definition: scrbar.cxx:1378
VclPtr< ScrollBar > m_aHorSBar
Definition: svimpbox.hxx:102
void SetSize(const Size &rSize)
virtual void KeyUp(bool bPageUp)
Definition: svimpbox.cxx:462
Point m_aEditClickPos
Definition: svimpbox.hxx:146
#define KEY_ESCAPE
Definition: keycodes.hxx:120
void SetRange(const Range &rRange)
Definition: scrbar.cxx:1339
const Color & GetColor() const
Definition: wall.cxx:204
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1156
void SetOrigin(const Point &rOrigin)
Definition: mapmod.cxx:102
bool SelMouseButtonUp(const MouseEvent &rMEvt)
Definition: seleng.cxx:237
WinBits m_nStyle
Definition: svimpbox.hxx:217
long Len() const
void SetRight(long v)
SvTreeListEntry * FirstVisible() const
Definition: treelist.hxx:237
std::unique_ptr< SvTreeList > pModel
Definition: treelist.hxx:216
bool IsSelected(SvTreeListEntry *pEntry) const
Definition: treelist.cxx:1372
SvTreeListEntry * FirstChild(SvTreeListEntry *pParent) const
bool MouseMoveCheckCtrl(const MouseEvent &rMEvt, SvTreeListEntry const *pEntry)
Definition: svimpbox.cxx:1881
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:304
void ShowFocusRect(const SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:3330
CommandEventId GetCommand() const
bool IsNodeButton(const Point &rPosPixel, SvTreeListEntry *pEntry) const
Definition: svimpbox.cxx:1932
#define KEY_F8
Definition: keycodes.hxx:90
void SetStateHilighted(bool bHilight)
Definition: svlbitm.hxx:215
SvViewDataEntry * GetViewDataEntry(SvTreeListEntry const *pEntry) const
long Bottom() const
virtual bool Collapse(SvTreeListEntry *pParent)
void ShowVerSBar()
Definition: svimpbox.cxx:1359
void DeselectAtPoint(const Point &rPoint) override
Definition: svimpbox.cxx:2664
SvImpLBox * pImp
Definition: svimpbox.hxx:49
void SetPageSize(long nNewSize)
Definition: scrbar.hxx:125
bool IsInside(const Point &rPOINT) const
void SelAllDestrAnch(bool bSelect, bool bDestroyAnchor=true, bool bSingleSelToo=false)
Definition: svimpbox.cxx:2789
const Image & GetBitmap1() const
Definition: svlbitm.hxx:268
tools::Rectangle GetVisibleArea() const
Definition: svimpbox.cxx:3072
SvTreeListEntry * Last() const
Definition: treelist.cxx:558
const AllSettings & GetSettings() const
Definition: outdev.hxx:420
bool ButtonUpCheckCtrl(const MouseEvent &rMEvt)
Definition: svimpbox.cxx:1908
ImpLBSelEng m_aFctSet
Definition: svimpbox.hxx:127
virtual sal_IntPtr GetTabPos(SvTreeListEntry *, SvLBoxTab *)
SvTreeListEntry * GetEntryAtVisPos(sal_uLong nVisPos) const
Definition: treelist.hxx:271
void DestroyAnchor()
Definition: svimpbox.hxx:323
#define KEY_COMMA
Definition: keycodes.hxx:132
void CollapsingEntry(SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:1543
const SvLBoxItem & GetItem(size_t nPos) const
virtual void PageUp(sal_uInt16 nDelta)
Definition: svimpbox.cxx:426
long GetPageSize() const
Definition: scrbar.hxx:126
virtual bool Expand(SvTreeListEntry *pParent)
bool IsRGBEqual(const Color &rColor) const
virtual Point GetEntryPosition(SvTreeListEntry *) const
Definition: svimpbox.hxx:400
static oslInterlockedCount s_nImageRefCount
Definition: svimpbox.hxx:110
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2825
std::unique_ptr< comphelper::string::NaturalStringSorter > m_pStringSorter
Definition: svimpbox.hxx:149
void GrabFocus()
Definition: window.cxx:2981
bool m_bSubLstOpDblClick
Definition: svimpbox.hxx:140
static void ShowQuickHelp(vcl::Window *pParent, const tools::Rectangle &rScreenRect, const OUString &rHelpText, QuickHelpFlags nStyle=QuickHelpFlags::NONE)
Definition: help.cxx:178
virtual void ShowFocus(const tools::Rectangle &rRect)
Definition: window2.cxx:49
#define DELETEZ(p)
long X() const
LBoxFlags m_nFlags
Definition: svimpbox.hxx:216
bool IsAddMode() const
Definition: seleng.hxx:163
#define KEY_END
Definition: keycodes.hxx:115
bool HasChildrenOnDemand() const
void SetCursor(SvTreeListEntry *pEntry, bool bForceNoSelect=false)
Definition: svimpbox.cxx:603
void CollapseTo(SvTreeListEntry *pParentToCollapse)
Definition: svimpbox.cxx:2110
Point GetEntryPosition(SvTreeListEntry *) const
#define KEY_DIVIDE
Definition: keycodes.hxx:130
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
Definition: window2.cxx:1257
virtual SvLBoxItemType GetType() const =0
void SetEndScrollHdl(const Link< ScrollBar *, void > &rLink)
Definition: scrbar.hxx:135
bool mbForceMakeVisible
Definition: svimpbox.hxx:144
long CalcOffset(long nItemLength, long nTabWidth)
void FindMostRight(SvTreeListEntry *pParent, SvTreeListEntry *EntryToIgnore)
Definition: svimpbox.cxx:3265
void SetLineSize(long nNewSize)
Definition: scrbar.hxx:123
const Point & GetMousePosPixel() const
void ShowCursor(bool bShow)
Definition: svimpbox.cxx:672
bool IsAtRootDepth(const SvTreeListEntry *pEntry) const
Definition: treelist.cxx:114
std::vector< std::unique_ptr< SvLBoxTab > > aTabs
SvTreeListEntry * Next(SvTreeListEntry *pEntry) const
SvTreeListEntry * LastSibling() const
void ReleaseMouse()
Definition: mouse.cxx:458
void SetVisibleArea(const tools::Rectangle &rNewArea)
Definition: seleng.hxx:114
tools::Rectangle GetClipRegionRect() const
Definition: svimpbox.cxx:860
SvTreeListEntry * m_pCursor
Definition: svimpbox.hxx:212
void PaintDDCursor(SvTreeListEntry *pEntry, bool bShow)
Definition: svimpbox.cxx:2904
WinBits const WB_HASLINES
#define KEY_RETURN
Definition: keycodes.hxx:119
SvTreeListEntry * LastVisible() const
Definition: treelist.hxx:246
void Invalidate()
Definition: svimpbox.cxx:3080
bool IsExpanded(SvTreeListEntry *pEntry) const
Definition: treelist.cxx:1345
bool m_bUpdateMode
Definition: svimpbox.hxx:136
const SvViewDataEntry * GetViewData(const SvTreeListEntry *pEntry) const
Definition: treelist.cxx:1389
int GetWidth(const SvTreeListBox *pView, const SvTreeListEntry *pEntry) const
static Image * s_pDefExpanded
Definition: svimpbox.hxx:109
SvTreeListEntry * First() const
long Max() const
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE) override
bool HasChildren() const
WinBits const WB_HIDESELECTION
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:53
virtual void Scroll(long nHorzScroll, long nVertScroll, ScrollFlags nFlags=ScrollFlags::NONE)
Definition: window.cxx:2945
bool IsAllExpanded(SvTreeListEntry *pEntry) const
Definition: treelist.cxx:1355
sal_uLong GetVisibleCount() const
Definition: treelist.hxx:234
bool IsShift() const
Definition: keycod.hxx:58
virtual SvTreeListEntry * GetClickedEntry(const Point &) const
Definition: svimpbox.cxx:757
#define KEY_DOWN
Definition: keycodes.hxx:110
void ClickHdl(SvTreeListEntry *)
Definition: svlbitm.cxx:290
void Stop()
Definition: scheduler.cxx:593
#define KEY_MULTIPLY
Definition: keycodes.hxx:129
void LoseFocus()
Definition: svimpbox.cxx:2587
SvTreeListEntry * pEdEntry
SvLBoxTab * GetTab(SvTreeListEntry const *, SvLBoxItem const *) const
SvLBoxTab * NextTab(SvLBoxTab const *)
Definition: svimpbox.cxx:3178
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
SelectionEngine m_aSelEng
Definition: svimpbox.hxx:219
WinBits const WB_NOINITIALSELECTION
void CalcCellFocusRect(SvTreeListEntry const *pEntry, tools::Rectangle &rRect)
Definition: svimpbox.cxx:216
bool IsVisible() const
Definition: window2.cxx:1091
long m_nNodeBmpTabDistance
Definition: svimpbox.hxx:224
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
bool IsLeft() const
Definition: event.hxx:133
SvTreeListEntry * GetEntry(SvTreeListEntry *pParent, sal_uLong nPos) const
void SetScrollHdl(const Link< ScrollBar *, void > &rLink)
Definition: scrbar.hxx:133
Definition: image.hxx:40
bool IsMod1() const
Definition: keycod.hxx:60
bool IsSelectable(const SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:3397
void Clear()
Definition: svimpbox.cxx:248
bool m_bSubLstOpLR
Definition: svimpbox.hxx:139
SvTreeListEntry * First() const
Definition: treelist.cxx:459
void SetBottom(long v)
const SvLBoxItem * GetFirstItem(SvLBoxItemType eType) const
#define NODE_BMP_TABDIST_NOTVALID
Definition: svimpbox.hxx:85
long m_nMostRight
Definition: svimpbox.hxx:132
Reference< XComponentContext > getProcessComponentContext()
short m_nVerSBarWidth
Definition: svimpbox.hxx:133
SvTreeListEntry * Last() const
void SetInvokeHandler(const Link< Timer *, void > &rLink)
Definition: timer.hxx:56
void AddAlways(bool bOn)
Definition: seleng.hxx:187
void SetUpdateMode(bool bMode)
Definition: svimpbox.cxx:3197
const Point & GetPosPixel() const
Definition: event.hxx:117
virtual void CursorDown()
Definition: svimpbox.cxx:345
virtual void ExecuteContextMenuAction(sal_uInt16 nSelectedPopupEntry)
void EntryCollapsed(SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:1502
const Point & GetOrigin() const
Definition: mapmod.cxx:170
virtual void InvalidateEntry(long nY) const
Definition: svimpbox.cxx:539
bool IsLineVisible(long nY) const
Definition: svimpbox.hxx:405
These events should run very fast!
WinBits const WB_AUTOHSCROLL
void SetFunctionSet(FunctionSet *pFuncs)
Definition: seleng.hxx:128
const Image & GetCollapsedNodeBmp()
Definition: svimpbox.hxx:375
SvTreeListEntry * m_pStartEntry
Definition: svimpbox.hxx:213
virtual long GetEntryLine(SvTreeListEntry *pEntry) const
Definition: svimpbox.cxx:1447
virtual void SyncVerThumb()
Definition: svimpbox.cxx:1423
void SetStyle(WinBits i_nWinStyle)
Definition: svimpbox.cxx:235
SvTreeListEntry * GetEntryAtAbsPos(sal_uLong nAbsPos) const
Definition: treelist.hxx:268
void FillView()
Definition: svimpbox.cxx:1314
#define KEY_HOME
Definition: keycodes.hxx:114
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
void SetLeft(long v)
void SetNodeBmpWidth(const Image &)
Definition: svimpbox.cxx:1569
SvLBoxButton * m_pActiveButton
Definition: svimpbox.hxx:98
short GetIndent() const
Point m_aAsyncBeginDragPos
Definition: svimpbox.hxx:129
WinBits GetStyle() const
Definition: window2.cxx:942
Definition: timer.hxx:26
virtual void KeyDown(bool bPageDown)
Definition: svimpbox.cxx:494
void SetPriority(TaskPriority ePriority)
Definition: scheduler.cxx:600
bool IsRight() const
Definition: event.hxx:137
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2819
virtual bool Select(SvTreeListEntry *pEntry, bool bSelect=true)
bool SetMostRight(SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:3207
sal_uLong GetVisiblePos(SvTreeListEntry const *pEntry) const
Definition: treelist.hxx:277
virtual VclPtr< PopupMenu > CreateContextMenu()
void ExpandAll()
Definition: svimpbox.cxx:2098
void BeginScroll()
Definition: svimpbox.cxx:3054
VclPtr< ScrollBar > m_aVerSBar
Definition: svimpbox.hxx:211
#define FIRST_ENTRY_TAB
Definition: svimpbox.hxx:86
bool m_bSubLstOpRet
Definition: svimpbox.hxx:138
Low, very idle cleanup tasks.
SvTreeFlags nTreeFlags
void SetNodeBmpTabDistance()
Definition: svimpbox.cxx:1575
bool HasFocus() const
Definition: window.cxx:2986
sal_uLong GetSelectionCount() const
Definition: treelist.cxx:1092
void Push(PushFlags nFlags=PushFlags::ALL)
Definition: outdevstate.cxx:60
bool IsSelected() const
sal_Int32 nPos
bool SupportsDoubleBuffering() const
Can the widget derived from this Window do the double-buffering via RenderContext properly...
Definition: window.cxx:3815
void setWidth(long nWidth)
bool m_bInVScrollHdl
Definition: svimpbox.hxx:221
virtual void SetPosPixel(const Point &rNewPos)
Definition: window2.cxx:1246
void RemovingEntry(SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:1616
SelectionMode GetSelectionMode() const
Definition: seleng.hxx:126
#define KEY_RIGHT
Definition: keycodes.hxx:113
SvTreeListEntry * m_pMostRightEntry
Definition: svimpbox.hxx:97
void EntryInserted(SvTreeListEntry *)
Definition: svimpbox.cxx:1800
void Command(const CommandEvent &rCEvt)
Definition: svimpbox.cxx:2920
virtual void NotifyEndScroll()
void SetThumbPos(long nThumbPos)
Definition: scrbar.cxx:1364
virtual ~ImpLBSelEng() override
Definition: svimpbox.cxx:2621
long Y() const
void DeselectAll() override
Definition: svimpbox.cxx:2672
bool HasFocus() const
bool IsAlwaysAdding() const
Definition: seleng.hxx:195
std::vector< std::unique_ptr< SvTreeListEntry > > SvTreeListEntries
SvTreeListEntry * m_pActiveEntry
Definition: svimpbox.hxx:99
void BeginDrag() override
Definition: svimpbox.cxx:2625
short UpdateContextBmpWidthVector(SvTreeListEntry const *pEntry, short nWidth)
Definition: svimpbox.cxx:152
void KeyLeftRight(long nDiff)
Definition: svimpbox.cxx:727
bool IsMod1() const
Definition: event.hxx:144
std::vector< short > m_aContextBmpWidthVector
Definition: svimpbox.hxx:151
#define KEY_UP
Definition: keycodes.hxx:111
bool IsMod2() const
Definition: keycod.hxx:62
WinBits const WB_DRAG
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2151
void SetDragTarget(bool bDragTarget)
void setHeight(long nHeight)