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