LibreOffice Module sc (master)  1
tabview.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <scitems.hxx>
21 #include <sfx2/viewfrm.hxx>
22 #include <sfx2/bindings.hxx>
23 #include <vcl/commandevent.hxx>
24 #include <vcl/help.hxx>
25 #include <vcl/settings.hxx>
26 #include <sal/log.hxx>
27 #include <tools/svborder.hxx>
28 #include <tools/json_writer.hxx>
29 
30 #include <pagedata.hxx>
31 #include <tabview.hxx>
32 #include <tabvwsh.hxx>
33 #include <document.hxx>
34 #include <gridwin.hxx>
35 #include <olinewin.hxx>
36 #include <olinetab.hxx>
37 #include <tabsplit.hxx>
38 #include <colrowba.hxx>
39 #include <tabcont.hxx>
40 #include <scmod.hxx>
41 #include <sc.hrc>
42 #include <globstr.hrc>
43 #include <scresid.hxx>
44 #include <drawview.hxx>
45 #include <docsh.hxx>
46 #include <viewuno.hxx>
47 #include <appoptio.hxx>
48 #include <attrib.hxx>
49 #include <comphelper/lok.hxx>
50 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
51 #include <sfx2/lokhelper.hxx>
52 
53 #include <boost/property_tree/ptree.hpp>
54 #include <boost/property_tree/json_parser.hpp>
55 
56 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
57 
58 #include <algorithm>
59 
61 
62 #define SPLIT_MARGIN 30
63 #define SPLIT_HANDLE_SIZE 5
64 constexpr sal_Int32 TAB_HEIGHT_MARGIN = 10;
65 
66 #define SC_ICONSIZE 36
67 
68 #define SC_SCROLLBAR_MIN 30
69 #define SC_TABBAR_MIN 6
70 
71 using namespace ::com::sun::star;
72 
73 // Corner-Button
74 
76  Window( pParent, WinBits( 0 ) ),
77  pViewData( pData )
78 {
79  EnableRTL( false );
80 }
81 
83 {
84 }
85 
86 void ScCornerButton::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
87 {
88  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
89  SetBackground(rStyleSettings.GetFaceColor());
90 
91  Size aSize(GetOutputSizePixel());
92  long nPosX = aSize.Width() - 1;
93  long nPosY = aSize.Height() - 1;
94 
95  Window::Paint(rRenderContext, rRect);
96 
97  bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
98  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, 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  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  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  long nBarX = 0;
300  long nBarY = 0;
301  long nOutlineX = 0;
302  long nOutlineY = 0;
303  long nOutPosX;
304  long nOutPosY;
305 
306  long nPosX = rOffset.X();
307  long nPosY = rOffset.Y();
308  long nSizeX = rSize.Width();
309  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  long nSplitSizeX = SPLIT_HANDLE_SIZE * fScaleFactor;
319  nSplitSizeX = 1;
320  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  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  long nSizeLt = 0; // left scroll bar
383  long nSizeRt = 0; // right scroll bar
384  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  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  long nSizeUp = 0; // upper scroll bar
481  long nSizeSp = 0; // splitter
482  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  long nSize1 = nSizeX;
527 
528  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  long nLeftSize = nSizeX;
577  long nRightSize = 0;
578  long nTopSize = 0;
579  long nBottomSize = nSizeY;
580  long nSplitPosX = nPosX;
581  long nSplitPosY = nPosY;
582 
584  {
585  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  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  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  {
735  bInZoomUpdate = true;
736  const Fraction& rOldX = GetViewData().GetZoomX();
737  const Fraction& rOldY = GetViewData().GetZoomY();
738  long nOldPercent = long(rOldY * 100);
739  sal_uInt16 nNewZoom = CalcZoom( eZoomType, static_cast<sal_uInt16>(nOldPercent) );
740  Fraction aNew( nNewZoom, 100 );
741 
742  if ( aNew != rOldX || aNew != rOldY )
743  {
744  SetZoom( aNew, aNew, false ); // always separately per sheet
745  PaintGrid();
746  PaintTop();
747  PaintLeft();
748  aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
749  aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
750  }
751  bInZoomUpdate = false;
752  }
753 }
754 
756 {
757  bool bResize = false;
759  if (aViewData.UpdateFixX())
760  bResize = true;
762  if (aViewData.UpdateFixY())
763  bResize = true;
764  if (bResize)
765  RepeatResize(false);
766 }
767 
768 void ScTabView::RepeatResize( bool bUpdateFix )
769 {
770  if ( bUpdateFix )
771  {
772  ScSplitMode eHSplit = aViewData.GetHSplitMode();
773  ScSplitMode eVSplit = aViewData.GetVSplitMode();
774 
775  // #i46796# UpdateFixX / UpdateFixY uses GetGridOffset, which requires the
776  // outline windows to be available. So UpdateShow has to be called before
777  // (also called from DoResize).
778  if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX )
779  UpdateShow();
780 
781  if ( eHSplit == SC_SPLIT_FIX )
783  if ( eVSplit == SC_SPLIT_FIX )
785  }
786 
788 
790 }
791 
792 void ScTabView::GetBorderSize( SvBorder& rBorder, const Size& /* rSize */ )
793 {
794  bool bScrollBars = aViewData.IsVScrollMode();
795  bool bHeaders = aViewData.IsHeaderMode();
796  bool bOutlMode = aViewData.IsOutlineMode();
797  bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
798  bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
799  bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
800 
801  rBorder = SvBorder();
802 
803  if (bScrollBars) // Scrollbars horizontal or vertical
804  {
805  rBorder.Right() += aVScrollBottom->GetSizePixel().Width();
806  rBorder.Bottom() += aHScrollLeft->GetSizePixel().Height();
807  }
808 
809  // Outline-Controls
810  if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
811  rBorder.Left() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
812  if (bHOutline && pColOutline[SC_SPLIT_LEFT])
813  rBorder.Top() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
814 
815  if (bHeaders) // column/row headers
816  {
817  rBorder.Left() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
818  rBorder.Top() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
819  }
820 
821  if ( bLayoutRTL )
822  ::std::swap( rBorder.Left(), rBorder.Right() );
823 }
824 
825 IMPL_LINK_NOARG(ScTabView, TabBarResize, TabBar*, void)
826 {
827  if (aViewData.IsHScrollMode())
828  {
829  const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel();
830  long nSize = pTabControl->GetSplitSize();
831 
832  if (aViewData.GetHSplitMode() != SC_SPLIT_FIX)
833  {
834  long nMax = pHSplitter->GetPosPixel().X();
835  if( pTabControl->IsEffectiveRTL() )
836  nMax = pFrameWin->GetSizePixel().Width() - nMax;
837  --nMax;
838  if (nSize>nMax) nSize = nMax;
839  }
840 
841  if ( nSize != pTabControl->GetSizePixel().Width() )
842  {
843  pTabControl->SetSizePixel( Size( nSize+nOverlap,
844  pTabControl->GetSizePixel().Height() ) );
845  RepeatResize();
846  }
847  }
848 }
849 
850 void ScTabView::SetTabBarWidth( long nNewWidth )
851 {
852  Size aSize = pTabControl->GetSizePixel();
853 
854  if ( aSize.Width() != nNewWidth )
855  {
856  aSize.setWidth( nNewWidth );
857  pTabControl->SetSizePixel( aSize );
858  }
859 }
860 
861 void ScTabView::SetRelTabBarWidth( double fRelTabBarWidth )
862 {
863  if( (0.0 <= fRelTabBarWidth) && (fRelTabBarWidth <= 1.0) )
864  if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
865  SetTabBarWidth( static_cast< long >( fRelTabBarWidth * nFrameWidth + 0.5 ) );
866 }
867 
868 void ScTabView::SetPendingRelTabBarWidth( double fRelTabBarWidth )
869 {
870  mfPendingTabBarWidth = fRelTabBarWidth;
871  SetRelTabBarWidth( fRelTabBarWidth );
872 }
873 
875 {
876  return pTabControl->GetSizePixel().Width();
877 }
878 
880 {
881  return 0.5;
882 }
883 
885 {
887  OSL_ENSURE(pGridWin[ePos],"no active window");
888  return pGridWin[ePos];
889 }
890 
892 {
893  for (VclPtr<ScGridWindow> & pWin : pGridWin)
894  if (pWin)
895  pWin->SetPointer( nPointer );
896 }
897 
899 {
901  if (pGridWin[ePos])
902  pGridWin[ePos]->GrabFocus();
903 }
904 
906 {
907  ScSplitPos eVal = SC_SPLIT_BOTTOMLEFT; // Default
908  for (sal_uInt16 i=0; i<4; i++)
909  if ( pGridWin[i] == pWindow )
910  eVal = static_cast<ScSplitPos>(i);
911 
912  return eVal;
913 }
914 
916 {
917  Point aPos;
918 
919  // size as in DoResize
920 
921  bool bHeaders = aViewData.IsHeaderMode();
922  bool bOutlMode = aViewData.IsOutlineMode();
923  bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
924  bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
925 
926  // Outline-Controls
927  if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
928  aPos.AdjustX(pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize() );
929  if (bHOutline && pColOutline[SC_SPLIT_LEFT])
930  aPos.AdjustY(pColOutline[SC_SPLIT_LEFT]->GetDepthSize() );
931 
932  if (bHeaders) // column/row headers
933  {
934  if (pRowBar[SC_SPLIT_BOTTOM])
935  aPos.AdjustX(pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() );
936  if (pColBar[SC_SPLIT_LEFT])
937  aPos.AdjustY(pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() );
938  }
939 
940  return aPos;
941 }
942 
943 // --- Scroll-Bars --------------------------------------------------------
944 
946 {
947  HideNoteMarker();
948 
949  bool bDone = false;
950  const CommandWheelData* pData = rCEvt.GetWheelData();
951  if (pData && pData->GetMode() == CommandWheelMode::ZOOM)
952  {
954  {
955  // for ole inplace editing, the scale is defined by the visarea and client size
956  // and can't be changed directly
957 
958  const Fraction& rOldY = aViewData.GetZoomY();
959  long nOld = static_cast<long>( rOldY * 100 );
960  long nNew;
961  if ( pData->GetDelta() < 0 )
962  nNew = std::max( long(MINZOOM), basegfx::zoomtools::zoomOut( nOld ));
963  else
964  nNew = std::min( long(MAXZOOM), basegfx::zoomtools::zoomIn( nOld ));
965  if ( nNew != nOld )
966  {
967  // scroll wheel doesn't set the AppOptions default
968 
969  bool bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
970  SetZoomType( SvxZoomType::PERCENT, bSyncZoom );
971  Fraction aFract( nNew, 100 );
972  SetZoom( aFract, aFract, bSyncZoom );
973  PaintGrid();
974  PaintTop();
975  PaintLeft();
976  aViewData.GetBindings().Invalidate( SID_ATTR_ZOOM );
977  aViewData.GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
978  }
979 
980  bDone = true;
981  }
982  }
983  else
984  {
985  ScHSplitPos eHPos = WhichH(ePos);
986  ScVSplitPos eVPos = WhichV(ePos);
987  ScrollBar* pHScroll = ( eHPos == SC_SPLIT_LEFT ) ? aHScrollLeft.get() : aHScrollRight.get();
988  ScrollBar* pVScroll = ( eVPos == SC_SPLIT_TOP ) ? aVScrollTop.get() : aVScrollBottom.get();
989  if ( pGridWin[ePos] )
990  bDone = pGridWin[ePos]->HandleScrollCommand( rCEvt, pHScroll, pVScroll );
991  }
992  return bDone;
993 }
994 
995 IMPL_LINK_NOARG(ScTabView, EndScrollHdl, ScrollBar*, void)
996 {
997  if ( bDragging )
998  {
999  UpdateScrollBars();
1000  bDragging = false;
1001  }
1002 }
1003 
1004 IMPL_LINK( ScTabView, ScrollHdl, ScrollBar*, pScroll, void )
1005 {
1006  bool bHoriz = ( pScroll == aHScrollLeft.get() || pScroll == aHScrollRight.get() );
1007  long nViewPos;
1008  if ( bHoriz )
1009  nViewPos = aViewData.GetPosX( (pScroll == aHScrollLeft.get()) ?
1011  else
1012  nViewPos = aViewData.GetPosY( (pScroll == aVScrollTop.get()) ?
1014 
1015  bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1016 
1017  ScrollType eType = pScroll->GetType();
1018  if ( eType == ScrollType::Drag )
1019  {
1020  if (!bDragging)
1021  {
1022  bDragging = true;
1023  nPrevDragPos = nViewPos;
1024  }
1025 
1026  // show scroll position
1027  // (only QuickHelp, there is no entry for it in the status bar)
1028 
1030  {
1031  Size aSize = pScroll->GetSizePixel();
1032 
1033  /* Convert scrollbar mouse position to screen position. If RTL
1034  mode of scrollbar differs from RTL mode of its parent, then the
1035  direct call to Window::OutputToNormalizedScreenPixel() will
1036  give unusable results, because calculation of screen position
1037  is based on parent orientation and expects equal orientation of
1038  the child position. Need to mirror mouse position before. */
1039  Point aMousePos = pScroll->GetPointerPosPixel();
1040  if( pScroll->IsRTLEnabled() != pScroll->GetParent()->IsRTLEnabled() )
1041  aMousePos.setX( aSize.Width() - aMousePos.X() - 1 );
1042  aMousePos = pScroll->OutputToNormalizedScreenPixel( aMousePos );
1043 
1044  // convert top-left position of scrollbar to screen position
1045  Point aPos = pScroll->OutputToNormalizedScreenPixel( Point() );
1046 
1047  // get scrollbar scroll position for help text (row number/column name)
1048  long nScrollMin = 0; // simulate RangeMin
1049  if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == aHScrollRight.get() )
1050  nScrollMin = aViewData.GetFixPosX();
1051  if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == aVScrollBottom.get() )
1052  nScrollMin = aViewData.GetFixPosY();
1053  long nScrollPos = GetScrollBarPos( *pScroll ) + nScrollMin;
1054 
1055  OUString aHelpStr;
1056  tools::Rectangle aRect;
1057  QuickHelpFlags nAlign;
1058  if (bHoriz)
1059  {
1060  aHelpStr = ScResId(STR_COLUMN) +
1061  " " + ScColToAlpha(static_cast<SCCOL>(nScrollPos));
1062 
1063  aRect.SetLeft( aMousePos.X() );
1064  aRect.SetTop( aPos.Y() - 4 );
1065  nAlign = QuickHelpFlags::Bottom|QuickHelpFlags::Center;
1066  }
1067  else
1068  {
1069  aHelpStr = ScResId(STR_ROW) +
1070  " " + OUString::number(nScrollPos + 1);
1071 
1072  // show quicktext always inside sheet area
1073  aRect.SetLeft( bLayoutRTL ? (aPos.X() + aSize.Width() + 8) : (aPos.X() - 8) );
1074  aRect.SetTop( aMousePos.Y() );
1075  nAlign = (bLayoutRTL ? QuickHelpFlags::Left : QuickHelpFlags::Right) | QuickHelpFlags::VCenter;
1076  }
1077  aRect.SetRight( aRect.Left() );
1078  aRect.SetBottom( aRect.Top() );
1079 
1080  Help::ShowQuickHelp(pScroll->GetParent(), aRect, aHelpStr, nAlign);
1081  }
1082  }
1083 
1084  long nDelta = pScroll->GetDelta();
1085  switch ( eType )
1086  {
1087  case ScrollType::LineUp:
1088  nDelta = -1;
1089  break;
1090  case ScrollType::LineDown:
1091  nDelta = 1;
1092  break;
1093  case ScrollType::PageUp:
1094  if ( pScroll == aHScrollLeft.get() ) nDelta = -static_cast<long>(aViewData.PrevCellsX( SC_SPLIT_LEFT ));
1095  if ( pScroll == aHScrollRight.get() ) nDelta = -static_cast<long>(aViewData.PrevCellsX( SC_SPLIT_RIGHT ));
1096  if ( pScroll == aVScrollTop.get() ) nDelta = -static_cast<long>(aViewData.PrevCellsY( SC_SPLIT_TOP ));
1097  if ( pScroll == aVScrollBottom.get() ) nDelta = -static_cast<long>(aViewData.PrevCellsY( SC_SPLIT_BOTTOM ));
1098  if (nDelta==0) nDelta=-1;
1099  break;
1100  case ScrollType::PageDown:
1101  if ( pScroll == aHScrollLeft.get() ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_LEFT );
1102  if ( pScroll == aHScrollRight.get() ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_RIGHT );
1103  if ( pScroll == aVScrollTop.get() ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_TOP );
1104  if ( pScroll == aVScrollBottom.get() ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM );
1105  if (nDelta==0) nDelta=1;
1106  break;
1107  case ScrollType::Drag:
1108  {
1109  // only scroll in the correct direction, do not jitter around hidden ranges
1110  long nScrollMin = 0; // simulate RangeMin
1111  if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == aHScrollRight.get() )
1112  nScrollMin = aViewData.GetFixPosX();
1113  if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == aVScrollBottom.get() )
1114  nScrollMin = aViewData.GetFixPosY();
1115 
1116  long nScrollPos = GetScrollBarPos( *pScroll ) + nScrollMin;
1117  nDelta = nScrollPos - nViewPos;
1118  if ( nScrollPos > nPrevDragPos )
1119  {
1120  if (nDelta<0) nDelta=0;
1121  }
1122  else if ( nScrollPos < nPrevDragPos )
1123  {
1124  if (nDelta>0) nDelta=0;
1125  }
1126  else
1127  nDelta = 0;
1128  nPrevDragPos = nScrollPos;
1129  }
1130  break;
1131  default:
1132  {
1133  // added to avoid warnings
1134  }
1135  }
1136 
1137  if (nDelta)
1138  {
1139  bool bUpdate = ( eType != ScrollType::Drag ); // don't alter the ranges while dragging
1140  if ( bHoriz )
1141  ScrollX( nDelta, (pScroll == aHScrollLeft.get()) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT, bUpdate );
1142  else
1143  ScrollY( nDelta, (pScroll == aVScrollTop.get()) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM, bUpdate );
1144  }
1145 }
1146 
1147 void ScTabView::ScrollX( long nDeltaX, ScHSplitPos eWhich, bool bUpdBars )
1148 {
1149  ScDocument* pDoc = aViewData.GetDocument();
1150  SCCOL nOldX = aViewData.GetPosX(eWhich);
1151  SCCOL nNewX = nOldX + static_cast<SCCOL>(nDeltaX);
1152  if ( nNewX < 0 )
1153  {
1154  nDeltaX -= nNewX;
1155  nNewX = 0;
1156  }
1157  if ( nNewX > pDoc->MaxCol() )
1158  {
1159  nDeltaX -= nNewX - pDoc->MaxCol();
1160  nNewX = pDoc->MaxCol();
1161  }
1162 
1163  SCCOL nDir = ( nDeltaX > 0 ) ? 1 : -1;
1164  SCTAB nTab = aViewData.GetTabNo();
1165  while ( pDoc->ColHidden(nNewX, nTab) &&
1166  nNewX+nDir >= 0 && nNewX+nDir <= pDoc->MaxCol() )
1167  nNewX = sal::static_int_cast<SCCOL>( nNewX + nDir );
1168 
1169  // freeze
1170 
1172  {
1173  if (eWhich == SC_SPLIT_LEFT)
1174  nNewX = nOldX; // always keep the left part
1175  else
1176  {
1177  SCCOL nFixX = aViewData.GetFixPosX();
1178  if (nNewX < nFixX)
1179  nNewX = nFixX;
1180  }
1181  }
1182  if (nNewX == nOldX)
1183  return;
1184 
1185  HideAllCursors();
1186 
1187  if ( nNewX >= 0 && nNewX <= pDoc->MaxCol() && nDeltaX )
1188  {
1189  SCCOL nTrackX = std::max( nOldX, nNewX );
1190 
1191  // with VCL Update() affects all windows at the moment, that is why
1192  // calling Update after scrolling of the GridWindow would possibly
1193  // already have painted the column/row bar with updated position. -
1194  // Therefore call Update once before on column/row bar
1195  if (pColBar[eWhich])
1196  pColBar[eWhich]->PaintImmediately();
1197 
1198  long nOldPos = aViewData.GetScrPos( nTrackX, 0, eWhich ).X();
1199  aViewData.SetPosX( eWhich, nNewX );
1200  long nDiff = aViewData.GetScrPos( nTrackX, 0, eWhich ).X() - nOldPos;
1201 
1202  if ( eWhich==SC_SPLIT_LEFT )
1203  {
1204  pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( nDiff, 0 );
1206  pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( nDiff, 0 );
1207  }
1208  else
1209  {
1210  pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( nDiff, 0 );
1212  pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( nDiff, 0 );
1213  }
1214  if (pColBar[eWhich]) { pColBar[eWhich]->Scroll( nDiff,0 ); pColBar[eWhich]->PaintImmediately(); }
1215  if (pColOutline[eWhich]) pColOutline[eWhich]->ScrollPixel( nDiff );
1216  if (bUpdBars)
1217  UpdateScrollBars();
1218  }
1219 
1220  if (nDeltaX==1 || nDeltaX==-1)
1221  pGridWin[aViewData.GetActivePart()]->PaintImmediately();
1222 
1223  ShowAllCursors();
1224 
1225  SetNewVisArea(); // MapMode must already be set
1226 
1227  TestHintWindow();
1228 }
1229 
1230 void ScTabView::ScrollY( long nDeltaY, ScVSplitPos eWhich, bool bUpdBars )
1231 {
1232  ScDocument* pDoc = aViewData.GetDocument();
1233  SCROW nOldY = aViewData.GetPosY(eWhich);
1234  SCROW nNewY = nOldY + static_cast<SCROW>(nDeltaY);
1235  if ( nNewY < 0 )
1236  {
1237  nDeltaY -= nNewY;
1238  nNewY = 0;
1239  }
1240  if ( nNewY > pDoc->MaxRow() )
1241  {
1242  nDeltaY -= nNewY - pDoc->MaxRow();
1243  nNewY = pDoc->MaxRow();
1244  }
1245 
1246  SCROW nDir = ( nDeltaY > 0 ) ? 1 : -1;
1247  SCTAB nTab = aViewData.GetTabNo();
1248  while ( pDoc->RowHidden(nNewY, nTab) &&
1249  nNewY+nDir >= 0 && nNewY+nDir <= pDoc->MaxRow() )
1250  nNewY += nDir;
1251 
1252  // freeze
1253 
1255  {
1256  if (eWhich == SC_SPLIT_TOP)
1257  nNewY = nOldY; // always keep the upper part
1258  else
1259  {
1260  SCROW nFixY = aViewData.GetFixPosY();
1261  if (nNewY < nFixY)
1262  nNewY = nFixY;
1263  }
1264  }
1265  if (nNewY == nOldY)
1266  return;
1267 
1268  HideAllCursors();
1269 
1270  if ( nNewY >= 0 && nNewY <= pDoc->MaxRow() && nDeltaY )
1271  {
1272  SCROW nTrackY = std::max( nOldY, nNewY );
1273 
1274  // adjust row headers before the actual scrolling, so it does not get painted twice
1275  // PosY may then also not be set yet, pass on new value
1276  SCROW nUNew = nNewY;
1277  UpdateHeaderWidth( &eWhich, &nUNew ); // adjust row headers
1278 
1279  if (pRowBar[eWhich])
1280  pRowBar[eWhich]->PaintImmediately();
1281 
1282  long nOldPos = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y();
1283  aViewData.SetPosY( eWhich, nNewY );
1284  long nDiff = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y() - nOldPos;
1285 
1286  if ( eWhich==SC_SPLIT_TOP )
1287  {
1288  pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( 0, nDiff );
1290  pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( 0, nDiff );
1291  }
1292  else
1293  {
1294  pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( 0, nDiff );
1296  pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( 0, nDiff );
1297  }
1298  if (pRowBar[eWhich]) { pRowBar[eWhich]->Scroll( 0,nDiff ); pRowBar[eWhich]->PaintImmediately(); }
1299  if (pRowOutline[eWhich]) pRowOutline[eWhich]->ScrollPixel( nDiff );
1300  if (bUpdBars)
1301  UpdateScrollBars();
1302  }
1303 
1304  if (nDeltaY==1 || nDeltaY==-1)
1305  pGridWin[aViewData.GetActivePart()]->PaintImmediately();
1306 
1307  ShowAllCursors();
1308 
1309  SetNewVisArea(); // MapMode must already be set
1310 
1311  TestHintWindow();
1312 }
1313 
1314 void ScTabView::ScrollLines( long nDeltaX, long nDeltaY )
1315 {
1316  ScSplitPos eWhich = aViewData.GetActivePart();
1317  if (nDeltaX)
1318  ScrollX(nDeltaX,WhichH(eWhich));
1319  if (nDeltaY)
1320  ScrollY(nDeltaY,WhichV(eWhich));
1321 }
1322 
1323 namespace
1324 {
1325 
1326 SCROW lcl_LastVisible( const ScViewData& rViewData )
1327 {
1328  // If many rows are hidden at end of the document (what kind of idiot does that?),
1329  // then there should not be a switch to wide row headers because of this
1331  ScDocument* pDoc = rViewData.GetDocument();
1332  SCTAB nTab = rViewData.GetTabNo();
1333 
1334  SCROW nVis = pDoc->MaxRow();
1335  while ( nVis > 0 && pDoc->GetRowHeight( nVis, nTab ) == 0 )
1336  --nVis;
1337  return nVis;
1338 }
1339 
1340 } // anonymous namespace
1341 
1342 void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY )
1343 {
1344  if (!pRowBar[SC_SPLIT_BOTTOM])
1345  return;
1346 
1347  ScDocument* pDoc = aViewData.GetDocument();
1348  SCROW nEndPos = pDoc->MaxRow();
1350  {
1351  // for OLE Inplace always MAXROW
1352 
1353  if ( pWhich && *pWhich == SC_SPLIT_BOTTOM && pPosY )
1354  nEndPos = *pPosY;
1355  else
1356  nEndPos = aViewData.GetPosY( SC_SPLIT_BOTTOM );
1357  nEndPos += aViewData.CellsAtY( nEndPos, 1, SC_SPLIT_BOTTOM ); // VisibleCellsY
1358  if (nEndPos > pDoc->MaxRow())
1359  nEndPos = lcl_LastVisible( aViewData );
1360 
1362  {
1363  SCROW nTopEnd;
1364  if ( pWhich && *pWhich == SC_SPLIT_TOP && pPosY )
1365  nTopEnd = *pPosY;
1366  else
1367  nTopEnd = aViewData.GetPosY( SC_SPLIT_TOP );
1368  nTopEnd += aViewData.CellsAtY( nTopEnd, 1, SC_SPLIT_TOP );// VisibleCellsY
1369  if (nTopEnd > pDoc->MaxRow())
1370  nTopEnd = lcl_LastVisible( aViewData );
1371 
1372  if ( nTopEnd > nEndPos )
1373  nEndPos = nTopEnd;
1374  }
1375  }
1376 
1377  long nSmall = pRowBar[SC_SPLIT_BOTTOM]->GetSmallWidth();
1378  long nBig = pRowBar[SC_SPLIT_BOTTOM]->GetBigWidth();
1379  long nDiff = nBig - nSmall;
1380 
1381  if (nEndPos>10000)
1382  nEndPos = 10000;
1383  else if (nEndPos<1) // avoid extra step at 0 (when only one row is visible)
1384  nEndPos = 1;
1385  long nWidth = nBig - ( 10000 - nEndPos ) * nDiff / 10000;
1386 
1387  if ( nWidth != pRowBar[SC_SPLIT_BOTTOM]->GetWidth() && !bInUpdateHeader )
1388  {
1389  bInUpdateHeader = true;
1390 
1391  pRowBar[SC_SPLIT_BOTTOM]->SetWidth( nWidth );
1392  if (pRowBar[SC_SPLIT_TOP])
1393  pRowBar[SC_SPLIT_TOP]->SetWidth( nWidth );
1394 
1395  RepeatResize();
1396 
1397  // on VCL there are endless updates (each Update is valid for all windows)
1398  //aCornerButton->Update(); // otherwise this never gets an Update
1399 
1400  bInUpdateHeader = false;
1401  }
1402 }
1403 
1404 static void ShowHide( vcl::Window* pWin, bool bShow )
1405 {
1406  OSL_ENSURE(pWin || !bShow, "window is not present");
1407  if (pWin)
1408  pWin->Show(bShow);
1409 }
1410 
1412 {
1413  bool bHScrollMode = aViewData.IsHScrollMode();
1414  bool bVScrollMode = aViewData.IsVScrollMode();
1415  bool bTabMode = aViewData.IsTabMode();
1416  bool bOutlMode = aViewData.IsOutlineMode();
1417  bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
1418  bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
1419  bool bHeader = aViewData.IsHeaderMode();
1420 
1421  bool bShowH = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE );
1422  bool bShowV = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE );
1423 
1424  if ( aViewData.GetDocShell()->IsPreview() )
1425  bHScrollMode = bVScrollMode = bTabMode = bHeader = bHOutline = bVOutline = false;
1426 
1427  // create Windows
1428 
1429  if (bShowH && !pGridWin[SC_SPLIT_BOTTOMRIGHT])
1430  {
1432  DoAddWin( pGridWin[SC_SPLIT_BOTTOMRIGHT] );
1433  }
1434  if (bShowV && !pGridWin[SC_SPLIT_TOPLEFT])
1435  {
1437  DoAddWin( pGridWin[SC_SPLIT_TOPLEFT] );
1438  }
1439  if (bShowH && bShowV && !pGridWin[SC_SPLIT_TOPRIGHT])
1440  {
1442  DoAddWin( pGridWin[SC_SPLIT_TOPRIGHT] );
1443  }
1444 
1445  if (bHOutline && !pColOutline[SC_SPLIT_LEFT])
1447  if (bShowH && bHOutline && !pColOutline[SC_SPLIT_RIGHT])
1449 
1450  if (bVOutline && !pRowOutline[SC_SPLIT_BOTTOM])
1452  if (bShowV && bVOutline && !pRowOutline[SC_SPLIT_TOP])
1454 
1455  if (bShowH && bHeader && !pColBar[SC_SPLIT_RIGHT])
1457  &aHdrFunc, pHdrSelEng.get(), this );
1458  if (bShowV && bHeader && !pRowBar[SC_SPLIT_TOP])
1460  &aHdrFunc, pHdrSelEng.get(), this );
1461 
1462  // show Windows
1463 
1464  ShowHide( aHScrollLeft.get(), bHScrollMode );
1465  ShowHide( aHScrollRight.get(), bShowH && bHScrollMode );
1466  ShowHide( aVScrollBottom.get(), bVScrollMode );
1467  ShowHide( aVScrollTop.get(), bShowV && bVScrollMode );
1468  ShowHide( aScrollBarBox.get(), bVScrollMode || bHScrollMode );
1469 
1470  ShowHide( pHSplitter, bHScrollMode || bShowH ); // always generated
1471  ShowHide( pVSplitter, bVScrollMode || bShowV );
1472  ShowHide( pTabControl, bTabMode );
1473 
1474  // from here dynamically generated
1475 
1476  ShowHide( pGridWin[SC_SPLIT_BOTTOMRIGHT], bShowH );
1477  ShowHide( pGridWin[SC_SPLIT_TOPLEFT], bShowV );
1478  ShowHide( pGridWin[SC_SPLIT_TOPRIGHT], bShowH && bShowV );
1479 
1480  ShowHide( pColOutline[SC_SPLIT_LEFT], bHOutline );
1481  ShowHide( pColOutline[SC_SPLIT_RIGHT], bShowH && bHOutline );
1482 
1483  ShowHide( pRowOutline[SC_SPLIT_BOTTOM], bVOutline );
1484  ShowHide( pRowOutline[SC_SPLIT_TOP], bShowV && bVOutline );
1485 
1486  ShowHide( pColBar[SC_SPLIT_RIGHT], bShowH && bHeader );
1487  ShowHide( pRowBar[SC_SPLIT_TOP], bShowV && bHeader );
1488 
1490 }
1491 
1493 {
1494  bool bChanged = false;
1495  for (VclPtr<ScGridWindow> & pWin : pGridWin)
1496  {
1497  if (!pWin || !pWin->IsVisible())
1498  continue;
1499 
1500  if (pWin->UpdateVisibleRange())
1501  bChanged = true;
1502  }
1503 
1504  return bChanged;
1505 }
1506 
1507 // --- Splitter --------------------------------------------------------
1508 
1509 IMPL_LINK( ScTabView, SplitHdl, Splitter*, pSplitter, void )
1510 {
1511  if ( pSplitter == pHSplitter )
1512  DoHSplit( pHSplitter->GetSplitPosPixel() );
1513  else
1514  DoVSplit( pVSplitter->GetSplitPosPixel() );
1515 
1516  if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1517  FreezeSplitters( true );
1518 
1519  DoResize( aBorderPos, aFrameSize );
1520 }
1521 
1522 void ScTabView::DoHSplit(long nSplitPos)
1523 {
1524  // nSplitPos is the real pixel position on the frame window,
1525  // mirroring for RTL has to be done here.
1526 
1527  bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1528  if ( bLayoutRTL )
1529  nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
1530 
1531  long nMinPos;
1532  long nMaxPos;
1533  SCCOL nOldDelta;
1534  SCCOL nNewDelta;
1535 
1536  nMinPos = SPLIT_MARGIN;
1537  if ( pRowBar[SC_SPLIT_BOTTOM] && pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() >= nMinPos )
1538  nMinPos = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() + 1;
1539  nMaxPos = aFrameSize.Width() - SPLIT_MARGIN;
1540 
1541  ScSplitMode aOldMode = aViewData.GetHSplitMode();
1542  ScSplitMode aNewMode = SC_SPLIT_NORMAL;
1543 
1544  aViewData.SetHSplitPos( nSplitPos );
1545  if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
1546  aNewMode = SC_SPLIT_NONE;
1547 
1548  aViewData.SetHSplitMode( aNewMode );
1549 
1550  if ( aNewMode != aOldMode )
1551  {
1552  UpdateShow(); // before ActivatePart !!
1553 
1554  if ( aNewMode == SC_SPLIT_NONE )
1555  {
1560  }
1561  else
1562  {
1563  nOldDelta = aViewData.GetPosX( SC_SPLIT_LEFT );
1564  long nLeftWidth = nSplitPos - pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
1565  if ( nLeftWidth < 0 ) nLeftWidth = 0;
1566  nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, SC_SPLIT_LEFT,
1567  static_cast<sal_uInt16>(nLeftWidth) );
1568  ScDocument* pDoc = aViewData.GetDocument();
1569  if ( nNewDelta > pDoc->MaxCol() )
1570  nNewDelta = pDoc->MaxCol();
1571  aViewData.SetPosX( SC_SPLIT_RIGHT, nNewDelta );
1572  if ( nNewDelta > aViewData.GetCurX() )
1575  else
1578  }
1579 
1580  // Form Layer needs to know the visible part of all windows
1581  // that is why MapMode must already be correct here
1582  for (VclPtr<ScGridWindow> & pWin : pGridWin)
1583  if (pWin)
1584  pWin->SetMapMode( pWin->GetDrawMapMode() );
1585  SetNewVisArea();
1586 
1587  PaintGrid();
1588  PaintTop();
1589 
1590  InvalidateSplit();
1591  }
1592 }
1593 
1594 void ScTabView::DoVSplit(long nSplitPos)
1595 {
1596  long nMinPos;
1597  long nMaxPos;
1598  SCROW nOldDelta;
1599  SCROW nNewDelta;
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  {
1617  UpdateShow(); // before ActivatePart !!
1618 
1619  if ( aNewMode == SC_SPLIT_NONE )
1620  {
1621  nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
1622  aViewData.SetPosY( SC_SPLIT_BOTTOM, nOldDelta );
1623 
1628  }
1629  else
1630  {
1631  if ( aOldMode == SC_SPLIT_NONE )
1632  nOldDelta = aViewData.GetPosY( SC_SPLIT_BOTTOM );
1633  else
1634  nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
1635 
1636  aViewData.SetPosY( SC_SPLIT_TOP, nOldDelta );
1637  long nTopHeight = nSplitPos - pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
1638  if ( nTopHeight < 0 ) nTopHeight = 0;
1639  nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, SC_SPLIT_TOP,
1640  static_cast<sal_uInt16>(nTopHeight) );
1641  ScDocument* pDoc = aViewData.GetDocument();
1642  if ( nNewDelta > pDoc->MaxRow() )
1643  nNewDelta = pDoc->MaxRow();
1644  aViewData.SetPosY( SC_SPLIT_BOTTOM, nNewDelta );
1645  if ( nNewDelta > aViewData.GetCurY() )
1648  else
1651  }
1652 
1653  // Form Layer needs to know the visible part of all windows
1654  // that is why MapMode must already be correct here
1655  for (VclPtr<ScGridWindow> & pWin : pGridWin)
1656  if (pWin)
1657  pWin->SetMapMode( pWin->GetDrawMapMode() );
1658  SetNewVisArea();
1659 
1660  PaintGrid();
1661  PaintLeft();
1662 
1663  InvalidateSplit();
1664  }
1665 }
1666 
1668 {
1669  ScDocument* pDoc = aViewData.GetDocument();
1670  SCCOL nCol = aViewData.GetCurX();
1671  SCROW nRow = aViewData.GetCurY();
1672  SCTAB nTab = aViewData.GetTabNo();
1673  long nPosX = 0;
1674  for (SCCOL i=0; i<nCol; i++)
1675  nPosX += pDoc->GetColWidth(i,nTab);
1676  nPosX = static_cast<long>(nPosX * HMM_PER_TWIPS);
1677  if ( pDoc->IsNegativePage( nTab ) )
1678  nPosX = -nPosX;
1679  long nPosY = static_cast<long>(pDoc->GetRowHeight( 0, nRow-1, nTab));
1680  nPosY = static_cast<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 long nBorder = 100; // leave 1mm for border
1688  long nNeededWidth = rSize.Width() + 2 * nBorder;
1689  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* pDoc = aViewData.GetDocument();
1710  SCTAB nTab = aViewData.GetTabNo();
1711  bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1712  long nLayoutSign = bLayoutRTL ? -1 : 1;
1713 
1714  long nDocX = static_cast<long>( static_cast<double>(pDoc->GetColOffset( pDoc->MaxCol() + 1, nTab )) * HMM_PER_TWIPS ) * nLayoutSign;
1715  long nDocY = static_cast<long>( static_cast<double>(pDoc->GetRowOffset( pDoc->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 = pDoc->GetMMRect( rCellRange.aStart.Col(), rCellRange.aStart.Row(),
1729  rCellRange.aEnd.Col(), rCellRange.aEnd.Row(), nTab );
1730 
1731  long nLeftSpace = aSelection.Left() - aVisible.Left();
1732  long nRightSpace = aVisible.Right() - aSelection.Right();
1733  long nTopSpace = aSelection.Top() - aVisible.Top();
1734  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* pDoc = aViewData.GetDocument();
1828  SCTAB nTab = aViewData.GetTabNo();
1829  bool bLayoutRTL = pDoc->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  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  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 
2240 {
2241  bool bChanged = false;
2242  for (VclPtr<ScGridWindow> & pWin : pGridWin)
2243  {
2244  if (!pWin || !pWin->IsVisible())
2245  continue;
2246 
2247  if (pWin->ContinueOnlineSpelling())
2248  bChanged = true;
2249  }
2250 
2251  return bChanged;
2252 }
2253 
2254 void ScTabView::EnableAutoSpell( bool bEnable )
2255 {
2256  for (VclPtr<ScGridWindow> & pWin : pGridWin)
2257  {
2258  if (!pWin)
2259  continue;
2260 
2261  pWin->EnableAutoSpell(bEnable);
2262  }
2263 }
2264 
2266 {
2267  for (VclPtr<ScGridWindow> & pWin : pGridWin)
2268  {
2269  if (!pWin)
2270  continue;
2271 
2272  pWin->ResetAutoSpell();
2273  }
2274 }
2275 
2276 void ScTabView::SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges )
2277 {
2278  for (VclPtr<ScGridWindow> & pWin: pGridWin)
2279  {
2280  if (!pWin)
2281  continue;
2282 
2283  pWin->SetAutoSpellData(nPosX, nPosY, pRanges);
2284  }
2285 }
2286 
2287 namespace
2288 {
2289 
2290 long lcl_GetRowHeightPx(const ScViewData &rViewData, SCROW nRow, SCTAB nTab)
2291 {
2292  const sal_uInt16 nSize = rViewData.GetDocument()->GetRowHeight(nRow, nTab);
2293  return ScViewData::ToPixel(nSize, rViewData.GetPPTY());
2294 }
2295 
2296 long lcl_GetColWidthPx(const ScViewData &rViewData, SCCOL nCol, SCTAB nTab)
2297 {
2298  const sal_uInt16 nSize = rViewData.GetDocument()->GetColWidth(nCol, nTab);
2299  return ScViewData::ToPixel(nSize, rViewData.GetPPTX());
2300 }
2301 
2302 void lcl_getGroupIndexes(const ScOutlineArray& rArray, SCCOLROW nStart, SCCOLROW nEnd, std::vector<size_t>& rGroupIndexes)
2303 {
2304  rGroupIndexes.clear();
2305  const size_t nGroupDepth = rArray.GetDepth();
2306  rGroupIndexes.resize(nGroupDepth);
2307 
2308  // Get first group per each level
2309  for (size_t nLevel = 0; nLevel < nGroupDepth; ++nLevel)
2310  {
2311  if (rArray.GetCount(nLevel))
2312  {
2313  // look for a group inside the [nStartRow+1, nEndRow] range
2314  size_t nIndex;
2315  bool bFound = rArray.GetEntryIndexInRange(nLevel, nStart + 1, nEnd, nIndex);
2316  if (bFound)
2317  {
2318  if (nIndex > 0)
2319  {
2320  // is there a previous group not inside the range
2321  // but anyway intersecting it ?
2322  const ScOutlineEntry* pPrevEntry = rArray.GetEntry(nLevel, nIndex - 1);
2323  if (pPrevEntry && nStart < pPrevEntry->GetEnd())
2324  {
2325  --nIndex;
2326  }
2327  }
2328  }
2329  else
2330  {
2331  // look for a group which contains nStartRow+1
2332  bFound = rArray.GetEntryIndex(nLevel, nStart + 1, nIndex);
2333  if (!bFound)
2334  {
2335  // look for a group which contains nEndRow
2336  bFound = rArray.GetEntryIndex(nLevel, nEnd, nIndex);
2337  }
2338  }
2339 
2340  if (bFound)
2341  {
2342  // skip groups with no visible control
2343  bFound = false;
2344  while (nIndex < rArray.GetCount(nLevel))
2345  {
2346  const ScOutlineEntry* pEntry = rArray.GetEntry(nLevel, nIndex);
2347  if (pEntry && pEntry->IsVisible())
2348  {
2349  bFound = true;
2350  break;
2351  }
2352  if (pEntry && pEntry->GetStart() > nEnd)
2353  {
2354  break;
2355  }
2356  ++nIndex;
2357  }
2358  }
2359 
2360  rGroupIndexes[nLevel] = bFound ? nIndex : -1;
2361  }
2362  }
2363 }
2364 
2365 void lcl_createGroupsData(
2366  SCCOLROW nHeaderIndex, SCCOLROW nEnd, long nSizePx, long nTotalPx,
2367  const ScOutlineArray& rArray, std::vector<size_t>& rGroupIndexes,
2368  std::vector<long>& rGroupStartPositions, OStringBuffer& rGroupsBuffer)
2369 {
2370  const size_t nGroupDepth = rArray.GetDepth();
2371  // create string data for group controls
2372  for (size_t nLevel = nGroupDepth - 1; nLevel != size_t(-1); --nLevel)
2373  {
2374  size_t nIndex = rGroupIndexes[nLevel];
2375  if (nIndex == size_t(-1))
2376  continue;
2377  const ScOutlineEntry* pEntry = rArray.GetEntry(nLevel, nIndex);
2378  if (pEntry)
2379  {
2380  if (nHeaderIndex < pEntry->GetStart())
2381  {
2382  continue;
2383  }
2384  else if (nHeaderIndex == pEntry->GetStart())
2385  {
2386  rGroupStartPositions[nLevel] = nTotalPx - nSizePx;
2387  }
2388  else if (nHeaderIndex > pEntry->GetStart() && (nHeaderIndex < nEnd && nHeaderIndex < pEntry->GetEnd()))
2389  {
2390  // for handling group started before the current view range
2391  if (rGroupStartPositions[nLevel] < 0)
2392  rGroupStartPositions[nLevel] *= -1;
2393  break;
2394  }
2395  if (nHeaderIndex == pEntry->GetEnd() || (nHeaderIndex == nEnd && rGroupStartPositions[nLevel] != -1))
2396  {
2397  // nHeaderIndex is the end col/row of a group or is the last col/row and a group started and not yet ended
2398 
2399  // append a new group control data
2400  auto len = rGroupsBuffer.getLength();
2401  if (len && rGroupsBuffer[len-1] == '}')
2402  {
2403  rGroupsBuffer.append(", ");
2404  }
2405 
2406  bool bGroupHidden = pEntry->IsHidden();
2407 
2408  rGroupsBuffer
2409  .append("{ \"level\": ").append(sal_Int32(nLevel + 1)).append(", ")
2410  .append("\"index\": ").append(sal_Int32(nIndex)).append(", ")
2411  .append("\"startPos\": ").append(rGroupStartPositions[nLevel]).append(", ")
2412  .append("\"endPos\": ").append(nTotalPx).append(", ")
2413  .append("\"hidden\": ").append(sal_Int32(bGroupHidden ? 1 : 0)).append(" }");
2414 
2415  // look for the next visible group control at level nLevel
2416  bool bFound = false;
2417  ++nIndex;
2418  while (nIndex < rArray.GetCount(nLevel))
2419  {
2420  pEntry = rArray.GetEntry(nLevel, nIndex);
2421  if (pEntry && pEntry->IsVisible())
2422  {
2423  bFound = true;
2424  break;
2425  }
2426  if (pEntry && pEntry->GetStart() > nEnd)
2427  {
2428  break;
2429  }
2430  ++nIndex;
2431  }
2432  rGroupIndexes[nLevel] = bFound ? nIndex : -1;
2433  rGroupStartPositions[nLevel] = -1;
2434  }
2435  }
2436  }
2437 }
2438 
2439 class ScRangeProvider
2440 {
2441 public:
2442  ScRangeProvider(const tools::Rectangle& rArea, bool bInPixels,
2443  ScViewData& rViewData):
2444  mrViewData(rViewData)
2445  {
2446  tools::Rectangle aAreaPx = bInPixels ? rArea :
2447  tools::Rectangle(rArea.Left() * mrViewData.GetPPTX(),
2448  rArea.Top() * mrViewData.GetPPTY(),
2449  rArea.Right() * mrViewData.GetPPTX(),
2450  rArea.Bottom() * mrViewData.GetPPTY());
2451  calculateBounds(aAreaPx);
2452  }
2453 
2454  const ScRange& getCellRange() const
2455  {
2456  return maRange;
2457  }
2458 
2459  void getColPositions(long& rStartColPos, long& rEndColPos) const
2460  {
2461  rStartColPos = maBoundPositions.Left();
2462  rEndColPos = maBoundPositions.Right();
2463  }
2464 
2465  void getRowPositions(long& rStartRowPos, long& rEndRowPos) const
2466  {
2467  rStartRowPos = maBoundPositions.Top();
2468  rEndRowPos = maBoundPositions.Bottom();
2469  }
2470 
2471 private:
2472  void calculateBounds(const tools::Rectangle& rAreaPx)
2473  {
2474  long nLeftPx = 0, nRightPx = 0;
2475  SCCOLROW nStartCol = -1, nEndCol = -1;
2476  calculateDimensionBounds(rAreaPx.Left(), rAreaPx.Right(), true,
2477  nStartCol, nEndCol, nLeftPx, nRightPx,
2478  mnEnlargeX, mrViewData);
2479  long nTopPx = 0, nBottomPx = 0;
2480  SCCOLROW nStartRow = -1, nEndRow = -1;
2481  calculateDimensionBounds(rAreaPx.Top(), rAreaPx.Bottom(), false,
2482  nStartRow, nEndRow, nTopPx, nBottomPx,
2483  mnEnlargeY, mrViewData);
2484 
2485  maRange.aStart.Set(nStartCol, nStartRow, mrViewData.GetTabNo());
2486  maRange.aEnd.Set(nEndCol, nEndRow, mrViewData.GetTabNo());
2487 
2488  maBoundPositions.SetLeft(nLeftPx);
2489  maBoundPositions.SetRight(nRightPx);
2490  maBoundPositions.SetTop(nTopPx);
2491  maBoundPositions.SetBottom(nBottomPx);
2492  }
2493 
2494  // All positions are in pixels.
2495  static void calculateDimensionBounds(const long nStartPos, const long nEndPos,
2496  bool bColumns, SCCOLROW& rStartIndex,
2497  SCCOLROW& rEndIndex, long& rBoundStart,
2498  long& rBoundEnd, SCCOLROW nEnlarge,
2499  ScViewData& rViewData)
2500  {
2501  ScPositionHelper& rPosHelper = bColumns ? rViewData.GetLOKWidthHelper() :
2502  rViewData.GetLOKHeightHelper();
2503  const auto& rStartNearest = rPosHelper.getNearestByPosition(nStartPos);
2504  const auto& rEndNearest = rPosHelper.getNearestByPosition(nEndPos);
2505 
2506  ScBoundsProvider aBoundsProvider(rViewData, rViewData.GetTabNo(), bColumns);
2507  aBoundsProvider.Compute(rStartNearest, rEndNearest, nStartPos, nEndPos);
2508  aBoundsProvider.EnlargeBy(nEnlarge);
2509  if (bColumns)
2510  {
2511  SCCOL nStartCol = -1, nEndCol = -1;
2512  aBoundsProvider.GetStartIndexAndPosition(nStartCol, rBoundStart);
2513  aBoundsProvider.GetEndIndexAndPosition(nEndCol, rBoundEnd);
2514  rStartIndex = nStartCol;
2515  rEndIndex = nEndCol;
2516  }
2517  else
2518  {
2519  SCROW nStartRow = -1, nEndRow = -1;
2520  aBoundsProvider.GetStartIndexAndPosition(nStartRow, rBoundStart);
2521  aBoundsProvider.GetEndIndexAndPosition(nEndRow, rBoundEnd);
2522  rStartIndex = nStartRow;
2523  rEndIndex = nEndRow;
2524  }
2525  }
2526 
2527 private:
2528 
2529  ScRange maRange;
2530  tools::Rectangle maBoundPositions;
2531  ScViewData& mrViewData;
2532  static const SCCOLROW mnEnlargeX = 2;
2533  static const SCCOLROW mnEnlargeY = 2;
2534 };
2535 
2536 void lcl_ExtendTiledDimension(bool bColumn, const SCCOLROW nEnd, const SCCOLROW nExtra,
2537  ScTabView& rTabView, ScViewData& rViewData)
2538 {
2539  ScDocument* pDoc = rViewData.GetDocument();
2540  // If we are approaching current max tiled row/col, signal a size changed event
2541  // and invalidate the involved area
2542  SCCOLROW nMaxTiledIndex = bColumn ? rViewData.GetMaxTiledCol() : rViewData.GetMaxTiledRow();
2543  SCCOLROW nHardLimit = !bColumn ? MAXTILEDROW : pDoc ? pDoc->MaxCol() : MAXCOL;
2544 
2545  if (nMaxTiledIndex >= nHardLimit)
2546  return;
2547 
2548  if (nEnd <= nMaxTiledIndex - nExtra) // No need to extend.
2549  return;
2550 
2551  ScDocShell* pDocSh = rViewData.GetDocShell();
2552  ScModelObj* pModelObj = pDocSh ?
2553  comphelper::getUnoTunnelImplementation<ScModelObj>( pDocSh->GetModel() ) : nullptr;
2554  Size aOldSize(0, 0);
2555  if (pModelObj)
2556  aOldSize = pModelObj->getDocumentSize();
2557 
2558  SCCOLROW nNewMaxTiledIndex = std::min(std::max(nEnd, nMaxTiledIndex) + nExtra, nHardLimit);
2559 
2560  if (bColumn)
2561  rViewData.SetMaxTiledCol(nNewMaxTiledIndex);
2562  else
2563  rViewData.SetMaxTiledRow(nNewMaxTiledIndex);
2564 
2565  Size aNewSize(0, 0);
2566  if (pModelObj)
2567  aNewSize = pModelObj->getDocumentSize();
2568 
2569  if (aOldSize == aNewSize)
2570  return;
2571 
2572  if (!pDocSh)
2573  return;
2574 
2575  // New area extended to the right/bottom of the sheet after last col/row
2576  // excluding overlapping area with aNewArea
2577  tools::Rectangle aNewArea = bColumn ?
2578  tools::Rectangle(aOldSize.getWidth(), 0, aNewSize.getWidth(), aNewSize.getHeight()):
2579  tools::Rectangle(0, aOldSize.getHeight(), aNewSize.getWidth(), aNewSize.getHeight());
2580 
2581  // Only invalidate if spreadsheet has extended to the right or bottom
2582  if ((bColumn && aNewArea.getWidth()) || (!bColumn && aNewArea.getHeight()))
2583  {
2584  rTabView.UpdateSelectionOverlay();
2585  SfxLokHelper::notifyInvalidation(rViewData.GetViewShell(), aNewArea.toString());
2586  }
2587 
2588  // Provide size in the payload, so clients don't have to query for that.
2589  std::stringstream ss;
2590  ss << aNewSize.Width() << ", " << aNewSize.Height();
2591  OString sSize = ss.str().c_str();
2592  ScModelObj* pModel = comphelper::getUnoTunnelImplementation<ScModelObj>(
2593  rViewData.GetViewShell()->GetCurrentDocument());
2594  SfxLokHelper::notifyDocumentSizeChanged(rViewData.GetViewShell(), sSize, pModel, false);
2595 }
2596 
2597 } // anonymous namespace
2598 
2600 {
2601  ScDocument* pDoc = aViewData.GetDocument();
2602  if (!pDoc)
2603  return;
2604 
2605  if (rRectangle.IsEmpty())
2606  return;
2607 
2608  bool bRangeHeaderSupport = comphelper::LibreOfficeKit::isRangeHeaders();
2609 
2610  rJsonWriter.put("commandName", ".uno:ViewRowColumnHeaders");
2611 
2612  SCTAB nTab = aViewData.GetTabNo();
2613  SCROW nStartRow = -1;
2614  SCROW nEndRow = -1;
2615  long nStartHeightPx = 0;
2616  SCCOL nStartCol = -1;
2617  SCCOL nEndCol = -1;
2618  long nStartWidthPx = 0;
2619 
2620  tools::Rectangle aOldVisArea(
2623 
2624  ScRangeProvider aRangeProvider(rRectangle, /* bInPixels */ false, aViewData);
2625  const ScRange& rCellRange = aRangeProvider.getCellRange();
2626 
2628 
2630 
2631  if (rRectangle.Top() < rRectangle.Bottom())
2632  {
2633  SAL_INFO("sc.lok.header", "Row Header: compute start/end rows.");
2634  long nEndHeightPx = 0;
2635  nStartRow = rCellRange.aStart.Row();
2636  nEndRow = rCellRange.aEnd.Row();
2637  aRangeProvider.getRowPositions(nStartHeightPx, nEndHeightPx);
2638 
2641  aViewData.GetLOKHeightHelper().insert(nStartRow, nStartHeightPx);
2642  aViewData.GetLOKHeightHelper().insert(nEndRow, nEndHeightPx);
2643 
2644  mnLOKStartHeaderRow = nStartRow;
2645  mnLOKEndHeaderRow = nEndRow;
2646  }
2647 
2648  long nVisibleRows = nEndRow - nStartRow;
2649  if (nVisibleRows < 25)
2650  nVisibleRows = 25;
2651 
2652  SAL_INFO("sc.lok.header", "Row Header: visible rows: " << nVisibleRows);
2653 
2654 
2655  // Get row groups
2656  // per each level store the index of the first group intersecting
2657  // [nStartRow, nEndRow] range
2658 
2659  const ScOutlineTable* pTable = pDoc->GetOutlineTable(nTab);
2660  const ScOutlineArray* pRowArray = pTable ? &(pTable->GetRowArray()) : nullptr;
2661  size_t nRowGroupDepth = 0;
2662  std::vector<size_t> aRowGroupIndexes;
2663  if (bRangeHeaderSupport && pTable)
2664  {
2665  nRowGroupDepth = pRowArray->GetDepth();
2666  lcl_getGroupIndexes(*pRowArray, nStartRow, nEndRow, aRowGroupIndexes);
2667  }
2668 
2671  lcl_ExtendTiledDimension(/* bColumn */ false, nEndRow, nVisibleRows, *this, aViewData);
2672 
2674 
2675  long nTotalPixels = nStartHeightPx;
2676  long nPrevSizePx = -1;
2677  OStringBuffer aRowGroupsBuffer = "\"rowGroups\": [\n";
2678  {
2679  auto rowsNode = rJsonWriter.startArray("rows");
2680 
2681  SAL_INFO("sc.lok.header", "Row Header: [create string data for rows]: start row: "
2682  << nStartRow << " start height: " << nTotalPixels);
2683 
2684  if (nStartRow != nEndRow)
2685  {
2686  auto node = rJsonWriter.startStruct();
2687  rJsonWriter.put("text", nStartRow + 1);
2688  rJsonWriter.put("size", nTotalPixels);
2689  rJsonWriter.put("groupLevels", static_cast<sal_Int64>(nRowGroupDepth));
2690  }
2691 
2692  std::vector<long> aRowGroupStartPositions(nRowGroupDepth, -nTotalPixels);
2693  for (SCROW nRow = nStartRow + 1; nRow <= nEndRow; ++nRow)
2694  {
2695  // nSize will be 0 for hidden rows.
2696  const long nSizePx = lcl_GetRowHeightPx(aViewData, nRow, nTab);
2697  nTotalPixels += nSizePx;
2698 
2699  if (bRangeHeaderSupport && nRowGroupDepth > 0)
2700  {
2701  lcl_createGroupsData(nRow, nEndRow, nSizePx, nTotalPixels,
2702  *pRowArray, aRowGroupIndexes, aRowGroupStartPositions,
2703  aRowGroupsBuffer);
2704  }
2705 
2706  if (bRangeHeaderSupport && nRow < nEndRow && nSizePx == nPrevSizePx)
2707  continue;
2708  nPrevSizePx = nSizePx;
2709 
2710  auto node = rJsonWriter.startStruct();
2711  rJsonWriter.put("text", pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow));
2712  rJsonWriter.put("size", nTotalPixels);
2713  }
2714 
2715  aRowGroupsBuffer.append("]");
2716  }
2717  if (nRowGroupDepth > 0)
2718  {
2719  aRowGroupsBuffer.append(",\n");
2720  rJsonWriter.putRaw(aRowGroupsBuffer.getStr());
2721  }
2723 
2724 
2726 
2728 
2729  if (rRectangle.Left() < rRectangle.Right())
2730  {
2731  SAL_INFO("sc.lok.header", "Column Header: compute start/end columns.");
2732  long nEndWidthPx = 0;
2733  nStartCol = rCellRange.aStart.Col();
2734  nEndCol = rCellRange.aEnd.Col();
2735  aRangeProvider.getColPositions(nStartWidthPx, nEndWidthPx);
2736 
2739  aViewData.GetLOKWidthHelper().insert(nStartCol, nStartWidthPx);
2740  aViewData.GetLOKWidthHelper().insert(nEndCol, nEndWidthPx);
2741 
2742  mnLOKStartHeaderCol = nStartCol;
2743  mnLOKEndHeaderCol = nEndCol;
2744  }
2745 
2746  long nVisibleCols = nEndCol - nStartCol;
2747  if (nVisibleCols < 10)
2748  nVisibleCols = 10;
2749 
2750 
2751  // Get column groups
2752  // per each level store the index of the first group intersecting
2753  // [nStartCol, nEndCol] range
2754 
2755  const ScOutlineArray* pColArray = pTable ? &(pTable->GetColArray()) : nullptr;
2756  size_t nColGroupDepth = 0;
2757  std::vector<size_t> aColGroupIndexes;
2758  if (bRangeHeaderSupport && pTable)
2759  {
2760  nColGroupDepth = pColArray->GetDepth();
2761  lcl_getGroupIndexes(*pColArray, nStartCol, nEndCol, aColGroupIndexes);
2762  }
2763 
2766  lcl_ExtendTiledDimension(/* bColumn */ true, nEndCol, nVisibleCols, *this, aViewData);
2767 
2769  OStringBuffer aColGroupsBuffer = "\"columnGroups\": [\n";
2770  {
2771  auto columnsNode = rJsonWriter.startArray("columns");
2772 
2773  nTotalPixels = nStartWidthPx;
2774  SAL_INFO("sc.lok.header", "Col Header: [create string data for cols]: start col: "
2775  << nStartRow << " start width: " << nTotalPixels);
2776 
2777  if (nStartCol != nEndCol)
2778  {
2779  auto node = rJsonWriter.startStruct();
2780  rJsonWriter.put("text", static_cast<sal_Int64>(nStartCol + 1));
2781  rJsonWriter.put("size", nTotalPixels);
2782  rJsonWriter.put("groupLevels", static_cast<sal_Int64>(nColGroupDepth));
2783  }
2784 
2785  std::vector<long> aColGroupStartPositions(nColGroupDepth, -nTotalPixels);
2786  nPrevSizePx = -1;
2787  for (SCCOL nCol = nStartCol + 1; nCol <= nEndCol; ++nCol)
2788  {
2789  // nSize will be 0 for hidden columns.
2790  const long nSizePx = lcl_GetColWidthPx(aViewData, nCol, nTab);
2791  nTotalPixels += nSizePx;
2792 
2793  if (bRangeHeaderSupport && nColGroupDepth > 0)
2794  lcl_createGroupsData(nCol, nEndCol, nSizePx, nTotalPixels,
2795  *pColArray, aColGroupIndexes,
2796  aColGroupStartPositions, aColGroupsBuffer);
2797 
2798  if (bRangeHeaderSupport && nCol < nEndCol && nSizePx == nPrevSizePx)
2799  continue;
2800  nPrevSizePx = nSizePx;
2801 
2802  OUString aText = bRangeHeaderSupport ?
2803  OUString::number(nCol + 1) : pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol);
2804 
2805  auto node = rJsonWriter.startStruct();
2806  rJsonWriter.put("text", aText);
2807  rJsonWriter.put("size", nTotalPixels);
2808  }
2809 
2810  aColGroupsBuffer.append("]");
2811  }
2812  if (nColGroupDepth > 0)
2813  {
2814  aColGroupsBuffer.append(",\n");
2815  rJsonWriter.putRaw(aColGroupsBuffer.getStr());
2816  }
2818 
2819  vcl::Region aNewVisArea(
2822  aNewVisArea.Exclude(aOldVisArea);
2823  tools::Rectangle aChangedArea = aNewVisArea.GetBoundRect();
2824  if (!aChangedArea.IsEmpty())
2825  {
2827  UpdateFormulas(aChangedArea.Left(), aChangedArea.Top(), aChangedArea.Right(), aChangedArea.Bottom());
2828  }
2829 }
2830 
2831 OString ScTabView::getSheetGeometryData(bool bColumns, bool bRows, bool bSizes, bool bHidden,
2832  bool bFiltered, bool bGroups)
2833 {
2834  boost::property_tree::ptree aTree;
2835  aTree.put("commandName", ".uno:SheetGeometryData");
2836  aTree.put("maxtiledcolumn", MAXCOL);
2837  aTree.put("maxtiledrow", MAXTILEDROW);
2838 
2839  auto getJSONString = [](const boost::property_tree::ptree& rTree) {
2840  std::stringstream aStream;
2841  boost::property_tree::write_json(aStream, rTree);
2842  return aStream.str();
2843  };
2844 
2845  ScDocument* pDoc = aViewData.GetDocument();
2846  if (!pDoc)
2847  return getJSONString(aTree).c_str();
2848 
2849  if ((!bSizes && !bHidden && !bFiltered && !bGroups) ||
2850  (!bColumns && !bRows))
2851  {
2852  return getJSONString(aTree).c_str();
2853  }
2854 
2855  struct GeomEntry
2856  {
2858  const char* pKey;
2859  bool bEnabled;
2860  };
2861 
2862  const GeomEntry aGeomEntries[] = {
2863  { SheetGeomType::SIZES, "sizes", bSizes },
2864  { SheetGeomType::HIDDEN, "hidden", bHidden },
2865  { SheetGeomType::FILTERED, "filtered", bFiltered },
2866  { SheetGeomType::GROUPS, "groups", bGroups }
2867  };
2868 
2869  struct DimensionEntry
2870  {
2871  const char* pKey;
2872  bool bDimIsCol;
2873  bool bEnabled;
2874  };
2875 
2876  const DimensionEntry aDimEntries[] = {
2877  { "columns", true, bColumns },
2878  { "rows", false, bRows }
2879  };
2880 
2881  SCTAB nTab = aViewData.GetTabNo();
2882 
2883  for (const auto& rDimEntry : aDimEntries)
2884  {
2885  if (!rDimEntry.bEnabled)
2886  continue;
2887 
2888  bool bDimIsCol = rDimEntry.bDimIsCol;
2889 
2890  boost::property_tree::ptree aDimTree;
2891  for (const auto& rGeomEntry : aGeomEntries)
2892  {
2893  if (!rGeomEntry.bEnabled)
2894  continue;
2895 
2896  OString aGeomDataEncoding = pDoc->dumpSheetGeomData(nTab, bDimIsCol, rGeomEntry.eType);
2897  // TODO: Investigate if we can avoid the copy of the 'value' string in put().
2898  aDimTree.put(rGeomEntry.pKey, aGeomDataEncoding.getStr());
2899  }
2900 
2901  aTree.add_child(rDimEntry.pKey, aDimTree);
2902  }
2903 
2904  return getJSONString(aTree).c_str();
2905 }
2906 
2908 {
2909  SAL_INFO("sc.lok.header",
2910  "extendTiledAreaIfNeeded: START: ClientView: ColRange["
2912  << "] RowRange[" << mnLOKStartHeaderRow << "," << mnLOKEndHeaderRow
2913  << "] MaxTiledCol = " << aViewData.GetMaxTiledCol()
2914  << " MaxTiledRow = " << aViewData.GetMaxTiledRow());
2915 
2916  const tools::Rectangle rVisArea = aViewData.getLOKVisibleArea();
2917  if (rVisArea.Top() >= rVisArea.Bottom() ||
2918  rVisArea.Left() >= rVisArea.Right())
2919  return;
2920 
2921  // Needed for conditional updating of visible-range/formula.
2922  tools::Rectangle aOldVisCellRange(mnLOKStartHeaderCol + 1, mnLOKStartHeaderRow + 1,
2924 
2925  ScRangeProvider aRangeProvider(rVisArea, /* bInPixels */ false, aViewData);
2926  // Index bounds.
2927  const ScRange& rCellRange = aRangeProvider.getCellRange();
2928  const SCCOL nStartCol = rCellRange.aStart.Col();
2929  const SCCOL nEndCol = rCellRange.aEnd.Col();
2930  const SCROW nStartRow = rCellRange.aStart.Row();
2931  const SCROW nEndRow = rCellRange.aEnd.Row();
2932 
2933  // Column/Row positions.
2934  long nStartColPos, nEndColPos, nStartRowPos, nEndRowPos;
2935  aRangeProvider.getColPositions(nStartColPos, nEndColPos);
2936  aRangeProvider.getRowPositions(nStartRowPos, nEndRowPos);
2937 
2938  ScPositionHelper& rWidthHelper = aViewData.GetLOKWidthHelper();
2939  ScPositionHelper& rHeightHelper = aViewData.GetLOKHeightHelper();
2940 
2941  // Update mnLOKStartHeaderCol and mnLOKEndHeaderCol members.
2942  // These are consulted in some ScGridWindow methods.
2943  if (mnLOKStartHeaderCol != nStartCol)
2944  {
2945  rWidthHelper.removeByIndex(mnLOKStartHeaderCol);
2946  rWidthHelper.insert(nStartCol, nStartColPos);
2947  mnLOKStartHeaderCol = nStartCol;
2948  }
2949 
2950  if (mnLOKEndHeaderCol != nEndCol)
2951  {
2952  rWidthHelper.removeByIndex(mnLOKEndHeaderCol);
2953  rWidthHelper.insert(nEndCol, nEndColPos);
2954  mnLOKEndHeaderCol = nEndCol;
2955  }
2956 
2957  // Update mnLOKStartHeaderRow and mnLOKEndHeaderRow members.
2958  // These are consulted in some ScGridWindow methods.
2959  if (mnLOKStartHeaderRow != nStartRow)
2960  {
2961  rHeightHelper.removeByIndex(mnLOKStartHeaderRow);
2962  rHeightHelper.insert(nStartRow, nStartRowPos);
2963  mnLOKStartHeaderRow = nStartRow;
2964  }
2965 
2966  if (mnLOKEndHeaderRow != nEndRow)
2967  {
2968  rHeightHelper.removeByIndex(mnLOKEndHeaderRow);
2969  rHeightHelper.insert(nEndRow, nEndRowPos);
2970  mnLOKEndHeaderRow = nEndRow;
2971  }
2972 
2973  constexpr SCCOL nMinExtraCols = 10;
2974  SCCOL nExtraCols = std::max<SCCOL>(nMinExtraCols, nEndCol - nStartCol);
2975  // If we are approaching current max tiled column, signal a size changed event
2976  // and invalidate the involved area.
2977  lcl_ExtendTiledDimension(/* bColumn */ true, nEndCol, nExtraCols, *this, aViewData);
2978 
2979  constexpr SCROW nMinExtraRows = 25;
2980  SCROW nExtraRows = std::max(nMinExtraRows, nEndRow - nStartRow);
2981  // If we are approaching current max tiled row, signal a size changed event
2982  // and invalidate the involved area.
2983  lcl_ExtendTiledDimension(/* bColumn */ false, nEndRow, nExtraRows, *this, aViewData);
2984 
2985  vcl::Region aNewVisCellRange(
2988  aNewVisCellRange.Exclude(aOldVisCellRange);
2989  tools::Rectangle aChangedCellRange = aNewVisCellRange.GetBoundRect();
2990  if (!aChangedCellRange.IsEmpty())
2991  {
2993  UpdateFormulas(aChangedCellRange.Left(), aChangedCellRange.Top(),
2994  aChangedCellRange.Right(), aChangedCellRange.Bottom());
2995  }
2996 
2997  SAL_INFO("sc.lok.header",
2998  "extendTiledAreaIfNeeded: END: ClientView: ColRange["
3000  << "] RowRange[" << mnLOKStartHeaderRow << "," << mnLOKEndHeaderRow
3001  << "] MaxTiledCol = " << aViewData.GetMaxTiledCol()
3002  << " MaxTiledRow = " << aViewData.GetMaxTiledRow());
3003 }
3004 
3005 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define MAXZOOM
Definition: global.hxx:76
virtual Point GetPosPixel() const
Point TopLeft() const
void TestHintWindow()
Definition: tabview3.cxx:768
SfxViewFrame * GetViewFrame() const
long getHeight() const
long Width() const
void SetVSplitMode(ScSplitMode eMode)
Definition: viewdata.hxx:439
SvxZoomType GetZoomType() const
Definition: tabview5.cxx:404
virtual void EnableRTL(bool bEnable=true) override
void LaunchDPFieldMenu(SCCOL nCol, SCROW nRow)
Definition: gridwin.cxx:940
void SelectAll(bool bContinue=false)
Definition: tabview2.cxx:1063
void SetDragRectPixel(const tools::Rectangle &rDragRect, vcl::Window *pRefWin=nullptr)
long GetWidth() const
void LaunchPageFieldMenu(SCCOL nCol, SCROW nRow)
Definition: gridwin.cxx:923
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: tabview.cxx:129
sal_Int32 nIndex
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:205
static void notifyDocumentSizeChanged(SfxViewShell const *pThisView, const OString &rPayload, vcl::ITiledRenderable *pDoc, bool bInvalidateAll=true)
long GetHeight() const
void SetTabBarWidth(long nNewWidth)
Sets an absolute tab bar width (in pixels).
Definition: tabview.cxx:850
std::array< VclPtr< ScRowBar >, 2 > pRowBar
Definition: tabview.hxx:145
ScVSplitPos WhichV(ScSplitPos ePos)
Definition: viewdata.hxx:714
VclPtr< ScrollBar > aHScrollLeft
Definition: tabview.hxx:153
SC_DLLPUBLIC bool IsNegativePage(SCTAB nTab) const
Definition: document.cxx:1002
SC_DLLPUBLIC bool IsHidden() const
Definition: olinetab.hxx:50
void SetFixPosY(SCROW nPos)
Definition: viewdata.hxx:443
SCROW mnLOKEndHeaderRow
Definition: tabview.hxx:200
MapMode GetDrawMapMode(bool bForce=false)
MapMode for the drawinglayer objects.
Definition: gridwin3.cxx:246
SCROW Row() const
Definition: address.hxx:262
ScVSplitPos
Definition: viewdata.hxx:47
long zoomIn(long nCurrent)
ScSplitPos FindWindow(const vcl::Window *pWindow) const
Definition: tabview.cxx:905
void LaunchDataSelectMenu(SCCOL nCol, SCROW nRow)
Definition: gridwin.cxx:1091
bool IsVScrollMode() const
Definition: viewdata.hxx:548
ScopedJsonWriterStruct startStruct()
const tools::Rectangle & getLOKVisibleArea() const
The visible area in the client (set by setClientVisibleArea).
Definition: viewdata.hxx:560
SCCOL mnLOKStartHeaderCol
Definition: tabview.hxx:201
VclPtr< ScrollBar > aVScrollBottom
Definition: tabview.hxx:152
std::unique_ptr< ContentProperties > pData
const Fraction & GetZoomX() const
Definition: viewdata.hxx:459
void SetSheetLayoutRTL(bool bSheetRTL)
Definition: tabcont.cxx:403
long Height() const
VclPtr< ScrollBar > aHScrollRight
Definition: tabview.hxx:154
SC_DLLPUBLIC SCCOLROW GetEnd() const
Definition: olinetab.cxx:42
long getWidth() const
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
Point aBorderPos
Definition: tabview.hxx:134
virtual void Resize() override
Definition: tabview.cxx:124
void RepeatResize(bool bUpdateFix=true)
Definition: tabview.cxx:768
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:708
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:1921
virtual Size GetSizePixel() const
SCROW GetMaxTiledRow() const
Definition: viewdata.hxx:423
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: tabview.cxx:86
virtual void SetSizePixel(const Size &rNewSize)
double mfPendingTabBarWidth
Definition: tabview.hxx:197
VclPtr< ScTabSplitter > pHSplitter
Definition: tabview.hxx:148
void SetDocumentModified()
Definition: docsh.cxx:2819
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:199
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
void SetHSplitPos(long nPos)
Definition: viewdata.hxx:440
OString dumpSheetGeomData(SCTAB nTab, bool bColumns, SheetGeomType eGeomType)
Serializes the specified sheet's geometry data.
void PaintGrid()
Definition: tabview3.cxx:2614
ScAddress aEnd
Definition: address.hxx:501
ScSplitPos GetActivePart() const
Definition: viewdata.hxx:398
void GetBorderSize(SvBorder &rBorder, const Size &rSize)
Definition: tabview.cxx:792
OString getSheetGeometryData(bool bColumns, bool bRows, bool bSizes, bool bHidden, bool bFiltered, bool bGroups)
Definition: tabview.cxx:2831
tools::Rectangle GetDesktopRectPixel() const
void RemoveHintWindow()
Definition: tabview3.cxx:865
void SetAutoSpellData(SCCOL nPosX, SCROW nPosY, const std::vector< editeng::MisspellRanges > *pRanges)
Definition: tabview.cxx:2276
WinBits const WB_VSCROLL
void UpdateAllOverlays()
Definition: tabview2.cxx:999
css::uno::Reference< css::frame::XModel > GetModel() const
const CommandWheelData * GetWheelData() const
void Invalidate(sal_uInt16 nId)
long & Left()
tools::Rectangle GetBoundRect() const
void LockModifiers(sal_uInt16 nModifiers)
Definition: tabview.cxx:1888
long AdjustHeight(long n)
css::chart::ChartAxisLabelPosition ePos
long & Bottom()
SCCOL GetPosX(ScHSplitPos eWhich, SCTAB nForTab=-1) const
Definition: viewdata.cxx:1344
None
SCCOL CellsAtX(SCCOL nPosX, SCCOL nDir, ScHSplitPos eWhichX, sal_uInt16 nScrSizeY=SC_SIZE_NONE) const
Definition: viewdata.cxx:2549
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:4164
void ResetAutoSpell()
Definition: tabview.cxx:2265
ScSplitPos
Definition: viewdata.hxx:45
virtual ~ScCornerButton() override
Definition: tabview.cxx:82
bool UpdateFixY(SCTAB nTab=MAXTAB+1)
Definition: viewdata.cxx:3957
bool GetEntryIndex(size_t nLevel, SCCOLROW nPos, size_t &rnIndex) const
Definition: olinetab.cxx:495
bool IsEmpty() const
StateChangedType
bool IsTabMode() const
Definition: viewdata.hxx:546
void UpdateAutoFillMark(bool bFromPaste=false)
Definition: tabview3.cxx:183
sal_Int64 WinBits
void StartDataSelect()
Definition: tabview.cxx:2179
void SetBackground()
long GetTabBarWidth() const
Returns the current tab bar width in pixels.
Definition: tabview.cxx:874
long Right() const
void UpdateFixPos()
Definition: tabview.cxx:755
Reference< XController > xController
void PaintLeft()
Definition: tabview3.cxx:2690
static void notifyInvalidation(SfxViewShell const *pThisView, const OString &rPayload)
bool GetEntryIndexInRange(size_t nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t &rnIndex) const
Definition: olinetab.cxx:515
void GetPosFromPixel(long nClickX, long nClickY, ScSplitPos eWhich, SCCOL &rPosX, SCROW &rPosY, bool bTestMerge=true, bool bRepair=false, SCTAB nForTab=-1)
Definition: viewdata.cxx:2700
bool IsFormulaMode()
Definition: scmod.cxx:1621
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:873
std::array< VclPtr< ScGridWindow >, 4 > pGridWin
Definition: tabview.hxx:143
SC_DLLPUBLIC void SetRelTabBarWidth(double fRelTabBarWidth)
Sets a relative tab bar width.
Definition: tabview.cxx:861
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:2827
void SetPendingRelTabBarWidth(double fRelTabBarWidth)
Sets a relative tab bar width.
Definition: tabview.cxx:868
WinBits const WB_HSCROLL
void SetFixPosX(SCCOL nPos)
Definition: viewdata.hxx:442
SfxFrame & GetFrame() const
size_t GetDepth() const
Definition: olinetab.hxx:111
SCCOL mnLOKEndHeaderCol
Definition: tabview.hxx:202
void BroadcastAccessibility(const SfxHint &rHint)
Definition: tabvwshh.cxx:235
void UpdateFormulas(SCCOL nStartCol=-1, SCROW nStartRow=-1, SCCOL nEndCol=-1, SCROW nEndRow=-1)
Definition: tabview3.cxx:2269
void putRaw(const rtl::OStringBuffer &)
#define HMM_PER_TWIPS
Definition: global.hxx:91
void ActivatePart(ScSplitPos eWhich)
Definition: tabview3.cxx:2861
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: tabview.cxx:115
long Top() const
ScDocument * GetDocument() const
Definition: viewdata.cxx:859
void DoHSplit(long nSplitPos)
Definition: tabview.cxx:1522
SCCOL GetMaxTiledCol() const
Definition: viewdata.hxx:422
SCROW GetPosY(ScVSplitPos eWhich, SCTAB nForTab=-1) const
Definition: viewdata.cxx:1358
ScSplitMode GetHSplitMode() const
Definition: viewdata.hxx:416
void DrawLine(const Point &rStartPt, const Point &rEndPt)
const Fraction & GetZoomY() const
Definition: viewdata.hxx:460
ScViewData & GetViewData()
Definition: tabview.hxx:332
void PaintTop()
Definition: tabview3.cxx:2625
ScGridWindow * GetActiveWin()
Definition: tabview.cxx:884
SC_DLLPUBLIC const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
Definition: document.cxx:4717
bool HasHintWindow() const
Definition: tabview3.cxx:863
void InterpretVisible()
Definition: tabview4.cxx:501
DocumentType eType
ScTabViewShell * GetViewShell() const
Definition: viewdata.hxx:357
void EnableInput(bool bEnable=true, bool bChild=true)
bool IsHScrollMode() const
Definition: viewdata.hxx:550
Point BottomRight() const
const Color & GetDarkShadowColor() const
bool ContinueOnlineSpelling()
Definition: tabview.cxx:2239
void SetZoom(const Fraction &rNewX, const Fraction &rNewY, bool bAll)
Definition: tabview5.cxx:414
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:872
void SetLineColor()
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: document.cxx:4448
bool ScrollCommand(const CommandEvent &rCEvt, ScSplitPos ePos)
Definition: tabview.cxx:945
void LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
Definition: gridwin.cxx:648
VclPtr< ScTabControl > pTabControl
Definition: tabview.hxx:150
void SetTop(long v)
bool IsModalMode(SfxObjectShell *pDocSh=nullptr)
Definition: scmod.cxx:1545
const value_type & getNearestByPosition(long nPos) const
Definition: viewdata.cxx:218
int i
Point GetScrPos(SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, bool bAllowNeg=false, SCTAB nForTab=-1) const
Definition: viewdata.cxx:2319
void DoAddWin(ScGridWindow *pWin)
Definition: tabview5.cxx:267
SC_DLLPUBLIC SCCOLROW GetStart() const
Definition: olinetab.hxx:43
Size aFrameSize
Definition: tabview.hxx:133
SfxBindings & GetBindings()
Definition: viewdata.cxx:3041
const ScOutlineArray & GetRowArray() const
Definition: olinetab.hxx:161
sal_Int16 SCCOL
Definition: types.hxx:22
void SetActivePointer(PointerStyle nPointer)
Definition: tabview.cxx:891
static void lcl_SetPosSize(vcl::Window &rWindow, const Point &rPos, const Size &rSize, long nTotalWidth, bool bLayoutRTL)
Definition: tabview.cxx:258
const ScOutlineArray & GetColArray() const
Definition: olinetab.hxx:159
void SetVisibleSize(long nNewSize)
#define SC_MOD()
Definition: scmod.hxx:253
static void ShowHide(vcl::Window *pWin, bool bShow)
Definition: tabview.cxx:1404
static bool IsQuickHelpEnabled()
size_t GetCount(size_t nLevel) const
Definition: olinetab.cxx:470
const vcl::Font & GetTabFont() const
const SCCOL MAXCOL
Definition: address.hxx:70
SfxBindings & GetBindings()
CommandWheelMode GetMode() const
void SetRange(const Range &rRange)
void UpdateHeaderWidth(const ScVSplitPos *pWhich=nullptr, const SCROW *pPosY=nullptr)
Definition: tabview.cxx:1342
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
bool IsPreview() const
void SetFixed(bool bSet)
Definition: tabsplit.cxx:45
ScrollType
QuickHelpFlags
void SetRight(long v)
void InitScrollBar(ScrollBar &rScrollBar, long nMaxVal)
Definition: tabview.cxx:222
OUString ScResId(const char *pId)
Definition: scdll.cxx:95
void SetActive()
Definition: tabvwsh4.cxx:259
long Bottom() const
virtual css::uno::Reference< css::frame::XModel > GetCurrentDocument() const
virtual void Start() override
long const nBorder
const Size & GetFontSize() const
constexpr sal_Int32 TAB_HEIGHT_MARGIN
Definition: tabview.cxx:64
void SetPageSize(long nNewSize)
const AllSettings & GetSettings() const
void InvalidateSplit()
Definition: tabview.cxx:2109
Size GetOutputSizePixel() const
VclPtr< ScrollBar > aVScrollTop
Definition: tabview.hxx:151
bool HasPageFieldDataAtCursor() const
Definition: tabview.cxx:2168
SC_DLLPUBLIC void ScrollLines(long nDeltaX, long nDeltaY)
Definition: tabview.cxx:1314
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:879
void RemoveSplit()
Definition: tabview.cxx:2065
void EnableAutoSpell(bool bEnable)
Definition: tabview.cxx:2254
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:392
bool bMinimized
Definition: tabview.hxx:204
Point OutputToAbsoluteScreenPixel(const Point &rPos) const
VclPtr< ScCornerButton > aTopButton
Definition: tabview.hxx:156
void put(const char *pPropName, const OUString &rPropValue)
SCCOL Col() const
Definition: address.hxx:267
#define SC_TABBAR_MIN
Definition: tabview.cxx:69
float GetDPIScaleFactor() const
void Compute(value_type aFirstNearest, value_type aSecondNearest, long nFirstBound, long nSecondBound)
Definition: viewdata.cxx:342
void EnableRefInput(bool bFlag)
Definition: tabview.cxx:2216
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
void extendTiledAreaIfNeeded()
Definition: tabview.cxx:2907
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:207
constexpr sal_uInt16 nScrollBarSize
void UpdateShow()
Definition: tabview.cxx:1411
void SetLineSize(long nNewSize)
Point PixelToLogic(const Point &rDevicePt) const
Point LogicToPixel(const Point &rLogicPt) const
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:2813
bool mbInlineWithScrollbar
Definition: tabview.hxx:215
WinBits const WB_SIZEABLE
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:241
void Exclude(const tools::Rectangle &rRegion)
void UpdateVarZoom()
Definition: tabview.cxx:728
const size_t nTabSize
double GetPPTY() const
Definition: viewdata.hxx:469
void HideAllCursors()
Definition: tabview3.cxx:215
void Stop()
MouseEvent aTimerMEvt
Definition: tabview.hxx:169
void SetTimer(ScGridWindow *pWin, const MouseEvent &rMEvt)
Definition: tabview.cxx:237
long GetDelta() const
bool UpdateFixX(SCTAB nTab=MAXTAB+1)
Definition: viewdata.cxx:3922
long & Right()
bool IsInPlace() const
std::unique_ptr< ScHeaderSelectionEngine > pHdrSelEng
Definition: tabview.hxx:128
bool UpdateVisibleRange()
Definition: tabview.cxx:1492
void getRowColumnHeaders(const tools::Rectangle &rRectangle, tools::JsonWriter &rJsonWriter)
Definition: tabview.cxx:2599
long zoomOut(long nCurrent)
const Point & GetMousePosPixel() const
Definition: gridwin.hxx:367
bool IsHeaderMode() const
Definition: viewdata.hxx:544
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:898
Timer aScrollTimer
Definition: tabview.hxx:167
VclPtr< ScCornerButton > aCornerButton
Definition: tabview.hxx:155
void SetScrollHdl(const Link< ScrollBar *, void > &rLink)
static VclPtr< reference_type > Create(Arg &&...arg)
void SetBottom(long v)
VclPtr< ScTabSplitter > pVSplitter
Definition: tabview.hxx:149
void SetPosY(ScVSplitPos eWhich, SCROW nNewPosY)
Definition: viewdata.cxx:2866
SC_DLLPUBLIC ScOutlineTable * GetOutlineTable(SCTAB nTab, bool bCreate=false)
Definition: documen3.cxx:717
void * p
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:401
ScViewData * pViewData
Definition: tabview.hxx:70
css::sheet::DataPilotFieldOrientation GetDPFieldOrientation(SCCOL nCol, SCROW nRow) const
Definition: gridwin2.cxx:54
const SCROW MAXTILEDROW
Definition: address.hxx:76
long Left() const
long GetVSplitPos() const
Definition: viewdata.hxx:419
IMPL_LINK(ScTabView, ScrollHdl, ScrollBar *, pScroll, void)
Definition: tabview.cxx:1004
PointerStyle
void ScrollY(long nDeltaY, ScVSplitPos eWhich, bool bUpdBars=true)
Definition: tabview.cxx:1230
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:904
void VisAreaChanged()
Definition: viewuno.cxx:1913
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
Definition: document.cxx:994
IMPL_LINK_NOARG(ScTabView, TimerHdl, Timer *, void)
Definition: tabview.cxx:250
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4432
ScSplitMode
Definition: viewdata.hxx:43
void HideListBox()
Definition: tabview3.cxx:2950
bool IsOutlineMode() const
Definition: viewdata.hxx:552
void SetZoomType(SvxZoomType eNew, bool bAll)
Definition: tabview5.cxx:409
long GetHSplitPos() const
Definition: viewdata.hxx:418
VclPtr< vcl::Window > pFrameWin
Definition: tabview.hxx:122
void SetMaxTiledCol(SCCOL nCol)
Definition: viewdata.cxx:1404
ScrollBar * get() const
void VisAreaChanged()
void SetLeft(long v)
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:2591
std::array< VclPtr< ScOutlineWindow >, 2 > pRowOutline
Definition: tabview.hxx:147
#define MINZOOM
Definition: global.hxx:75
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
void ScrollX(long nDeltaX, ScHSplitPos eWhich, bool bUpdBars=true)
Definition: tabview.cxx:1147
#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
long GetScrollBarSize() const
void removeByIndex(index_type nIndex)
Definition: viewdata.cxx:144
VclPtr< ScGridWindow > pTimerWindow
Definition: tabview.hxx:168
ScTabView(const ScTabView &)=delete
make noncopyable
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4123
void SetVSplitPos(long nPos)
Definition: viewdata.hxx:441
rtl::OString toString() const
Point GetGridOffset() const
Definition: tabview.cxx:915
Point GetMousePosPixel()
Definition: tabview.cxx:1899
static long ToPixel(sal_uInt16 nTwips, double nFactor)
Definition: viewdata.hxx:686
void setWidth(long nWidth)
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:1429
void SplitAtPixel(const Point &rPixel)
Definition: tabview.cxx:2094
ScSplitMode GetVSplitMode() const
Definition: viewdata.hxx:417
void insert(index_type nIndex, long nPos)
Definition: viewdata.cxx:132
long & Top()
B2DRange maRange
sal_Int16 SCTAB
Definition: types.hxx:23
virtual Size getDocumentSize() override
Definition: docuno.cxx:650
void ShowAllCursors()
Definition: tabview3.cxx:229
SCCOL GetCurX() const
Definition: viewdata.hxx:401
bool IsMod1() const
WinBits const WB_DRAG
ScCornerButton(vcl::Window *pParent, ScViewData *pData)
Definition: tabview.cxx:75
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
void Init()
Definition: tabview5.cxx:58
void DoVSplit(long nSplitPos)
Definition: tabview.cxx:1594