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