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