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