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