LibreOffice Module sc (master)  1
olinewin.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <string_view>
23 
24 #include <vcl/image.hxx>
25 #include <vcl/taskpanelist.hxx>
26 #include <vcl/settings.hxx>
27 #include <osl/diagnose.h>
28 
29 #include <olinewin.hxx>
30 #include <olinetab.hxx>
31 #include <document.hxx>
32 #include <dbfunc.hxx>
33 #include <bitmaps.hlst>
34 
37 
38 const size_t SC_OL_NOLEVEL = static_cast< size_t >( -1 );
39 const size_t SC_OL_HEADERENTRY = static_cast< size_t >( -1 );
40 
42  Window( pParent ),
43  mrViewData( *pViewData ),
44  meWhich( eWhich ),
45  mbHoriz( eMode == SC_OUTLINE_HOR ),
46  mbMirrorEntries( false ), // updated in SetHeaderSize
47  mbMirrorLevels( false ), // updated in SetHeaderSize
48  maLineColor( COL_BLACK ),
49  mnHeaderSize( 0 ),
50  mnHeaderPos( 0 ),
51  mnMainFirstPos( 0 ),
52  mnMainLastPos( 0 ),
53  mbMTActive( false ),
54  mbMTPressed( false ),
55  mnFocusLevel( 0 ),
56  mnFocusEntry( SC_OL_HEADERENTRY ),
57  mbDontDrawFocus( false )
58 {
59  EnableRTL( false ); // mirroring is done manually
60 
61  InitSettings();
63  SetHeaderSize( 0 );
64 
65  // insert the window into task pane list for "F6 cycling"
66  if( SystemWindow* pSysWin = GetSystemWindow() )
67  if( TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList() )
68  pTaskPaneList->AddWindow( this );
69 }
70 
72 {
73  disposeOnce();
74 }
75 
77 {
78  // remove the window from task pane list
79  if( SystemWindow* pSysWin = GetSystemWindow() )
80  if( TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList() )
81  pTaskPaneList->RemoveWindow( this );
83 }
84 
86 {
87  bool bLayoutRTL = GetDoc().IsLayoutRTL( GetTab() );
88  mbMirrorEntries = bLayoutRTL && mbHoriz;
89  mbMirrorLevels = bLayoutRTL && !mbHoriz;
90 
91  bool bNew = (nNewSize != mnHeaderSize);
92  mnHeaderSize = nNewSize;
96  if ( bNew )
97  Invalidate();
98 }
99 
101 {
103  if ( nSize > 0 )
104  nSize += 2 * SC_OL_POSOFFSET + 1;
105  return nSize;
106 }
107 
109 {
110  HideFocus();
111  mbDontDrawFocus = true;
112 
113  tools::Long nStart = mnMainFirstPos;
114  tools::Long nEnd = mnMainLastPos;
115 
116  tools::Long nInvStart, nInvEnd;
117  if (nDiff < 0)
118  {
119  nStart -= nDiff;
120  nInvStart = nEnd + nDiff;
121  nInvEnd = nEnd;
122  }
123  else
124  {
125  nEnd -= nDiff;
126  nInvStart = nStart;
127  nInvEnd = nStart + nDiff;
128  }
129 
130  ScrollRel( nDiff, nStart, nEnd );
131  Invalidate( GetRectangle( 0, nInvStart, GetOutputSizeLevel() - 1, nInvEnd ) );
132 
133  // if focus becomes invisible, move it to next visible button
134  ImplMoveFocusToVisible( nDiff < 0 );
135 
136  mbDontDrawFocus = false;
137  ShowFocus();
138 }
139 
140 void ScOutlineWindow::ScrollRel( tools::Long nEntryDiff, tools::Long nEntryStart, tools::Long nEntryEnd )
141 {
142  tools::Rectangle aRect( GetRectangle( 0, nEntryStart, GetOutputSizeLevel() - 1, nEntryEnd ) );
143  if ( mbHoriz )
144  Scroll( nEntryDiff, 0, aRect );
145  else
146  Scroll( 0, nEntryDiff, aRect );
147 }
148 
149 // internal -------------------------------------------------------------------
150 
152 {
153  const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
154  SetBackground( rStyleSettings.GetFaceColor() );
155  maLineColor = rStyleSettings.GetButtonTextColor();
156  Invalidate();
157 }
158 
160 {
161  const ScOutlineTable* pTable = GetDoc().GetOutlineTable( GetTab() );
162  if ( !pTable ) return nullptr;
163  return mbHoriz ? &pTable->GetColArray() : &pTable->GetRowArray();
164 }
165 
166 const ScOutlineEntry* ScOutlineWindow::GetOutlineEntry( size_t nLevel, size_t nEntry ) const
167 {
168  const ScOutlineArray* pArray = GetOutlineArray();
169  return pArray ? pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) ) : nullptr;
170 }
171 
172 bool ScOutlineWindow::IsHidden( SCCOLROW nColRowIndex ) const
173 {
174  return mbHoriz ?
175  GetDoc().ColHidden(static_cast<SCCOL>(nColRowIndex), GetTab()) :
176  GetDoc().RowHidden(static_cast<SCROW>(nColRowIndex), GetTab());
177 }
178 
179 bool ScOutlineWindow::IsFiltered( SCCOLROW nColRowIndex ) const
180 {
181  // columns cannot be filtered
182  return !mbHoriz && GetDoc().RowFiltered( static_cast<SCROW>(nColRowIndex), GetTab() );
183 }
184 
185 bool ScOutlineWindow::IsFirstVisible( SCCOLROW nColRowIndex ) const
186 {
187  bool bAllHidden = true;
188  for ( SCCOLROW nPos = 0; (nPos < nColRowIndex) && bAllHidden; ++nPos )
189  bAllHidden = IsHidden( nPos );
190  return bAllHidden;
191 }
192 
193 void ScOutlineWindow::GetVisibleRange( SCCOLROW& rnColRowStart, SCCOLROW& rnColRowEnd ) const
194 {
195  if ( mbHoriz )
196  {
197  rnColRowStart = mrViewData.GetPosX( WhichH( meWhich ) );
198  rnColRowEnd = rnColRowStart + mrViewData.VisibleCellsX( WhichH( meWhich ) );
199  }
200  else
201  {
202  rnColRowStart = mrViewData.GetPosY( WhichV( meWhich ) );
203  rnColRowEnd = rnColRowStart + mrViewData.VisibleCellsY( WhichV( meWhich ) );
204  }
205 
206  // include collapsed columns/rows in front of visible range
207  while ( (rnColRowStart > 0) && IsHidden( rnColRowStart - 1 ) )
208  --rnColRowStart;
209 }
210 
212 {
213  return mbHoriz ? Point( nEntryPos, nLevelPos ) : Point( nLevelPos, nEntryPos );
214 }
215 
217  tools::Long nLevelStart, tools::Long nEntryStart, tools::Long nLevelEnd, tools::Long nEntryEnd ) const
218 {
219  return tools::Rectangle( GetPoint( nLevelStart, nEntryStart ), GetPoint( nLevelEnd, nEntryEnd ) );
220 }
221 
223 {
224  Size aSize( GetOutputSizePixel() );
225  return mbHoriz ? aSize.Height() : aSize.Width();
226 }
227 
229 {
230  Size aSize( GetOutputSizePixel() );
231  return mbHoriz ? aSize.Width() : aSize.Height();
232 }
233 
235 {
236  const ScOutlineArray* pArray = GetOutlineArray();
237  size_t nLevelCount = pArray ? pArray->GetDepth() : 0;
238  return nLevelCount ? (nLevelCount + 1) : 0;
239 }
240 
242 {
243  // #i51970# must always return the *left* edge of the area used by a level
244  tools::Long nPos = static_cast< tools::Long >( SC_OL_POSOFFSET + nLevel * SC_OL_BITMAPSIZE );
245  return mbMirrorLevels ? (GetOutputSizeLevel() - nPos - SC_OL_BITMAPSIZE) : nPos;
246 }
247 
249 {
250  if( mbMirrorLevels ) nLevelPos = GetOutputSizeLevel() - nLevelPos - 1;
251  tools::Long nStart = SC_OL_POSOFFSET;
252  if ( nLevelPos < nStart ) return SC_OL_NOLEVEL;
253  size_t nLevel = static_cast< size_t >( (nLevelPos - nStart) / SC_OL_BITMAPSIZE );
254  return (nLevel < GetLevelCount()) ? nLevel : SC_OL_NOLEVEL;
255 }
256 
258 {
259  tools::Long nDocPos = mbHoriz ?
260  mrViewData.GetScrPos( static_cast<SCCOL>(nColRowIndex), 0, meWhich, true ).X() :
261  mrViewData.GetScrPos( 0, static_cast<SCROW>(nColRowIndex), meWhich, true ).Y();
262  return mnMainFirstPos + nDocPos;
263 }
264 
266 {
267  return mnHeaderPos + (mnHeaderSize - SC_OL_BITMAPSIZE) / 2;
268 }
269 
271  size_t nLevel, size_t nEntry,
272  tools::Long& rnStartPos, tools::Long& rnEndPos, tools::Long& rnImagePos ) const
273 {
274  const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
275  if ( !pEntry || !pEntry->IsVisible() )
276  return false;
277 
278  SCCOLROW nStart = pEntry->GetStart();
279  SCCOLROW nEnd = pEntry->GetEnd();
280 
281  tools::Long nEntriesSign = mbMirrorEntries ? -1 : 1;
282 
283  // --- common calculation ---
284 
285  rnStartPos = GetColRowPos( nStart );
286  rnEndPos = GetColRowPos( nEnd + 1 );
287 
288  bool bHidden = IsHidden( nStart );
289  rnImagePos = bHidden ?
290  (rnStartPos - ( SC_OL_BITMAPSIZE / 2 ) * nEntriesSign) :
291  rnStartPos + nEntriesSign;
292  tools::Long nCenter = (rnStartPos + rnEndPos - SC_OL_BITMAPSIZE * nEntriesSign +
293  ( mbMirrorEntries ? 1 : 0 )) / 2;
294  rnImagePos = mbMirrorEntries ? std::max( rnImagePos, nCenter ) : std::min( rnImagePos, nCenter );
295 
296  // --- refinements ---
297 
298  // do not cut leftmost/topmost image
299  if ( bHidden && IsFirstVisible( nStart ) )
300  rnImagePos = rnStartPos;
301 
302  // do not cover previous collapsed image
303  bool bDoNoCover = !bHidden && nEntry;
304  const ScOutlineEntry* pPrevEntry = bDoNoCover ? GetOutlineEntry(nLevel, nEntry - 1) : nullptr;
305  if (pPrevEntry)
306  {
307  SCCOLROW nPrevEnd = pPrevEntry->GetEnd();
308  if ( (nPrevEnd + 1 == nStart) && IsHidden( nPrevEnd ) )
309  {
310  if ( IsFirstVisible( pPrevEntry->GetStart() ) )
311  rnStartPos += SC_OL_BITMAPSIZE * nEntriesSign;
312  else
313  rnStartPos += ( SC_OL_BITMAPSIZE / 2 ) * nEntriesSign;
314  rnImagePos = rnStartPos;
315  }
316  }
317 
318  // restrict rnStartPos...rnEndPos to valid area
319  rnStartPos = std::max( rnStartPos, mnMainFirstPos );
320  rnEndPos = std::max( rnEndPos, mnMainFirstPos );
321 
322  if ( mbMirrorEntries )
323  rnImagePos -= SC_OL_BITMAPSIZE - 1; // start pos aligns with right edge of bitmap
324 
325  // --- all rows filtered? ---
326 
327  bool bVisible = true;
328  if ( !mbHoriz )
329  {
330  bVisible = false;
331  for ( SCCOLROW nRow = nStart; (nRow <= nEnd) && !bVisible; ++nRow )
332  bVisible = !IsFiltered( nRow );
333  }
334  return bVisible;
335 }
336 
337 bool ScOutlineWindow::GetImagePos( size_t nLevel, size_t nEntry, Point& rPos ) const
338 {
339  bool bRet = nLevel < GetLevelCount();
340  if ( bRet )
341  {
342  tools::Long nLevelPos = GetLevelPos( nLevel );
343  if ( nEntry == SC_OL_HEADERENTRY )
344  rPos = GetPoint( nLevelPos, GetHeaderEntryPos() );
345  else
346  {
347  tools::Long nStartPos, nEndPos, nImagePos;
348  bRet = GetEntryPos( nLevel, nEntry, nStartPos, nEndPos, nImagePos );
349  rPos = GetPoint( nLevelPos, nImagePos );
350  }
351  }
352  return bRet;
353 }
354 
355 bool ScOutlineWindow::IsButtonVisible( size_t nLevel, size_t nEntry ) const
356 {
357  bool bRet = false;
358  if ( nEntry == SC_OL_HEADERENTRY )
359  bRet = (mnHeaderSize > 0) && (nLevel < GetLevelCount());
360  else
361  {
362  const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
363  if ( pEntry && pEntry->IsVisible() )
364  {
365  SCCOLROW nStart, nEnd;
366  GetVisibleRange( nStart, nEnd );
367  bRet = (nStart <= pEntry->GetStart()) && (pEntry->GetStart() <= nEnd);
368  }
369  }
370  return bRet;
371 }
372 
373 bool ScOutlineWindow::ItemHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry, bool& rbButton ) const
374 {
375  const ScOutlineArray* pArray = GetOutlineArray();
376  if ( !pArray ) return false;
377 
378  SCCOLROW nStartIndex, nEndIndex;
379  GetVisibleRange( nStartIndex, nEndIndex );
380 
381  size_t nLevel = GetLevelFromPos( mbHoriz ? rPos.Y() : rPos.X() );
382  if ( nLevel == SC_OL_NOLEVEL )
383  return false;
384 
385  tools::Long nEntryMousePos = mbHoriz ? rPos.X() : rPos.Y();
386 
387  // --- level buttons ---
388 
389  if ( mnHeaderSize > 0 )
390  {
391  tools::Long nImagePos = GetHeaderEntryPos();
392  if ( (nImagePos <= nEntryMousePos) && (nEntryMousePos < nImagePos + SC_OL_BITMAPSIZE) )
393  {
394  rnLevel = nLevel;
395  rnEntry = SC_OL_HEADERENTRY;
396  rbButton = true;
397  return true;
398  }
399  }
400 
401  // --- expand/collapse buttons and expanded lines ---
402 
403  // search outline entries backwards
404  size_t nEntry = pArray->GetCount( sal::static_int_cast<sal_uInt16>(nLevel) );
405  while ( nEntry )
406  {
407  --nEntry;
408 
409  const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
410  sal::static_int_cast<sal_uInt16>(nEntry) );
411  SCCOLROW nStart = pEntry->GetStart();
412  SCCOLROW nEnd = pEntry->GetEnd();
413 
414  if ( (nEnd >= nStartIndex) && (nStart <= nEndIndex) )
415  {
416  tools::Long nStartPos, nEndPos, nImagePos;
417  if ( GetEntryPos( nLevel, nEntry, nStartPos, nEndPos, nImagePos ) )
418  {
419  rnLevel = nLevel;
420  rnEntry = nEntry;
421 
422  // button?
423  if ( (nStart >= nStartIndex) && (nImagePos <= nEntryMousePos) && (nEntryMousePos < nImagePos + SC_OL_BITMAPSIZE) )
424  {
425  rbButton = true;
426  return true;
427  }
428 
429  // line?
430  if ( mbMirrorEntries )
431  ::std::swap( nStartPos, nEndPos ); // in RTL mode, nStartPos is the larger value
432  if ( (nStartPos <= nEntryMousePos) && (nEntryMousePos <= nEndPos) )
433  {
434  rbButton = false;
435  return true;
436  }
437  }
438  }
439  }
440 
441  return false;
442 }
443 
444 bool ScOutlineWindow::ButtonHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const
445 {
446  bool bButton;
447  bool bRet = ItemHit( rPos, rnLevel, rnEntry, bButton );
448  return bRet && bButton;
449 }
450 
451 bool ScOutlineWindow::LineHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const
452 {
453  bool bButton;
454  bool bRet = ItemHit( rPos, rnLevel, rnEntry, bButton );
455  return bRet && !bButton;
456 }
457 
458 void ScOutlineWindow::DoFunction( size_t nLevel, size_t nEntry ) const
459 {
460  ScDBFunc& rFunc = *mrViewData.GetView();
461  if ( nEntry == SC_OL_HEADERENTRY )
462  rFunc.SelectLevel( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel) );
463  else
464  {
465  const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
466  if ( pEntry )
467  {
468  if ( pEntry->IsHidden() )
469  rFunc.ShowOutline( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) );
470  else
471  rFunc.HideOutline( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) );
472  }
473  }
474 }
475 
476 void ScOutlineWindow::DoExpand( size_t nLevel, size_t nEntry ) const
477 {
478  const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
479  if ( pEntry && pEntry->IsHidden() )
480  DoFunction( nLevel, nEntry );
481 }
482 
483 void ScOutlineWindow::DoCollapse( size_t nLevel, size_t nEntry ) const
484 {
485  const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
486  if ( pEntry && !pEntry->IsHidden() )
487  DoFunction( nLevel, nEntry );
488 }
489 
491 {
492  Window::Resize();
493  SetHeaderSize( mnHeaderSize ); // recalculates header/group positions
494  if ( !IsFocusButtonVisible() )
495  {
496  HideFocus();
497  ShowFocus(); // calculates valid position
498  }
499 }
500 
502 {
503  if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
504  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
505  {
506  InitSettings();
507  Invalidate();
508  }
509  Window::DataChanged( rDCEvt );
510 }
511 
512 // drawing --------------------------------------------------------------------
513 
515 {
517  GetPoint( 0, mnMainFirstPos ),
519 }
520 
522  tools::Long nLevelStart, tools::Long nEntryStart, tools::Long nLevelEnd, tools::Long nEntryEnd )
523 {
524  GetOutDev()->DrawLine( GetPoint( nLevelStart, nEntryStart ), GetPoint( nLevelEnd, nEntryEnd ) );
525 }
526 
528  tools::Long nLevelStart, tools::Long nEntryStart, tools::Long nLevelEnd, tools::Long nEntryEnd )
529 {
530  GetOutDev()->DrawRect( GetRectangle( nLevelStart, nEntryStart, nLevelEnd, nEntryEnd ) );
531 }
532 
533 namespace
534 {
535  Image GetImage(const OUString& rId)
536  {
537  return Image(StockImage::Yes, rId);
538  }
539 }
540 
541 void ScOutlineWindow::DrawImageRel(tools::Long nLevelPos, tools::Long nEntryPos, const OUString& rId)
542 {
543  const Image& rImage = GetImage(rId);
544  GetOutDev()->SetLineColor();
545  GetOutDev()->SetFillColor( GetBackground().GetColor() );
546  Point aPos( GetPoint( nLevelPos, nEntryPos ) );
547  GetOutDev()->DrawRect( tools::Rectangle( aPos, rImage.GetSizePixel() ) );
548  GetOutDev()->DrawImage( aPos, rImage );
549 }
550 
551 void ScOutlineWindow::DrawBorderRel( size_t nLevel, size_t nEntry, bool bPressed )
552 {
553  Point aPos;
554  if ( GetImagePos( nLevel, nEntry, aPos ) )
555  {
556  OUString sId = bPressed ? OUString(RID_BMP_PRESSED) : OUString(RID_BMP_NOTPRESSED);
557  bool bClip = (nEntry != SC_OL_HEADERENTRY);
558  if ( bClip )
560  GetOutDev()->DrawImage(aPos, GetImage(sId));
561  if ( bClip )
563  }
564  mbMTPressed = bPressed;
565 }
566 
568 {
569  if ( !HasFocus() )
570  return;
571 
572  // first move to a visible position
573  ImplMoveFocusToVisible( true );
574 
575  if ( !IsFocusButtonVisible() )
576  return;
577 
578  Point aPos;
579  if ( GetImagePos( mnFocusLevel, mnFocusEntry, aPos ) )
580  {
581  aPos += Point( 1, 1 );
583  bool bClip = (mnFocusEntry != SC_OL_HEADERENTRY);
584  if ( bClip )
586  InvertTracking( maFocusRect, ShowTrackFlags::Small | ShowTrackFlags::TrackWindow );
587  if ( bClip )
589  }
590 }
591 
593 {
594  if ( !maFocusRect.IsEmpty() )
595  {
596  bool bClip = (mnFocusEntry != SC_OL_HEADERENTRY);
597  if ( bClip )
599  InvertTracking( maFocusRect, ShowTrackFlags::Small | ShowTrackFlags::TrackWindow );
600  if ( bClip )
603  }
604 }
605 
606 const std::u16string_view aLevelBmps[]=
607 {
608  u"" RID_BMP_LEVEL1,
609  u"" RID_BMP_LEVEL2,
610  u"" RID_BMP_LEVEL3,
611  u"" RID_BMP_LEVEL4,
612  u"" RID_BMP_LEVEL5,
613  u"" RID_BMP_LEVEL6,
614  u"" RID_BMP_LEVEL7,
615  u"" RID_BMP_LEVEL8
616 };
617 
618 void ScOutlineWindow::Paint( vcl::RenderContext& /*rRenderContext*/, const tools::Rectangle& /* rRect */ )
619 {
620  tools::Long nEntriesSign = mbMirrorEntries ? -1 : 1;
621  tools::Long nLevelsSign = mbMirrorLevels ? -1 : 1;
622 
623  Size aSize = GetOutputSizePixel();
624  tools::Long nLevelEnd = (mbHoriz ? aSize.Height() : aSize.Width()) - 1;
625  tools::Long nEntryEnd = (mbHoriz ? aSize.Width() : aSize.Height()) - 1;
626 
628  tools::Long nBorderPos = mbMirrorLevels ? 0 : nLevelEnd;
629  DrawLineRel( nBorderPos, 0, nBorderPos, nEntryEnd );
630 
631  const ScOutlineArray* pArray = GetOutlineArray();
632  if ( !pArray ) return;
633 
634  size_t nLevelCount = GetLevelCount();
635 
636  // --- draw header images ---
637 
638  if ( mnHeaderSize > 0 )
639  {
640  tools::Long nEntryPos = GetHeaderEntryPos();
641  for ( size_t nLevel = 0; nLevel < nLevelCount; ++nLevel )
642  DrawImageRel(GetLevelPos(nLevel), nEntryPos, OUString(aLevelBmps[nLevel]));
643 
645  tools::Long nLinePos = mnHeaderPos + (mbMirrorEntries ? 0 : (mnHeaderSize - 1));
646  DrawLineRel( 0, nLinePos, nLevelEnd, nLinePos );
647  }
648 
649  // --- draw lines & collapse/expand images ---
650 
652 
653  SCCOLROW nStartIndex, nEndIndex;
654  GetVisibleRange( nStartIndex, nEndIndex );
655 
656  for ( size_t nLevel = 0; nLevel + 1 < nLevelCount; ++nLevel )
657  {
658  tools::Long nLevelPos = GetLevelPos( nLevel );
659  tools::Long nEntryPos1 = 0, nEntryPos2 = 0, nImagePos = 0;
660 
661  size_t nEntryCount = pArray->GetCount( sal::static_int_cast<sal_uInt16>(nLevel) );
662  size_t nEntry;
663 
664  // first draw all lines in the current level
665  GetOutDev()->SetLineColor();
667  for ( nEntry = 0; nEntry < nEntryCount; ++nEntry )
668  {
669  const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
670  sal::static_int_cast<sal_uInt16>(nEntry) );
671  SCCOLROW nStart = pEntry->GetStart();
672  SCCOLROW nEnd = pEntry->GetEnd();
673 
674  // visible range?
675  bool bDraw = (nEnd >= nStartIndex) && (nStart <= nEndIndex);
676  // find output coordinates
677  if ( bDraw )
678  bDraw = GetEntryPos( nLevel, nEntry, nEntryPos1, nEntryPos2, nImagePos );
679  // draw, if not collapsed
680  if ( bDraw && !pEntry->IsHidden() )
681  {
682  if ( nStart >= nStartIndex )
683  nEntryPos1 += nEntriesSign;
684  nEntryPos2 -= 2 * nEntriesSign;
685  tools::Long nLinePos = nLevelPos;
686  if ( mbMirrorLevels )
687  nLinePos += SC_OL_BITMAPSIZE - 1; // align with right edge of bitmap
688  DrawRectRel( nLinePos, nEntryPos1, nLinePos + nLevelsSign, nEntryPos2 );
689 
690  if ( nEnd <= nEndIndex )
691  DrawRectRel( nLinePos, nEntryPos2 - nEntriesSign,
692  nLinePos + ( SC_OL_BITMAPSIZE / 3 ) * nLevelsSign, nEntryPos2 );
693  }
694  }
695 
696  // draw all images in the level from last to first
697  nEntry = nEntryCount;
698  while ( nEntry )
699  {
700  --nEntry;
701 
702  const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
703  sal::static_int_cast<sal_uInt16>(nEntry) );
704  SCCOLROW nStart = pEntry->GetStart();
705 
706  // visible range?
707  bool bDraw = (nStartIndex <= nStart) && (nStart <= nEndIndex + 1);
708  // find output coordinates
709  if ( bDraw )
710  bDraw = GetEntryPos( nLevel, nEntry, nEntryPos1, nEntryPos2, nImagePos );
711  // draw, if not hidden by higher levels
712  if ( bDraw )
713  {
714  OUString sImageId = pEntry->IsHidden() ? OUString(RID_BMP_PLUS) : OUString(RID_BMP_MINUS);
715  DrawImageRel(nLevelPos, nImagePos, sImageId);
716  }
717  }
718  }
719 
721 
722  if ( !mbDontDrawFocus )
723  ShowFocus();
724 }
725 
726 // focus ----------------------------------------------------------------------
727 
730 static bool lcl_RotateValue( size_t& rnValue, size_t nMin, size_t nMax, bool bForward )
731 {
732  OSL_ENSURE( nMin <= nMax, "lcl_RotateValue - invalid range" );
733  OSL_ENSURE( nMax < static_cast< size_t >( -1 ), "lcl_RotateValue - range overflow" );
734  bool bWrap = false;
735  if ( bForward )
736  {
737  if ( rnValue < nMax )
738  ++rnValue;
739  else
740  {
741  rnValue = nMin;
742  bWrap = true;
743  }
744  }
745  else
746  {
747  if ( rnValue > nMin )
748  --rnValue;
749  else
750  {
751  rnValue = nMax;
752  bWrap = true;
753  }
754  }
755  return bWrap;
756 }
757 
759 {
761 }
762 
763 bool ScOutlineWindow::ImplMoveFocusByEntry( bool bForward, bool bFindVisible )
764 {
765  const ScOutlineArray* pArray = GetOutlineArray();
766  if ( !pArray )
767  return false;
768 
769  bool bWrapped = false;
770  size_t nEntryCount = pArray->GetCount( sal::static_int_cast<sal_uInt16>(mnFocusLevel) );
771  // #i29530# entry count may be decreased after changing active sheet
772  if( mnFocusEntry >= nEntryCount )
774  size_t nOldEntry = mnFocusEntry;
775 
776  do
777  {
779  {
780  // move from header to first or last entry
781  if ( nEntryCount > 0 )
782  mnFocusEntry = bForward ? 0 : (nEntryCount - 1);
783  /* wrapped, if forward from right header to first entry,
784  or if backward from left header to last entry */
785  // Header and entries are now always in consistent order,
786  // so there's no need to check for mirroring here.
787  if ( !nEntryCount || !bForward )
788  bWrapped = true;
789  }
790  else if ( lcl_RotateValue( mnFocusEntry, 0, nEntryCount - 1, bForward ) )
791  {
792  // lcl_RotateValue returns true -> wrapped the entry range -> move to header
794  /* wrapped, if forward from last entry to left header,
795  or if backward from first entry to right header */
796  if ( bForward )
797  bWrapped = true;
798  }
799  }
800  while ( bFindVisible && !IsFocusButtonVisible() && (nOldEntry != mnFocusEntry) );
801 
802  return bWrapped;
803 }
804 
806 {
807  const ScOutlineArray* pArray = GetOutlineArray();
808  if ( !pArray )
809  return false;
810 
811  bool bWrapped = false;
812  size_t nLevelCount = GetLevelCount();
813 
815  {
816  if ( nLevelCount > 0 )
817  bWrapped = lcl_RotateValue( mnFocusLevel, 0, nLevelCount - 1, bForward );
818  }
819  else
820  {
821  const ScOutlineEntry* pEntry = pArray->GetEntry(
823 
824  if ( pEntry )
825  {
826  SCCOLROW nStart = pEntry->GetStart();
827  SCCOLROW nEnd = pEntry->GetEnd();
828  size_t nNewLevel = mnFocusLevel;
829  size_t nNewEntry = 0;
830 
831  bool bFound = false;
832  if ( bForward && (mnFocusLevel + 2 < nLevelCount) )
833  {
834  // next level -> find first child entry
835  nNewLevel = mnFocusLevel + 1;
836  bFound = pArray->GetEntryIndexInRange(nNewLevel, nStart, nEnd, nNewEntry);
837  }
838  else if ( !bForward && (mnFocusLevel > 0) )
839  {
840  // previous level -> find parent entry
841  nNewLevel = mnFocusLevel - 1;
842  bFound = pArray->GetEntryIndex(nNewLevel, nStart, nNewEntry);
843  }
844 
845  if ( bFound && IsButtonVisible( nNewLevel, nNewEntry ) )
846  {
847  mnFocusLevel = nNewLevel;
848  mnFocusEntry = nNewEntry;
849  }
850  }
851  }
852 
853  return bWrapped;
854 }
855 
857 {
858  bool bRet = false;
859  size_t nOldLevel = mnFocusLevel;
860  size_t nOldEntry = mnFocusEntry;
861 
862  do
863  {
864  /* one level up, if backward from left header,
865  or one level down, if forward from right header */
866  if ( (!bForward) && (mnFocusEntry == SC_OL_HEADERENTRY) )
867  bRet |= ImplMoveFocusByLevel( bForward );
868  // move to next/previous entry
869  bool bWrapInLevel = ImplMoveFocusByEntry( bForward, false );
870  bRet |= bWrapInLevel;
871  /* one level up, if wrapped backward to right header,
872  or one level down, if wrapped forward to right header */
873  if ( bForward && bWrapInLevel )
874  bRet |= ImplMoveFocusByLevel( bForward );
875  }
876  while ( !IsFocusButtonVisible() && ((nOldLevel != mnFocusLevel) || (nOldEntry != mnFocusEntry)) );
877 
878  return bRet;
879 }
880 
882 {
883  // first try to find an entry in the same level
884  if ( !IsFocusButtonVisible() )
885  ImplMoveFocusByEntry( bForward, true );
886  // then try to find any other entry
887  if ( !IsFocusButtonVisible() )
888  ImplMoveFocusByTabOrder( bForward );
889 }
890 
892 {
893  HideFocus();
894  ImplMoveFocusByEntry( bForward, true );
895  ShowFocus();
896 }
897 
899 {
900  HideFocus();
901  ImplMoveFocusByLevel( bForward );
902  ShowFocus();
903 }
904 
906 {
907  HideFocus();
908  ImplMoveFocusByTabOrder( bForward );
909  ShowFocus();
910 }
911 
913 {
914  Window::GetFocus();
915  ShowFocus();
916 }
917 
919 {
920  HideFocus();
921  Window::LoseFocus();
922 }
923 
924 // mouse ----------------------------------------------------------------------
925 
926 void ScOutlineWindow::StartMouseTracking( size_t nLevel, size_t nEntry )
927 {
928  mbMTActive = true;
929  mnMTLevel = nLevel;
930  mnMTEntry = nEntry;
931  DrawBorderRel( nLevel, nEntry, true );
932 }
933 
935 {
936  if ( mbMTPressed )
937  DrawBorderRel( mnMTLevel, mnMTEntry, false );
938  mbMTActive = false;
939 }
940 
942 {
943  if ( IsMouseTracking() )
944  {
945  size_t nLevel, nEntry;
946  bool bHit = false;
947 
948  if ( ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry ) )
949  bHit = (nLevel == mnMTLevel) && (nEntry == mnMTEntry);
950 
951  if ( bHit != mbMTPressed )
953  }
954 }
955 
957 {
958  if ( IsMouseTracking() )
959  {
961 
962  size_t nLevel, nEntry;
963  if ( ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry ) )
964  if ( (nLevel == mnMTLevel) && (nEntry == mnMTEntry) )
965  DoFunction( nLevel, nEntry );
966  }
967 }
968 
970 {
971  size_t nLevel, nEntry;
972  bool bHit = ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry );
973  if ( bHit )
974  StartMouseTracking( nLevel, nEntry );
975  else if ( rMEvt.GetClicks() == 2 )
976  {
977  bHit = LineHit( rMEvt.GetPosPixel(), nLevel, nEntry );
978  if ( bHit )
979  DoFunction( nLevel, nEntry );
980  }
981 
982  // if an item has been hit and window is focused, move focus to this item
983  if ( bHit && HasFocus() )
984  {
985  HideFocus();
986  mnFocusLevel = nLevel;
987  mnFocusEntry = nEntry;
988  ShowFocus();
989  }
990 }
991 
992 // keyboard -------------------------------------------------------------------
993 
995 {
996  const vcl::KeyCode& rKCode = rKEvt.GetKeyCode();
997  bool bNoMod = !rKCode.GetModifier();
998  bool bShift = (rKCode.GetModifier() == KEY_SHIFT);
999  bool bCtrl = (rKCode.GetModifier() == KEY_MOD1);
1000 
1001  sal_uInt16 nCode = rKCode.GetCode();
1002  bool bUpDownKey = (nCode == KEY_UP) || (nCode == KEY_DOWN);
1003  bool bLeftRightKey = (nCode == KEY_LEFT) || (nCode == KEY_RIGHT);
1004 
1005  // TAB key
1006  if ( (nCode == KEY_TAB) && (bNoMod || bShift) )
1007  // move forward without SHIFT key
1008  MoveFocusByTabOrder( bNoMod ); // TAB uses logical order, regardless of mirroring
1009 
1010  // LEFT/RIGHT/UP/DOWN keys
1011  else if ( bNoMod && (bUpDownKey || bLeftRightKey) )
1012  {
1013  bool bForward = (nCode == KEY_DOWN) || (nCode == KEY_RIGHT);
1014  if ( mbHoriz == bLeftRightKey )
1015  // move inside level with LEFT/RIGHT in horizontal and with UP/DOWN in vertical
1016  MoveFocusByEntry( bForward != mbMirrorEntries );
1017  else
1018  // move to next/prev level with LEFT/RIGHT in vertical and with UP/DOWN in horizontal
1019  MoveFocusByLevel( bForward != mbMirrorLevels );
1020  }
1021 
1022  // CTRL + number
1023  else if ( bCtrl && (nCode >= KEY_1) && (nCode <= KEY_9) )
1024  {
1025  size_t nLevel = static_cast< size_t >( nCode - KEY_1 );
1026  if ( nLevel < GetLevelCount() )
1027  DoFunction( nLevel, SC_OL_HEADERENTRY );
1028  }
1029 
1030  // other key codes
1031  else switch ( rKCode.GetFullCode() )
1032  {
1033  case KEY_ADD: DoExpand( mnFocusLevel, mnFocusEntry ); break;
1035  case KEY_SPACE:
1037  default: Window::KeyInput( rKEvt );
1038  }
1039 }
1040 
1041 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetClipRegion()
Size GetSizePixel() const
bool mbMirrorEntries
true = Horizontal orientation.
Definition: olinewin.hxx:38
void SetBackground()
size_t mnMTLevel
Last position of main area in entry direction.
Definition: olinewin.hxx:47
bool bVisible
bool IsButtonVisible(size_t nLevel, size_t nEntry) const
Returns true, if the button of the specified entry is visible in the window.
Definition: olinewin.cxx:355
SystemWindow * GetSystemWindow() const
ScVSplitPos WhichV(ScSplitPos ePos)
Definition: viewdata.hxx:718
constexpr sal_uInt16 KEY_MOD1
void DrawImage(const Point &rPos, const Image &rImage, DrawImageFlags nStyle=DrawImageFlags::NONE)
bool mbMirrorLevels
true = mirror the order of entries (including header)
Definition: olinewin.hxx:39
SC_DLLPUBLIC bool IsHidden() const
Definition: olinetab.hxx:49
const ScOutlineArray * GetOutlineArray() const
Returns the outline array of the corresponding document.
Definition: olinewin.cxx:159
void ScrollPixel(tools::Long nDiff)
Scrolls the window content by the specified amount of pixels.
Definition: olinewin.cxx:108
virtual void dispose() override
Definition: olinewin.cxx:76
virtual void EnableRTL(bool bEnable=true)
bool mbHoriz
Which area in split window.
Definition: olinewin.hxx:37
void DrawLineRel(tools::Long nLevelStart, tools::Long nEntryStart, tools::Long nLevelEnd, tools::Long nEntryEnd)
Converts coordinates to real window points and draws the line.
Definition: olinewin.cxx:521
void SetHeaderSize(tools::Long nNewSize)
Sets the size of the header area (width/height dep.
Definition: olinewin.cxx:85
SC_DLLPUBLIC SCCOLROW GetEnd() const
Definition: olinetab.cxx:42
void InvertTracking(const tools::Rectangle &rRect, ShowTrackFlags nFlags)
const size_t SC_OL_HEADERENTRY
Definition: olinewin.cxx:39
size_t mnFocusLevel
Focus rectangle on screen.
Definition: olinewin.hxx:53
long Long
tools::Long GetColRowPos(SCCOLROW nColRowIndex) const
Returns the start coordinate of the specified column/row in the window.
Definition: olinewin.cxx:257
const StyleSettings & GetStyleSettings() const
ScHSplitPos WhichH(ScSplitPos ePos)
Definition: viewdata.hxx:712
const Color & GetFaceColor() const
void ScrollRel(tools::Long nEntryDiff, tools::Long nEntryStart, tools::Long nEntryEnd)
Scrolls the specified range of the window in entry-relative direction.
Definition: olinewin.cxx:140
bool ImplMoveFocusByEntry(bool bForward, bool bFindVisible)
Calculates index of next/previous focus button in the current level (no paint).
Definition: olinewin.cxx:763
ScOutlineEntry * GetEntry(size_t nLevel, size_t nIndex)
Definition: olinetab.cxx:428
sal_uInt16 GetCode() const
bool ImplMoveFocusByTabOrder(bool bForward)
Calculates position of focus button in tab order.
Definition: olinewin.cxx:856
DataChangedEventType GetType() const
bool IsHidden(SCCOLROW nColRowIndex) const
Returns true, if the column/row is hidden.
Definition: olinewin.cxx:172
void DoCollapse(size_t nLevel, size_t nEntry) const
Collapses the specified entry (does nothing with header entries).
Definition: olinewin.cxx:483
virtual void Resize() override
Definition: olinewin.cxx:490
bool IsMouseTracking() const
Returns whether mouse tracking mode is active.
Definition: olinewin.hxx:181
size_t mnMTEntry
Mouse tracking: Level of active button.
Definition: olinewin.hxx:48
constexpr sal_uInt16 KEY_SPACE
void EndMouseTracking()
Ends mouse tracking.
Definition: olinewin.cxx:934
virtual void dispose() override
constexpr sal_uInt16 KEY_ADD
const tools::Long SC_OL_POSOFFSET
Definition: olinewin.cxx:36
Color maLineColor
true = mirror the order of levels, including the border
Definition: olinewin.hxx:41
SCCOL GetPosX(ScHSplitPos eWhich, SCTAB nForTab=-1) const
Definition: viewdata.cxx:1394
void DrawBorderRel(size_t nLevel, size_t nEntry, bool bPressed)
Draws a pressed or unpressed border.
Definition: olinewin.cxx:551
constexpr sal_uInt16 KEY_UP
ScSplitPos
Definition: viewdata.hxx:44
void ShowOutline(bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry, bool bRecord=true, bool bPaint=true)
Definition: dbfunc3.cxx:266
bool GetEntryIndex(size_t nLevel, SCCOLROW nPos, size_t &rnIndex) const
Definition: olinetab.cxx:481
constexpr sal_uInt16 KEY_9
constexpr tools::Long Width() const
sal_uInt16 GetClicks() const
bool LineHit(const Point &rPos, size_t &rnLevel, size_t &rnEntry) const
Returns true, if rPos is over the line of an expanded group.
Definition: olinewin.cxx:451
bool GetEntryIndexInRange(size_t nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t &rnIndex) const
Definition: olinetab.cxx:501
tools::Long GetDepthSize() const
Returns the width/height the window needs to show all levels.
Definition: olinewin.cxx:100
bool GetImagePos(size_t nLevel, size_t nEntry, Point &rPos) const
Calculates the absolute position of the image of the specified outline entry.
Definition: olinewin.cxx:337
void SetEntryAreaClipRegion()
Sets a clip region for the window area without header.
Definition: olinewin.cxx:514
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:23
void DrawRectRel(tools::Long nLevelStart, tools::Long nEntryStart, tools::Long nLevelEnd, tools::Long nEntryEnd)
Converts coordinates to real window points and draws the rectangle.
Definition: olinewin.cxx:527
SCCOL VisibleCellsX(ScHSplitPos eWhichX) const
Definition: viewdata.cxx:2674
constexpr sal_uInt16 KEY_1
tools::Long mnMainFirstPos
Position of the header area in entry direction.
Definition: olinewin.hxx:44
size_t GetDepth() const
Definition: olinetab.hxx:110
AllSettingsFlags GetFlags() const
size_t mnFocusEntry
Level of focused button.
Definition: olinewin.hxx:54
Point GetPoint(tools::Long nLevelPos, tools::Long nEntryPos) const
Returns the point in the window of the specified position.
Definition: olinewin.cxx:211
bool ButtonHit(const Point &rPos, size_t &rnLevel, size_t &rnEntry) const
Returns true, if rPos is inside of a button.
Definition: olinewin.cxx:444
virtual void LoseFocus() override
Definition: olinewin.cxx:918
void DoFunction(size_t nLevel, size_t nEntry) const
Performs an action with the specified item.
Definition: olinewin.cxx:458
ScViewData & mrViewData
Definition: olinewin.hxx:35
sal_uInt16 GetModifier() const
bool mbMTActive
Mouse tracking: Entry index of active button.
Definition: olinewin.hxx:49
void GetVisibleRange(SCCOLROW &rnColRowStart, SCCOLROW &rnColRowEnd) const
Returns the currently visible column/row range.
Definition: olinewin.cxx:193
SCROW GetPosY(ScVSplitPos eWhich, SCTAB nForTab=-1) const
Definition: viewdata.cxx:1408
void DrawLine(const Point &rStartPt, const Point &rEndPt)
sal_uInt16 nCode
tools::Long GetHeaderEntryPos() const
Returns the entry position of header images.
Definition: olinewin.cxx:265
void DrawRect(const tools::Rectangle &rRect)
constexpr bool IsEmpty() const
SCROW VisibleCellsY(ScVSplitPos eWhichY) const
Definition: viewdata.cxx:2679
bool IsFiltered(SCCOLROW nColRowIndex) const
Returns true, if the column/row is filtered.
Definition: olinewin.cxx:179
constexpr sal_uInt16 KEY_DOWN
void SetLineColor()
void MoveFocusByEntry(bool bForward)
Focuses next/previous button in the current level.
Definition: olinewin.cxx:891
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: document.cxx:4476
void HideFocus()
Erases the focus rectangle from the focused button.
Definition: olinewin.cxx:592
virtual void GetFocus() override
Definition: olinewin.cxx:912
Point GetScrPos(SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, bool bAllowNeg=false, SCTAB nForTab=-1) const
Definition: viewdata.cxx:2366
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: olinewin.cxx:969
SC_DLLPUBLIC SCCOLROW GetStart() const
Definition: olinetab.hxx:42
size_t GetLevelFromPos(tools::Long nLevelPos) const
Returns the level of the passed pixel position.
Definition: olinewin.cxx:248
SC_DLLPUBLIC bool RowFiltered(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4530
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: olinewin.cxx:501
const ScOutlineArray & GetRowArray() const
Definition: olinetab.hxx:160
tools::Long GetOutputSizeLevel() const
Returns the window size for the level coordinate.
Definition: olinewin.cxx:222
const ScOutlineArray & GetColArray() const
Definition: olinetab.hxx:158
size_t GetCount(size_t nLevel) const
Definition: olinetab.cxx:456
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
tools::Rectangle maFocusRect
Mouse tracking: Button currently drawn pressed?
Definition: olinewin.hxx:52
virtual void MouseMove(const MouseEvent &rMEvt) override
Definition: olinewin.cxx:941
void SetFillColor()
const AllSettings & GetSettings() const
float u
size_t GetLevelCount() const
Returns the count of levels of the outline array.
Definition: olinewin.cxx:234
tools::Long mnMainLastPos
First position of main area in entry direction.
Definition: olinewin.hxx:45
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: olinewin.cxx:618
void SelectLevel(bool bColumns, sal_uInt16 nLevel, bool bRecord=true)
Definition: dbfunc3.cxx:232
ScDocument & GetDoc() const
Returns the calc document.
Definition: olinewin.hxx:81
tools::Long mnHeaderPos
Size of the header area in entry direction.
Definition: olinewin.hxx:43
const tools::Long SC_OL_BITMAPSIZE
Definition: olinewin.cxx:35
virtual ~ScOutlineWindow() override
Definition: olinewin.cxx:71
void ShowFocus()
Draws the focus rectangle into the focused button.
Definition: olinewin.cxx:567
constexpr sal_uInt16 KEY_RETURN
ScOutlineWindow(vcl::Window *pParent, ScOutlineMode eMode, ScViewData *pViewData, ScSplitPos eWhich)
Do not redraw focus in next Paint().
Definition: olinewin.cxx:41
ScDBFunc * GetView() const
Definition: viewdata.cxx:855
ScOutlineMode
Definition: olinewin.hxx:28
constexpr sal_uInt16 KEY_RIGHT
const size_t SC_OL_NOLEVEL
Definition: olinewin.cxx:38
bool mbDontDrawFocus
Entry index of focused button.
Definition: olinewin.hxx:55
bool IsFirstVisible(SCCOLROW nColRowIndex) const
Returns true, if all columns/rows before nColRowIndex are hidden.
Definition: olinewin.cxx:185
const vcl::KeyCode & GetKeyCode() const
bool mbMTPressed
Mouse tracking active?
Definition: olinewin.hxx:50
bool ImplMoveFocusByLevel(bool bForward)
Calculates position of focus button in next/previous level (no paint).
Definition: olinewin.cxx:805
bool IsFocusButtonVisible() const
Returns true, if the focused button is visible in the window.
Definition: olinewin.cxx:758
tools::Rectangle GetRectangle(tools::Long nLevelStart, tools::Long nEntryStart, tools::Long nLevelEnd, tools::Long nEntryEnd) const
Returns the rectangle in the window of the specified position.
Definition: olinewin.cxx:216
constexpr sal_uInt16 KEY_SUBTRACT
void HideOutline(bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry, bool bRecord=true, bool bPaint=true)
Definition: dbfunc3.cxx:286
tools::Long mnHeaderSize
Line color for expanded groups.
Definition: olinewin.hxx:42
virtual void Scroll(tools::Long nHorzScroll, tools::Long nVertScroll, ScrollFlags nFlags=ScrollFlags::NONE)
void InitSettings()
Initializes color and image settings.
Definition: olinewin.cxx:151
const Color & GetButtonTextColor() const
constexpr tools::Long Height() const
void DrawImageRel(tools::Long nLevelPos, tools::Long nEntryPos, const OUString &rId)
Draws the specified image unpressed.
Definition: olinewin.cxx:541
::OutputDevice const * GetOutDev() const
SC_DLLPUBLIC ScOutlineTable * GetOutlineTable(SCTAB nTab, bool bCreate=false)
Definition: documen3.cxx:736
tools::Long GetLevelPos(size_t nLevel) const
Returns the pixel position of the specified level.
Definition: olinewin.cxx:241
ScSplitPos meWhich
View data containing the document.
Definition: olinewin.hxx:36
void StartMouseTracking(size_t nLevel, size_t nEntry)
Starts mouse tracking after click on a button.
Definition: olinewin.cxx:926
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
SCTAB GetTab() const
Returns the current sheet index.
Definition: olinewin.hxx:83
const Point & GetPosPixel() const
sal_uInt16 GetFullCode() const
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
Definition: document.cxx:985
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4460
Size GetOutputSizePixel() const
void MoveFocusByTabOrder(bool bForward)
Focuses next/previous button in tab order.
Definition: olinewin.cxx:905
OUString sId
const std::u16string_view aLevelBmps[]
Definition: olinewin.cxx:606
void MoveFocusByLevel(bool bForward)
Focuses button in next/previous level.
Definition: olinewin.cxx:898
void DoExpand(size_t nLevel, size_t nEntry) const
Expands the specified entry (does nothing with header entries).
Definition: olinewin.cxx:476
tools::Long GetOutputSizeEntry() const
Returns the window size for the entry coordinate.
Definition: olinewin.cxx:228
constexpr sal_uInt16 KEY_LEFT
const ScOutlineEntry * GetOutlineEntry(size_t nLevel, size_t nEntry) const
Returns the specified outline entry.
Definition: olinewin.cxx:166
constexpr sal_uInt16 KEY_SHIFT
bool GetEntryPos(size_t nLevel, size_t nEntry, tools::Long &rnStartPos, tools::Long &rnEndPos, tools::Long &rnImagePos) const
Calculates the coordinates the outline entry takes in the window.
Definition: olinewin.cxx:270
const Wallpaper & GetBackground() const
bool HasFocus() const
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: olinewin.cxx:994
static bool lcl_RotateValue(size_t &rnValue, size_t nMin, size_t nMax, bool bForward)
Increments or decrements a value and wraps at the specified limits.
Definition: olinewin.cxx:730
virtual void MouseButtonUp(const MouseEvent &rMEvt) override
Definition: olinewin.cxx:956
SC_DLLPUBLIC bool IsVisible() const
Definition: olinetab.hxx:54
sal_uInt16 nPos
constexpr sal_uInt16 KEY_TAB
void ImplMoveFocusToVisible(bool bForward)
If the focused entry is invisible, tries to move to visible position.
Definition: olinewin.cxx:881
bool ItemHit(const Point &rPos, size_t &rnLevel, size_t &rnEntry, bool &rbButton) const
Returns true, if rPos is inside of a button or over the line of an expanded group.
Definition: olinewin.cxx:373