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