LibreOffice Module sc (master)  1
tabview.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 <scitems.hxx>
21 #include <sfx2/viewfrm.hxx>
22 #include <sfx2/bindings.hxx>
23 #include <vcl/commandevent.hxx>
24 #include <vcl/help.hxx>
25 #include <vcl/settings.hxx>
26 #include <sal/log.hxx>
27 #include <tools/svborder.hxx>
28 #include <tools/json_writer.hxx>
29 #include <o3tl/unit_conversion.hxx>
30 
31 #include <pagedata.hxx>
32 #include <tabview.hxx>
33 #include <tabvwsh.hxx>
34 #include <document.hxx>
35 #include <gridwin.hxx>
36 #include <olinewin.hxx>
37 #include <olinetab.hxx>
38 #include <tabsplit.hxx>
39 #include <colrowba.hxx>
40 #include <tabcont.hxx>
41 #include <scmod.hxx>
42 #include <sc.hrc>
43 #include <globstr.hrc>
44 #include <scresid.hxx>
45 #include <drawview.hxx>
46 #include <docsh.hxx>
47 #include <viewuno.hxx>
48 #include <appoptio.hxx>
49 #include <attrib.hxx>
50 #include <spellcheckcontext.hxx>
51 #include <comphelper/lok.hxx>
52 #include <sfx2/lokhelper.hxx>
53 #include <osl/diagnose.h>
54 
55 #include <boost/property_tree/ptree.hpp>
56 #include <boost/property_tree/json_parser.hpp>
57 
58 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
59 
60 #include <algorithm>
61 
63 
64 #define SPLIT_MARGIN 30
65 #define SPLIT_HANDLE_SIZE 5
66 constexpr sal_Int32 TAB_HEIGHT_MARGIN = 10;
67 
68 #define SC_ICONSIZE 36
69 
70 #define SC_SCROLLBAR_MIN 30
71 #define SC_TABBAR_MIN 6
72 
73 using namespace ::com::sun::star;
74 
75 // Corner-Button
76 
78  Window( pParent, WinBits( 0 ) ),
79  pViewData( pData )
80 {
81  EnableRTL( false );
82 }
83 
85 {
86 }
87 
88 void ScCornerButton::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
89 {
90  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
91  SetBackground(rStyleSettings.GetFaceColor());
92 
93  Size aSize(GetOutputSizePixel());
94  tools::Long nPosX = aSize.Width() - 1;
95  tools::Long nPosY = aSize.Height() - 1;
96 
97  Window::Paint(rRenderContext, rRect);
98 
99  bool bLayoutRTL = pViewData->GetDocument().IsLayoutRTL( pViewData->GetTabNo() );
100  tools::Long nDarkX = bLayoutRTL ? 0 : nPosX;
101 
102  // both buttons have the same look now - only dark right/bottom lines
103  rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
104  rRenderContext.DrawLine(Point(0, nPosY), Point(nPosX, nPosY));
105  rRenderContext.DrawLine(Point(nDarkX, 0), Point(nDarkX, nPosY));
106 }
107 
109 {
110  Window::StateChanged( nType );
111 
112  const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
113  SetBackground( rStyleSettings.GetFaceColor() );
114  Invalidate();
115 }
116 
118 {
119  Window::DataChanged( rDCEvt );
120 
121  const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
122  SetBackground( rStyleSettings.GetFaceColor() );
123  Invalidate();
124 }
125 
127 {
128  Invalidate();
129 }
130 
132 {
133  ScModule* pScMod = SC_MOD();
134  bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
135  if (!bDisable)
136  {
137  ScTabViewShell* pViewSh = pViewData->GetViewShell();
138  pViewSh->SetActive(); // Appear and SetViewFrame
139  pViewSh->ActiveGrabFocus();
140 
141  bool bControl = rMEvt.IsMod1();
142  pViewSh->SelectAll( bControl );
143  }
144 }
145 namespace
146 {
147 
148 bool lcl_HasColOutline( const ScViewData& rViewData )
149 {
150  const ScOutlineTable* pTable = rViewData.GetDocument().GetOutlineTable(rViewData.GetTabNo());
151  if (pTable)
152  {
153  const ScOutlineArray& rArray = pTable->GetColArray();
154  if ( rArray.GetDepth() > 0 )
155  return true;
156  }
157  return false;
158 }
159 
160 bool lcl_HasRowOutline( const ScViewData& rViewData )
161 {
162  const ScOutlineTable* pTable = rViewData.GetDocument().GetOutlineTable(rViewData.GetTabNo());
163  if (pTable)
164  {
165  const ScOutlineArray& rArray = pTable->GetRowArray();
166  if ( rArray.GetDepth() > 0 )
167  return true;
168  }
169  return false;
170 }
171 
172 } // anonymous namespace
173 
174 ScTabView::ScTabView( vcl::Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
175  pFrameWin( pParent ),
176  aViewData( rDocSh, pViewShell ),
177  aFunctionSet( &aViewData ),
178  aHdrFunc( &aViewData ),
179  aVScrollTop( VclPtr<ScrollBar>::Create( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ) ),
180  aVScrollBottom( VclPtr<ScrollBar>::Create( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ) ),
181  aHScrollLeft( VclPtr<ScrollBar>::Create( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ) ),
182  aHScrollRight( VclPtr<ScrollBar>::Create( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ) ),
183  aCornerButton( VclPtr<ScCornerButton>::Create( pFrameWin, &aViewData ) ),
184  aTopButton( VclPtr<ScCornerButton>::Create( pFrameWin, &aViewData ) ),
185  aScrollBarBox( VclPtr<ScrollBarBox>::Create( pFrameWin, WB_SIZEABLE ) ),
186  aScrollTimer("ScTabView aScrollTimer"),
187  pTimerWindow( nullptr ),
188  aExtraEditViewManager( pViewShell, pGridWin ),
189  nTipVisible( nullptr ),
190  nTipAlign( QuickHelpFlags::NONE ),
191  nPrevDragPos( 0 ),
192  meBlockMode(None),
193  nBlockStartX( 0 ),
194  nBlockStartXOrig( 0 ),
195  nBlockEndX( 0 ),
196  nBlockStartY( 0 ),
197  nBlockStartYOrig( 0 ),
198  nBlockEndY( 0 ),
199  nBlockStartZ( 0 ),
200  nBlockEndZ( 0 ),
201  nOldCurX( 0 ),
202  nOldCurY( 0 ),
203  mfPendingTabBarWidth( -1.0 ),
204  mnLOKStartHeaderRow( -2 ),
205  mnLOKEndHeaderRow( -1 ),
206  mnLOKStartHeaderCol( -2 ),
207  mnLOKEndHeaderCol( -1 ),
208  bMinimized( false ),
209  bInUpdateHeader( false ),
210  bInActivatePart( false ),
211  bInZoomUpdate( false ),
212  bMoveIsShift( false ),
213  bDrawSelMode( false ),
214  bLockPaintBrush( false ),
215  bDragging( false ),
216  bBlockNeg( false ),
217  bBlockCols( false ),
218  bBlockRows( false ),
219  mbInlineWithScrollbar( false )
220 {
221  Init();
222 }
223 
224 void ScTabView::InitScrollBar( ScrollBar& rScrollBar, tools::Long nMaxVal )
225 {
226  rScrollBar.SetRange( Range( 0, nMaxVal ) );
227  rScrollBar.SetLineSize( 1 );
228  rScrollBar.SetPageSize( 1 ); // is queried separately
229  rScrollBar.SetVisibleSize( 10 ); // is reset by Resize
230 
231  rScrollBar.SetScrollHdl( LINK(this, ScTabView, ScrollHdl) );
232  rScrollBar.SetEndScrollHdl( LINK(this, ScTabView, EndScrollHdl) );
233 
235 }
236 
237 // Scroll-Timer
238 
239 void ScTabView::SetTimer( ScGridWindow* pWin, const MouseEvent& rMEvt )
240 {
241  pTimerWindow = pWin;
242  aTimerMEvt = rMEvt;
244 }
245 
247 {
248  aScrollTimer.Stop();
249  pTimerWindow = nullptr;
250 }
251 
252 IMPL_LINK_NOARG(ScTabView, TimerHdl, Timer *, void)
253 {
254  if (pTimerWindow)
255  pTimerWindow->MouseMove( aTimerMEvt );
256 }
257 
258 // --- Resize ---------------------------------------------------------------------
259 
260 static void lcl_SetPosSize( vcl::Window& rWindow, const Point& rPos, const Size& rSize,
261  tools::Long nTotalWidth, bool bLayoutRTL )
262 {
263  Point aNewPos = rPos;
264  if ( bLayoutRTL )
265  {
266  aNewPos.setX( nTotalWidth - rPos.X() - rSize.Width() );
267  if ( aNewPos == rWindow.GetPosPixel() && rSize.Width() != rWindow.GetSizePixel().Width() )
268  {
269  // Document windows are manually painted right-to-left, so they need to
270  // be repainted if the size changes.
271  rWindow.Invalidate();
272  }
273  }
274  rWindow.SetPosSizePixel( aNewPos, rSize );
275 }
276 
277 void ScTabView::DoResize( const Point& rOffset, const Size& rSize, bool bInner )
278 {
279  HideListBox();
280 
281  bool bHasHint = HasHintWindow();
282  if (bHasHint)
284 
285  bool bLayoutRTL = aViewData.GetDocument().IsLayoutRTL( aViewData.GetTabNo() );
286  tools::Long nTotalWidth = rSize.Width();
287  if ( bLayoutRTL )
288  nTotalWidth += 2*rOffset.X();
289 
290  bool bVScroll = aViewData.IsVScrollMode();
291  bool bHScroll = aViewData.IsHScrollMode();
292  bool bTabControl = aViewData.IsTabMode();
293  bool bHeaders = aViewData.IsHeaderMode();
294  bool bOutlMode = aViewData.IsOutlineMode();
295  bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
296  bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
297 
298  if ( aViewData.GetDocShell()->IsPreview() )
299  bHScroll = bVScroll = bTabControl = bHeaders = bHOutline = bVOutline = false;
300 
301  tools::Long nBarX = 0;
302  tools::Long nBarY = 0;
303  tools::Long nOutlineX = 0;
304  tools::Long nOutlineY = 0;
305  tools::Long nOutPosX;
306  tools::Long nOutPosY;
307 
308  tools::Long nPosX = rOffset.X();
309  tools::Long nPosY = rOffset.Y();
310  tools::Long nSizeX = rSize.Width();
311  tools::Long nSizeY = rSize.Height();
312 
313  bMinimized = ( nSizeX<=SC_ICONSIZE || nSizeY<=SC_ICONSIZE );
314  if ( bMinimized )
315  return;
316 
317  float fScaleFactor = pFrameWin->GetDPIScaleFactor();
318 
319  tools::Long nSplitSizeX = SPLIT_HANDLE_SIZE * fScaleFactor;
321  nSplitSizeX = 1;
322  tools::Long nSplitSizeY = SPLIT_HANDLE_SIZE * fScaleFactor;
324  nSplitSizeY = 1;
325 
326  aBorderPos = rOffset;
327  aFrameSize = rSize;
328 
329  const StyleSettings& rStyleSettings = pFrameWin->GetSettings().GetStyleSettings();
330 
331 
332  Size aFontSize = rStyleSettings.GetTabFont().GetFontSize();
333  MapMode aPtMapMode(MapUnit::MapPoint);
334  aFontSize = pFrameWin->LogicToPixel(aFontSize, aPtMapMode);
335  sal_Int32 nTabHeight = aFontSize.Height() + TAB_HEIGHT_MARGIN;
336 
338  {
339  if ( aViewData.GetHSplitPos() > nSizeX - SPLIT_MARGIN )
340  {
344  InvalidateSplit();
345  }
346  }
348  {
349  if ( aViewData.GetVSplitPos() > nSizeY - SPLIT_MARGIN )
350  {
354  InvalidateSplit();
355  }
356  }
357 
358  UpdateShow();
359 
360  if (bHScroll || bVScroll) // Scrollbars horizontal or vertical
361  {
362  tools::Long nScrollBarSize = rStyleSettings.GetScrollBarSize();
363  if (bVScroll)
364  {
365  nBarX = nScrollBarSize;
366  nSizeX -= nBarX;
367  }
368  if (bHScroll)
369  {
370  nBarY = nTabHeight;
371 
373  nBarY += nScrollBarSize;
374 
375  nSizeY -= nBarY;
376  }
377 
378  // window at the bottom right
379  lcl_SetPosSize( *aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
380  nTotalWidth, bLayoutRTL );
381 
382  if (bHScroll) // Scrollbars horizontal
383  {
384  tools::Long nSizeLt = 0; // left scroll bar
385  tools::Long nSizeRt = 0; // right scroll bar
386  tools::Long nSizeSp = 0; // splitter
387 
388  switch (aViewData.GetHSplitMode())
389  {
390  case SC_SPLIT_NONE:
391  nSizeSp = nSplitSizeX;
392  nSizeLt = nSizeX - nSizeSp; // Convert the corner
393  break;
394  case SC_SPLIT_NORMAL:
395  nSizeSp = nSplitSizeX;
396  nSizeLt = aViewData.GetHSplitPos();
397  break;
398  case SC_SPLIT_FIX:
399  nSizeSp = 0;
400  nSizeLt = 0;
401  break;
402  }
403  nSizeRt = nSizeX - nSizeLt - nSizeSp;
404 
405  tools::Long nTabSize = 0;
406 
407  if (bTabControl)
408  {
409  // pending relative tab bar width from extended document options
410  if( mfPendingTabBarWidth >= 0.0 )
411  {
413  mfPendingTabBarWidth = -1.0;
414  }
415 
417  {
418  nTabSize = pTabControl->GetSizePixel().Width();
419 
420  if ( aViewData.GetHSplitMode() != SC_SPLIT_FIX ) // left Scrollbar
421  {
422  if (nTabSize > nSizeLt-SC_SCROLLBAR_MIN)
423  nTabSize = nSizeLt-SC_SCROLLBAR_MIN;
424  if (nTabSize < SC_TABBAR_MIN)
425  nTabSize = SC_TABBAR_MIN;
426  nSizeLt -= nTabSize;
427  }
428  else // right Scrollbar
429  {
430  if (nTabSize > nSizeRt-SC_SCROLLBAR_MIN)
431  nTabSize = nSizeRt-SC_SCROLLBAR_MIN;
432  if (nTabSize < SC_TABBAR_MIN)
433  nTabSize = SC_TABBAR_MIN;
434  nSizeRt -= nTabSize;
435  }
436  }
437  }
438 
440  {
441  Point aTabPoint(nPosX, nPosY + nSizeY);
442  Size aTabSize(nTabSize, nBarY);
443  lcl_SetPosSize(*pTabControl, aTabPoint, aTabSize, nTotalWidth, bLayoutRTL);
444  pTabControl->SetSheetLayoutRTL(bLayoutRTL);
445 
446  Point aHScrollLeftPoint(nPosX + nTabSize, nPosY + nSizeY);
447  Size aHScrollLeftSize(nSizeLt, nBarY);
448  lcl_SetPosSize(*aHScrollLeft, aHScrollLeftPoint, aHScrollLeftSize, nTotalWidth, bLayoutRTL);
449 
450  Point aHSplitterPoint(nPosX + nTabSize + nSizeLt, nPosY + nSizeY);
451  Size aHSplitterSize(nSizeSp, nBarY);
452  lcl_SetPosSize(*pHSplitter, aHSplitterPoint, aHSplitterSize, nTotalWidth, bLayoutRTL);
453 
454  Point aHScrollRightPoint(nPosX + nTabSize + nSizeLt + nSizeSp, nPosY + nSizeY);
455  Size aHScrollRightSize(nSizeRt, nBarY);
456  lcl_SetPosSize(*aHScrollRight, aHScrollRightPoint, aHScrollRightSize, nTotalWidth, bLayoutRTL);
457  }
458  else
459  {
460  Point aTabPoint(nPosX, nPosY + nSizeY + nScrollBarSize);
461  Size aTabSize(nSizeX, nTabHeight);
462  lcl_SetPosSize(*pTabControl, aTabPoint, aTabSize, nTotalWidth, bLayoutRTL);
463  pTabControl->SetSheetLayoutRTL(bLayoutRTL);
464 
465  Point aHScrollLeftPoint(nPosX, nPosY + nSizeY);
466  Size aHScrollLeftSize(nSizeLt, nScrollBarSize);
467  lcl_SetPosSize(*aHScrollLeft, aHScrollLeftPoint, aHScrollLeftSize, nTotalWidth, bLayoutRTL);
468 
469  Point aHSplitterPoint(nPosX + nSizeLt, nPosY + nSizeY);
470  Size aHSplitterSize(nSizeSp, nScrollBarSize);
471  lcl_SetPosSize(*pHSplitter, aHSplitterPoint, aHSplitterSize, nTotalWidth, bLayoutRTL);
472 
473  Point aHScrollRightPoint(nPosX + nSizeLt + nSizeSp, nPosY + nSizeY);
474  Size aHScrollRightSize(nSizeRt, nScrollBarSize);
475  lcl_SetPosSize(*aHScrollRight, aHScrollRightPoint, aHScrollRightSize, nTotalWidth, bLayoutRTL);
476  }
477  // SetDragRectPixel is done below
478  }
479 
480  if (bVScroll)
481  {
482  tools::Long nSizeUp = 0; // upper scroll bar
483  tools::Long nSizeSp = 0; // splitter
484  tools::Long nSizeDn; // lower scroll bar
485 
486  switch (aViewData.GetVSplitMode())
487  {
488  case SC_SPLIT_NONE:
489  nSizeUp = 0;
490  nSizeSp = nSplitSizeY;
491  break;
492  case SC_SPLIT_NORMAL:
493  nSizeUp = aViewData.GetVSplitPos();
494  nSizeSp = nSplitSizeY;
495  break;
496  case SC_SPLIT_FIX:
497  nSizeUp = 0;
498  nSizeSp = 0;
499  break;
500  }
501  nSizeDn = nSizeY - nSizeUp - nSizeSp;
502 
503  lcl_SetPosSize( *aVScrollTop, Point(nPosX + nSizeX, nPosY),
504  Size(nBarX, nSizeUp), nTotalWidth, bLayoutRTL );
505  lcl_SetPosSize( *pVSplitter, Point( nPosX + nSizeX, nPosY+nSizeUp ),
506  Size( nBarX, nSizeSp ), nTotalWidth, bLayoutRTL );
507  lcl_SetPosSize( *aVScrollBottom, Point(nPosX + nSizeX,
508  nPosY + nSizeUp + nSizeSp),
509  Size(nBarX, nSizeDn), nTotalWidth, bLayoutRTL );
510 
511  // SetDragRectPixel is done below
512  }
513  }
514 
515  // SetDragRectPixel also without Scrollbars etc., when already split
516  if ( bHScroll || aViewData.GetHSplitMode() != SC_SPLIT_NONE )
518  tools::Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
519  if ( bVScroll || aViewData.GetVSplitMode() != SC_SPLIT_NONE )
521  tools::Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
522 
523  if (bTabControl && ! bHScroll )
524  {
525  nBarY = aHScrollLeft->GetSizePixel().Height();
526  nBarX = aVScrollBottom->GetSizePixel().Width();
527 
528  tools::Long nSize1 = nSizeX;
529 
530  tools::Long nTabSize = nSize1;
531  if (nTabSize < 0) nTabSize = 0;
532 
533  lcl_SetPosSize( *pTabControl, Point(nPosX, nPosY+nSizeY-nBarY),
534  Size(nTabSize, nBarY), nTotalWidth, bLayoutRTL );
535  nSizeY -= nBarY;
536  lcl_SetPosSize( *aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
537  nTotalWidth, bLayoutRTL );
538 
539  if( bVScroll )
540  {
541  Size aVScrSize = aVScrollBottom->GetSizePixel();
542  aVScrSize.AdjustHeight( -nBarY );
543  aVScrollBottom->SetSizePixel( aVScrSize );
544  }
545  }
546 
547  nOutPosX = nPosX;
548  nOutPosY = nPosY;
549 
550  // Outline-Controls
551  if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
552  {
553  nOutlineX = pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
554  nSizeX -= nOutlineX;
555  nPosX += nOutlineX;
556  }
557  if (bHOutline && pColOutline[SC_SPLIT_LEFT])
558  {
559  nOutlineY = pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
560  nSizeY -= nOutlineY;
561  nPosY += nOutlineY;
562  }
563 
564  if (bHeaders) // column/row header
565  {
566  nBarX = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
567  nBarY = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
568  nSizeX -= nBarX;
569  nSizeY -= nBarY;
570  nPosX += nBarX;
571  nPosY += nBarY;
572  }
573  else
574  nBarX = nBarY = 0;
575 
576  // evaluate splitter
577 
578  tools::Long nLeftSize = nSizeX;
579  tools::Long nRightSize = 0;
580  tools::Long nTopSize = 0;
581  tools::Long nBottomSize = nSizeY;
582  tools::Long nSplitPosX = nPosX;
583  tools::Long nSplitPosY = nPosY;
584 
586  {
587  tools::Long nSplitHeight = rSize.Height();
589  {
590  // Do not allow freeze splitter to overlap scroll bar/tab bar
591  if ( bHScroll )
592  nSplitHeight -= aHScrollLeft->GetSizePixel().Height();
593  else if ( bTabControl && pTabControl )
594  nSplitHeight -= pTabControl->GetSizePixel().Height();
595  }
596  nSplitPosX = aViewData.GetHSplitPos();
598  Point(nSplitPosX, nOutPosY),
599  Size(nSplitSizeX, nSplitHeight - nTabHeight), nTotalWidth, bLayoutRTL);
600  nLeftSize = nSplitPosX - nPosX;
601  nSplitPosX += nSplitSizeX;
602  nRightSize = nSizeX - nLeftSize - nSplitSizeX;
603  }
605  {
606  tools::Long nSplitWidth = rSize.Width();
607  if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && bVScroll )
608  nSplitWidth -= aVScrollBottom->GetSizePixel().Width();
609  nSplitPosY = aViewData.GetVSplitPos();
611  Point( nOutPosX, nSplitPosY ), Size( nSplitWidth, nSplitSizeY ), nTotalWidth, bLayoutRTL );
612  nTopSize = nSplitPosY - nPosY;
613  nSplitPosY += nSplitSizeY;
614  nBottomSize = nSizeY - nTopSize - nSplitSizeY;
615  }
616 
617  // ShowHide for pColOutline / pRowOutline happens in UpdateShow
618 
619  if (bHOutline) // Outline-Controls
620  {
621  if (pColOutline[SC_SPLIT_LEFT])
622  {
623  pColOutline[SC_SPLIT_LEFT]->SetHeaderSize( nBarX );
624  lcl_SetPosSize( *pColOutline[SC_SPLIT_LEFT],
625  Point(nPosX-nBarX,nOutPosY), Size(nLeftSize+nBarX,nOutlineY), nTotalWidth, bLayoutRTL );
626  }
628  {
629  pColOutline[SC_SPLIT_RIGHT]->SetHeaderSize( 0 ); // always call to update RTL flag
630  lcl_SetPosSize( *pColOutline[SC_SPLIT_RIGHT],
631  Point(nSplitPosX,nOutPosY), Size(nRightSize,nOutlineY), nTotalWidth, bLayoutRTL );
632  }
633  }
634  if (bVOutline)
635  {
636  if (nTopSize)
637  {
638  if (pRowOutline[SC_SPLIT_TOP] && pRowOutline[SC_SPLIT_BOTTOM])
639  {
640  pRowOutline[SC_SPLIT_TOP]->SetHeaderSize( nBarY );
642  Point(nOutPosX,nPosY-nBarY), Size(nOutlineX,nTopSize+nBarY), nTotalWidth, bLayoutRTL );
643  pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( 0 );
644  lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
645  Point(nOutPosX,nSplitPosY), Size(nOutlineX,nBottomSize), nTotalWidth, bLayoutRTL );
646  }
647  }
648  else if (pRowOutline[SC_SPLIT_BOTTOM])
649  {
650  pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( nBarY );
651  lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
652  Point(nOutPosX,nSplitPosY-nBarY), Size(nOutlineX,nBottomSize+nBarY), nTotalWidth, bLayoutRTL );
653  }
654  }
655  if (bHOutline && bVOutline)
656  {
657  lcl_SetPosSize( *aTopButton, Point(nOutPosX,nOutPosY), Size(nOutlineX,nOutlineY), nTotalWidth, bLayoutRTL );
658  aTopButton->Show();
659  }
660  else
661  aTopButton->Hide();
662 
663  if (bHeaders) // column/row header
664  {
665  lcl_SetPosSize( *pColBar[SC_SPLIT_LEFT],
666  Point(nPosX,nPosY-nBarY), Size(nLeftSize,nBarY), nTotalWidth, bLayoutRTL );
667  if (pColBar[SC_SPLIT_RIGHT])
668  lcl_SetPosSize( *pColBar[SC_SPLIT_RIGHT],
669  Point(nSplitPosX,nPosY-nBarY), Size(nRightSize,nBarY), nTotalWidth, bLayoutRTL );
670 
671  if (pRowBar[SC_SPLIT_TOP])
672  lcl_SetPosSize( *pRowBar[SC_SPLIT_TOP],
673  Point(nPosX-nBarX,nPosY), Size(nBarX,nTopSize), nTotalWidth, bLayoutRTL );
674  lcl_SetPosSize( *pRowBar[SC_SPLIT_BOTTOM],
675  Point(nPosX-nBarX,nSplitPosY), Size(nBarX,nBottomSize), nTotalWidth, bLayoutRTL );
676 
677  lcl_SetPosSize( *aCornerButton, Point(nPosX-nBarX,nPosY-nBarY), Size(nBarX,nBarY), nTotalWidth, bLayoutRTL );
678  aCornerButton->Show();
679  pColBar[SC_SPLIT_LEFT]->Show();
680  pRowBar[SC_SPLIT_BOTTOM]->Show();
681  }
682  else
683  {
684  aCornerButton->Hide();
685  pColBar[SC_SPLIT_LEFT]->Hide(); // always here
686  pRowBar[SC_SPLIT_BOTTOM]->Hide();
687  }
688 
689  // Grid-Windows
690 
691  if (bInner)
692  {
693  tools::Long nInnerPosX = bLayoutRTL ? ( nTotalWidth - nPosX - nLeftSize ) : nPosX;
694  pGridWin[SC_SPLIT_BOTTOMLEFT]->SetPosPixel( Point(nInnerPosX,nSplitPosY) );
695  }
696  else
697  {
699  Point(nPosX,nSplitPosY), Size(nLeftSize,nBottomSize), nTotalWidth, bLayoutRTL );
702  Point(nSplitPosX,nSplitPosY), Size(nRightSize,nBottomSize), nTotalWidth, bLayoutRTL );
705  Point(nPosX,nPosY), Size(nLeftSize,nTopSize), nTotalWidth, bLayoutRTL );
708  Point(nSplitPosX,nPosY), Size(nRightSize,nTopSize), nTotalWidth, bLayoutRTL );
709  }
710 
711  // update scroll bars
712 
713  if (!bInUpdateHeader)
714  {
715  UpdateScrollBars(); // don't reset scroll bars when scrolling
717 
718  InterpretVisible(); // have everything calculated before painting
719  }
720 
721  if (bHasHint)
722  TestHintWindow(); // reposition
723 
724  UpdateVarZoom(); // update variable zoom types (after resizing GridWindows)
725 
727  aViewData.GetViewShell()->BroadcastAccessibility(SfxHint(SfxHintId::ScAccWindowResized));
728 }
729 
731 {
732  // update variable zoom types
733 
734  SvxZoomType eZoomType = GetZoomType();
735  if (eZoomType == SvxZoomType::PERCENT || bInZoomUpdate)
736  return;
737 
738  bInZoomUpdate = true;
739  const Fraction& rOldX = GetViewData().GetZoomX();
740  const Fraction& rOldY = GetViewData().GetZoomY();
741  tools::Long nOldPercent = tools::Long(rOldY * 100);
742  sal_uInt16 nNewZoom = CalcZoom( eZoomType, static_cast<sal_uInt16>(nOldPercent) );
743  Fraction aNew( nNewZoom, 100 );
744 
745  if ( aNew != rOldX || aNew != rOldY )
746  {
747  SetZoom( aNew, aNew, false ); // always separately per sheet
748  PaintGrid();
749  PaintTop();
750  PaintLeft();
751  aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
752  aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
753  aViewData.GetBindings().Invalidate(SID_ZOOM_IN);
754  aViewData.GetBindings().Invalidate(SID_ZOOM_OUT);
755  }
756  bInZoomUpdate = false;
757 }
758 
760 {
761  bool bResize = false;
763  if (aViewData.UpdateFixX())
764  bResize = true;
766  if (aViewData.UpdateFixY())
767  bResize = true;
768  if (bResize)
769  RepeatResize(false);
770 }
771 
772 void ScTabView::RepeatResize( bool bUpdateFix )
773 {
774  if ( bUpdateFix )
775  {
776  ScSplitMode eHSplit = aViewData.GetHSplitMode();
777  ScSplitMode eVSplit = aViewData.GetVSplitMode();
778 
779  // #i46796# UpdateFixX / UpdateFixY uses GetGridOffset, which requires the
780  // outline windows to be available. So UpdateShow has to be called before
781  // (also called from DoResize).
782  if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX )
783  UpdateShow();
784 
785  if ( eHSplit == SC_SPLIT_FIX )
787  if ( eVSplit == SC_SPLIT_FIX )
789  }
790 
792 
794 }
795 
796 void ScTabView::GetBorderSize( SvBorder& rBorder, const Size& /* rSize */ )
797 {
798  bool bScrollBars = aViewData.IsVScrollMode();
799  bool bHeaders = aViewData.IsHeaderMode();
800  bool bOutlMode = aViewData.IsOutlineMode();
801  bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
802  bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
803  bool bLayoutRTL = aViewData.GetDocument().IsLayoutRTL( aViewData.GetTabNo() );
804 
805  rBorder = SvBorder();
806 
807  if (bScrollBars) // Scrollbars horizontal or vertical
808  {
809  rBorder.Right() += aVScrollBottom->GetSizePixel().Width();
810  rBorder.Bottom() += aHScrollLeft->GetSizePixel().Height();
811  }
812 
813  // Outline-Controls
814  if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
815  rBorder.Left() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
816  if (bHOutline && pColOutline[SC_SPLIT_LEFT])
817  rBorder.Top() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
818 
819  if (bHeaders) // column/row headers
820  {
821  rBorder.Left() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
822  rBorder.Top() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
823  }
824 
825  if ( bLayoutRTL )
826  ::std::swap( rBorder.Left(), rBorder.Right() );
827 }
828 
829 IMPL_LINK_NOARG(ScTabView, TabBarResize, TabBar*, void)
830 {
831  if (!aViewData.IsHScrollMode())
832  return;
833 
834  tools::Long nSize = pTabControl->GetSplitSize();
835 
836  if (aViewData.GetHSplitMode() != SC_SPLIT_FIX)
837  {
838  tools::Long nMax = pHSplitter->GetPosPixel().X();
839  if( pTabControl->IsEffectiveRTL() )
840  nMax = pFrameWin->GetSizePixel().Width() - nMax;
841  --nMax;
842  if (nSize>nMax) nSize = nMax;
843  }
844 
845  if ( nSize != pTabControl->GetSizePixel().Width() )
846  {
847  pTabControl->SetSizePixel( Size( nSize,
848  pTabControl->GetSizePixel().Height() ) );
849  RepeatResize();
850  }
851 }
852 
854 {
855  Size aSize = pTabControl->GetSizePixel();
856 
857  if ( aSize.Width() != nNewWidth )
858  {
859  aSize.setWidth( nNewWidth );
860  pTabControl->SetSizePixel( aSize );
861  }
862 }
863 
864 void ScTabView::SetRelTabBarWidth( double fRelTabBarWidth )
865 {
866  if( (0.0 <= fRelTabBarWidth) && (fRelTabBarWidth <= 1.0) )
867  if( tools::Long nFrameWidth = pFrameWin->GetSizePixel().Width() )
868  SetTabBarWidth( static_cast< tools::Long >( fRelTabBarWidth * nFrameWidth + 0.5 ) );
869 }
870 
871 void ScTabView::SetPendingRelTabBarWidth( double fRelTabBarWidth )
872 {
873  mfPendingTabBarWidth = fRelTabBarWidth;
874  SetRelTabBarWidth( fRelTabBarWidth );
875 }
876 
878 {
879  return pTabControl->GetSizePixel().Width();
880 }
881 
883 {
884  return 0.5;
885 }
886 
888 {
890  OSL_ENSURE(pGridWin[ePos],"no active window");
891  return pGridWin[ePos];
892 }
893 
895 {
896  for (VclPtr<ScGridWindow> & pWin : pGridWin)
897  if (pWin)
898  pWin->SetPointer( nPointer );
899 }
900 
902 {
904  if (pGridWin[ePos])
905  pGridWin[ePos]->GrabFocus();
906 }
907 
909 {
910  ScSplitPos eVal = SC_SPLIT_BOTTOMLEFT; // Default
911  for (sal_uInt16 i=0; i<4; i++)
912  if ( pGridWin[i] == pWindow )
913  eVal = static_cast<ScSplitPos>(i);
914 
915  return eVal;
916 }
917 
919 {
920  Point aPos;
921 
922  // size as in DoResize
923 
924  bool bHeaders = aViewData.IsHeaderMode();
925  bool bOutlMode = aViewData.IsOutlineMode();
926  bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
927  bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
928 
929  // Outline-Controls
930  if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
931  aPos.AdjustX(pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize() );
932  if (bHOutline && pColOutline[SC_SPLIT_LEFT])
933  aPos.AdjustY(pColOutline[SC_SPLIT_LEFT]->GetDepthSize() );
934 
935  if (bHeaders) // column/row headers
936  {
937  if (pRowBar[SC_SPLIT_BOTTOM])
938  aPos.AdjustX(pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() );
939  if (pColBar[SC_SPLIT_LEFT])
940  aPos.AdjustY(pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() );
941  }
942 
943  return aPos;
944 }
945 
946 // --- Scroll-Bars --------------------------------------------------------
947 
949 {
950  HideNoteMarker();
951 
952  bool bDone = false;
953  const CommandWheelData* pData = rCEvt.GetWheelData();
954  if (pData && pData->GetMode() == CommandWheelMode::ZOOM)
955  {
957  {
958  // for ole inplace editing, the scale is defined by the visarea and client size
959  // and can't be changed directly
960 
961  const Fraction& rOldY = aViewData.GetZoomY();
962  tools::Long nOld = static_cast<tools::Long>( rOldY * 100 );
963  tools::Long nNew;
964  if ( pData->GetDelta() < 0 )
965  nNew = std::max( tools::Long(MINZOOM), basegfx::zoomtools::zoomOut( nOld ));
966  else
967  nNew = std::min( tools::Long(MAXZOOM), basegfx::zoomtools::zoomIn( nOld ));
968  if ( nNew != nOld )
969  {
970  // scroll wheel doesn't set the AppOptions default
971 
972  bool bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
973  SetZoomType( SvxZoomType::PERCENT, bSyncZoom );
974  Fraction aFract( nNew, 100 );
975  SetZoom( aFract, aFract, bSyncZoom );
976  PaintGrid();
977  PaintTop();
978  PaintLeft();
979  aViewData.GetBindings().Invalidate( SID_ATTR_ZOOM );
980  aViewData.GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
981  aViewData.GetBindings().Invalidate( SID_ZOOM_IN);
982  aViewData.GetBindings().Invalidate( SID_ZOOM_OUT);
983  }
984 
985  bDone = true;
986  }
987  }
988  else
989  {
990  ScHSplitPos eHPos = WhichH(ePos);
991  ScVSplitPos eVPos = WhichV(ePos);
992  ScrollBar* pHScroll = ( eHPos == SC_SPLIT_LEFT ) ? aHScrollLeft.get() : aHScrollRight.get();
993  ScrollBar* pVScroll = ( eVPos == SC_SPLIT_TOP ) ? aVScrollTop.get() : aVScrollBottom.get();
994  if ( pGridWin[ePos] )
995  bDone = pGridWin[ePos]->HandleScrollCommand( rCEvt, pHScroll, pVScroll );
996  }
997  return bDone;
998 }
999 
1000 IMPL_LINK_NOARG(ScTabView, EndScrollHdl, ScrollBar*, void)
1001 {
1002  if ( bDragging )
1003  {
1004  UpdateScrollBars();
1005  bDragging = false;
1006  }
1007 }
1008 
1009 IMPL_LINK( ScTabView, ScrollHdl, ScrollBar*, pScroll, void )
1010 {
1011  bool bHoriz = ( pScroll == aHScrollLeft.get() || pScroll == aHScrollRight.get() );
1012  tools::Long nViewPos;
1013  if ( bHoriz )
1014  nViewPos = aViewData.GetPosX( (pScroll == aHScrollLeft.get()) ?
1016  else
1017  nViewPos = aViewData.GetPosY( (pScroll == aVScrollTop.get()) ?
1019 
1020  bool bLayoutRTL = aViewData.GetDocument().IsLayoutRTL( aViewData.GetTabNo() );
1021 
1022  ScrollType eType = pScroll->GetType();
1023  if ( eType == ScrollType::Drag )
1024  {
1025  if (!bDragging)
1026  {
1027  bDragging = true;
1028  nPrevDragPos = nViewPos;
1029  }
1030 
1031  // show scroll position
1032  // (only QuickHelp, there is no entry for it in the status bar)
1033 
1035  {
1036  Size aSize = pScroll->GetSizePixel();
1037 
1038  /* Convert scrollbar mouse position to screen position. If RTL
1039  mode of scrollbar differs from RTL mode of its parent, then the
1040  direct call to Window::OutputToNormalizedScreenPixel() will
1041  give unusable results, because calculation of screen position
1042  is based on parent orientation and expects equal orientation of
1043  the child position. Need to mirror mouse position before. */
1044  Point aMousePos = pScroll->GetPointerPosPixel();
1045  if( pScroll->IsRTLEnabled() != pScroll->GetParent()->IsRTLEnabled() )
1046  aMousePos.setX( aSize.Width() - aMousePos.X() - 1 );
1047  aMousePos = pScroll->OutputToNormalizedScreenPixel( aMousePos );
1048 
1049  // convert top-left position of scrollbar to screen position
1050  Point aPos = pScroll->OutputToNormalizedScreenPixel( Point() );
1051 
1052  // get scrollbar scroll position for help text (row number/column name)
1053  tools::Long nScrollMin = 0; // simulate RangeMin
1054  if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == aHScrollRight.get() )
1055  nScrollMin = aViewData.GetFixPosX();
1056  if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == aVScrollBottom.get() )
1057  nScrollMin = aViewData.GetFixPosY();
1058  tools::Long nScrollPos = GetScrollBarPos( *pScroll ) + nScrollMin;
1059 
1060  OUString aHelpStr;
1061  tools::Rectangle aRect;
1062  QuickHelpFlags nAlign;
1063  if (bHoriz)
1064  {
1065  aHelpStr = ScResId(STR_COLUMN) +
1066  " " + ScColToAlpha(static_cast<SCCOL>(nScrollPos));
1067 
1068  aRect.SetLeft( aMousePos.X() );
1069  aRect.SetTop( aPos.Y() - 4 );
1070  nAlign = QuickHelpFlags::Bottom|QuickHelpFlags::Center;
1071  }
1072  else
1073  {
1074  aHelpStr = ScResId(STR_ROW) +
1075  " " + OUString::number(nScrollPos + 1);
1076 
1077  // show quicktext always inside sheet area
1078  aRect.SetLeft( bLayoutRTL ? (aPos.X() + aSize.Width() + 8) : (aPos.X() - 8) );
1079  aRect.SetTop( aMousePos.Y() );
1080  nAlign = (bLayoutRTL ? QuickHelpFlags::Left : QuickHelpFlags::Right) | QuickHelpFlags::VCenter;
1081  }
1082  aRect.SetRight( aRect.Left() );
1083  aRect.SetBottom( aRect.Top() );
1084 
1085  Help::ShowQuickHelp(pScroll->GetParent(), aRect, aHelpStr, nAlign);
1086  }
1087  }
1088 
1089  tools::Long nDelta = pScroll->GetDelta();
1090  switch ( eType )
1091  {
1092  case ScrollType::LineUp:
1093  nDelta = -1;
1094  break;
1095  case ScrollType::LineDown:
1096  nDelta = 1;
1097  break;
1098  case ScrollType::PageUp:
1099  if ( pScroll == aHScrollLeft.get() ) nDelta = -static_cast<tools::Long>(aViewData.PrevCellsX( SC_SPLIT_LEFT ));
1100  if ( pScroll == aHScrollRight.get() ) nDelta = -static_cast<tools::Long>(aViewData.PrevCellsX( SC_SPLIT_RIGHT ));
1101  if ( pScroll == aVScrollTop.get() ) nDelta = -static_cast<tools::Long>(aViewData.PrevCellsY( SC_SPLIT_TOP ));
1102  if ( pScroll == aVScrollBottom.get() ) nDelta = -static_cast<tools::Long>(aViewData.PrevCellsY( SC_SPLIT_BOTTOM ));
1103  if (nDelta==0) nDelta=-1;
1104  break;
1105  case ScrollType::PageDown:
1106  if ( pScroll == aHScrollLeft.get() ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_LEFT );
1107  if ( pScroll == aHScrollRight.get() ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_RIGHT );
1108  if ( pScroll == aVScrollTop.get() ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_TOP );
1109  if ( pScroll == aVScrollBottom.get() ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM );
1110  if (nDelta==0) nDelta=1;
1111  break;
1112  case ScrollType::Drag:
1113  {
1114  // only scroll in the correct direction, do not jitter around hidden ranges
1115  tools::Long nScrollMin = 0; // simulate RangeMin
1116  if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == aHScrollRight.get() )
1117  nScrollMin = aViewData.GetFixPosX();
1118  if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == aVScrollBottom.get() )
1119  nScrollMin = aViewData.GetFixPosY();
1120 
1121  tools::Long nScrollPos = GetScrollBarPos( *pScroll ) + nScrollMin;
1122  nDelta = nScrollPos - nViewPos;
1123  if ( nScrollPos > nPrevDragPos )
1124  {
1125  if (nDelta<0) nDelta=0;
1126  }
1127  else if ( nScrollPos < nPrevDragPos )
1128  {
1129  if (nDelta>0) nDelta=0;
1130  }
1131  else
1132  nDelta = 0;
1133  nPrevDragPos = nScrollPos;
1134  }
1135  break;
1136  default:
1137  {
1138  // added to avoid warnings
1139  }
1140  }
1141 
1142  if (nDelta)
1143  {
1144  bool bUpdate = ( eType != ScrollType::Drag ); // don't alter the ranges while dragging
1145  if ( bHoriz )
1146  ScrollX( nDelta, (pScroll == aHScrollLeft.get()) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT, bUpdate );
1147  else
1148  ScrollY( nDelta, (pScroll == aVScrollTop.get()) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM, bUpdate );
1149  }
1150 }
1151 
1152 void ScTabView::ScrollX( tools::Long nDeltaX, ScHSplitPos eWhich, bool bUpdBars )
1153 {
1154  ScDocument& rDoc = aViewData.GetDocument();
1155  SCCOL nOldX = aViewData.GetPosX(eWhich);
1156  SCCOL nNewX = nOldX + static_cast<SCCOL>(nDeltaX);
1157  if ( nNewX < 0 )
1158  {
1159  nDeltaX -= nNewX;
1160  nNewX = 0;
1161  }
1162  if ( nNewX > rDoc.MaxCol() )
1163  {
1164  nDeltaX -= nNewX - rDoc.MaxCol();
1165  nNewX = rDoc.MaxCol();
1166  }
1167 
1168  SCCOL nDir = ( nDeltaX > 0 ) ? 1 : -1;
1169  SCTAB nTab = aViewData.GetTabNo();
1170  while ( rDoc.ColHidden(nNewX, nTab) &&
1171  nNewX+nDir >= 0 && nNewX+nDir <= rDoc.MaxCol() )
1172  nNewX = sal::static_int_cast<SCCOL>( nNewX + nDir );
1173 
1174  // freeze
1175 
1177  {
1178  if (eWhich == SC_SPLIT_LEFT)
1179  nNewX = nOldX; // always keep the left part
1180  else
1181  {
1182  SCCOL nFixX = aViewData.GetFixPosX();
1183  if (nNewX < nFixX)
1184  nNewX = nFixX;
1185  }
1186  }
1187  if (nNewX == nOldX)
1188  return;
1189 
1190  HideAllCursors();
1191 
1192  if ( nNewX >= 0 && nNewX <= rDoc.MaxCol() && nDeltaX )
1193  {
1194  SCCOL nTrackX = std::max( nOldX, nNewX );
1195 
1196  // with VCL Update() affects all windows at the moment, that is why
1197  // calling Update after scrolling of the GridWindow would possibly
1198  // already have painted the column/row bar with updated position. -
1199  // Therefore call Update once before on column/row bar
1200  if (pColBar[eWhich])
1201  pColBar[eWhich]->PaintImmediately();
1202 
1203  tools::Long nOldPos = aViewData.GetScrPos( nTrackX, 0, eWhich ).X();
1204  aViewData.SetPosX( eWhich, nNewX );
1205  tools::Long nDiff = aViewData.GetScrPos( nTrackX, 0, eWhich ).X() - nOldPos;
1206 
1207  if ( eWhich==SC_SPLIT_LEFT )
1208  {
1209  pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( nDiff, 0 );
1211  pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( nDiff, 0 );
1212  }
1213  else
1214  {
1215  pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( nDiff, 0 );
1217  pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( nDiff, 0 );
1218  }
1219  if (pColBar[eWhich]) { pColBar[eWhich]->Scroll( nDiff,0 ); pColBar[eWhich]->PaintImmediately(); }
1220  if (pColOutline[eWhich]) pColOutline[eWhich]->ScrollPixel( nDiff );
1221  if (bUpdBars)
1222  UpdateScrollBars();
1223  }
1224 
1225  if (nDeltaX==1 || nDeltaX==-1)
1226  pGridWin[aViewData.GetActivePart()]->PaintImmediately();
1227 
1228  ShowAllCursors();
1229 
1230  SetNewVisArea(); // MapMode must already be set
1231 
1232  TestHintWindow();
1233 }
1234 
1235 void ScTabView::ScrollY( tools::Long nDeltaY, ScVSplitPos eWhich, bool bUpdBars )
1236 {
1237  ScDocument& rDoc = aViewData.GetDocument();
1238  SCROW nOldY = aViewData.GetPosY(eWhich);
1239  SCROW nNewY = nOldY + static_cast<SCROW>(nDeltaY);
1240  if ( nNewY < 0 )
1241  {
1242  nDeltaY -= nNewY;
1243  nNewY = 0;
1244  }
1245  if ( nNewY > rDoc.MaxRow() )
1246  {
1247  nDeltaY -= nNewY - rDoc.MaxRow();
1248  nNewY = rDoc.MaxRow();
1249  }
1250 
1251  SCROW nDir = ( nDeltaY > 0 ) ? 1 : -1;
1252  SCTAB nTab = aViewData.GetTabNo();
1253  while ( rDoc.RowHidden(nNewY, nTab) &&
1254  nNewY+nDir >= 0 && nNewY+nDir <= rDoc.MaxRow() )
1255  nNewY += nDir;
1256 
1257  // freeze
1258 
1260  {
1261  if (eWhich == SC_SPLIT_TOP)
1262  nNewY = nOldY; // always keep the upper part
1263  else
1264  {
1265  SCROW nFixY = aViewData.GetFixPosY();
1266  if (nNewY < nFixY)
1267  nNewY = nFixY;
1268  }
1269  }
1270  if (nNewY == nOldY)
1271  return;
1272 
1273  HideAllCursors();
1274 
1275  if ( nNewY >= 0 && nNewY <= rDoc.MaxRow() && nDeltaY )
1276  {
1277  SCROW nTrackY = std::max( nOldY, nNewY );
1278 
1279  // adjust row headers before the actual scrolling, so it does not get painted twice
1280  // PosY may then also not be set yet, pass on new value
1281  SCROW nUNew = nNewY;
1282  UpdateHeaderWidth( &eWhich, &nUNew ); // adjust row headers
1283 
1284  if (pRowBar[eWhich])
1285  pRowBar[eWhich]->PaintImmediately();
1286 
1287  tools::Long nOldPos = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y();
1288  aViewData.SetPosY( eWhich, nNewY );
1289  tools::Long nDiff = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y() - nOldPos;
1290 
1291  if ( eWhich==SC_SPLIT_TOP )
1292  {
1293  pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( 0, nDiff );
1295  pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( 0, nDiff );
1296  }
1297  else
1298  {
1299  pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( 0, nDiff );
1301  pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( 0, nDiff );
1302  }
1303  if (pRowBar[eWhich]) { pRowBar[eWhich]->Scroll( 0,nDiff ); pRowBar[eWhich]->PaintImmediately(); }
1304  if (pRowOutline[eWhich]) pRowOutline[eWhich]->ScrollPixel( nDiff );
1305  if (bUpdBars)
1306  UpdateScrollBars();
1307  }
1308 
1309  if (nDeltaY==1 || nDeltaY==-1)
1310  pGridWin[aViewData.GetActivePart()]->PaintImmediately();
1311 
1312  ShowAllCursors();
1313 
1314  SetNewVisArea(); // MapMode must already be set
1315 
1316  TestHintWindow();
1317 }
1318 
1320 {
1321  ScSplitPos eWhich = aViewData.GetActivePart();
1322  if (nDeltaX)
1323  ScrollX(nDeltaX,WhichH(eWhich));
1324  if (nDeltaY)
1325  ScrollY(nDeltaY,WhichV(eWhich));
1326 }
1327 
1328 namespace
1329 {
1330 
1331 SCROW lcl_LastVisible( const ScViewData& rViewData )
1332 {
1333  // If many rows are hidden at end of the document,
1334  // then there should not be a switch to wide row headers because of this
1335  ScDocument& rDoc = rViewData.GetDocument();
1336  SCTAB nTab = rViewData.GetTabNo();
1337 
1338  SCROW nVis = rDoc.MaxRow();
1339  SCROW startRow;
1340  while ( nVis > 0 && rDoc.GetRowHeight( nVis, nTab, &startRow, nullptr ) == 0 )
1341  nVis = std::max<SCROW>( startRow - 1, 0 );
1342  return nVis;
1343 }
1344 
1345 } // anonymous namespace
1346 
1347 void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY )
1348 {
1349  if (!pRowBar[SC_SPLIT_BOTTOM])
1350  return;
1351 
1352  ScDocument& rDoc = aViewData.GetDocument();
1353  SCROW nEndPos = rDoc.MaxRow();
1355  {
1356  // for OLE Inplace always MAXROW
1357 
1358  if ( pWhich && *pWhich == SC_SPLIT_BOTTOM && pPosY )
1359  nEndPos = *pPosY;
1360  else
1361  nEndPos = aViewData.GetPosY( SC_SPLIT_BOTTOM );
1362  nEndPos += aViewData.CellsAtY( nEndPos, 1, SC_SPLIT_BOTTOM ); // VisibleCellsY
1363  if (nEndPos > rDoc.MaxRow())
1364  nEndPos = lcl_LastVisible( aViewData );
1365 
1367  {
1368  SCROW nTopEnd;
1369  if ( pWhich && *pWhich == SC_SPLIT_TOP && pPosY )
1370  nTopEnd = *pPosY;
1371  else
1372  nTopEnd = aViewData.GetPosY( SC_SPLIT_TOP );
1373  nTopEnd += aViewData.CellsAtY( nTopEnd, 1, SC_SPLIT_TOP );// VisibleCellsY
1374  if (nTopEnd > rDoc.MaxRow())
1375  nTopEnd = lcl_LastVisible( aViewData );
1376 
1377  if ( nTopEnd > nEndPos )
1378  nEndPos = nTopEnd;
1379  }
1380  }
1381 
1382  tools::Long nSmall = pRowBar[SC_SPLIT_BOTTOM]->GetSmallWidth();
1383  tools::Long nBig = pRowBar[SC_SPLIT_BOTTOM]->GetBigWidth();
1384  tools::Long nDiff = nBig - nSmall;
1385 
1386  if (nEndPos>10000)
1387  nEndPos = 10000;
1388  else if (nEndPos<1) // avoid extra step at 0 (when only one row is visible)
1389  nEndPos = 1;
1390  tools::Long nWidth = nBig - ( 10000 - nEndPos ) * nDiff / 10000;
1391 
1392  if (nWidth == pRowBar[SC_SPLIT_BOTTOM]->GetWidth() || bInUpdateHeader)
1393  return;
1394 
1395  bInUpdateHeader = true;
1396 
1397  pRowBar[SC_SPLIT_BOTTOM]->SetWidth( nWidth );
1398  if (pRowBar[SC_SPLIT_TOP])
1399  pRowBar[SC_SPLIT_TOP]->SetWidth( nWidth );
1400 
1401  RepeatResize();
1402 
1403  // on VCL there are endless updates (each Update is valid for all windows)
1404  //aCornerButton->Update(); // otherwise this never gets an Update
1405 
1406  bInUpdateHeader = false;
1407 }
1408 
1409 static void ShowHide( vcl::Window* pWin, bool bShow )
1410 {
1411  OSL_ENSURE(pWin || !bShow, "window is not present");
1412  if (pWin)
1413  pWin->Show(bShow);
1414 }
1415 
1417 {
1418  bool bHScrollMode = aViewData.IsHScrollMode();
1419  bool bVScrollMode = aViewData.IsVScrollMode();
1420  bool bTabMode = aViewData.IsTabMode();
1421  bool bOutlMode = aViewData.IsOutlineMode();
1422  bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
1423  bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
1424  bool bHeader = aViewData.IsHeaderMode();
1425 
1426  bool bShowH = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE );
1427  bool bShowV = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE );
1428 
1429  if ( aViewData.GetDocShell()->IsPreview() )
1430  bHScrollMode = bVScrollMode = bTabMode = bHeader = bHOutline = bVOutline = false;
1431 
1432  // create Windows
1433 
1434  if (bShowH && !pGridWin[SC_SPLIT_BOTTOMRIGHT])
1435  {
1437  DoAddWin( pGridWin[SC_SPLIT_BOTTOMRIGHT] );
1438  }
1439  if (bShowV && !pGridWin[SC_SPLIT_TOPLEFT])
1440  {
1442  DoAddWin( pGridWin[SC_SPLIT_TOPLEFT] );
1443  }
1444  if (bShowH && bShowV && !pGridWin[SC_SPLIT_TOPRIGHT])
1445  {
1447  DoAddWin( pGridWin[SC_SPLIT_TOPRIGHT] );
1448  }
1449 
1450  if (bHOutline && !pColOutline[SC_SPLIT_LEFT])
1452  if (bShowH && bHOutline && !pColOutline[SC_SPLIT_RIGHT])
1454 
1455  if (bVOutline && !pRowOutline[SC_SPLIT_BOTTOM])
1457  if (bShowV && bVOutline && !pRowOutline[SC_SPLIT_TOP])
1459 
1460  if (bShowH && bHeader && !pColBar[SC_SPLIT_RIGHT])
1462  &aHdrFunc, pHdrSelEng.get(), this );
1463  if (bShowV && bHeader && !pRowBar[SC_SPLIT_TOP])
1465  &aHdrFunc, pHdrSelEng.get(), this );
1466 
1467  // show Windows
1468 
1469  ShowHide( aHScrollLeft.get(), bHScrollMode );
1470  ShowHide( aHScrollRight.get(), bShowH && bHScrollMode );
1471  ShowHide( aVScrollBottom.get(), bVScrollMode );
1472  ShowHide( aVScrollTop.get(), bShowV && bVScrollMode );
1473  ShowHide( aScrollBarBox.get(), bVScrollMode || bHScrollMode );
1474 
1475  ShowHide( pHSplitter, bHScrollMode || bShowH ); // always generated
1476  ShowHide( pVSplitter, bVScrollMode || bShowV );
1477  ShowHide( pTabControl, bTabMode );
1478 
1479  // from here dynamically generated
1480 
1481  ShowHide( pGridWin[SC_SPLIT_BOTTOMRIGHT], bShowH );
1482  ShowHide( pGridWin[SC_SPLIT_TOPLEFT], bShowV );
1483  ShowHide( pGridWin[SC_SPLIT_TOPRIGHT], bShowH && bShowV );
1484 
1485  ShowHide( pColOutline[SC_SPLIT_LEFT], bHOutline );
1486  ShowHide( pColOutline[SC_SPLIT_RIGHT], bShowH && bHOutline );
1487 
1488  ShowHide( pRowOutline[SC_SPLIT_BOTTOM], bVOutline );
1489  ShowHide( pRowOutline[SC_SPLIT_TOP], bShowV && bVOutline );
1490 
1491  ShowHide( pColBar[SC_SPLIT_RIGHT], bShowH && bHeader );
1492  ShowHide( pRowBar[SC_SPLIT_TOP], bShowV && bHeader );
1493 
1495 }
1496 
1498 {
1499  bool bChanged = false;
1500  for (VclPtr<ScGridWindow> & pWin : pGridWin)
1501  {
1502  if (!pWin || !pWin->IsVisible())
1503  continue;
1504 
1505  if (pWin->UpdateVisibleRange())
1506  bChanged = true;
1507  }
1508 
1509  return bChanged;
1510 }
1511 
1512 // --- Splitter --------------------------------------------------------
1513 
1514 IMPL_LINK( ScTabView, SplitHdl, Splitter*, pSplitter, void )
1515 {
1516  if ( pSplitter == pHSplitter )
1517  DoHSplit( pHSplitter->GetSplitPosPixel() );
1518  else
1519  DoVSplit( pVSplitter->GetSplitPosPixel() );
1520 
1521  if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1522  FreezeSplitters( true );
1523 
1524  DoResize( aBorderPos, aFrameSize );
1525 }
1526 
1528 {
1529  // nSplitPos is the real pixel position on the frame window,
1530  // mirroring for RTL has to be done here.
1531 
1532  bool bLayoutRTL = aViewData.GetDocument().IsLayoutRTL( aViewData.GetTabNo() );
1533  if ( bLayoutRTL )
1534  nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
1535 
1536  tools::Long nMinPos;
1537  tools::Long nMaxPos;
1538 
1539  nMinPos = SPLIT_MARGIN;
1540  if ( pRowBar[SC_SPLIT_BOTTOM] && pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() >= nMinPos )
1541  nMinPos = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() + 1;
1542  nMaxPos = aFrameSize.Width() - SPLIT_MARGIN;
1543 
1544  ScSplitMode aOldMode = aViewData.GetHSplitMode();
1545  ScSplitMode aNewMode = SC_SPLIT_NORMAL;
1546 
1547  aViewData.SetHSplitPos( nSplitPos );
1548  if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
1549  aNewMode = SC_SPLIT_NONE;
1550 
1551  aViewData.SetHSplitMode( aNewMode );
1552 
1553  if ( aNewMode == aOldMode )
1554  return;
1555 
1556  UpdateShow(); // before ActivatePart !!
1557 
1558  if ( aNewMode == SC_SPLIT_NONE )
1559  {
1564  }
1565  else
1566  {
1567  SCCOL nOldDelta = aViewData.GetPosX( SC_SPLIT_LEFT );
1568  tools::Long nLeftWidth = nSplitPos - pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
1569  if ( nLeftWidth < 0 ) nLeftWidth = 0;
1570  SCCOL nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, SC_SPLIT_LEFT,
1571  static_cast<sal_uInt16>(nLeftWidth) );
1572  ScDocument& rDoc = aViewData.GetDocument();
1573  if ( nNewDelta > rDoc.MaxCol() )
1574  nNewDelta = rDoc.MaxCol();
1575  aViewData.SetPosX( SC_SPLIT_RIGHT, nNewDelta );
1576  if ( nNewDelta > aViewData.GetCurX() )
1579  else
1582  }
1583 
1584  // Form Layer needs to know the visible part of all windows
1585  // that is why MapMode must already be correct here
1586  for (VclPtr<ScGridWindow> & pWin : pGridWin)
1587  if (pWin)
1588  pWin->SetMapMode( pWin->GetDrawMapMode() );
1589  SetNewVisArea();
1590 
1591  PaintGrid();
1592  PaintTop();
1593 
1594  InvalidateSplit();
1595 }
1596 
1598 {
1599  tools::Long nMinPos;
1600  tools::Long nMaxPos;
1601  SCROW nOldDelta;
1602 
1603  nMinPos = SPLIT_MARGIN;
1604  if ( pColBar[SC_SPLIT_LEFT] && pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() >= nMinPos )
1605  nMinPos = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() + 1;
1606  nMaxPos = aFrameSize.Height() - SPLIT_MARGIN;
1607 
1608  ScSplitMode aOldMode = aViewData.GetVSplitMode();
1609  ScSplitMode aNewMode = SC_SPLIT_NORMAL;
1610 
1611  aViewData.SetVSplitPos( nSplitPos );
1612  if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
1613  aNewMode = SC_SPLIT_NONE;
1614 
1615  aViewData.SetVSplitMode( aNewMode );
1616 
1617  if ( aNewMode == aOldMode )
1618  return;
1619 
1620  UpdateShow(); // before ActivatePart !!
1621 
1622  if ( aNewMode == SC_SPLIT_NONE )
1623  {
1624  nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
1625  aViewData.SetPosY( SC_SPLIT_BOTTOM, nOldDelta );
1626 
1631  }
1632  else
1633  {
1634  if ( aOldMode == SC_SPLIT_NONE )
1635  nOldDelta = aViewData.GetPosY( SC_SPLIT_BOTTOM );
1636  else
1637  nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
1638 
1639  aViewData.SetPosY( SC_SPLIT_TOP, nOldDelta );
1640  tools::Long nTopHeight = nSplitPos - pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
1641  if ( nTopHeight < 0 ) nTopHeight = 0;
1642  SCROW nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, SC_SPLIT_TOP,
1643  static_cast<sal_uInt16>(nTopHeight) );
1644  ScDocument& rDoc = aViewData.GetDocument();
1645  if ( nNewDelta > rDoc.MaxRow() )
1646  nNewDelta = rDoc.MaxRow();
1647  aViewData.SetPosY( SC_SPLIT_BOTTOM, nNewDelta );
1648  if ( nNewDelta > aViewData.GetCurY() )
1651  else
1654  }
1655 
1656  // Form Layer needs to know the visible part of all windows
1657  // that is why MapMode must already be correct here
1658  for (VclPtr<ScGridWindow> & pWin : pGridWin)
1659  if (pWin)
1660  pWin->SetMapMode( pWin->GetDrawMapMode() );
1661  SetNewVisArea();
1662 
1663  PaintGrid();
1664  PaintLeft();
1665 
1666  InvalidateSplit();
1667 }
1668 
1670 {
1671  ScDocument& rDoc = aViewData.GetDocument();
1672  SCCOL nCol = aViewData.GetCurX();
1673  SCROW nRow = aViewData.GetCurY();
1674  SCTAB nTab = aViewData.GetTabNo();
1675  tools::Long nPosX = 0;
1676  for (SCCOL i=0; i<nCol; i++)
1677  nPosX += rDoc.GetColWidth(i,nTab);
1679  if ( rDoc.IsNegativePage( nTab ) )
1680  nPosX = -nPosX;
1681  tools::Long nPosY = rDoc.GetRowHeight( 0, nRow-1, nTab);
1683  return Point(nPosX,nPosY);
1684 }
1685 
1686 Point ScTabView::GetChartInsertPos( const Size& rSize, const ScRange& rCellRange )
1687 {
1688  Point aInsertPos;
1689  const tools::Long nBorder = 100; // leave 1mm for border
1690  tools::Long nNeededWidth = rSize.Width() + 2 * nBorder;
1691  tools::Long nNeededHeight = rSize.Height() + 2 * nBorder;
1692 
1693  // use the active window, or lower/right if frozen (as in CalcZoom)
1694  ScSplitPos eUsedPart = aViewData.GetActivePart();
1696  eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
1698  eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1699 
1700  ScGridWindow* pWin = pGridWin[eUsedPart].get();
1701  OSL_ENSURE( pWin, "Window not found" );
1702  if (pWin)
1703  {
1704  ActivatePart( eUsedPart );
1705 
1706  // get the visible rectangle in logic units
1707  bool bLOKActive = comphelper::LibreOfficeKit::isActive();
1708  MapMode aDrawMode = pWin->GetDrawMapMode();
1709  tools::Rectangle aVisible(
1710  bLOKActive ?
1711  OutputDevice::LogicToLogic( aViewData.getLOKVisibleArea(), MapMode(MapUnit::MapTwip), MapMode(MapUnit::Map100thMM) )
1712  : pWin->PixelToLogic( tools::Rectangle( Point(0,0), pWin->GetOutputSizePixel() ), aDrawMode ) );
1713 
1714  ScDocument& rDoc = aViewData.GetDocument();
1715  SCTAB nTab = aViewData.GetTabNo();
1716  bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
1717  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1718 
1719  tools::Long nDocX = o3tl::convert(rDoc.GetColOffset(rDoc.MaxCol() + 1, nTab), o3tl::Length::twip, o3tl::Length::mm100) * nLayoutSign;
1720  tools::Long nDocY = o3tl::convert(rDoc.GetRowOffset( rDoc.MaxRow() + 1, nTab ), o3tl::Length::twip, o3tl::Length::mm100);
1721 
1722  if ( aVisible.Left() * nLayoutSign > nDocX * nLayoutSign )
1723  aVisible.SetLeft( nDocX );
1724  if ( aVisible.Right() * nLayoutSign > nDocX * nLayoutSign )
1725  aVisible.SetRight( nDocX );
1726  if ( aVisible.Top() > nDocY )
1727  aVisible.SetTop( nDocY );
1728  if ( aVisible.Bottom() > nDocY )
1729  aVisible.SetBottom( nDocY );
1730 
1731  // get the logic position of the selection
1732 
1733  tools::Rectangle aSelection = rDoc.GetMMRect( rCellRange.aStart.Col(), rCellRange.aStart.Row(),
1734  rCellRange.aEnd.Col(), rCellRange.aEnd.Row(), nTab );
1735 
1736  if (bLOKActive && bLayoutRTL)
1737  {
1738  // In this case we operate in negative X coordinates. The rectangle aSelection already
1739  // has negative X coordinates. So the x coordinates in the rectangle aVisible(from getLOKVisibleArea)
1740  // need be negated to match.
1741  aVisible = tools::Rectangle(-aVisible.Right(), aVisible.Top(), -aVisible.Left(), aVisible.Bottom());
1742  }
1743 
1744  tools::Long nLeftSpace = aSelection.Left() - aVisible.Left();
1745  tools::Long nRightSpace = aVisible.Right() - aSelection.Right();
1746  tools::Long nTopSpace = aSelection.Top() - aVisible.Top();
1747  tools::Long nBottomSpace = aVisible.Bottom() - aSelection.Bottom();
1748 
1749  bool bFitLeft = ( nLeftSpace >= nNeededWidth );
1750  bool bFitRight = ( nRightSpace >= nNeededWidth );
1751 
1752  if ( bFitLeft || bFitRight )
1753  {
1754  // first preference: completely left or right of the selection
1755 
1756  // if both fit, prefer left in RTL mode, right otherwise
1757  bool bPutLeft = bFitLeft && ( bLayoutRTL || !bFitRight );
1758 
1759  if ( bPutLeft )
1760  aInsertPos.setX( aSelection.Left() - nNeededWidth );
1761  else
1762  aInsertPos.setX( aSelection.Right() + 1 );
1763 
1764  // align with top of selection (is moved again if it doesn't fit)
1765  aInsertPos.setY( std::max( aSelection.Top(), aVisible.Top() ) );
1766  }
1767  else if ( nTopSpace >= nNeededHeight || nBottomSpace >= nNeededHeight )
1768  {
1769  // second preference: completely above or below the selection
1770  if ( nBottomSpace > nNeededHeight ) // bottom is preferred
1771  aInsertPos.setY( aSelection.Bottom() + 1 );
1772  else
1773  aInsertPos.setY( aSelection.Top() - nNeededHeight );
1774 
1775  // align with (logic) left edge of selection (moved again if it doesn't fit)
1776  if ( bLayoutRTL )
1777  aInsertPos.setX( std::min( aSelection.Right(), aVisible.Right() ) - nNeededWidth + 1 );
1778  else
1779  aInsertPos.setX( std::max( aSelection.Left(), aVisible.Left() ) );
1780  }
1781  else
1782  {
1783  // place to the (logic) right of the selection and move so it fits
1784 
1785  if ( bLayoutRTL )
1786  aInsertPos.setX( aSelection.Left() - nNeededWidth );
1787  else
1788  aInsertPos.setX( aSelection.Right() + 1 );
1789  aInsertPos.setY( std::max( aSelection.Top(), aVisible.Top() ) );
1790  }
1791 
1792  // move the position if the object doesn't fit in the screen
1793 
1794  tools::Rectangle aCompareRect( aInsertPos, Size( nNeededWidth, nNeededHeight ) );
1795  if ( aCompareRect.Right() > aVisible.Right() )
1796  aInsertPos.AdjustX( -(aCompareRect.Right() - aVisible.Right()) );
1797  if ( aCompareRect.Bottom() > aVisible.Bottom() )
1798  aInsertPos.AdjustY( -(aCompareRect.Bottom() - aVisible.Bottom()) );
1799 
1800  if ( aInsertPos.X() < aVisible.Left() )
1801  aInsertPos.setX( aVisible.Left() );
1802  if ( aInsertPos.Y() < aVisible.Top() )
1803  aInsertPos.setY( aVisible.Top() );
1804 
1805  // nNeededWidth / nNeededHeight includes all borders - move aInsertPos to the
1806  // object position, inside the border
1807 
1808  aInsertPos.AdjustX(nBorder );
1809  aInsertPos.AdjustY(nBorder );
1810  }
1811  return aInsertPos;
1812 }
1813 
1814 Point ScTabView::GetChartDialogPos( const Size& rDialogSize, const tools::Rectangle& rLogicChart )
1815 {
1816  // rDialogSize must be in pixels, rLogicChart in 1/100 mm. Return value is in pixels.
1817 
1818  Point aRet;
1819 
1820  // use the active window, or lower/right if frozen (as in CalcZoom)
1821  ScSplitPos eUsedPart = aViewData.GetActivePart();
1823  eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
1825  eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1826 
1827  ScGridWindow* pWin = pGridWin[eUsedPart].get();
1828  OSL_ENSURE( pWin, "Window not found" );
1829  if (pWin)
1830  {
1831  MapMode aDrawMode = pWin->GetDrawMapMode();
1832  tools::Rectangle aObjPixel = pWin->LogicToPixel( rLogicChart, aDrawMode );
1833  tools::Rectangle aObjAbs( pWin->OutputToAbsoluteScreenPixel( aObjPixel.TopLeft() ),
1834  pWin->OutputToAbsoluteScreenPixel( aObjPixel.BottomRight() ) );
1835 
1836  tools::Rectangle aDesktop = pWin->GetDesktopRectPixel();
1837  Size aSpace = pWin->LogicToPixel( Size(8, 12), MapMode(MapUnit::MapAppFont));
1838 
1839  ScDocument& rDoc = aViewData.GetDocument();
1840  SCTAB nTab = aViewData.GetTabNo();
1841  bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
1842 
1843  bool bCenterHor = false;
1844 
1845  if ( aDesktop.Bottom() - aObjAbs.Bottom() >= rDialogSize.Height() + aSpace.Height() )
1846  {
1847  // first preference: below the chart
1848 
1849  aRet.setY( aObjAbs.Bottom() + aSpace.Height() );
1850  bCenterHor = true;
1851  }
1852  else if ( aObjAbs.Top() - aDesktop.Top() >= rDialogSize.Height() + aSpace.Height() )
1853  {
1854  // second preference: above the chart
1855 
1856  aRet.setY( aObjAbs.Top() - rDialogSize.Height() - aSpace.Height() );
1857  bCenterHor = true;
1858  }
1859  else
1860  {
1861  bool bFitLeft = ( aObjAbs.Left() - aDesktop.Left() >= rDialogSize.Width() + aSpace.Width() );
1862  bool bFitRight = ( aDesktop.Right() - aObjAbs.Right() >= rDialogSize.Width() + aSpace.Width() );
1863 
1864  if ( bFitLeft || bFitRight )
1865  {
1866  // if both fit, prefer right in RTL mode, left otherwise
1867  bool bPutRight = bFitRight && ( bLayoutRTL || !bFitLeft );
1868  if ( bPutRight )
1869  aRet.setX( aObjAbs.Right() + aSpace.Width() );
1870  else
1871  aRet.setX( aObjAbs.Left() - rDialogSize.Width() - aSpace.Width() );
1872 
1873  // center vertically
1874  aRet.setY( aObjAbs.Top() + ( aObjAbs.GetHeight() - rDialogSize.Height() ) / 2 );
1875  }
1876  else
1877  {
1878  // doesn't fit on any edge - put at the bottom of the screen
1879  aRet.setY( aDesktop.Bottom() - rDialogSize.Height() );
1880  bCenterHor = true;
1881  }
1882  }
1883  if ( bCenterHor )
1884  aRet.setX( aObjAbs.Left() + ( aObjAbs.GetWidth() - rDialogSize.Width() ) / 2 );
1885 
1886  // limit to screen (centering might lead to invalid positions)
1887  if ( aRet.X() + rDialogSize.Width() - 1 > aDesktop.Right() )
1888  aRet.setX( aDesktop.Right() - rDialogSize.Width() + 1 );
1889  if ( aRet.X() < aDesktop.Left() )
1890  aRet.setX( aDesktop.Left() );
1891  if ( aRet.Y() + rDialogSize.Height() - 1 > aDesktop.Bottom() )
1892  aRet.setY( aDesktop.Bottom() - rDialogSize.Height() + 1 );
1893  if ( aRet.Y() < aDesktop.Top() )
1894  aRet.setY( aDesktop.Top() );
1895  }
1896 
1897  return aRet;
1898 }
1899 
1900 void ScTabView::LockModifiers( sal_uInt16 nModifiers )
1901 {
1902  pSelEngine->LockModifiers( nModifiers );
1903  pHdrSelEng->LockModifiers( nModifiers );
1904 }
1905 
1907 {
1908  return pSelEngine->GetLockedModifiers();
1909 }
1910 
1912 {
1913  Point aPos;
1914  ScGridWindow* pWin = GetActiveWin();
1915 
1916  if ( pWin )
1917  aPos = pWin->GetMousePosPixel();
1918 
1919  return aPos;
1920 }
1921 
1922 void ScTabView::FreezeSplitters( bool bFreeze, SplitMethod eSplitMethod, SCCOLROW nFreezeIndex)
1923 {
1924  if ((eSplitMethod == SC_SPLIT_METHOD_COL || eSplitMethod == SC_SPLIT_METHOD_ROW) && nFreezeIndex < 0)
1925  nFreezeIndex = 0;
1926 
1929 
1931  if ( eOldV != SC_SPLIT_NONE )
1932  ePos = SC_SPLIT_TOPLEFT;
1933  vcl::Window* pWin = pGridWin[ePos];
1934 
1935  bool bLayoutRTL = aViewData.GetDocument().IsLayoutRTL( aViewData.GetTabNo() );
1936 
1937  if ( bFreeze )
1938  {
1939  Point aWinStart = pWin->GetPosPixel();
1941 
1942  Point aSplit;
1943  SCCOL nPosX = 1;
1944  SCROW nPosY = 1;
1945  if (eOldV != SC_SPLIT_NONE || eOldH != SC_SPLIT_NONE)
1946  {
1947  if ( eOldV != SC_SPLIT_NONE && (eSplitMethod == SC_SPLIT_METHOD_ROW || eSplitMethod == SC_SPLIT_METHOD_CURSOR))
1948  aSplit.setY( aViewData.GetVSplitPos() - aWinStart.Y() );
1949 
1950  if ( eOldH != SC_SPLIT_NONE && (eSplitMethod == SC_SPLIT_METHOD_COL || eSplitMethod == SC_SPLIT_METHOD_CURSOR))
1951  {
1952  tools::Long nSplitPos = aViewData.GetHSplitPos();
1953  if ( bLayoutRTL )
1954  nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
1955  aSplit.setX( nSplitPos - aWinStart.X() );
1956  }
1957 
1958  aViewData.GetPosFromPixel( aSplit.X(), aSplit.Y(), ePos, nPosX, nPosY );
1959  bool bLeft;
1960  bool bTop;
1961  aViewData.GetMouseQuadrant( aSplit, ePos, nPosX, nPosY, bLeft, bTop );
1962  if (eSplitMethod == SC_SPLIT_METHOD_COL)
1963  nPosX = static_cast<SCCOL>(nFreezeIndex);
1964  else if (!bLeft)
1965  ++nPosX;
1966  if (eSplitMethod == SC_SPLIT_METHOD_ROW)
1967  nPosY = static_cast<SCROW>(nFreezeIndex);
1968  else if (!bTop)
1969  ++nPosY;
1970  }
1971  else
1972  {
1973  switch(eSplitMethod)
1974  {
1975  case SC_SPLIT_METHOD_ROW:
1976  {
1977  nPosX = 0;
1978  nPosY = static_cast<SCROW>(nFreezeIndex);
1979  }
1980  break;
1981  case SC_SPLIT_METHOD_COL:
1982  {
1983  nPosX = static_cast<SCCOL>(nFreezeIndex);
1984  nPosY = 0;
1985  }
1986  break;
1988  {
1989  nPosX = aViewData.GetCurX();
1990  nPosY = aViewData.GetCurY();
1991  }
1992  break;
1993  }
1994  }
1995 
1997  SCROW nBottomPos = nPosY;
1998  SCCOL nLeftPos = aViewData.GetPosX(SC_SPLIT_LEFT);
1999  SCCOL nRightPos = nPosX;
2000 
2001  if (eSplitMethod == SC_SPLIT_METHOD_ROW || eSplitMethod == SC_SPLIT_METHOD_CURSOR)
2002  {
2003  if (eOldV != SC_SPLIT_NONE)
2004  {
2005  nTopPos = aViewData.GetPosY(SC_SPLIT_TOP);
2006  if (aViewData.GetPosY(SC_SPLIT_BOTTOM) > nBottomPos)
2007  nBottomPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
2008  }
2009  aSplit = aViewData.GetScrPos( nPosX, nPosY, ePos, true );
2010  if (aSplit.Y() > 0)
2011  {
2013  aViewData.SetVSplitPos( aSplit.Y() + aWinStart.Y() );
2014  aViewData.SetFixPosY( nPosY );
2015 
2016  aViewData.SetPosY(SC_SPLIT_TOP, nTopPos);
2017  aViewData.SetPosY(SC_SPLIT_BOTTOM, nBottomPos);
2018  }
2019  else
2021  }
2022 
2023  if (eSplitMethod == SC_SPLIT_METHOD_COL || eSplitMethod == SC_SPLIT_METHOD_CURSOR)
2024  {
2025  if (eOldH != SC_SPLIT_NONE)
2026  {
2027  if (aViewData.GetPosX(SC_SPLIT_RIGHT) > nRightPos)
2028  nRightPos = aViewData.GetPosX(SC_SPLIT_RIGHT);
2029  }
2030  aSplit = aViewData.GetScrPos( nPosX, nPosY, ePos, true );
2031  if (nPosX > aViewData.GetPosX(SC_SPLIT_LEFT)) // (aSplit.X() > 0) doesn't work for RTL
2032  {
2033  tools::Long nSplitPos = aSplit.X() + aWinStart.X();
2034  if ( bLayoutRTL )
2035  nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
2036 
2038  aViewData.SetHSplitPos( nSplitPos );
2039  aViewData.SetFixPosX( nPosX );
2040 
2041  aViewData.SetPosX(SC_SPLIT_LEFT, nLeftPos);
2042  aViewData.SetPosX(SC_SPLIT_RIGHT, nRightPos);
2043  }
2044  else
2046  }
2047  }
2048  else // unfreeze
2049  {
2050  if ( eOldH == SC_SPLIT_FIX )
2052  if ( eOldV == SC_SPLIT_FIX )
2054  }
2055 
2056  // Form Layer needs to know the visible part of all windows
2057  // that is why MapMode must already be correct here
2058  for (VclPtr<ScGridWindow> & p : pGridWin)
2059  if (p)
2060  p->SetMapMode( p->GetDrawMapMode() );
2061  SetNewVisArea();
2062 
2063  RepeatResize(false);
2064 
2065  UpdateShow();
2066  PaintLeft();
2067  PaintTop();
2068  PaintGrid();
2069 
2070  // SC_FOLLOW_NONE: only update active part
2073 
2074  InvalidateSplit();
2075 }
2076 
2078 {
2079  DoHSplit( 0 );
2080  DoVSplit( 0 );
2081  RepeatResize();
2082 }
2083 
2085 {
2088  ePos = SC_SPLIT_TOPLEFT;
2089  vcl::Window* pWin = pGridWin[ePos];
2090  Point aWinStart = pWin->GetPosPixel();
2091 
2092  SCCOL nPosX = aViewData.GetCurX();
2093  SCROW nPosY = aViewData.GetCurY();
2094  Point aSplit = aViewData.GetScrPos( nPosX, nPosY, ePos, true );
2095  if ( nPosX > 0 )
2096  DoHSplit( aSplit.X() + aWinStart.X() );
2097  else
2098  DoHSplit( 0 );
2099  if ( nPosY > 0 )
2100  DoVSplit( aSplit.Y() + aWinStart.Y() );
2101  else
2102  DoVSplit( 0 );
2103  RepeatResize();
2104 }
2105 
2106 void ScTabView::SplitAtPixel( const Point& rPixel )
2107 {
2108  // pixel is relative to the entire View, not to the first GridWin
2109 
2110  if ( rPixel.X() > 0 )
2111  DoHSplit( rPixel.X() );
2112  else
2113  DoHSplit( 0 );
2114  if ( rPixel.Y() > 0 )
2115  DoVSplit( rPixel.Y() );
2116  else
2117  DoVSplit( 0 );
2118  RepeatResize();
2119 }
2120 
2122 {
2123  SfxBindings& rBindings = aViewData.GetBindings();
2124  rBindings.Invalidate( SID_WINDOW_SPLIT );
2125  rBindings.Invalidate( SID_WINDOW_FIX );
2126  rBindings.Invalidate( SID_WINDOW_FIX_COL );
2127  rBindings.Invalidate( SID_WINDOW_FIX_ROW );
2128 
2131 }
2132 
2134 {
2135  // Draw-MapMode must be set for Controls when VisAreaChanged
2136  // (also when Edit-MapMode is set instead)
2137  MapMode aOldMode[4];
2138  MapMode aDrawMode[4];
2139  sal_uInt16 i;
2140  for (i=0; i<4; i++)
2141  if (pGridWin[i])
2142  {
2143  aOldMode[i] = pGridWin[i]->GetMapMode();
2144  aDrawMode[i] = pGridWin[i]->GetDrawMapMode();
2145  if (aDrawMode[i] != aOldMode[i])
2146  pGridWin[i]->SetMapMode(aDrawMode[i]);
2147  }
2148 
2150  if (pActive)
2152  if (pDrawView)
2153  pDrawView->VisAreaChanged(nullptr); // no window passed on -> for all windows
2154 
2155  UpdateAllOverlays(); // #i79909# with drawing MapMode set
2156 
2157  for (i=0; i<4; i++)
2158  if (pGridWin[i] && aDrawMode[i] != aOldMode[i])
2159  {
2160  pGridWin[i]->flushOverlayManager(); // #i79909# flush overlays before switching to edit MapMode
2161  pGridWin[i]->SetMapMode(aOldMode[i]);
2162  }
2163 
2164  SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
2165  if (pViewFrame)
2166  {
2167  SfxFrame& rFrame = pViewFrame->GetFrame();
2168  css::uno::Reference<css::frame::XController> xController = rFrame.GetController();
2169  if (xController.is())
2170  {
2171  ScTabViewObj* pImp = comphelper::getFromUnoTunnel<ScTabViewObj>( xController );
2172  if (pImp)
2173  pImp->VisAreaChanged();
2174  }
2175  }
2177  aViewData.GetViewShell()->BroadcastAccessibility(SfxHint(SfxHintId::ScAccVisAreaChanged));
2178 }
2179 
2181 {
2182  ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()].get();
2183  SCCOL nCol = aViewData.GetCurX();
2184  SCROW nRow = aViewData.GetCurY();
2185  if (pWin)
2186  return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE;
2187 
2188  return false;
2189 }
2190 
2192 {
2193  ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()].get();
2194  SCCOL nCol = aViewData.GetCurX();
2195  SCROW nRow = aViewData.GetCurY();
2196 
2197  if (!pWin)
2198  return;
2199 
2200  switch (pWin->GetDPFieldOrientation(nCol, nRow))
2201  {
2202  case sheet::DataPilotFieldOrientation_PAGE:
2203  // #i36598# If the cursor is on a page field's data cell,
2204  // no meaningful input is possible anyway, so this function
2205  // can be used to select a page field entry.
2206  pWin->LaunchPageFieldMenu( nCol, nRow );
2207  return;
2208  case sheet::DataPilotFieldOrientation_COLUMN:
2209  case sheet::DataPilotFieldOrientation_ROW:
2210  pWin->LaunchDPFieldMenu( nCol, nRow );
2211  return;
2212  default:
2213  ;
2214  }
2215 
2216  // Do autofilter if the current cell has autofilter button. Otherwise do
2217  // a normal data select popup.
2218  const ScMergeFlagAttr* pAttr =
2220  nCol, nRow, aViewData.GetTabNo(), ATTR_MERGE_FLAG);
2221 
2222  if (pAttr->HasAutoFilter())
2223  pWin->LaunchAutoFilterMenu(nCol, nRow);
2224  else
2225  pWin->LaunchDataSelectMenu(nCol, nRow);
2226 }
2227 
2229 {
2230  aHScrollLeft->EnableInput(bFlag);
2231  aHScrollRight->EnableInput(bFlag);
2232  aVScrollBottom->EnableInput(bFlag);
2233  aVScrollTop->EnableInput(bFlag);
2234  aScrollBarBox->EnableInput(bFlag);
2235 
2236  // from here on dynamically created ones
2237 
2238  if(pTabControl!=nullptr) pTabControl->EnableInput(bFlag);
2239 
2240  for (auto& p : pGridWin)
2241  if (p)
2242  p->EnableInput(bFlag, false);
2243  for (auto& p : pColBar)
2244  if (p)
2245  p->EnableInput(bFlag, false);
2246  for (auto& p : pRowBar)
2247  if (p)
2248  p->EnableInput(bFlag, false);
2249 }
2250 
2251 void ScTabView::EnableAutoSpell( bool bEnable )
2252 {
2253  if (bEnable)
2254  mpSpellCheckCxt =
2255  std::make_shared<sc::SpellCheckContext>(&aViewData.GetDocument(),
2256  aViewData.GetTabNo());
2257  else
2258  mpSpellCheckCxt.reset();
2259 
2260  for (VclPtr<ScGridWindow> & pWin : pGridWin)
2261  {
2262  if (!pWin)
2263  continue;
2264 
2265  pWin->SetAutoSpellContext(mpSpellCheckCxt);
2266  }
2267 }
2268 
2270 {
2271  for (VclPtr<ScGridWindow> & pWin : pGridWin)
2272  {
2273  if (!pWin)
2274  continue;
2275 
2276  pWin->ResetAutoSpell();
2277  }
2278 }
2279 
2281 {
2282  for (VclPtr<ScGridWindow> & pWin : pGridWin)
2283  {
2284  if (!pWin)
2285  continue;
2286 
2287  pWin->ResetAutoSpellForContentChange();
2288  }
2289 }
2290 
2291 void ScTabView::SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges )
2292 {
2293  for (VclPtr<ScGridWindow> & pWin: pGridWin)
2294  {
2295  if (!pWin)
2296  continue;
2297 
2298  pWin->SetAutoSpellData(nPosX, nPosY, pRanges);
2299  }
2300 }
2301 
2302 namespace
2303 {
2304 
2305 tools::Long lcl_GetRowHeightPx(const ScViewData &rViewData, SCROW nRow, SCTAB nTab)
2306 {
2307  const sal_uInt16 nSize = rViewData.GetDocument().GetRowHeight(nRow, nTab);
2308  return ScViewData::ToPixel(nSize, rViewData.GetPPTY());
2309 }
2310 
2311 tools::Long lcl_GetColWidthPx(const ScViewData &rViewData, SCCOL nCol, SCTAB nTab)
2312 {
2313  const sal_uInt16 nSize = rViewData.GetDocument().GetColWidth(nCol, nTab);
2314  return ScViewData::ToPixel(nSize, rViewData.GetPPTX());
2315 }
2316 
2317 void lcl_getGroupIndexes(const ScOutlineArray& rArray, SCCOLROW nStart, SCCOLROW nEnd, std::vector<size_t>& rGroupIndexes)
2318 {
2319  rGroupIndexes.clear();
2320  const size_t nGroupDepth = rArray.GetDepth();
2321  rGroupIndexes.resize(nGroupDepth);
2322 
2323  // Get first group per each level
2324  for (size_t nLevel = 0; nLevel < nGroupDepth; ++nLevel)
2325  {
2326  if (rArray.GetCount(nLevel))
2327  {
2328  // look for a group inside the [nStartRow+1, nEndRow] range
2329  size_t nIndex;
2330  bool bFound = rArray.GetEntryIndexInRange(nLevel, nStart + 1, nEnd, nIndex);
2331  if (bFound)
2332  {
2333  if (nIndex > 0)
2334  {
2335  // is there a previous group not inside the range
2336  // but anyway intersecting it ?
2337  const ScOutlineEntry* pPrevEntry = rArray.GetEntry(nLevel, nIndex - 1);
2338  if (pPrevEntry && nStart < pPrevEntry->GetEnd())
2339  {
2340  --nIndex;
2341  }
2342  }
2343  }
2344  else
2345  {
2346  // look for a group which contains nStartRow+1
2347  bFound = rArray.GetEntryIndex(nLevel, nStart + 1, nIndex);
2348  if (!bFound)
2349  {
2350  // look for a group which contains nEndRow
2351  bFound = rArray.GetEntryIndex(nLevel, nEnd, nIndex);
2352  }
2353  }
2354 
2355  if (bFound)
2356  {
2357  // skip groups with no visible control
2358  bFound = false;
2359  while (nIndex < rArray.GetCount(nLevel))
2360  {
2361  const ScOutlineEntry* pEntry = rArray.GetEntry(nLevel, nIndex);
2362  if (pEntry && pEntry->IsVisible())
2363  {
2364  bFound = true;
2365  break;
2366  }
2367  if (pEntry && pEntry->GetStart() > nEnd)
2368  {
2369  break;
2370  }
2371  ++nIndex;
2372  }
2373  }
2374 
2375  rGroupIndexes[nLevel] = bFound ? nIndex : -1;
2376  }
2377  }
2378 }
2379 
2380 void lcl_createGroupsData(
2381  SCCOLROW nHeaderIndex, SCCOLROW nEnd, tools::Long nSizePx, tools::Long nTotalPx,
2382  const ScOutlineArray& rArray, std::vector<size_t>& rGroupIndexes,
2383  std::vector<tools::Long>& rGroupStartPositions, OStringBuffer& rGroupsBuffer)
2384 {
2385  const size_t nGroupDepth = rArray.GetDepth();
2386  // create string data for group controls
2387  for (size_t nLevel = nGroupDepth - 1; nLevel != size_t(-1); --nLevel)
2388  {
2389  size_t nIndex = rGroupIndexes[nLevel];
2390  if (nIndex == size_t(-1))
2391  continue;
2392  const ScOutlineEntry* pEntry = rArray.GetEntry(nLevel, nIndex);
2393  if (pEntry)
2394  {
2395  if (nHeaderIndex < pEntry->GetStart())
2396  {
2397  continue;
2398  }
2399  else if (nHeaderIndex == pEntry->GetStart())
2400  {
2401  rGroupStartPositions[nLevel] = nTotalPx - nSizePx;
2402  }
2403  else if (nHeaderIndex > pEntry->GetStart() && (nHeaderIndex < nEnd && nHeaderIndex < pEntry->GetEnd()))
2404  {
2405  // for handling group started before the current view range
2406  if (rGroupStartPositions[nLevel] < 0)
2407  rGroupStartPositions[nLevel] *= -1;
2408  break;
2409  }
2410  if (nHeaderIndex == pEntry->GetEnd() || (nHeaderIndex == nEnd && rGroupStartPositions[nLevel] != -1))
2411  {
2412  // nHeaderIndex is the end col/row of a group or is the last col/row and a group started and not yet ended
2413 
2414  // append a new group control data
2415  auto len = rGroupsBuffer.getLength();
2416  if (len && rGroupsBuffer[len-1] == '}')
2417  {
2418  rGroupsBuffer.append(", ");
2419  }
2420 
2421  bool bGroupHidden = pEntry->IsHidden();
2422 
2423  rGroupsBuffer.append(
2424  "{ \"level\": " + OString::number(nLevel + 1) + ", "
2425  "\"index\": " + OString::number(nIndex) + ", "
2426  "\"startPos\": " + OString::number(rGroupStartPositions[nLevel]) + ", "
2427  "\"endPos\": " + OString::number(nTotalPx) + ", "
2428  "\"hidden\": " + OString::number(bGroupHidden ? 1 : 0) + " }");
2429 
2430  // look for the next visible group control at level nLevel
2431  bool bFound = false;
2432  ++nIndex;
2433  while (nIndex < rArray.GetCount(nLevel))
2434  {
2435  pEntry = rArray.GetEntry(nLevel, nIndex);
2436  if (pEntry && pEntry->IsVisible())
2437  {
2438  bFound = true;
2439  break;
2440  }
2441  if (pEntry && pEntry->GetStart() > nEnd)
2442  {
2443  break;
2444  }
2445  ++nIndex;
2446  }
2447  rGroupIndexes[nLevel] = bFound ? nIndex : -1;
2448  rGroupStartPositions[nLevel] = -1;
2449  }
2450  }
2451  }
2452 }
2453 
2454 class ScRangeProvider
2455 {
2456 public:
2457  ScRangeProvider(const tools::Rectangle& rArea, bool bInPixels,
2458  ScViewData& rViewData):
2459  mrViewData(rViewData)
2460  {
2461  tools::Rectangle aAreaPx = bInPixels ? rArea :
2462  tools::Rectangle(rArea.Left() * mrViewData.GetPPTX(),
2463  rArea.Top() * mrViewData.GetPPTY(),
2464  rArea.Right() * mrViewData.GetPPTX(),
2465  rArea.Bottom() * mrViewData.GetPPTY());
2466  calculateBounds(aAreaPx);
2467  }
2468 
2469  const ScRange& getCellRange() const
2470  {
2471  return maRange;
2472  }
2473 
2474  void getColPositions(tools::Long& rStartColPos, tools::Long& rEndColPos) const
2475  {
2476  rStartColPos = maBoundPositions.Left();
2477  rEndColPos = maBoundPositions.Right();
2478  }
2479 
2480  void getRowPositions(tools::Long& rStartRowPos, tools::Long& rEndRowPos) const
2481  {
2482  rStartRowPos = maBoundPositions.Top();
2483  rEndRowPos = maBoundPositions.Bottom();
2484  }
2485 
2486 private:
2487  void calculateBounds(const tools::Rectangle& rAreaPx)
2488  {
2489  tools::Long nLeftPx = 0, nRightPx = 0;
2490  SCCOLROW nStartCol = -1, nEndCol = -1;
2491  calculateDimensionBounds(rAreaPx.Left(), rAreaPx.Right(), true,
2492  nStartCol, nEndCol, nLeftPx, nRightPx,
2493  mnEnlargeX, mrViewData);
2494  tools::Long nTopPx = 0, nBottomPx = 0;
2495  SCCOLROW nStartRow = -1, nEndRow = -1;
2496  calculateDimensionBounds(rAreaPx.Top(), rAreaPx.Bottom(), false,
2497  nStartRow, nEndRow, nTopPx, nBottomPx,
2498  mnEnlargeY, mrViewData);
2499 
2500  maRange.aStart.Set(nStartCol, nStartRow, mrViewData.GetTabNo());
2501  maRange.aEnd.Set(nEndCol, nEndRow, mrViewData.GetTabNo());
2502 
2503  maBoundPositions.SetLeft(nLeftPx);
2504  maBoundPositions.SetRight(nRightPx);
2505  maBoundPositions.SetTop(nTopPx);
2506  maBoundPositions.SetBottom(nBottomPx);
2507  }
2508 
2509  // All positions are in pixels.
2510  static void calculateDimensionBounds(const tools::Long nStartPos, const tools::Long nEndPos,
2511  bool bColumns, SCCOLROW& rStartIndex,
2512  SCCOLROW& rEndIndex, tools::Long& rBoundStart,
2513  tools::Long& rBoundEnd, SCCOLROW nEnlarge,
2514  ScViewData& rViewData)
2515  {
2516  ScPositionHelper& rPosHelper = bColumns ? rViewData.GetLOKWidthHelper() :
2517  rViewData.GetLOKHeightHelper();
2518  const auto& rStartNearest = rPosHelper.getNearestByPosition(nStartPos);
2519  const auto& rEndNearest = rPosHelper.getNearestByPosition(nEndPos);
2520 
2521  ScBoundsProvider aBoundsProvider(rViewData, rViewData.GetTabNo(), bColumns);
2522  aBoundsProvider.Compute(rStartNearest, rEndNearest, nStartPos, nEndPos);
2523  aBoundsProvider.EnlargeBy(nEnlarge);
2524  if (bColumns)
2525  {
2526  SCCOL nStartCol = -1, nEndCol = -1;
2527  aBoundsProvider.GetStartIndexAndPosition(nStartCol, rBoundStart);
2528  aBoundsProvider.GetEndIndexAndPosition(nEndCol, rBoundEnd);
2529  rStartIndex = nStartCol;
2530  rEndIndex = nEndCol;
2531  }
2532  else
2533  {
2534  SCROW nStartRow = -1, nEndRow = -1;
2535  aBoundsProvider.GetStartIndexAndPosition(nStartRow, rBoundStart);
2536  aBoundsProvider.GetEndIndexAndPosition(nEndRow, rBoundEnd);
2537  rStartIndex = nStartRow;
2538  rEndIndex = nEndRow;
2539  }
2540  }
2541 
2542 private:
2543 
2544  ScRange maRange;
2545  tools::Rectangle maBoundPositions;
2546  ScViewData& mrViewData;
2547  static const SCCOLROW mnEnlargeX = 2;
2548  static const SCCOLROW mnEnlargeY = 2;
2549 };
2550 
2551 void lcl_ExtendTiledDimension(bool bColumn, const SCCOLROW nEnd, const SCCOLROW nExtra,
2552  ScTabView& rTabView, ScViewData& rViewData)
2553 {
2554  ScDocument& rDoc = rViewData.GetDocument();
2555  // If we are approaching current max tiled row/col, signal a size changed event
2556  // and invalidate the involved area
2557  SCCOLROW nMaxTiledIndex = bColumn ? rViewData.GetMaxTiledCol() : rViewData.GetMaxTiledRow();
2558  SCCOLROW nHardLimit = !bColumn ? MAXTILEDROW : rDoc.MaxCol();
2559 
2560  if (nMaxTiledIndex >= nHardLimit)
2561  return;
2562 
2563  if (nEnd <= nMaxTiledIndex - nExtra) // No need to extend.
2564  return;
2565 
2566  ScDocShell* pDocSh = rViewData.GetDocShell();
2567  ScModelObj* pModelObj = pDocSh ?
2568  comphelper::getFromUnoTunnel<ScModelObj>( pDocSh->GetModel() ) : nullptr;
2569  Size aOldSize(0, 0);
2570  if (pModelObj)
2571  aOldSize = pModelObj->getDocumentSize();
2572 
2573  SCCOLROW nNewMaxTiledIndex = std::min(std::max(nEnd, nMaxTiledIndex) + nExtra, nHardLimit);
2574 
2575  if (bColumn)
2576  rViewData.SetMaxTiledCol(nNewMaxTiledIndex);
2577  else
2578  rViewData.SetMaxTiledRow(nNewMaxTiledIndex);
2579 
2580  Size aNewSize(0, 0);
2581  if (pModelObj)
2582  aNewSize = pModelObj->getDocumentSize();
2583 
2584  if (aOldSize == aNewSize)
2585  return;
2586 
2587  if (!pDocSh)
2588  return;
2589 
2590  // New area extended to the right/bottom of the sheet after last col/row
2591  // excluding overlapping area with aNewArea
2592  tools::Rectangle aNewArea = bColumn ?
2593  tools::Rectangle(aOldSize.getWidth(), 0, aNewSize.getWidth(), aNewSize.getHeight()):
2594  tools::Rectangle(0, aOldSize.getHeight(), aNewSize.getWidth(), aNewSize.getHeight());
2595 
2596  // Only invalidate if spreadsheet has extended to the right or bottom
2597  if ((bColumn && aNewArea.getWidth()) || (!bColumn && aNewArea.getHeight()))
2598  {
2599  rTabView.UpdateSelectionOverlay();
2600  SfxLokHelper::notifyInvalidation(rViewData.GetViewShell(), &aNewArea);
2601  }
2602 
2603  // Provide size in the payload, so clients don't have to query for that.
2604  std::stringstream ss;
2605  ss << aNewSize.Width() << ", " << aNewSize.Height();
2606  OString sSize = ss.str().c_str();
2607  ScModelObj* pModel = comphelper::getFromUnoTunnel<ScModelObj>(
2608  rViewData.GetViewShell()->GetCurrentDocument());
2609  SfxLokHelper::notifyDocumentSizeChanged(rViewData.GetViewShell(), sSize, pModel, false);
2610 }
2611 
2612 } // anonymous namespace
2613 
2615 {
2616  ScDocument& rDoc = aViewData.GetDocument();
2617 
2618  if (rRectangle.IsEmpty())
2619  return;
2620 
2621  bool bRangeHeaderSupport = comphelper::LibreOfficeKit::isRangeHeaders();
2622 
2623  rJsonWriter.put("commandName", ".uno:ViewRowColumnHeaders");
2624 
2625  SCTAB nTab = aViewData.GetTabNo();
2626  SCROW nStartRow = -1;
2627  SCROW nEndRow = -1;
2628  tools::Long nStartHeightPx = 0;
2629  SCCOL nStartCol = -1;
2630  SCCOL nEndCol = -1;
2631  tools::Long nStartWidthPx = 0;
2632 
2633  tools::Rectangle aOldVisArea(
2636 
2637  ScRangeProvider aRangeProvider(rRectangle, /* bInPixels */ false, aViewData);
2638  const ScRange& rCellRange = aRangeProvider.getCellRange();
2639 
2641 
2643 
2644  if (rRectangle.Top() < rRectangle.Bottom())
2645  {
2646  SAL_INFO("sc.lok.header", "Row Header: compute start/end rows.");
2647  tools::Long nEndHeightPx = 0;
2648  nStartRow = rCellRange.aStart.Row();
2649  nEndRow = rCellRange.aEnd.Row();
2650  aRangeProvider.getRowPositions(nStartHeightPx, nEndHeightPx);
2651 
2654  aViewData.GetLOKHeightHelper().insert(nStartRow, nStartHeightPx);
2655  aViewData.GetLOKHeightHelper().insert(nEndRow, nEndHeightPx);
2656 
2657  mnLOKStartHeaderRow = nStartRow;
2658  mnLOKEndHeaderRow = nEndRow;
2659  }
2660 
2661  sal_Int32 nVisibleRows = nEndRow - nStartRow;
2662  if (nVisibleRows < 25)
2663  nVisibleRows = 25;
2664 
2665  SAL_INFO("sc.lok.header", "Row Header: visible rows: " << nVisibleRows);
2666 
2667 
2668  // Get row groups
2669  // per each level store the index of the first group intersecting
2670  // [nStartRow, nEndRow] range
2671 
2672  const ScOutlineTable* pTable = rDoc.GetOutlineTable(nTab);
2673  const ScOutlineArray* pRowArray = pTable ? &(pTable->GetRowArray()) : nullptr;
2674  size_t nRowGroupDepth = 0;
2675  std::vector<size_t> aRowGroupIndexes;
2676  if (bRangeHeaderSupport && pTable)
2677  {
2678  nRowGroupDepth = pRowArray->GetDepth();
2679  lcl_getGroupIndexes(*pRowArray, nStartRow, nEndRow, aRowGroupIndexes);
2680  }
2681 
2684  lcl_ExtendTiledDimension(/* bColumn */ false, nEndRow, nVisibleRows, *this, aViewData);
2685 
2687 
2688  tools::Long nTotalPixels = nStartHeightPx;
2689  tools::Long nPrevSizePx = -1;
2690  OStringBuffer aRowGroupsBuffer = "\"rowGroups\": [\n";
2691  {
2692  auto rowsNode = rJsonWriter.startArray("rows");
2693 
2694  SAL_INFO("sc.lok.header", "Row Header: [create string data for rows]: start row: "
2695  << nStartRow << " start height: " << nTotalPixels);
2696 
2697  if (nStartRow != nEndRow)
2698  {
2699  auto node = rJsonWriter.startStruct();
2700  rJsonWriter.put("text", nStartRow + 1);
2701  rJsonWriter.put("size", nTotalPixels);
2702  rJsonWriter.put("groupLevels", static_cast<sal_Int64>(nRowGroupDepth));
2703  }
2704 
2705  std::vector<tools::Long> aRowGroupStartPositions(nRowGroupDepth, -nTotalPixels);
2706  for (SCROW nRow = nStartRow + 1; nRow <= nEndRow; ++nRow)
2707  {
2708  // nSize will be 0 for hidden rows.
2709  const tools::Long nSizePx = lcl_GetRowHeightPx(aViewData, nRow, nTab);
2710  nTotalPixels += nSizePx;
2711 
2712  if (bRangeHeaderSupport && nRowGroupDepth > 0)
2713  {
2714  lcl_createGroupsData(nRow, nEndRow, nSizePx, nTotalPixels,
2715  *pRowArray, aRowGroupIndexes, aRowGroupStartPositions,
2716  aRowGroupsBuffer);
2717  }
2718 
2719  if (bRangeHeaderSupport && nRow < nEndRow && nSizePx == nPrevSizePx)
2720  continue;
2721  nPrevSizePx = nSizePx;
2722 
2723  auto node = rJsonWriter.startStruct();
2724  rJsonWriter.put("text", pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow));
2725  rJsonWriter.put("size", nTotalPixels);
2726  }
2727 
2728  aRowGroupsBuffer.append("]");
2729  }
2730  if (nRowGroupDepth > 0)
2731  {
2732  aRowGroupsBuffer.append(",\n");
2733  rJsonWriter.putRaw(aRowGroupsBuffer);
2734  }
2736 
2737 
2739 
2741 
2742  if (rRectangle.Left() < rRectangle.Right())
2743  {
2744  SAL_INFO("sc.lok.header", "Column Header: compute start/end columns.");
2745  tools::Long nEndWidthPx = 0;
2746  nStartCol = rCellRange.aStart.Col();
2747  nEndCol = rCellRange.aEnd.Col();
2748  aRangeProvider.getColPositions(nStartWidthPx, nEndWidthPx);
2749 
2752  aViewData.GetLOKWidthHelper().insert(nStartCol, nStartWidthPx);
2753  aViewData.GetLOKWidthHelper().insert(nEndCol, nEndWidthPx);
2754 
2755  mnLOKStartHeaderCol = nStartCol;
2756  mnLOKEndHeaderCol = nEndCol;
2757  }
2758 
2759  sal_Int32 nVisibleCols = nEndCol - nStartCol;
2760  if (nVisibleCols < 10)
2761  nVisibleCols = 10;
2762 
2763 
2764  // Get column groups
2765  // per each level store the index of the first group intersecting
2766  // [nStartCol, nEndCol] range
2767 
2768  const ScOutlineArray* pColArray = pTable ? &(pTable->GetColArray()) : nullptr;
2769  size_t nColGroupDepth = 0;
2770  std::vector<size_t> aColGroupIndexes;
2771  if (bRangeHeaderSupport && pTable)
2772  {
2773  nColGroupDepth = pColArray->GetDepth();
2774  lcl_getGroupIndexes(*pColArray, nStartCol, nEndCol, aColGroupIndexes);
2775  }
2776 
2779  lcl_ExtendTiledDimension(/* bColumn */ true, nEndCol, nVisibleCols, *this, aViewData);
2780 
2782  OStringBuffer aColGroupsBuffer = "\"columnGroups\": [\n";
2783  {
2784  auto columnsNode = rJsonWriter.startArray("columns");
2785 
2786  nTotalPixels = nStartWidthPx;
2787  SAL_INFO("sc.lok.header", "Col Header: [create string data for cols]: start col: "
2788  << nStartRow << " start width: " << nTotalPixels);
2789 
2790  if (nStartCol != nEndCol)
2791  {
2792  auto node = rJsonWriter.startStruct();
2793  rJsonWriter.put("text", static_cast<sal_Int64>(nStartCol + 1));
2794  rJsonWriter.put("size", nTotalPixels);
2795  rJsonWriter.put("groupLevels", static_cast<sal_Int64>(nColGroupDepth));
2796  }
2797 
2798  std::vector<tools::Long> aColGroupStartPositions(nColGroupDepth, -nTotalPixels);
2799  nPrevSizePx = -1;
2800  for (SCCOL nCol = nStartCol + 1; nCol <= nEndCol; ++nCol)
2801  {
2802  // nSize will be 0 for hidden columns.
2803  const tools::Long nSizePx = lcl_GetColWidthPx(aViewData, nCol, nTab);
2804  nTotalPixels += nSizePx;
2805 
2806  if (bRangeHeaderSupport && nColGroupDepth > 0)
2807  lcl_createGroupsData(nCol, nEndCol, nSizePx, nTotalPixels,
2808  *pColArray, aColGroupIndexes,
2809  aColGroupStartPositions, aColGroupsBuffer);
2810 
2811  if (bRangeHeaderSupport && nCol < nEndCol && nSizePx == nPrevSizePx)
2812  continue;
2813  nPrevSizePx = nSizePx;
2814 
2815  OUString aText = bRangeHeaderSupport ?
2816  OUString::number(nCol + 1) : pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol);
2817 
2818  auto node = rJsonWriter.startStruct();
2819  rJsonWriter.put("text", aText);
2820  rJsonWriter.put("size", nTotalPixels);
2821  }
2822 
2823  aColGroupsBuffer.append("]");
2824  }
2825  if (nColGroupDepth > 0)
2826  {
2827  aColGroupsBuffer.append(",\n");
2828  rJsonWriter.putRaw(aColGroupsBuffer);
2829  }
2831 
2832  vcl::Region aNewVisArea(
2835  aNewVisArea.Exclude(aOldVisArea);
2836  tools::Rectangle aChangedArea = aNewVisArea.GetBoundRect();
2837  if (!aChangedArea.IsEmpty())
2838  {
2840  UpdateFormulas(aChangedArea.Left(), aChangedArea.Top(), aChangedArea.Right(), aChangedArea.Bottom());
2841  }
2842 }
2843 
2844 OString ScTabView::getSheetGeometryData(bool bColumns, bool bRows, bool bSizes, bool bHidden,
2845  bool bFiltered, bool bGroups)
2846 {
2847  ScDocument& rDoc = aViewData.GetDocument();
2848 
2849  boost::property_tree::ptree aTree;
2850  aTree.put("commandName", ".uno:SheetGeometryData");
2851  aTree.put("maxtiledcolumn", rDoc.MaxCol());
2852  aTree.put("maxtiledrow", MAXTILEDROW);
2853 
2854  auto getJSONString = [](const boost::property_tree::ptree& rTree) {
2855  std::stringstream aStream;
2856  boost::property_tree::write_json(aStream, rTree);
2857  return aStream.str();
2858  };
2859 
2860  if ((!bSizes && !bHidden && !bFiltered && !bGroups) ||
2861  (!bColumns && !bRows))
2862  {
2863  return getJSONString(aTree).c_str();
2864  }
2865 
2866  struct GeomEntry
2867  {
2869  const char* pKey;
2870  bool bEnabled;
2871  };
2872 
2873  const GeomEntry aGeomEntries[] = {
2874  { SheetGeomType::SIZES, "sizes", bSizes },
2875  { SheetGeomType::HIDDEN, "hidden", bHidden },
2876  { SheetGeomType::FILTERED, "filtered", bFiltered },
2877  { SheetGeomType::GROUPS, "groups", bGroups }
2878  };
2879 
2880  struct DimensionEntry
2881  {
2882  const char* pKey;
2883  bool bDimIsCol;
2884  bool bEnabled;
2885  };
2886 
2887  const DimensionEntry aDimEntries[] = {
2888  { "columns", true, bColumns },
2889  { "rows", false, bRows }
2890  };
2891 
2892  SCTAB nTab = aViewData.GetTabNo();
2893 
2894  for (const auto& rDimEntry : aDimEntries)
2895  {
2896  if (!rDimEntry.bEnabled)
2897  continue;
2898 
2899  bool bDimIsCol = rDimEntry.bDimIsCol;
2900 
2901  boost::property_tree::ptree aDimTree;
2902  for (const auto& rGeomEntry : aGeomEntries)
2903  {
2904  if (!rGeomEntry.bEnabled)
2905  continue;
2906 
2907  OString aGeomDataEncoding = rDoc.dumpSheetGeomData(nTab, bDimIsCol, rGeomEntry.eType);
2908  // TODO: Investigate if we can avoid the copy of the 'value' string in put().
2909  aDimTree.put(rGeomEntry.pKey, aGeomDataEncoding.getStr());
2910  }
2911 
2912  aTree.add_child(rDimEntry.pKey, aDimTree);
2913  }
2914 
2915  return getJSONString(aTree).c_str();
2916 }
2917 
2919 {
2920  SAL_INFO("sc.lok.header",
2921  "extendTiledAreaIfNeeded: START: ClientView: ColRange["
2923  << "] RowRange[" << mnLOKStartHeaderRow << "," << mnLOKEndHeaderRow
2924  << "] MaxTiledCol = " << aViewData.GetMaxTiledCol()
2925  << " MaxTiledRow = " << aViewData.GetMaxTiledRow());
2926 
2927  const tools::Rectangle rVisArea = aViewData.getLOKVisibleArea();
2928  if (rVisArea.Top() >= rVisArea.Bottom() ||
2929  rVisArea.Left() >= rVisArea.Right())
2930  return;
2931 
2932  // Needed for conditional updating of visible-range/formula.
2933  tools::Rectangle aOldVisCellRange(mnLOKStartHeaderCol + 1, mnLOKStartHeaderRow + 1,
2935 
2936  ScRangeProvider aRangeProvider(rVisArea, /* bInPixels */ false, aViewData);
2937  // Index bounds.
2938  const ScRange& rCellRange = aRangeProvider.getCellRange();
2939  const SCCOL nStartCol = rCellRange.aStart.Col();
2940  const SCCOL nEndCol = rCellRange.aEnd.Col();
2941  const SCROW nStartRow = rCellRange.aStart.Row();
2942  const SCROW nEndRow = rCellRange.aEnd.Row();
2943 
2944  // Column/Row positions.
2945  tools::Long nStartColPos, nEndColPos, nStartRowPos, nEndRowPos;
2946  aRangeProvider.getColPositions(nStartColPos, nEndColPos);
2947  aRangeProvider.getRowPositions(nStartRowPos, nEndRowPos);
2948 
2949  ScPositionHelper& rWidthHelper = aViewData.GetLOKWidthHelper();
2950  ScPositionHelper& rHeightHelper = aViewData.GetLOKHeightHelper();
2951 
2952  // Update mnLOKStartHeaderCol and mnLOKEndHeaderCol members.
2953  // These are consulted in some ScGridWindow methods.
2954  if (mnLOKStartHeaderCol != nStartCol)
2955  {
2956  rWidthHelper.removeByIndex(mnLOKStartHeaderCol);
2957  rWidthHelper.insert(nStartCol, nStartColPos);
2958  mnLOKStartHeaderCol = nStartCol;
2959  }
2960 
2961  if (mnLOKEndHeaderCol != nEndCol)
2962  {
2963  rWidthHelper.removeByIndex(mnLOKEndHeaderCol);
2964  rWidthHelper.insert(nEndCol, nEndColPos);
2965  mnLOKEndHeaderCol = nEndCol;
2966  }
2967 
2968  // Update mnLOKStartHeaderRow and mnLOKEndHeaderRow members.
2969  // These are consulted in some ScGridWindow methods.
2970  if (mnLOKStartHeaderRow != nStartRow)
2971  {
2972  rHeightHelper.removeByIndex(mnLOKStartHeaderRow);
2973  rHeightHelper.insert(nStartRow, nStartRowPos);
2974  mnLOKStartHeaderRow = nStartRow;
2975  }
2976 
2977  if (mnLOKEndHeaderRow != nEndRow)
2978  {
2979  rHeightHelper.removeByIndex(mnLOKEndHeaderRow);
2980  rHeightHelper.insert(nEndRow, nEndRowPos);
2981  mnLOKEndHeaderRow = nEndRow;
2982  }
2983 
2984  constexpr SCCOL nMinExtraCols = 10;
2985  SCCOL nExtraCols = std::max<SCCOL>(nMinExtraCols, nEndCol - nStartCol);
2986  // If we are approaching current max tiled column, signal a size changed event
2987  // and invalidate the involved area.
2988  lcl_ExtendTiledDimension(/* bColumn */ true, nEndCol, nExtraCols, *this, aViewData);
2989 
2990  constexpr SCROW nMinExtraRows = 25;
2991  SCROW nExtraRows = std::max(nMinExtraRows, nEndRow - nStartRow);
2992  // If we are approaching current max tiled row, signal a size changed event
2993  // and invalidate the involved area.
2994  lcl_ExtendTiledDimension(/* bColumn */ false, nEndRow, nExtraRows, *this, aViewData);
2995 
2996  vcl::Region aNewVisCellRange(
2999  aNewVisCellRange.Exclude(aOldVisCellRange);
3000  tools::Rectangle aChangedCellRange = aNewVisCellRange.GetBoundRect();
3001  if (!aChangedCellRange.IsEmpty())
3002  {
3004  UpdateFormulas(aChangedCellRange.Left(), aChangedCellRange.Top(),
3005  aChangedCellRange.Right(), aChangedCellRange.Bottom());
3006  }
3007 
3008  SAL_INFO("sc.lok.header",
3009  "extendTiledAreaIfNeeded: END: ClientView: ColRange["
3011  << "] RowRange[" << mnLOKStartHeaderRow << "," << mnLOKEndHeaderRow
3012  << "] MaxTiledCol = " << aViewData.GetMaxTiledCol()
3013  << " MaxTiledRow = " << aViewData.GetMaxTiledRow());
3014 }
3015 
3016 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define MAXZOOM
Definition: global.hxx:79
virtual Point GetPosPixel() const
void TestHintWindow()
Definition: tabview3.cxx:783
SfxViewFrame * GetViewFrame() const
void SetVSplitMode(ScSplitMode eMode)
Definition: viewdata.hxx:439
SvxZoomType GetZoomType() const
Definition: tabview5.cxx:417
virtual void EnableRTL(bool bEnable=true) override
void LaunchDPFieldMenu(SCCOL nCol, SCROW nRow)
Definition: gridwin.cxx:1233
void SelectAll(bool bContinue=false)
Definition: tabview2.cxx:1099
void SetBackground()
void SetDragRectPixel(const tools::Rectangle &rDragRect, vcl::Window *pRefWin=nullptr)
void LaunchPageFieldMenu(SCCOL nCol, SCROW nRow)
Definition: gridwin.cxx:1215
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: tabview.cxx:131
sal_Int32 nIndex
void DoHSplit(tools::Long nSplitPos)
Definition: tabview.cxx:1527
static void notifyInvalidation(SfxViewShell const *pThisView, tools::Rectangle const *)
ScAddress aStart
Definition: address.hxx:497
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
void FreezeSplitters(bool bFreeze, SplitMethod eSplitMethod=SC_SPLIT_METHOD_CURSOR, SCCOLROW nFreezeIndex=-1)
Definition: tabview.cxx:1922
bool bInUpdateHeader
Definition: tabview.hxx:206
static void notifyDocumentSizeChanged(SfxViewShell const *pThisView, const OString &rPayload, vcl::ITiledRenderable *pDoc, bool bInvalidateAll=true)
void Compute(value_type aFirstNearest, value_type aSecondNearest, tools::Long nFirstBound, tools::Long nSecondBound)
Definition: viewdata.cxx:348
std::array< VclPtr< ScRowBar >, 2 > pRowBar
Definition: tabview.hxx:144
ScVSplitPos WhichV(ScSplitPos ePos)
Definition: viewdata.hxx:728
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
VclPtr< ScrollBar > aHScrollLeft
Definition: tabview.hxx:152
SC_DLLPUBLIC bool IsNegativePage(SCTAB nTab) const
Definition: document.cxx:997
SC_DLLPUBLIC bool IsHidden() const
Definition: olinetab.hxx:49
void SetFixPosY(SCROW nPos)
Definition: viewdata.hxx:443
SCROW mnLOKEndHeaderRow
Definition: tabview.hxx:201
MapMode GetDrawMapMode(bool bForce=false)
MapMode for the drawinglayer objects.
Definition: gridwin3.cxx:252
SCROW Row() const
Definition: address.hxx:274
ScVSplitPos
Definition: viewdata.hxx:46
void setWidth(tools::Long nWidth)
ScSplitPos FindWindow(const vcl::Window *pWindow) const
Definition: tabview.cxx:908
static void lcl_SetPosSize(vcl::Window &rWindow, const Point &rPos, const Size &rSize, tools::Long nTotalWidth, bool bLayoutRTL)
Definition: tabview.cxx:260
void LaunchDataSelectMenu(SCCOL nCol, SCROW nRow)
Definition: gridwin.cxx:1377
bool IsVScrollMode() const
Definition: viewdata.hxx:563
ScopedJsonWriterStruct startStruct()
const tools::Rectangle & getLOKVisibleArea() const
The visible area in the client (set by setClientVisibleArea).
Definition: viewdata.hxx:573
virtual void EnableRTL(bool bEnable=true)
SCCOL mnLOKStartHeaderCol
Definition: tabview.hxx:202
VclPtr< ScrollBar > aVScrollBottom
Definition: tabview.hxx:151
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
const Fraction & GetZoomX() const
Definition: viewdata.hxx:459
tools::Long getWidth() const
void SetSheetLayoutRTL(bool bSheetRTL)
Definition: tabcont.cxx:414
void SetHSplitPos(tools::Long nPos)
Definition: viewdata.hxx:440
constexpr tools::Long Left() const
VclPtr< ScrollBar > aHScrollRight
Definition: tabview.hxx:153
std::unique_ptr< sal_Int32[]> pData
SC_DLLPUBLIC SCCOLROW GetEnd() const
Definition: olinetab.cxx:42
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
Point aBorderPos
Definition: tabview.hxx:133
virtual void Resize() override
Definition: tabview.cxx:126
void RepeatResize(bool bUpdateFix=true)
Definition: tabview.cxx:772
long Long
Point GetChartInsertPos(const Size &rSize, const ScRange &rCellRange)
Definition: tabview.cxx:1686
const StyleSettings & GetStyleSettings() const
void HideNoteMarker()
Definition: tabview2.cxx:1420
ScopedJsonWriterArray startArray(const char *)
SCROW GetCurY() const
Definition: viewdata.hxx:402
ScHSplitPos WhichH(ScSplitPos ePos)
Definition: viewdata.hxx:722
const Color & GetFaceColor() const
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
#define SC_ICONSIZE
Definition: tabview.cxx:68
void ScColToAlpha(OUStringBuffer &rBuf, SCCOL nCol)
append alpha representation of column to buffer
Definition: address.cxx:1884
css::uno::Reference< css::frame::XModel3 > GetModel() const
virtual Size GetSizePixel() const
SCROW GetMaxTiledRow() const
Definition: viewdata.hxx:423
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: tabview.cxx:88
virtual void SetSizePixel(const Size &rNewSize)
double mfPendingTabBarWidth
Definition: tabview.hxx:198
VclPtr< ScTabSplitter > pHSplitter
Definition: tabview.hxx:147
void SetDocumentModified()
Definition: docsh.cxx:2959
void InitScrollBar(ScrollBar &rScrollBar, tools::Long nMaxVal)
Definition: tabview.cxx:224
double GetPPTX() const
Definition: viewdata.hxx:468
SCROW GetFixPosY() const
Definition: viewdata.hxx:421
sal_uInt16 GetLockedModifiers() const
Definition: tabview.cxx:1906
ScOutlineEntry * GetEntry(size_t nLevel, size_t nIndex)
Definition: olinetab.cxx:428
SCROW mnLOKStartHeaderRow
Definition: tabview.hxx:200
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
OString dumpSheetGeomData(SCTAB nTab, bool bColumns, SheetGeomType eGeomType)
Serializes the specified sheet's geometry data.
void PaintGrid()
Definition: tabview3.cxx:2635
ScAddress aEnd
Definition: address.hxx:498
ScSplitPos GetActivePart() const
Definition: viewdata.hxx:398
void GetBorderSize(SvBorder &rBorder, const Size &rSize)
Definition: tabview.cxx:796
ScDocument & GetDocument() const
Definition: viewdata.hxx:380
OString getSheetGeometryData(bool bColumns, bool bRows, bool bSizes, bool bHidden, bool bFiltered, bool bGroups)
Definition: tabview.cxx:2844
tools::Rectangle GetDesktopRectPixel() const
void RemoveHintWindow()
Definition: tabview3.cxx:881
void SetAutoSpellData(SCCOL nPosX, SCROW nPosY, const std::vector< editeng::MisspellRanges > *pRanges)
Definition: tabview.cxx:2291
WinBits const WB_VSCROLL
void UpdateAllOverlays()
Definition: tabview2.cxx:1035
const CommandWheelData * GetWheelData() const
void insert(index_type nIndex, tools::Long nPos)
Definition: viewdata.cxx:138
tools::Long GetTabBarWidth() const
Returns the current tab bar width in pixels.
Definition: tabview.cxx:877
void Invalidate(sal_uInt16 nId)
tools::Rectangle GetBoundRect() const
void LockModifiers(sal_uInt16 nModifiers)
Definition: tabview.cxx:1900
css::chart::ChartAxisLabelPosition ePos
SCCOL GetPosX(ScHSplitPos eWhich, SCTAB nForTab=-1) const
Definition: viewdata.cxx:1402
None
SCCOL CellsAtX(SCCOL nPosX, SCCOL nDir, ScHSplitPos eWhichX, sal_uInt16 nScrSizeY=SC_SIZE_NONE) const
Definition: viewdata.cxx:2623
SC_DLLPUBLIC void ScrollLines(tools::Long nDeltaX, tools::Long nDeltaY)
Definition: tabview.cxx:1319
virtual void StateChanged(StateChangedType nType) override
Definition: tabview.cxx:108
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4211
void ResetAutoSpell()
Definition: tabview.cxx:2269
ScSplitPos
Definition: viewdata.hxx:44
void ScrollX(tools::Long nDeltaX, ScHSplitPos eWhich, bool bUpdBars=true)
Definition: tabview.cxx:1152
virtual ~ScCornerButton() override
Definition: tabview.cxx:84
bool UpdateFixY(SCTAB nTab=MAXTAB+1)
Definition: viewdata.cxx:4055
bool GetEntryIndex(size_t nLevel, SCCOLROW nPos, size_t &rnIndex) const
Definition: olinetab.cxx:481
tools::Long getHeight() const
StateChangedType
constexpr tools::Long Width() const
bool IsTabMode() const
Definition: viewdata.hxx:562
void UpdateAutoFillMark(bool bFromPaste=false)
Definition: tabview3.cxx:187
sal_Int64 WinBits
void StartDataSelect()
Definition: tabview.cxx:2191
static tools::Long ToPixel(sal_uInt16 nTwips, double nFactor)
Definition: viewdata.hxx:700
void UpdateFixPos()
Definition: tabview.cxx:759
Reference< XController > xController
void PaintLeft()
Definition: tabview3.cxx:2713
tools::Long GetVSplitPos() const
Definition: viewdata.hxx:419
void SetPageSize(tools::Long nNewSize)
bool GetEntryIndexInRange(size_t nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t &rnIndex) const
Definition: olinetab.cxx:501
bool IsFormulaMode()
Definition: scmod.cxx:1678
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:892
std::array< VclPtr< ScGridWindow >, 4 > pGridWin
Definition: tabview.hxx:142
SC_DLLPUBLIC void SetRelTabBarWidth(double fRelTabBarWidth)
Sets a relative tab bar width.
Definition: tabview.cxx:864
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:23
void SetPosX(ScHSplitPos eWhich, SCCOL nNewPosX)
Definition: viewdata.cxx:2903
std::shared_ptr< sc::SpellCheckContext > mpSpellCheckCxt
Definition: tabview.hxx:158
void SetPendingRelTabBarWidth(double fRelTabBarWidth)
Sets a relative tab bar width.
Definition: tabview.cxx:871
WinBits const WB_HSCROLL
void SetFixPosX(SCCOL nPos)
Definition: viewdata.hxx:442
SfxFrame & GetFrame() const
size_t GetDepth() const
Definition: olinetab.hxx:110
SCCOL mnLOKEndHeaderCol
Definition: tabview.hxx:203
void BroadcastAccessibility(const SfxHint &rHint)
Definition: tabvwshh.cxx:236
constexpr tools::Long GetWidth() const
void UpdateFormulas(SCCOL nStartCol=-1, SCROW nStartRow=-1, SCCOL nEndCol=-1, SCROW nEndRow=-1)
Definition: tabview3.cxx:2287
void ActivatePart(ScSplitPos eWhich)
Definition: tabview3.cxx:2886
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: tabview.cxx:117
tools::Long & Bottom()
SCCOL GetMaxTiledCol() const
Definition: viewdata.hxx:422
SCROW GetPosY(ScVSplitPos eWhich, SCTAB nForTab=-1) const
Definition: viewdata.cxx:1416
ScSplitMode GetHSplitMode() const
Definition: viewdata.hxx:416
tools::Long & Top()
void DrawLine(const Point &rStartPt, const Point &rEndPt)
const Fraction & GetZoomY() const
Definition: viewdata.hxx:460
ScViewData & GetViewData()
Definition: tabview.hxx:333
void PaintTop()
Definition: tabview3.cxx:2646
ScGridWindow * GetActiveWin()
Definition: tabview.cxx:887
SC_DLLPUBLIC const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
Definition: document.cxx:4764
void SetLineSize(tools::Long nNewSize)
bool HasHintWindow() const
Definition: tabview3.cxx:879
void InterpretVisible()
Definition: tabview4.cxx:499
constexpr bool IsEmpty() const
constexpr void SetLeft(tools::Long v)
DocumentType eType
ScTabViewShell * GetViewShell() const
Definition: viewdata.hxx:357
tools::Long zoomOut(tools::Long nCurrent)
void EnableInput(bool bEnable=true, bool bChild=true)
bool IsHScrollMode() const
Definition: viewdata.hxx:564
const Color & GetDarkShadowColor() const
void SetZoom(const Fraction &rNewX, const Fraction &rNewY, bool bAll)
Definition: tabview5.cxx:427
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:891
void SetLineColor()
sal_Int32 GetScrollBarSize() const
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: document.cxx:4495
bool ScrollCommand(const CommandEvent &rCEvt, ScSplitPos ePos)
Definition: tabview.cxx:948
void LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
Definition: gridwin.cxx:837
VclPtr< ScTabControl > pTabControl
Definition: tabview.hxx:149
Point LogicToPixel(const Point &rLogicPt) const
bool IsModalMode(SfxObjectShell *pDocSh=nullptr)
Definition: scmod.cxx:1594
int i
Point GetScrPos(SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, bool bAllowNeg=false, SCTAB nForTab=-1) const
Definition: viewdata.cxx:2375
void DoAddWin(ScGridWindow *pWin)
Definition: tabview5.cxx:271
SC_DLLPUBLIC SCCOLROW GetStart() const
Definition: olinetab.hxx:42
Size aFrameSize
Definition: tabview.hxx:132
SfxBindings & GetBindings()
Definition: viewdata.cxx:3123
const ScOutlineArray & GetRowArray() const
Definition: olinetab.hxx:160
void GetPosFromPixel(tools::Long nClickX, tools::Long nClickY, ScSplitPos eWhich, SCCOL &rPosX, SCROW &rPosY, bool bTestMerge=true, bool bRepair=false, SCTAB nForTab=-1)
Definition: viewdata.cxx:2774
sal_Int16 SCCOL
Definition: types.hxx:21
void SetActivePointer(PointerStyle nPointer)
Definition: tabview.cxx:894
const ScOutlineArray & GetColArray() const
Definition: olinetab.hxx:158
tools::Long zoomIn(tools::Long nCurrent)
#define SC_MOD()
Definition: scmod.hxx:249
static void ShowHide(vcl::Window *pWin, bool bShow)
Definition: tabview.cxx:1409
static bool IsQuickHelpEnabled()
void SetVisibleSize(tools::Long nNewSize)
size_t GetCount(size_t nLevel) const
Definition: olinetab.cxx:456
const vcl::Font & GetTabFont() const
SfxBindings & GetBindings()
CommandWheelMode GetMode() const
void SetRange(const Range &rRange)
void UpdateHeaderWidth(const ScVSplitPos *pWhich=nullptr, const SCROW *pPosY=nullptr)
Definition: tabview.cxx:1347
tools::Long GetHSplitPos() const
Definition: viewdata.hxx:418
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
bool IsPreview() const
void SetFixed(bool bSet)
Definition: tabsplit.cxx:45
ScrollType
QuickHelpFlags
constexpr tools::Long Right() const
const AllSettings & GetSettings() const
virtual void Start(bool bStartTimer=true) override
void SetActive()
Definition: tabvwsh4.cxx:275
virtual css::uno::Reference< css::frame::XModel > GetCurrentDocument() const
const Size & GetFontSize() const
constexpr tools::Long Top() const
constexpr sal_Int32 TAB_HEIGHT_MARGIN
Definition: tabview.cxx:66
void DoVSplit(tools::Long nSplitPos)
Definition: tabview.cxx:1597
void SetVSplitPos(tools::Long nPos)
Definition: viewdata.hxx:441
constexpr void SetRight(tools::Long v)
const AllSettings & GetSettings() const
void InvalidateSplit()
Definition: tabview.cxx:2121
constexpr void SetBottom(tools::Long v)
Point PixelToLogic(const Point &rDevicePt) const
VclPtr< ScrollBar > aVScrollTop
Definition: tabview.hxx:150
bool HasPageFieldDataAtCursor() const
Definition: tabview.cxx:2180
sal_uInt16 CalcZoom(SvxZoomType eType, sal_uInt16 nOldZoom)
Definition: tabview2.cxx:1214
static SC_DLLPUBLIC double GetRelTabBarWidth()
Returns the current tab bar width relative to the frame window width (0.0 ...
Definition: tabview.cxx:882
void RemoveSplit()
Definition: tabview.cxx:2077
void EnableAutoSpell(bool bEnable)
Definition: tabview.cxx:2251
VclPtr< ScrollBarBox > aScrollBarBox
Definition: tabview.hxx:156
void SplitAtCursor()
Definition: tabview.cxx:2084
void UpdateSelectionOverlay()
Definition: tabview2.cxx:1021
void ResetTimer()
Definition: tabview.cxx:246
static void ShowQuickHelp(vcl::Window *pParent, const tools::Rectangle &rScreenRect, const OUString &rHelpText, QuickHelpFlags nStyle=QuickHelpFlags::NONE)
void UpdateScrollBars(HeaderType eHeaderType=BOTH_HEADERS)
Definition: tabview4.cxx:390
constexpr void SetTop(tools::Long v)
bool bMinimized
Definition: tabview.hxx:205
Point OutputToAbsoluteScreenPixel(const Point &rPos) const
VclPtr< ScCornerButton > aTopButton
Definition: tabview.hxx:155
void put(const char *pPropName, const OUString &rPropValue)
SCCOL Col() const
Definition: address.hxx:279
#define SC_TABBAR_MIN
Definition: tabview.cxx:71
void EnableRefInput(bool bFlag)
Definition: tabview.cxx:2228
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
void extendTiledAreaIfNeeded()
Definition: tabview.cxx:2918
constexpr Point TopLeft() const
void SetNewVisArea()
Definition: tabview.cxx:2133
float GetDPIScaleFactor() const
SheetGeomType
Represents the type of sheet geometry data.
Definition: document.hxx:275
void SetEndScrollHdl(const Link< ScrollBar *, void > &rLink)
bool bInZoomUpdate
Definition: tabview.hxx:208
constexpr sal_uInt16 nScrollBarSize
void UpdateShow()
Definition: tabview.cxx:1416
constexpr tools::Long Bottom() const
tools::Long const nBorder
std::array< VclPtr< ScOutlineWindow >, 2 > pColOutline
Definition: tabview.hxx:145
SCCOL GetFixPosX() const
Definition: viewdata.hxx:420
void GetMouseQuadrant(const Point &rClickPos, ScSplitPos eWhich, SCCOL nPosX, SCROW nPosY, bool &rLeft, bool &rTop)
Definition: viewdata.cxx:2889
bool mbInlineWithScrollbar
Definition: tabview.hxx:216
WinBits const WB_SIZEABLE
tools::Long & Right()
ScHSplitPos
Definition: viewdata.hxx:45
constexpr TypedWhichId< ScMergeFlagAttr > ATTR_MERGE_FLAG(145)
sal_Int32 SCROW
Definition: types.hxx:17
bool HasAccessibilityObjects() const
Definition: tabvwshh.cxx:242
void Exclude(const tools::Rectangle &rRegion)
void UpdateVarZoom()
Definition: tabview.cxx:730
const size_t nTabSize
double GetPPTY() const
Definition: viewdata.hxx:469
void ResetAutoSpellForContentChange()
Definition: tabview.cxx:2280
void HideAllCursors()
Definition: tabview3.cxx:220
void Stop()
MouseEvent aTimerMEvt
Definition: tabview.hxx:170
void SetTimer(ScGridWindow *pWin, const MouseEvent &rMEvt)
Definition: tabview.cxx:239
bool UpdateFixX(SCTAB nTab=MAXTAB+1)
Definition: viewdata.cxx:4020
bool IsInPlace() const
constexpr tools::Long Height() const
std::unique_ptr< ScHeaderSelectionEngine > pHdrSelEng
Definition: tabview.hxx:127
bool UpdateVisibleRange()
Definition: tabview.cxx:1497
void getRowColumnHeaders(const tools::Rectangle &rRectangle, tools::JsonWriter &rJsonWriter)
Definition: tabview.cxx:2614
const Point & GetMousePosPixel() const
Definition: gridwin.hxx:390
void ScrollY(tools::Long nDeltaY, ScVSplitPos eWhich, bool bUpdBars=true)
Definition: tabview.cxx:1235
bool IsHeaderMode() const
Definition: viewdata.hxx:560
ScHeaderFunctionSet aHdrFunc
Definition: tabview.hxx:128
#define SAL_INFO(area, stream)
css::uno::Reference< css::frame::XController > GetController() const
void ActiveGrabFocus()
Definition: tabview.cxx:901
Timer aScrollTimer
Definition: tabview.hxx:168
VclPtr< ScCornerButton > aCornerButton
Definition: tabview.hxx:154
void SetScrollHdl(const Link< ScrollBar *, void > &rLink)
static VclPtr< reference_type > Create(Arg &&...arg)
VclPtr< ScTabSplitter > pVSplitter
Definition: tabview.hxx:148
void SetPosY(ScVSplitPos eWhich, SCROW nNewPosY)
Definition: viewdata.cxx:2942
SC_DLLPUBLIC ScOutlineTable * GetOutlineTable(SCTAB nTab, bool bCreate=false)
Definition: documen3.cxx:739
const value_type & getNearestByPosition(tools::Long nPos) const
Definition: viewdata.cxx:224
void * p
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
ScViewData * pViewData
Definition: tabview.hxx:69
void putRaw(std::string_view)
css::sheet::DataPilotFieldOrientation GetDPFieldOrientation(SCCOL nCol, SCROW nRow) const
Definition: gridwin2.cxx:54
const SCROW MAXTILEDROW
Definition: address.hxx:77
IMPL_LINK(ScTabView, ScrollHdl, ScrollBar *, pScroll, void)
Definition: tabview.cxx:1009
tools::Long AdjustHeight(tools::Long n)
PointerStyle
ScPositionHelper & GetLOKWidthHelper()
Definition: viewdata.hxx:410
std::array< VclPtr< ScColBar >, 2 > pColBar
Definition: tabview.hxx:143
#define SPLIT_MARGIN
Definition: tabview.cxx:64
std::unique_ptr< ScViewSelectionEngine > pSelEngine
Definition: tabview.hxx:124
void AlignToCursor(SCCOL nCurX, SCROW nCurY, ScFollowMode eMode, const ScSplitPos *pWhich=nullptr)
Definition: tabview3.cxx:920
void VisAreaChanged()
Definition: viewuno.cxx:1923
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
Definition: document.cxx:989
IMPL_LINK_NOARG(ScTabView, TimerHdl, Timer *, void)
Definition: tabview.cxx:252
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4479
ScSplitMode
Definition: viewdata.hxx:42
void HideListBox()
Definition: tabview3.cxx:2975
Size GetOutputSizePixel() const
bool IsOutlineMode() const
Definition: viewdata.hxx:565
constexpr Point BottomRight() const
void SetZoomType(SvxZoomType eNew, bool bAll)
Definition: tabview5.cxx:422
VclPtr< vcl::Window > pFrameWin
Definition: tabview.hxx:121
void SetMaxTiledCol(SCCOL nCol)
Definition: viewdata.cxx:1462
tools::Long GetDelta() const
ScrollBar * get() const
void VisAreaChanged()
Point GetInsertPos() const
Definition: tabview.cxx:1669
SCROW CellsAtY(SCROW nPosY, SCROW nDir, ScVSplitPos eWhichY, sal_uInt16 nScrSizeX=SC_SIZE_NONE) const
Definition: viewdata.cxx:2665
std::array< VclPtr< ScOutlineWindow >, 2 > pRowOutline
Definition: tabview.hxx:146
#define MINZOOM
Definition: global.hxx:78
Point GetChartDialogPos(const Size &rDialogSize, const tools::Rectangle &rLogicChart)
Definition: tabview.cxx:1814
void SetHSplitMode(ScSplitMode eMode)
Definition: viewdata.hxx:438
ScViewData aViewData
Definition: tabview.hxx:122
#define SC_SCROLLBAR_MIN
Definition: tabview.cxx:70
SvxZoomType
#define SPLIT_HANDLE_SIZE
Definition: tabview.cxx:65
std::unique_ptr< ScDrawView > pDrawView
Definition: tabview.hxx:130
ScPositionHelper & GetLOKHeightHelper()
Definition: viewdata.hxx:411
bool HasAutoFilter() const
Definition: attrib.hxx:103
void removeByIndex(index_type nIndex)
Definition: viewdata.cxx:150
VclPtr< ScGridWindow > pTimerWindow
Definition: tabview.hxx:169
ScTabView(const ScTabView &)=delete
make noncopyable
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4170
tools::Long & Left()
Point GetGridOffset() const
Definition: tabview.cxx:918
Point GetMousePosPixel()
Definition: tabview.cxx:1911
void SetTabBarWidth(tools::Long nNewWidth)
Sets an absolute tab bar width (in pixels).
Definition: tabview.cxx:853
void DoResize(const Point &rOffset, const Size &rSize, bool bInner=false)
Definition: tabview.cxx:277
SC_DLLPUBLIC bool IsVisible() const
Definition: olinetab.hxx:54
void SetMaxTiledRow(SCROW nRow)
Definition: viewdata.cxx:1484
void SplitAtPixel(const Point &rPixel)
Definition: tabview.cxx:2106
ScSplitMode GetVSplitMode() const
Definition: viewdata.hxx:417
B2DRange maRange
sal_Int16 SCTAB
Definition: types.hxx:22
virtual Size getDocumentSize() override
Definition: docuno.cxx:657
void ShowAllCursors()
Definition: tabview3.cxx:234
SCCOL GetCurX() const
Definition: viewdata.hxx:401
bool IsMod1() const
bool m_bDetectedRangeSegmentation false
constexpr tools::Long GetHeight() const
WinBits const WB_DRAG
ScCornerButton(vcl::Window *pParent, ScViewData *pData)
Definition: tabview.cxx:77
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
void Init()
Definition: tabview5.cxx:59