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