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 
2020  {
2021  Point aPos(rMEvt.GetPosPixel());
2022  SvTreeListEntry* pEntry = GetEntry(aPos);
2023  // tdf#143245 ActivateOnSingleClick only
2024  // if the 'up' is at the active entry
2025  // typically selected by the 'down'
2026  if (!pEntry || pEntry != m_pCursor)
2027  return;
2029  }
2030 }
2031 
2033 {
2034  Point aPos = rMEvt.GetPosPixel();
2035  SvTreeListEntry* pEntry = GetClickedEntry(aPos);
2036  if ( !MouseMoveCheckCtrl( rMEvt, pEntry ) && ( m_aSelEng.GetSelectionMode() != SelectionMode::NONE ) )
2037  {
2038  m_aSelEng.SelMouseMove(rMEvt);
2040  {
2041  if (aPos.X() < 0 || aPos.Y() < 0 || aPos.X() > m_aOutputSize.Width() || aPos.Y() > m_aOutputSize.Height())
2042  pEntry = nullptr;
2043  else
2044  pEntry = GetEntry(aPos);
2045  if (!pEntry)
2046  m_pView->SelectAll(false);
2047  else if (!m_pView->IsSelected(pEntry) && IsSelectable(pEntry))
2048  m_pView->Select(pEntry);
2049  }
2050  }
2051 }
2052 
2054 {
2055  sal_uInt16 nRefDepth = m_pTree->GetDepth(m_pCursor);
2057  while (pCur && m_pTree->GetDepth(pCur) > nRefDepth)
2058  {
2059  if (pCur->HasChildren() && !m_pView->IsExpanded(pCur))
2060  m_pView->Expand(pCur);
2061  pCur = m_pTree->Next(pCur);
2062  }
2063 }
2064 
2065 void SvImpLBox::CollapseTo(SvTreeListEntry* pParentToCollapse)
2066 {
2067  // collapse all parents until we get to the given parent to collapse
2068  if (!pParentToCollapse)
2069  return;
2070 
2071  sal_uInt16 nRefDepth;
2072  // special case explorer: if the root only has a single
2073  // entry, don't collapse the root entry
2074  if (m_pTree->GetChildList(nullptr).size() < 2)
2075  {
2076  nRefDepth = 1;
2077  pParentToCollapse = m_pCursor;
2078  while (m_pTree->GetParent(pParentToCollapse)
2079  && m_pTree->GetDepth(m_pTree->GetParent(pParentToCollapse)) > 0)
2080  {
2081  pParentToCollapse = m_pTree->GetParent(pParentToCollapse);
2082  }
2083  }
2084  else
2085  nRefDepth = m_pTree->GetDepth(pParentToCollapse);
2086 
2087  if (m_pView->IsExpanded(pParentToCollapse))
2088  m_pView->Collapse(pParentToCollapse);
2089  SvTreeListEntry* pCur = m_pTree->Next(pParentToCollapse);
2090  while (pCur && m_pTree->GetDepth(pCur) > nRefDepth)
2091  {
2092  if (pCur->HasChildren() && m_pView->IsExpanded(pCur))
2093  m_pView->Collapse(pCur);
2094  pCur = m_pTree->Next(pCur);
2095  }
2096 }
2097 
2098 bool SvImpLBox::KeyInput( const KeyEvent& rKEvt)
2099 {
2100  m_aEditIdle.Stop();
2101  const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
2102 
2103  if( rKeyCode.IsMod2() )
2104  return false; // don't evaluate Alt key
2105 
2107 
2108  if( !m_pCursor )
2110  if( !m_pCursor )
2111  return false;
2112 
2113  bool bKeyUsed = true;
2114 
2115  sal_uInt16 nDelta = static_cast<sal_uInt16>(m_aVerSBar->GetPageSize());
2116  sal_uInt16 aCode = rKeyCode.GetCode();
2117 
2118  bool bShift = rKeyCode.IsShift();
2119  bool bMod1 = rKeyCode.IsMod1();
2120 
2121  SvTreeListEntry* pNewCursor;
2122 
2123  switch( aCode )
2124  {
2125  case KEY_UP:
2126  if( !IsEntryInView( m_pCursor ) )
2128 
2129  pNewCursor = m_pCursor;
2130  do
2131  {
2132  pNewCursor = m_pView->PrevVisible(pNewCursor);
2133  } while( pNewCursor && !IsSelectable(pNewCursor) );
2134 
2135  // if there is no next entry, take the current one
2136  // this ensures that in case of _one_ entry in the list, this entry is selected when pressing
2137  // the cursor key
2138  if (!pNewCursor)
2139  pNewCursor = m_pCursor;
2140 
2141  m_aSelEng.CursorPosChanging( bShift, bMod1 );
2142  SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
2143  if( !IsEntryInView( pNewCursor ) )
2144  KeyUp( false );
2145  break;
2146 
2147  case KEY_DOWN:
2148  if( !IsEntryInView( m_pCursor ) )
2150 
2151  pNewCursor = m_pCursor;
2152  do
2153  {
2154  pNewCursor = m_pView->NextVisible(pNewCursor);
2155  } while( pNewCursor && !IsSelectable(pNewCursor) );
2156 
2157  // if there is no next entry, take the current one
2158  // this ensures that in case of _one_ entry in the list, this entry is selected when pressing
2159  // the cursor key
2160  // 06.09.20001 - 83416 - frank.schoenheit@sun.com
2161  if ( !pNewCursor && m_pCursor )
2162  pNewCursor = m_pCursor;
2163 
2164  if( pNewCursor )
2165  {
2166  m_aSelEng.CursorPosChanging( bShift, bMod1 );
2167  if( IsEntryInView( pNewCursor ) )
2168  SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
2169  else
2170  {
2171  if( m_pCursor )
2172  m_pView->Select( m_pCursor, false );
2173  KeyDown( false );
2174  SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
2175  }
2176  }
2177  else
2178  KeyDown( false ); // because scrollbar range might still
2179  // allow scrolling
2180  break;
2181 
2182  case KEY_RIGHT:
2183  {
2184  if( m_bSubLstOpLR )
2185  {
2186  // only try to expand if sublist is expandable,
2187  // otherwise ignore the key press
2188  if( IsExpandable() && !m_pView->IsExpanded( m_pCursor ) )
2189  m_pView->Expand( m_pCursor );
2190  }
2191  else if (m_aHorSBar->IsVisible())
2192  {
2193  tools::Long nThumb = m_aHorSBar->GetThumbPos();
2194  nThumb += m_aHorSBar->GetLineSize();
2195  tools::Long nOldThumb = m_aHorSBar->GetThumbPos();
2196  m_aHorSBar->SetThumbPos( nThumb );
2197  nThumb = nOldThumb;
2198  nThumb -= m_aHorSBar->GetThumbPos();
2199  nThumb *= -1;
2200  if( nThumb )
2201  {
2202  KeyLeftRight( nThumb );
2203  }
2204  }
2205  else
2206  bKeyUsed = false;
2207  break;
2208  }
2209 
2210  case KEY_LEFT:
2211  {
2212  if (m_aHorSBar->IsVisible())
2213  {
2214  tools::Long nThumb = m_aHorSBar->GetThumbPos();
2215  nThumb -= m_aHorSBar->GetLineSize();
2216  tools::Long nOldThumb = m_aHorSBar->GetThumbPos();
2217  m_aHorSBar->SetThumbPos( nThumb );
2218  nThumb = nOldThumb;
2219  nThumb -= m_aHorSBar->GetThumbPos();
2220  if( nThumb )
2221  {
2222  KeyLeftRight( -nThumb );
2223  }
2224  else if( m_bSubLstOpLR )
2225  {
2226  if( IsExpandable() && m_pView->IsExpanded( m_pCursor ) )
2228  else
2229  {
2230  pNewCursor = m_pView->GetParent( m_pCursor );
2231  if( pNewCursor )
2232  SetCursor( pNewCursor );
2233  }
2234  }
2235  }
2236  else if( m_bSubLstOpLR )
2237  {
2238  if( IsExpandable() && m_pView->IsExpanded( m_pCursor ) )
2240  else
2241  {
2242  pNewCursor = m_pView->GetParent( m_pCursor );
2243  if( pNewCursor )
2244  SetCursor( pNewCursor );
2245  }
2246  }
2247  else
2248  bKeyUsed = false;
2249  break;
2250  }
2251 
2252  case KEY_PAGEUP:
2253  if( !bMod1 )
2254  {
2255  pNewCursor = m_pView->PrevVisible(m_pCursor, nDelta);
2256 
2257  while( nDelta && pNewCursor && !IsSelectable(pNewCursor) )
2258  {
2259  pNewCursor = m_pView->NextVisible(pNewCursor);
2260  nDelta--;
2261  }
2262 
2263  if( nDelta )
2264  {
2265  DBG_ASSERT(pNewCursor && pNewCursor!=m_pCursor, "Cursor?");
2266  m_aSelEng.CursorPosChanging( bShift, bMod1 );
2267  if( IsEntryInView( pNewCursor ) )
2268  SetCursor( pNewCursor );
2269  else
2270  {
2271  SetCursor( pNewCursor );
2272  KeyUp( true );
2273  }
2274  }
2275  }
2276  else
2277  bKeyUsed = false;
2278  break;
2279 
2280  case KEY_PAGEDOWN:
2281  if( !bMod1 )
2282  {
2283  pNewCursor= m_pView->NextVisible(m_pCursor, nDelta);
2284 
2285  while( nDelta && pNewCursor && !IsSelectable(pNewCursor) )
2286  {
2287  pNewCursor = m_pView->PrevVisible(pNewCursor);
2288  nDelta--;
2289  }
2290 
2291  if( nDelta && pNewCursor )
2292  {
2293  DBG_ASSERT(pNewCursor && pNewCursor!=m_pCursor, "Cursor?");
2294  m_aSelEng.CursorPosChanging( bShift, bMod1 );
2295  if( IsEntryInView( pNewCursor ) )
2296  SetCursor( pNewCursor );
2297  else
2298  {
2299  SetCursor( pNewCursor );
2300  KeyDown( true );
2301  }
2302  }
2303  else
2304  KeyDown( false ); // see also: KEY_DOWN
2305  }
2306  else
2307  bKeyUsed = false;
2308  break;
2309 
2310  case KEY_SPACE:
2312  {
2313  if ( bMod1 )
2314  {
2315  if ( m_pView->GetSelectionMode() == SelectionMode::Multiple && !bShift )
2316  // toggle selection
2318  }
2319  else if ( !bShift /*&& !bMod1*/ )
2320  {
2321  if ( m_aSelEng.IsAddMode() )
2322  {
2323  // toggle selection
2325  }
2326  else if ( !m_pView->IsSelected( m_pCursor ) )
2327  {
2328  SelAllDestrAnch( false );
2329  m_pView->Select( m_pCursor );
2330  }
2331  else
2332  bKeyUsed = false;
2333  }
2334  else
2335  bKeyUsed = false;
2336  }
2337  else
2338  bKeyUsed = false;
2339  break;
2340 
2341  case KEY_RETURN:
2342  bKeyUsed = !m_pView->DoubleClickHdl();
2343  break;
2344 
2345  case KEY_F2:
2346  if( !bShift && !bMod1 )
2347  {
2348  m_aEditClickPos = Point( -1, -1 );
2349  EditTimerCall( nullptr );
2350  }
2351  else
2352  bKeyUsed = false;
2353  break;
2354 
2355  case KEY_F8:
2356  if( bShift && m_pView->GetSelectionMode()==SelectionMode::Multiple &&
2357  !(m_nStyle & WB_SIMPLEMODE))
2358  {
2359  if( m_aSelEng.IsAlwaysAdding() )
2360  m_aSelEng.AddAlways( false );
2361  else
2362  m_aSelEng.AddAlways( true );
2363  }
2364  else
2365  bKeyUsed = false;
2366  break;
2367 
2368  case KEY_ADD:
2369  if (!m_pView->IsExpanded(m_pCursor))
2371  if (bMod1)
2372  ExpandAll();
2373  break;
2374 
2375  case KEY_A:
2376  if( bMod1 )
2377  SelAllDestrAnch( true );
2378  else
2379  bKeyUsed = false;
2380  break;
2381 
2382  case KEY_SUBTRACT:
2385  if (bMod1)
2387  break;
2388 
2389  case KEY_MULTIPLY:
2390  if( bMod1 )
2391  {
2392  // only try to expand/collapse if sublist is expandable,
2393  // otherwise ignore the key press
2394  if( IsExpandable() )
2395  {
2397  {
2399  ExpandAll();
2400  }
2401  else
2403  }
2404  }
2405  else
2406  bKeyUsed = false;
2407  break;
2408 
2409  case KEY_DIVIDE :
2410  if( bMod1 )
2411  SelAllDestrAnch( true );
2412  else
2413  bKeyUsed = false;
2414  break;
2415 
2416  case KEY_COMMA :
2417  if( bMod1 )
2418  SelAllDestrAnch( false );
2419  else
2420  bKeyUsed = false;
2421  break;
2422 
2423  case KEY_HOME :
2424  pNewCursor = m_pView->GetModel()->First();
2425 
2426  while( pNewCursor && !IsSelectable(pNewCursor) )
2427  {
2428  pNewCursor = m_pView->NextVisible(pNewCursor);
2429  }
2430 
2431  if( pNewCursor && pNewCursor != m_pCursor )
2432  {
2433 // SelAllDestrAnch( false );
2434  m_aSelEng.CursorPosChanging( bShift, bMod1 );
2435  SetCursor( pNewCursor );
2436  if( !IsEntryInView( pNewCursor ) )
2437  MakeVisible( pNewCursor );
2438  }
2439  else
2440  bKeyUsed = false;
2441  break;
2442 
2443  case KEY_END :
2444  pNewCursor = m_pView->GetModel()->Last();
2445 
2446  while( pNewCursor && !IsSelectable(pNewCursor) )
2447  {
2448  pNewCursor = m_pView->PrevVisible(pNewCursor);
2449  }
2450 
2451  if( pNewCursor && pNewCursor != m_pCursor)
2452  {
2453 // SelAllDestrAnch( false );
2454  m_aSelEng.CursorPosChanging( bShift, bMod1 );
2455  SetCursor( pNewCursor );
2456  if( !IsEntryInView( pNewCursor ) )
2457  MakeVisible( pNewCursor );
2458  }
2459  else
2460  bKeyUsed = false;
2461  break;
2462 
2463  case KEY_ESCAPE:
2464  case KEY_TAB:
2465  case KEY_DELETE:
2466  case KEY_BACKSPACE:
2467  // must not be handled because this quits dialogs and does other magic things...
2468  // if there are other single keys which should not be handled, they can be added here
2469  bKeyUsed = false;
2470  break;
2471 
2472  default:
2473  // is there any reason why we should eat the events here? The only place where this is called
2474  // is from SvTreeListBox::KeyInput. If we set bKeyUsed to true here, then the key input
2475  // is just silenced. However, we want SvLBox::KeyInput to get a chance, to do the QuickSelection
2476  // handling.
2477  // (The old code here which intentionally set bKeyUsed to sal_True said this was because of "quick search"
2478  // handling, but actually there was no quick search handling anymore. We just re-implemented it.)
2479  // #i31275# / 2009-06-16 / frank.schoenheit@sun.com
2480  bKeyUsed = false;
2481  break;
2482  }
2483  return bKeyUsed;
2484 }
2485 
2487 {
2488  if( m_pCursor )
2489  {
2490  m_pView->SetEntryFocus( m_pCursor, true );
2491  ShowCursor( true );
2492 // auskommentiert wg. deselectall
2493 // if( bSimpleTravel && !pView->IsSelected(pCursor) )
2494 // pView->Select( pCursor, true );
2495  }
2496  if( m_nStyle & WB_HIDESELECTION )
2497  {
2498  SvTreeListEntry* pEntry = m_pView->FirstSelected();
2499  while( pEntry )
2500  {
2501  InvalidateEntry( pEntry );
2502  pEntry = m_pView->NextSelected( pEntry );
2503  }
2504  }
2505 }
2506 
2508 {
2509  m_aEditIdle.Stop();
2510  if( m_pCursor )
2511  m_pView->SetEntryFocus( m_pCursor,false );
2512  ShowCursor( false );
2513 
2514  if( m_nStyle & WB_HIDESELECTION )
2515  {
2516  SvTreeListEntry* pEntry = m_pView ? m_pView->FirstSelected() : nullptr;
2517  while( pEntry )
2518  {
2519  InvalidateEntry( pEntry );
2520  pEntry = m_pView->NextSelected( pEntry );
2521  }
2522  }
2523 }
2524 
2525 
2526 // ********************************************************************
2527 // SelectionEngine
2528 // ********************************************************************
2529 
2530 void SvImpLBox::SelectEntry( SvTreeListEntry* pEntry, bool bSelect )
2531 {
2532  m_pView->Select( pEntry, bSelect );
2533 }
2534 
2536 {
2537  pImp = pImpl;
2538  pView = pV;
2539 }
2540 
2542 {
2543 }
2544 
2546 {
2547  pImp->BeginDrag();
2548 }
2549 
2551 {
2553 }
2554 
2556 {
2557  pImp->m_pAnchor = nullptr;
2558 }
2559 
2560 void ImpLBSelEng::SetCursorAtPoint(const Point& rPoint, bool bDontSelectAtCursor)
2561 {
2562  SvTreeListEntry* pNewCursor = pImp->MakePointVisible( rPoint );
2563  if( pNewCursor )
2564  {
2565  // at SimpleTravel, the SetCursor is selected and the select handler is
2566  // called
2567  //if( !bDontSelectAtCursor && !pImp->bSimpleTravel )
2568  // pImp->SelectEntry( pNewCursor, true );
2569  pImp->SetCursor( pNewCursor, bDontSelectAtCursor );
2570  }
2571 }
2572 
2573 bool ImpLBSelEng::IsSelectionAtPoint( const Point& rPoint )
2574 {
2575  SvTreeListEntry* pEntry = pImp->MakePointVisible( rPoint );
2576  if( pEntry )
2577  return pView->IsSelected(pEntry);
2578  return false;
2579 }
2580 
2581 void ImpLBSelEng::DeselectAtPoint( const Point& rPoint )
2582 {
2583  SvTreeListEntry* pEntry = pImp->MakePointVisible( rPoint );
2584  if( !pEntry )
2585  return;
2586  pImp->SelectEntry( pEntry, false );
2587 }
2588 
2590 {
2591  pImp->SelAllDestrAnch( false, false ); // don't reset SelectionEngine!
2593 }
2594 
2595 // ***********************************************************************
2596 // Selection
2597 // ***********************************************************************
2598 
2600 {
2601  SvTreeListEntry* pEntry;
2602  sal_uLong nAnchorVisPos = m_pView->GetVisiblePos( m_pAnchor );
2603  sal_uLong nOldVisPos = m_pView->GetVisiblePos( pOldCursor );
2604  sal_uLong nNewVisPos = m_pView->GetVisiblePos( pNewCursor );
2605 
2606  if( nOldVisPos > nAnchorVisPos ||
2607  ( nAnchorVisPos==nOldVisPos && nNewVisPos > nAnchorVisPos) )
2608  {
2609  if( nNewVisPos > nOldVisPos )
2610  {
2611  pEntry = pOldCursor;
2612  while( pEntry && pEntry != pNewCursor )
2613  {
2614  m_pView->Select( pEntry );
2615  pEntry = m_pView->NextVisible(pEntry);
2616  }
2617  if( pEntry )
2618  m_pView->Select( pEntry );
2619  return;
2620  }
2621 
2622  if( nNewVisPos < nAnchorVisPos )
2623  {
2624  pEntry = m_pAnchor;
2625  while( pEntry && pEntry != pOldCursor )
2626  {
2627  m_pView->Select( pEntry, false );
2628  pEntry = m_pView->NextVisible(pEntry);
2629  }
2630  if( pEntry )
2631  m_pView->Select( pEntry, false );
2632 
2633  pEntry = pNewCursor;
2634  while( pEntry && pEntry != m_pAnchor )
2635  {
2636  m_pView->Select( pEntry );
2637  pEntry = m_pView->NextVisible(pEntry);
2638  }
2639  if( pEntry )
2640  m_pView->Select( pEntry );
2641  return;
2642  }
2643 
2644  if( nNewVisPos < nOldVisPos )
2645  {
2646  pEntry = m_pView->NextVisible(pNewCursor);
2647  while( pEntry && pEntry != pOldCursor )
2648  {
2649  m_pView->Select( pEntry, false );
2650  pEntry = m_pView->NextVisible(pEntry);
2651  }
2652  if( pEntry )
2653  m_pView->Select( pEntry, false );
2654  return;
2655  }
2656  }
2657  else
2658  {
2659  if( nNewVisPos < nOldVisPos ) // enlarge selection
2660  {
2661  pEntry = pNewCursor;
2662  while( pEntry && pEntry != pOldCursor )
2663  {
2664  m_pView->Select( pEntry );
2665  pEntry = m_pView->NextVisible(pEntry);
2666  }
2667  if( pEntry )
2668  m_pView->Select( pEntry );
2669  return;
2670  }
2671 
2672  if( nNewVisPos > nAnchorVisPos )
2673  {
2674  pEntry = pOldCursor;
2675  while( pEntry && pEntry != m_pAnchor )
2676  {
2677  m_pView->Select( pEntry, false );
2678  pEntry = m_pView->NextVisible(pEntry);
2679  }
2680  if( pEntry )
2681  m_pView->Select( pEntry, false );
2682  pEntry = m_pAnchor;
2683  while( pEntry && pEntry != pNewCursor )
2684  {
2685  m_pView->Select( pEntry );
2686  pEntry = m_pView->NextVisible(pEntry);
2687  }
2688  if( pEntry )
2689  m_pView->Select( pEntry );
2690  return;
2691  }
2692 
2693  if( nNewVisPos > nOldVisPos )
2694  {
2695  pEntry = pOldCursor;
2696  while( pEntry && pEntry != pNewCursor )
2697  {
2698  m_pView->Select( pEntry, false );
2699  pEntry = m_pView->NextVisible(pEntry);
2700  }
2701  return;
2702  }
2703  }
2704 }
2705 
2707  bool bSelect, bool bDestroyAnchor, bool bSingleSelToo )
2708 {
2709  SvTreeListEntry* pEntry;
2711  if( bSelect && m_bSimpleTravel )
2712  {
2713  if( m_pCursor && !m_pView->IsSelected( m_pCursor ))
2714  {
2715  m_pView->Select( m_pCursor );
2716  }
2717  return;
2718  }
2719  if( !bSelect && m_pView->GetSelectionCount() == 0 )
2720  {
2721  if( m_bSimpleTravel && ( !GetUpdateMode() || !m_pCursor) )
2723  return;
2724  }
2725  if( bSelect && m_pView->GetSelectionCount() == m_pView->GetEntryCount())
2726  return;
2727  if( !bSingleSelToo && m_bSimpleTravel )
2728  return;
2729 
2730  if( !bSelect && m_pView->GetSelectionCount()==1 && m_pCursor &&
2732  {
2733  m_pView->Select( m_pCursor, false );
2734  if( bDestroyAnchor )
2735  DestroyAnchor(); // delete anchor & reset SelectionEngine
2736  else
2737  m_pAnchor = nullptr; // always delete internal anchor
2738  return;
2739  }
2740 
2741  if( m_bSimpleTravel && !m_pCursor && !GetUpdateMode() )
2743 
2744  ShowCursor( false );
2745  bool bUpdate = GetUpdateMode();
2746 
2747  m_nFlags |= LBoxFlags::IgnoreSelect; // EntryInserted should not do anything
2748  pEntry = m_pTree->First();
2749  while( pEntry )
2750  {
2751  if( m_pView->Select( pEntry, bSelect ) )
2752  {
2753  if( bUpdate && m_pView->IsEntryVisible(pEntry) )
2754  {
2755  tools::Long nY = GetEntryLine( pEntry );
2756  if( IsLineVisible( nY ) )
2757  InvalidateEntry(pEntry);
2758  }
2759  }
2760  pEntry = m_pTree->Next( pEntry );
2761  }
2763 
2764  if( bDestroyAnchor )
2765  DestroyAnchor(); // delete anchor & reset SelectionEngine
2766  else
2767  m_pAnchor = nullptr; // always delete internal anchor
2768  ShowCursor( true );
2769 }
2770 
2772 {
2773  m_aSelEng.SetSelectionMode( eSelMode);
2774  if( eSelMode == SelectionMode::Single )
2775  m_bSimpleTravel = true;
2776  else
2777  m_bSimpleTravel = false;
2778  if( (m_nStyle & WB_SIMPLEMODE) && (eSelMode == SelectionMode::Multiple) )
2779  m_aSelEng.AddAlways( true );
2780 }
2781 
2782 // ***********************************************************************
2783 // Drag & Drop
2784 // ***********************************************************************
2785 
2787 {
2788  if( eDDMode != DragDropMode::NONE )
2789  {
2791  m_aSelEng.EnableDrag( true );
2792  }
2793  else
2794  {
2796  m_aSelEng.EnableDrag( false );
2797  }
2798 }
2799 
2801 {
2804 }
2805 
2807 {
2808  if (pEntry)
2809  {
2810 
2811  SvViewDataEntry* pViewData = m_pView->GetViewData(pEntry);
2812  pViewData->SetDragTarget(bShow);
2813 #ifdef MACOSX
2814  // in MacOS we need to draw directly (as we are synchronous) or no invalidation happens
2815  m_pView->PaintEntry1(*pEntry, GetEntryLine(pEntry), *m_pView->GetOutDev());
2816 #else
2817  InvalidateEntry(pEntry);
2818 #endif
2819  }
2820 }
2821 
2822 void SvImpLBox::Command( const CommandEvent& rCEvt )
2823 {
2824  CommandEventId nCommand = rCEvt.GetCommand();
2825 
2826  if( nCommand == CommandEventId::ContextMenu )
2827  m_aEditIdle.Stop();
2828 
2829  // scroll mouse event?
2830  if (nCommand == CommandEventId::Wheel ||
2831  nCommand == CommandEventId::StartAutoScroll ||
2832  nCommand == CommandEventId::AutoScroll ||
2833  nCommand == CommandEventId::Gesture)
2834  {
2836  return;
2837  }
2838 
2839  const Point& rPos = rCEvt.GetMousePosPixel();
2840  if( rPos.X() < m_aOutputSize.Width() && rPos.Y() < m_aOutputSize.Height() )
2841  m_aSelEng.Command( rCEvt );
2842 }
2843 
2845 {
2846  Point aPos( m_pView->GetMapMode().GetOrigin() );
2847  aPos.setX( aPos.X() * -1 );
2848  tools::Rectangle aRect( aPos, m_aOutputSize );
2849  return aRect;
2850 }
2851 
2853 {
2855 }
2856 
2858 {
2861  )
2862  SelAllDestrAnch( false );
2863  if ( pEntry )
2864  MakeVisible( pEntry );
2865  SetCursor( pEntry );
2866  if ( pEntry && ( m_aSelEng.GetSelectionMode() != SelectionMode::NONE ) )
2867  m_pView->Select( pEntry );
2868 }
2869 
2870 IMPL_LINK_NOARG(SvImpLBox, EditTimerCall, Timer *, void)
2871 {
2872  if( !m_pView->IsInplaceEditingEnabled() )
2873  return;
2874 
2875  bool bIsMouseTriggered = m_aEditClickPos.X() >= 0;
2876  if ( bIsMouseTriggered )
2877  {
2878  Point aCurrentMousePos = m_pView->GetPointerPosPixel();
2879  if ( ( std::abs( aCurrentMousePos.X() - m_aEditClickPos.X() ) > 5 )
2880  || ( std::abs( aCurrentMousePos.Y() - m_aEditClickPos.Y() ) > 5 )
2881  )
2882  {
2883  return;
2884  }
2885  }
2886 
2887  SvTreeListEntry* pEntry = GetCurEntry();
2888  if( pEntry )
2889  {
2890  ShowCursor( false );
2891  m_pView->ImplEditEntry( pEntry );
2892  ShowCursor( true );
2893  }
2894 }
2895 
2896 bool SvImpLBox::RequestHelp( const HelpEvent& rHEvt )
2897 {
2898  if( rHEvt.GetMode() & HelpEventMode::QUICK )
2899  {
2901  if( !GetVisibleArea().IsInside( aPos ))
2902  return false;
2903 
2904  SvTreeListEntry* pEntry = GetEntry( aPos );
2905  if( pEntry )
2906  {
2907  // recalculate text rectangle
2908  SvLBoxTab* pTab;
2909  SvLBoxItem* pItem = m_pView->GetItem( pEntry, aPos.X(), &pTab );
2910  if (!pItem || pItem->GetType() != SvLBoxItemType::String)
2911  return false;
2912 
2913  aPos = GetEntryPosition( pEntry );
2914  aPos.setX( m_pView->GetTabPos( pEntry, pTab ) ); //pTab->GetPos();
2915  Size aSize(pItem->GetWidth(m_pView, pEntry), pItem->GetHeight(m_pView, pEntry));
2916  SvLBoxTab* pNextTab = NextTab( pTab );
2917  bool bItemClipped = false;
2918  // is the item cut off by its right neighbor?
2919  if( pNextTab && m_pView->GetTabPos(pEntry,pNextTab) < aPos.X()+aSize.Width() )
2920  {
2921  aSize.setWidth( pNextTab->GetPos() - pTab->GetPos() );
2922  bItemClipped = true;
2923  }
2924  tools::Rectangle aItemRect( aPos, aSize );
2925 
2926  tools::Rectangle aViewRect( GetVisibleArea() );
2927 
2928  if( bItemClipped || !aViewRect.IsInside( aItemRect ) )
2929  {
2930  // clip the right edge of the item at the edge of the view
2931  //if( aItemRect.Right() > aViewRect.Right() )
2932  // aItemRect.Right() = aViewRect.Right();
2933 
2934  Point aPt = m_pView->OutputToScreenPixel( aItemRect.TopLeft() );
2935  aItemRect.SetLeft( aPt.X() );
2936  aItemRect.SetTop( aPt.Y() );
2937  aPt = m_pView->OutputToScreenPixel( aItemRect.BottomRight() );
2938  aItemRect.SetRight( aPt.X() );
2939  aItemRect.SetBottom( aPt.Y() );
2940 
2941  Help::ShowQuickHelp( m_pView, aItemRect,
2942  static_cast<SvLBoxString*>(pItem)->GetText(), QuickHelpFlags::Left | QuickHelpFlags::VCenter );
2943  return true;
2944  }
2945  }
2946  }
2947  return false;
2948 }
2949 
2951 {
2952  sal_uInt16 nTabCount = m_pView->TabCount();
2953  if( nTabCount <= 1 )
2954  return nullptr;
2955  for( int nTab=0; nTab < (nTabCount-1); nTab++)
2956  {
2957  if( m_pView->aTabs[nTab].get() == pTab )
2958  return m_pView->aTabs[nTab+1].get();
2959  }
2960  return nullptr;
2961 }
2962 
2963 void SvImpLBox::SetUpdateMode( bool bMode )
2964 {
2965  if( m_bUpdateMode != bMode )
2966  {
2967  m_bUpdateMode = bMode;
2968  if( m_bUpdateMode )
2969  UpdateAll( false );
2970  }
2971 }
2972 
2974 {
2976  {
2978  m_pView->SetTabs();
2980  }
2981 
2982  sal_uInt16 nLastTab = m_pView->aTabs.size() - 1;
2983  sal_uInt16 nLastItem = pEntry->ItemCount() - 1;
2984  if( !m_pView->aTabs.empty() && nLastItem != USHRT_MAX )
2985  {
2986  if( nLastItem < nLastTab )
2987  nLastTab = nLastItem;
2988 
2989  SvLBoxTab* pTab = m_pView->aTabs[ nLastTab ].get();
2990  SvLBoxItem& rItem = pEntry->GetItem( nLastTab );
2991 
2992  tools::Long nTabPos = m_pView->GetTabPos( pEntry, pTab );
2993 
2994  tools::Long nMaxRight = GetOutputSize().Width();
2995  Point aPos( m_pView->GetMapMode().GetOrigin() );
2996  aPos.setX( aPos.X() * -1 ); // conversion document coordinates
2997  nMaxRight = nMaxRight + aPos.X() - 1;
2998 
2999  tools::Long nNextTab = nTabPos < nMaxRight ? nMaxRight : nMaxRight + 50;
3000  tools::Long nTabWidth = nNextTab - nTabPos + 1;
3001  auto nItemSize = rItem.GetWidth(m_pView,pEntry);
3002  tools::Long nOffset = pTab->CalcOffset( nItemSize, nTabWidth );
3003 
3004  tools::Long nRight = nTabPos + nOffset + nItemSize;
3005  if( nRight > m_nMostRight )
3006  {
3007  m_nMostRight = nRight;
3008  m_pMostRightEntry = pEntry;
3009  }
3010  }
3011 }
3012 
3014 {
3015  m_nMostRight = -1;
3016  m_pMostRightEntry = nullptr;
3017  if( !m_pView->GetModel() )
3018  return;
3019 
3020  SvTreeListEntry* pEntry = m_pView->FirstVisible();
3021  while( pEntry )
3022  {
3023  SetMostRight( pEntry );
3024  pEntry = m_pView->NextVisible( pEntry );
3025  }
3026 }
3027 
3029 {
3030  if( !pParent )
3031  FindMostRight();
3032  else
3033  FindMostRight_Impl( pParent );
3034 }
3035 
3037 {
3038  SvTreeListEntries& rList = m_pTree->GetChildList( pParent );
3039 
3040  size_t nCount = rList.size();
3041  for( size_t nCur = 0; nCur < nCount; nCur++ )
3042  {
3043  SvTreeListEntry* pChild = rList[nCur].get();
3044  SetMostRight( pChild );
3045  if( pChild->HasChildren() && m_pView->IsExpanded( pChild ))
3046  FindMostRight_Impl( pChild );
3047  }
3048 }
3049 
3051 {
3053  m_nCurUserEvent == nullptr )
3054  {
3056  }
3057 }
3058 
3060 {
3062 }
3063 
3064 IMPL_LINK(SvImpLBox, MyUserEvent, void*, pArg, void )
3065 {
3066  m_nCurUserEvent = nullptr;
3067  if( !pArg )
3068  {
3069  m_pView->Invalidate();
3070  m_pView->PaintImmediately();
3071  }
3072  else
3073  {
3074  FindMostRight();
3075  ShowVerSBar();
3076  m_pView->Invalidate( GetVisibleArea() );
3077  }
3078 }
3079 
3080 
3082 {
3083  if( m_nCurUserEvent != nullptr )
3084  {
3086  m_nCurUserEvent = nullptr;
3087  }
3088 }
3089 
3091 {
3092  if ( s_pDefCollapsed )
3093  // assume that all or nothing is initialized
3094  return;
3095 
3096  s_pDefCollapsed = new Image(StockImage::Yes, RID_BMP_TREENODE_COLLAPSED);
3097  s_pDefExpanded = new Image(StockImage::Yes, RID_BMP_TREENODE_EXPANDED);
3098 }
3099 
3100 
3102 {
3104  return *s_pDefExpanded;
3105 }
3106 
3107 
3109 {
3111  return *s_pDefCollapsed;
3112 }
3113 
3114 
3115 void SvImpLBox::CallEventListeners( VclEventId nEvent, void* pData )
3116 {
3117  if ( m_pView )
3118  m_pView->CallImplEventListeners( nEvent, pData);
3119 }
3120 
3121 
3123 {
3124  if( pEntry )
3125  {
3126  SvViewDataEntry* pViewDataNewCur = m_pView->GetViewDataEntry(pEntry);
3127  return (pViewDataNewCur == nullptr) || pViewDataNewCur->IsSelectable();
3128  }
3129  else
3130  {
3131  return false;
3132  }
3133 }
3134 
3135 /* 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:2560
bool RequestHelp(const HelpEvent &rHEvt)
Definition: svimpbox.cxx:2896
void SelectEntry(SvTreeListEntry *pEntry, bool bSelect)
Definition: svimpbox.cxx:2530
tools::Long Len() const
SvTreeListEntry * NextVisible(SvTreeListEntry *pEntry) const
Definition: treelist.hxx:235
void CaptureMouse()
Definition: mouse.cxx:445
const Wallpaper & GetBackground() const
Definition: outdev.hxx:520
void HideFocus()
Definition: window2.cxx:93
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:2032
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:346
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:2800
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:2392
void EntryExpanded(SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:1417
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1256
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:2486
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:2573
static const Image & GetDefaultCollapsedNodeImage()
Definition: svimpbox.cxx:3108
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:49
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:3081
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:1288
bool HandleScrollCommand(const CommandEvent &rCmd, ScrollBar *pHScrl, ScrollBar *pVScrl)
Definition: window2.cxx:598
void EnableDrag(bool bOn)
Definition: seleng.hxx:190
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:3059
HelpEventMode GetMode() const
Definition: event.hxx:208
void SetCurEntry(SvTreeListEntry *)
Definition: svimpbox.cxx:2857
static const Image & GetDefaultExpandedNodeImage()
Definition: svimpbox.cxx:3101
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:2599
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
SvTreeListEntry * Next(SvTreeListEntry *pEntry, sal_uInt16 *pDepth=nullptr) const
Definition: treelist.cxx:467
VclPtr< ScrollBarBox > m_aScrBarBox
Definition: svimpbox.hxx:96
const SvTreeListEntry * GetParent(const SvTreeListEntry *pEntry) const
Definition: treelist.cxx:1506
void SetDragDropMode(DragDropMode eDDMode)
Definition: svimpbox.cxx:2786
SvTreeListEntry * FirstSelected() const
Definition: treelist.hxx:252
WinBits const WB_HSCROLL
const Point & GetMousePosPixel() const
Definition: seleng.hxx:143
void RecalcFocusRect()
Definition: svimpbox.cxx:559
int nCount
void Hide()
Definition: window.hxx:884
constexpr sal_uInt16 KEY_PAGEUP
Definition: keycodes.hxx:116
SvTreeListEntry * NextSibling() const
VclPtr< SvTreeListBox > pView
Definition: svimpbox.hxx:44
constexpr sal_uInt16 KEY_F2
Definition: keycodes.hxx:84
VclEventId
Definition: vclevent.hxx:37
void Pop()
Definition: stack.cxx:93
void EndEditing(bool bCancel=false)
void SetSelectionMode(SelectionMode eSelMode)
Definition: svimpbox.cxx:2771
bool ButtonDownCheckExpand(const MouseEvent &, SvTreeListEntry *)
Definition: svimpbox.cxx:1891
static void implInitDefaultNodeImages()
Definition: svimpbox.cxx:3090
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:2098
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:160
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 *)
constexpr void SetLeft(tools::Long v)
void DestroyAnchor() override
Definition: svimpbox.cxx:2555
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
SvTreeListEntry * GetEntryAtAbsPos(sal_uInt32 nAbsPos) const
Definition: treelist.hxx:258
void CreateAnchor() override
Definition: svimpbox.cxx:2550
void SetLineColor()
Definition: line.cxx:36
void OnCurrentEntryChanged()
bool HasViewData() const
Definition: treelist.cxx:1050
ImpLBSelEng(SvImpLBox *pImp, SvTreeListBox *pView)
Definition: svimpbox.cxx:2535
tools::Long GetPageSize() const
Definition: scrbar.hxx:126
void CallEventListeners(VclEventId nEvent, void *pData=nullptr)
Definition: svimpbox.cxx:3115
size_t ItemCount() const
sal_uInt32 GetVisibleCount() const
Definition: treelist.hxx:229
void ExpandSelectionOnMouseMove(bool bExpand=true)
Definition: seleng.hxx:165
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:381
bool IsEditable() const
SvTreeListEntry * m_pAnchor
Definition: svimpbox.hxx:89
bool IsMod2() const
Definition: event.hxx:162
void NotifyTabsChanged()
Definition: svimpbox.cxx:3050
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:1164
void SetOrigin(const Point &rOrigin)
Definition: mapmod.cxx:104
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:168
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:2581
constexpr tools::Long Top() const
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:2706
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.
constexpr void SetRight(tools::Long v)
tools::Rectangle GetVisibleArea() const
Definition: svimpbox.cxx:2844
SvTreeListEntry * Last() const
Definition: treelist.cxx:554
const AllSettings & GetSettings() const
Definition: outdev.hxx:288
bool ButtonUpCheckCtrl(const MouseEvent &rMEvt)
Definition: svimpbox.cxx:1844
constexpr void SetBottom(tools::Long v)
ImpLBSelEng m_aFctSet
Definition: svimpbox.hxx:120
void DestroyAnchor()
Definition: svimpbox.hxx:299
void FindMostRight_Impl(SvTreeListEntry *pParent)
Definition: svimpbox.cxx:3036
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)
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:2799
std::unique_ptr< comphelper::string::NaturalStringSorter > m_pStringSorter
Definition: svimpbox.hxx:133
void GrabFocus()
Definition: window.cxx:2966
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:51
LBoxFlags m_nFlags
Definition: svimpbox.hxx:195
constexpr void SetTop(tools::Long v)
bool IsAddMode() const
Definition: seleng.hxx:174
bool HasChildrenOnDemand() const
void SetCursor(SvTreeListEntry *pEntry, bool bForceNoSelect=false)
Definition: svimpbox.cxx:576
void CollapseTo(SvTreeListEntry *pParentToCollapse)
Definition: svimpbox.cxx:2065
constexpr sal_uInt16 KEY_RETURN
Definition: keycodes.hxx:119
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
Definition: window2.cxx:1262
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
constexpr tools::Long Bottom() 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:2973
SvTreeListEntry * LastSibling() const
void ReleaseMouse()
Definition: mouse.cxx:463
void SetVisibleArea(const tools::Rectangle &rNewArea)
Definition: seleng.hxx:125
tools::Rectangle GetClipRegionRect() const
Definition: svimpbox.cxx:831
SvTreeListEntry * m_pCursor
Definition: svimpbox.hxx:190
void PaintDDCursor(SvTreeListEntry *pEntry, bool bShow)
Definition: svimpbox.cxx:2806
WinBits const WB_HASLINES
SvTreeListEntry * LastVisible() const
Definition: treelist.hxx:241
void Invalidate()
Definition: svimpbox.cxx:2852
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:54
virtual SvTreeListEntry * GetClickedEntry(const Point &) const
Definition: svimpbox.cxx:728
constexpr sal_uInt16 KEY_SUBTRACT
Definition: keycodes.hxx:128
void FindMostRight()
Definition: svimpbox.cxx:3013
void ClickHdl(SvTreeListEntry *)
Definition: svlbitm.cxx:352
void Stop()
Definition: scheduler.cxx:590
virtual void Scroll(tools::Long nHorzScroll, tools::Long nVertScroll, ScrollFlags nFlags=ScrollFlags::NONE)
Definition: window.cxx:2934
void LoseFocus()
Definition: svimpbox.cxx:2507
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:2950
SelectionEngine m_aSelEng
Definition: svimpbox.hxx:198
WinBits const WB_NOINITIALSELECTION
bool IsVisible() const
Definition: window2.cxx:1096
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:56
bool IsSelectable(const SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:3122
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:198
void SetUpdateMode(bool bMode)
Definition: svimpbox.cxx:2963
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:140
WinBits const WB_AUTOHSCROLL
void SetFunctionSet(FunctionSet *pFuncs)
Definition: seleng.hxx:139
constexpr sal_uInt16 KEY_BACKSPACE
Definition: keycodes.hxx:122
const Image & GetCollapsedNodeBmp()
Definition: svimpbox.hxx:351
SvTreeListEntry * m_pStartEntry
Definition: svimpbox.hxx:192
constexpr Point BottomRight() const
virtual void SyncVerThumb()
Definition: svimpbox.cxx:1359
void SetStyle(WinBits i_nWinStyle)
Definition: svimpbox.cxx:216
void setHeight(tools::Long nHeight)
virtual void Start(bool bStartTimer=true) override
Schedules the task for execution.
Definition: idle.cxx:34
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:947
Definition: timer.hxx:26
virtual void KeyDown(bool bPageDown)
Definition: svimpbox.cxx:473
tools::Long GetPos() const
void SetPriority(TaskPriority ePriority)
Definition: scheduler.cxx:597
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:2793
bool Select(SvTreeListEntry *pEntry, bool bSelect=true)
virtual Point GetEntryPosition(const SvTreeListEntry *) const
Definition: svimpbox.hxx:376
VCL_DLLPRIVATE void PaintEntry1(SvTreeListEntry &, tools::Long nLine, vcl::RenderContext &rRenderContext)
void ExpandAll()
Definition: svimpbox.cxx:2053
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:2971
void Push(PushFlags nFlags=PushFlags::ALL)
Definition: stack.cxx:34
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:1251
SvTreeListEntry * GetEntryAtVisPos(sal_uInt32 nVisPos) const
Definition: treelist.hxx:261
void RemovingEntry(SvTreeListEntry *pEntry)
Definition: svimpbox.cxx:1552
SelectionMode GetSelectionMode() const
Definition: seleng.hxx:137
SvTreeListEntry * m_pMostRightEntry
Definition: svimpbox.hxx:90
void EntryInserted(SvTreeListEntry *)
Definition: svimpbox.cxx:1736
void Command(const CommandEvent &rCEvt)
Definition: svimpbox.cxx:2822
virtual ~ImpLBSelEng() override
Definition: svimpbox.cxx:2541
sal_uInt16 nPos
constexpr sal_uInt16 KEY_TAB
Definition: keycodes.hxx:121
void DeselectAll() override
Definition: svimpbox.cxx:2589
bool HasFocus() const
bool IsAlwaysAdding() const
Definition: seleng.hxx:206
std::vector< std::unique_ptr< SvTreeListEntry > > SvTreeListEntries
SvTreeListEntry * m_pActiveEntry
Definition: svimpbox.hxx:92
void BeginDrag() override
Definition: svimpbox.cxx:2545
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:58
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:2177
void SetDragTarget(bool bDragTarget)