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