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