Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / view / tabview.cxx
blobe4671f6da2edbef9f9051db532eb4bf7b77567e9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <vcl/svapp.hxx>
22 #include "scitems.hxx"
23 #include <sfx2/viewfrm.hxx>
24 #include <sfx2/bindings.hxx>
25 #include <vcl/help.hxx>
26 #include <vcl/settings.hxx>
28 #include "tabview.hxx"
29 #include "tabvwsh.hxx"
30 #include "document.hxx"
31 #include "gridwin.hxx"
32 #include "olinewin.hxx"
33 #include "olinetab.hxx"
34 #include "tabsplit.hxx"
35 #include "colrowba.hxx"
36 #include "tabcont.hxx"
37 #include "scmod.hxx"
38 #include "sc.hrc"
39 #include "viewutil.hxx"
40 #include "globstr.hrc"
41 #include "drawview.hxx"
42 #include "docsh.hxx"
43 #include "viewuno.hxx"
44 #include "AccessibilityHints.hxx"
45 #include "appoptio.hxx"
46 #include "attrib.hxx"
47 #include "hintwin.hxx"
49 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
51 #include <string>
52 #include <algorithm>
53 #include <boost/property_tree/json_parser.hpp>
55 #include <basegfx/tools/zoomtools.hxx>
57 #define SPLIT_MARGIN 30
58 #define SPLIT_HANDLE_SIZE 5
59 #define WIDTH_MARGIN 5
61 #define SC_ICONSIZE 36
63 #define SC_SCROLLBAR_MIN 30
64 #define SC_TABBAR_MIN 6
66 using namespace ::com::sun::star;
68 // Corner-Button
70 ScCornerButton::ScCornerButton( vcl::Window* pParent, ScViewData* pData, bool bAdditional ) :
71 Window( pParent, WinBits( 0 ) ),
72 pViewData( pData ),
73 bAdd( bAdditional )
75 EnableRTL( false );
78 ScCornerButton::~ScCornerButton()
82 void ScCornerButton::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
84 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
85 SetBackground(rStyleSettings.GetFaceColor());
87 Size aSize(GetOutputSizePixel());
88 long nPosX = aSize.Width() - 1;
89 long nPosY = aSize.Height() - 1;
91 Window::Paint(rRenderContext, rRect);
93 bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
94 long nDarkX = bLayoutRTL ? 0 : nPosX;
96 if (!bAdd)
98 // match the shaded look of column/row headers
100 Color aFace(rStyleSettings.GetFaceColor());
101 Color aWhite(COL_WHITE);
102 Color aCenter(aFace);
103 aCenter.Merge(aWhite, 0xd0); // lighten up a bit
104 Color aOuter(aFace );
105 aOuter.Merge(aWhite, 0xa0); // lighten up more
107 long nCenterX = (aSize.Width() / 2) - 1;
108 long nCenterY = (aSize.Height() / 2) - 1;
110 rRenderContext.SetLineColor();
111 rRenderContext.SetFillColor(aCenter);
112 rRenderContext.DrawRect(Rectangle(nCenterX, nCenterY, nCenterX, nPosY));
113 rRenderContext.DrawRect(Rectangle(nCenterX, nCenterY, nDarkX, nCenterY));
114 rRenderContext.SetFillColor(aOuter);
115 rRenderContext.DrawRect(Rectangle(0, 0, nPosX, nCenterY - 1));
116 if (bLayoutRTL)
117 rRenderContext.DrawRect(Rectangle(nCenterX + 1, nCenterY, nPosX, nPosY));
118 else
119 rRenderContext.DrawRect(Rectangle(0, nCenterY, nCenterX - 1, nPosY));
122 // both buttons have the same look now - only dark right/bottom lines
123 rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
124 rRenderContext.DrawLine(Point(0, nPosY), Point(nPosX, nPosY));
125 rRenderContext.DrawLine(Point(nDarkX, 0), Point(nDarkX, nPosY));
128 void ScCornerButton::StateChanged( StateChangedType nType )
130 Window::StateChanged( nType );
132 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
133 SetBackground( rStyleSettings.GetFaceColor() );
134 Invalidate();
137 void ScCornerButton::DataChanged( const DataChangedEvent& rDCEvt )
139 Window::DataChanged( rDCEvt );
141 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
142 SetBackground( rStyleSettings.GetFaceColor() );
143 Invalidate();
146 void ScCornerButton::Resize()
148 Invalidate();
151 void ScCornerButton::MouseButtonDown( const MouseEvent& rMEvt )
153 ScModule* pScMod = SC_MOD();
154 bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
155 if (!bDisable)
157 ScTabViewShell* pViewSh = pViewData->GetViewShell();
158 pViewSh->SetActive(); // Appear and SetViewFrame
159 pViewSh->ActiveGrabFocus();
161 bool bControl = rMEvt.IsMod1();
162 pViewSh->SelectAll( bControl );
165 namespace
168 bool lcl_HasColOutline( const ScViewData& rViewData )
170 const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
171 if (pTable)
173 const ScOutlineArray& rArray = pTable->GetColArray();
174 if ( rArray.GetDepth() > 0 )
175 return true;
177 return false;
180 bool lcl_HasRowOutline( const ScViewData& rViewData )
182 const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
183 if (pTable)
185 const ScOutlineArray& rArray = pTable->GetRowArray();
186 if ( rArray.GetDepth() > 0 )
187 return true;
189 return false;
192 } // anonymous namespace
194 ScTabView::ScTabView( vcl::Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
195 pFrameWin( pParent ),
196 aViewData( &rDocSh, pViewShell ),
197 pSelEngine( nullptr ),
198 aFunctionSet( &aViewData ),
199 pHdrSelEng( nullptr ),
200 aHdrFunc( &aViewData ),
201 pDrawView( nullptr ),
202 aVScrollTop( VclPtr<ScrollBar>::Create( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ) ),
203 aVScrollBottom( VclPtr<ScrollBar>::Create( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ) ),
204 aHScrollLeft( VclPtr<ScrollBar>::Create( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ) ),
205 aHScrollRight( VclPtr<ScrollBar>::Create( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ) ),
206 aCornerButton( VclPtr<ScCornerButton>::Create( pFrameWin, &aViewData, false ) ),
207 aTopButton( VclPtr<ScCornerButton>::Create( pFrameWin, &aViewData, true ) ),
208 aScrollBarBox( VclPtr<ScrollBarBox>::Create( pFrameWin, WB_SIZEABLE ) ),
209 mpInputHintWindow( nullptr ),
210 pPageBreakData( nullptr ),
211 pBrushDocument( nullptr ),
212 pDrawBrushSet( nullptr ),
213 pTimerWindow( nullptr ),
214 nTipVisible( 0 ),
215 nPrevDragPos( 0 ),
216 meBlockMode(None),
217 nBlockStartX( 0 ),
218 nBlockStartXOrig( 0 ),
219 nBlockEndX( 0 ),
220 nBlockStartY( 0 ),
221 nBlockStartYOrig( 0 ),
222 nBlockEndY( 0 ),
223 nBlockStartZ( 0 ),
224 nBlockEndZ( 0 ),
225 nOldCurX( 0 ),
226 nOldCurY( 0 ),
227 mfPendingTabBarWidth( -1.0 ),
228 bMinimized( false ),
229 bInUpdateHeader( false ),
230 bInActivatePart( false ),
231 bInZoomUpdate( false ),
232 bMoveIsShift( false ),
233 bDrawSelMode( false ),
234 bLockPaintBrush( false ),
235 bDragging( false ),
236 bBlockNeg( false ),
237 bBlockCols( false ),
238 bBlockRows( false ),
239 mbInlineWithScrollbar( false )
241 Init();
244 void ScTabView::InitScrollBar( ScrollBar& rScrollBar, long nMaxVal )
246 rScrollBar.SetRange( Range( 0, nMaxVal ) );
247 rScrollBar.SetLineSize( 1 );
248 rScrollBar.SetPageSize( 1 ); // is queried separately
249 rScrollBar.SetVisibleSize( 10 ); // is reset by Resize
251 rScrollBar.SetScrollHdl( LINK(this, ScTabView, ScrollHdl) );
252 rScrollBar.SetEndScrollHdl( LINK(this, ScTabView, EndScrollHdl) );
254 rScrollBar.EnableRTL( aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ) );
257 // Scroll-Timer
259 void ScTabView::SetTimer( ScGridWindow* pWin, const MouseEvent& rMEvt )
261 pTimerWindow = pWin;
262 aTimerMEvt = rMEvt;
263 aScrollTimer.Start();
266 void ScTabView::ResetTimer()
268 aScrollTimer.Stop();
269 pTimerWindow = nullptr;
272 IMPL_LINK_NOARG_TYPED(ScTabView, TimerHdl, Timer *, void)
274 if (pTimerWindow)
275 pTimerWindow->MouseMove( aTimerMEvt );
278 // --- Resize ---------------------------------------------------------------------
280 static void lcl_SetPosSize( vcl::Window& rWindow, const Point& rPos, const Size& rSize,
281 long nTotalWidth, bool bLayoutRTL )
283 Point aNewPos = rPos;
284 if ( bLayoutRTL )
286 aNewPos.X() = nTotalWidth - rPos.X() - rSize.Width();
287 if ( aNewPos == rWindow.GetPosPixel() && rSize.Width() != rWindow.GetSizePixel().Width() )
289 // Document windows are manually painted right-to-left, so they need to
290 // be repainted if the size changes.
291 rWindow.Invalidate();
294 rWindow.SetPosSizePixel( aNewPos, rSize );
297 void ScTabView::DoResize( const Point& rOffset, const Size& rSize, bool bInner )
299 HideListBox();
301 bool bHasHint = HasHintWindow();
302 if (bHasHint)
303 RemoveHintWindow();
305 bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
306 long nTotalWidth = rSize.Width();
307 if ( bLayoutRTL )
308 nTotalWidth += 2*rOffset.X();
310 bool bVScroll = aViewData.IsVScrollMode();
311 bool bHScroll = aViewData.IsHScrollMode();
312 bool bTabControl = aViewData.IsTabMode();
313 bool bHeaders = aViewData.IsHeaderMode();
314 bool bOutlMode = aViewData.IsOutlineMode();
315 bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
316 bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
318 if ( aViewData.GetDocShell()->IsPreview() )
319 bHScroll = bVScroll = bTabControl = bHeaders = bHOutline = bVOutline = false;
321 long nBarX = 0;
322 long nBarY = 0;
323 long nOutlineX = 0;
324 long nOutlineY = 0;
325 long nOutPosX;
326 long nOutPosY;
328 long nPosX = rOffset.X();
329 long nPosY = rOffset.Y();
330 long nSizeX = rSize.Width();
331 long nSizeY = rSize.Height();
333 bMinimized = ( nSizeX<=SC_ICONSIZE || nSizeY<=SC_ICONSIZE );
334 if ( bMinimized )
335 return;
337 sal_Int32 aScaleFactor = pFrameWin->GetDPIScaleFactor();
339 long nSplitSizeX = SPLIT_HANDLE_SIZE * aScaleFactor;
340 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
341 nSplitSizeX = 1;
342 long nSplitSizeY = SPLIT_HANDLE_SIZE * aScaleFactor;
343 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
344 nSplitSizeY = 1;
346 aBorderPos = rOffset;
347 aFrameSize = rSize;
349 const StyleSettings& rStyleSettings = pFrameWin->GetSettings().GetStyleSettings();
351 sal_Int32 nTabWidth = pFrameWin->GetFont().GetFontHeight() + WIDTH_MARGIN;
353 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
355 if ( aViewData.GetHSplitPos() > nSizeX - SPLIT_MARGIN )
357 aViewData.SetHSplitMode( SC_SPLIT_NONE );
358 if ( WhichH( aViewData.GetActivePart() ) == SC_SPLIT_RIGHT )
359 ActivatePart( SC_SPLIT_BOTTOMLEFT );
360 InvalidateSplit();
363 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
365 if ( aViewData.GetVSplitPos() > nSizeY - SPLIT_MARGIN )
367 aViewData.SetVSplitMode( SC_SPLIT_NONE );
368 if ( WhichV( aViewData.GetActivePart() ) == SC_SPLIT_TOP )
369 ActivatePart( SC_SPLIT_BOTTOMLEFT );
370 InvalidateSplit();
374 UpdateShow();
376 if (bHScroll || bVScroll) // Scrollbars horizontal or vertical
378 long nScrollBarSize = rStyleSettings.GetScrollBarSize();
379 if (bVScroll)
381 nBarX = nScrollBarSize;
382 nSizeX -= nBarX;
384 if (bHScroll)
386 nBarY = nTabWidth;
388 if (!mbInlineWithScrollbar)
389 nBarY += nScrollBarSize;
391 nSizeY -= nBarY;
394 // window at the bottom right
395 lcl_SetPosSize( *aScrollBarBox.get(), Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
396 nTotalWidth, bLayoutRTL );
398 if (bHScroll) // Scrollbars horizontal
400 long nSizeLt = 0; // left scroll bar
401 long nSizeRt = 0; // right scroll bar
402 long nSizeSp = 0; // splitter
404 switch (aViewData.GetHSplitMode())
406 case SC_SPLIT_NONE:
407 nSizeSp = nSplitSizeX;
408 nSizeLt = nSizeX - nSizeSp; // Covert the corner
409 break;
410 case SC_SPLIT_NORMAL:
411 nSizeSp = nSplitSizeX;
412 nSizeLt = aViewData.GetHSplitPos();
413 break;
414 case SC_SPLIT_FIX:
415 nSizeSp = 0;
416 nSizeLt = 0;
417 break;
419 nSizeRt = nSizeX - nSizeLt - nSizeSp;
421 long nTabSize = 0;
423 if (bTabControl)
425 // pending relative tab bar width from extended document options
426 if( mfPendingTabBarWidth >= 0.0 )
428 SetRelTabBarWidth( mfPendingTabBarWidth );
429 mfPendingTabBarWidth = -1.0;
432 if (mbInlineWithScrollbar)
434 nTabSize = pTabControl->GetSizePixel().Width();
436 if ( aViewData.GetHSplitMode() != SC_SPLIT_FIX ) // left Scrollbar
438 if (nTabSize > nSizeLt-SC_SCROLLBAR_MIN)
439 nTabSize = nSizeLt-SC_SCROLLBAR_MIN;
440 if (nTabSize < SC_TABBAR_MIN)
441 nTabSize = SC_TABBAR_MIN;
442 nSizeLt -= nTabSize;
444 else // right Scrollbar
446 if (nTabSize > nSizeRt-SC_SCROLLBAR_MIN)
447 nTabSize = nSizeRt-SC_SCROLLBAR_MIN;
448 if (nTabSize < SC_TABBAR_MIN)
449 nTabSize = SC_TABBAR_MIN;
450 nSizeRt -= nTabSize;
455 if (mbInlineWithScrollbar)
457 Point aTabPoint(nPosX, nPosY + nSizeY);
458 Size aTabSize(nTabSize, nBarY);
459 lcl_SetPosSize(*pTabControl.get(), aTabPoint, aTabSize, nTotalWidth, bLayoutRTL);
460 pTabControl->SetSheetLayoutRTL(bLayoutRTL);
462 Point aHScrollLeftPoint(nPosX + nTabSize, nPosY + nSizeY);
463 Size aHScrollLeftSize(nSizeLt, nBarY);
464 lcl_SetPosSize(*aHScrollLeft.get(), aHScrollLeftPoint, aHScrollLeftSize, nTotalWidth, bLayoutRTL);
466 Point aHSplitterPoint(nPosX + nTabSize + nSizeLt, nPosY + nSizeY);
467 Size aHSplitterSize(nSizeSp, nBarY);
468 lcl_SetPosSize(*pHSplitter.get(), aHSplitterPoint, aHSplitterSize, nTotalWidth, bLayoutRTL);
470 Point aHScrollRightPoint(nPosX + nTabSize + nSizeLt + nSizeSp, nPosY + nSizeY);
471 Size aHScrollRightSize(nSizeRt, nBarY);
472 lcl_SetPosSize(*aHScrollRight.get(), aHScrollRightPoint, aHScrollRightSize, nTotalWidth, bLayoutRTL);
474 else
476 Point aTabPoint(nPosX, nPosY + nSizeY + nScrollBarSize);
477 Size aTabSize(nSizeX, nTabWidth);
478 lcl_SetPosSize(*pTabControl.get(), aTabPoint, aTabSize, nTotalWidth, bLayoutRTL);
479 pTabControl->SetSheetLayoutRTL(bLayoutRTL);
481 Point aHScrollLeftPoint(nPosX, nPosY + nSizeY);
482 Size aHScrollLeftSize(nSizeLt, nScrollBarSize);
483 lcl_SetPosSize(*aHScrollLeft.get(), aHScrollLeftPoint, aHScrollLeftSize, nTotalWidth, bLayoutRTL);
485 Point aHSplitterPoint(nPosX + nSizeLt, nPosY + nSizeY);
486 Size aHSplitterSize(nSizeSp, nScrollBarSize);
487 lcl_SetPosSize(*pHSplitter.get(), aHSplitterPoint, aHSplitterSize, nTotalWidth, bLayoutRTL);
489 Point aHScrollRightPoint(nPosX + nSizeLt + nSizeSp, nPosY + nSizeY);
490 Size aHScrollRightSize(nSizeRt, nScrollBarSize);
491 lcl_SetPosSize(*aHScrollRight.get(), aHScrollRightPoint, aHScrollRightSize, nTotalWidth, bLayoutRTL);
493 // SetDragRectPixel is done below
496 if (bVScroll)
498 long nSizeUp = 0; // upper scroll bar
499 long nSizeSp = 0; // splitter
500 long nSizeDn; // lower scroll bar
502 switch (aViewData.GetVSplitMode())
504 case SC_SPLIT_NONE:
505 nSizeUp = 0;
506 nSizeSp = nSplitSizeY;
507 break;
508 case SC_SPLIT_NORMAL:
509 nSizeUp = aViewData.GetVSplitPos();
510 nSizeSp = nSplitSizeY;
511 break;
512 case SC_SPLIT_FIX:
513 nSizeUp = 0;
514 nSizeSp = 0;
515 break;
517 nSizeDn = nSizeY - nSizeUp - nSizeSp;
519 lcl_SetPosSize( *aVScrollTop.get(), Point(nPosX + nSizeX, nPosY),
520 Size(nBarX, nSizeUp), nTotalWidth, bLayoutRTL );
521 lcl_SetPosSize( *pVSplitter, Point( nPosX + nSizeX, nPosY+nSizeUp ),
522 Size( nBarX, nSizeSp ), nTotalWidth, bLayoutRTL );
523 lcl_SetPosSize( *aVScrollBottom.get(), Point(nPosX + nSizeX,
524 nPosY + nSizeUp + nSizeSp),
525 Size(nBarX, nSizeDn), nTotalWidth, bLayoutRTL );
527 // SetDragRectPixel is done below
531 // SetDragRectPixel also without Scrollbars etc., when already split
532 if ( bHScroll || aViewData.GetHSplitMode() != SC_SPLIT_NONE )
533 pHSplitter->SetDragRectPixel(
534 Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
535 if ( bVScroll || aViewData.GetVSplitMode() != SC_SPLIT_NONE )
536 pVSplitter->SetDragRectPixel(
537 Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
539 if (bTabControl && ! bHScroll )
541 nBarY = aHScrollLeft->GetSizePixel().Height();
542 nBarX = aVScrollBottom->GetSizePixel().Width();
544 long nSize1 = nSizeX;
546 long nTabSize = nSize1;
547 if (nTabSize < 0) nTabSize = 0;
549 lcl_SetPosSize( *pTabControl.get(), Point(nPosX, nPosY+nSizeY-nBarY),
550 Size(nTabSize, nBarY), nTotalWidth, bLayoutRTL );
551 nSizeY -= nBarY;
552 lcl_SetPosSize( *aScrollBarBox.get(), Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
553 nTotalWidth, bLayoutRTL );
555 if( bVScroll )
557 Size aVScrSize = aVScrollBottom->GetSizePixel();
558 aVScrSize.Height() -= nBarY;
559 aVScrollBottom->SetSizePixel( aVScrSize );
563 nOutPosX = nPosX;
564 nOutPosY = nPosY;
566 // Outline-Controls
567 if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
569 nOutlineX = pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
570 nSizeX -= nOutlineX;
571 nPosX += nOutlineX;
573 if (bHOutline && pColOutline[SC_SPLIT_LEFT])
575 nOutlineY = pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
576 nSizeY -= nOutlineY;
577 nPosY += nOutlineY;
580 if (bHeaders) // column/row header
582 nBarX = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
583 nBarY = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
584 nSizeX -= nBarX;
585 nSizeY -= nBarY;
586 nPosX += nBarX;
587 nPosY += nBarY;
589 else
590 nBarX = nBarY = 0;
592 // evaluate splitter
594 long nLeftSize = nSizeX;
595 long nRightSize = 0;
596 long nTopSize = 0;
597 long nBottomSize = nSizeY;
598 long nSplitPosX = nPosX;
599 long nSplitPosY = nPosY;
601 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
603 long nSplitHeight = rSize.Height();
604 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
606 // Do not allow freeze splitter to overlap scroll bar/tab bar
607 if ( bHScroll )
608 nSplitHeight -= aHScrollLeft->GetSizePixel().Height();
609 else if ( bTabControl && pTabControl )
610 nSplitHeight -= pTabControl->GetSizePixel().Height();
612 nSplitPosX = aViewData.GetHSplitPos();
613 lcl_SetPosSize( *pHSplitter,
614 Point(nSplitPosX, nOutPosY),
615 Size( nSplitSizeX, nSplitHeight - nTabWidth ), nTotalWidth, bLayoutRTL );
616 nLeftSize = nSplitPosX - nPosX;
617 nSplitPosX += nSplitSizeX;
618 nRightSize = nSizeX - nLeftSize - nSplitSizeX;
620 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
622 long nSplitWidth = rSize.Width();
623 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && bVScroll )
624 nSplitWidth -= aVScrollBottom->GetSizePixel().Width();
625 nSplitPosY = aViewData.GetVSplitPos();
626 lcl_SetPosSize( *pVSplitter,
627 Point( nOutPosX, nSplitPosY ), Size( nSplitWidth, nSplitSizeY ), nTotalWidth, bLayoutRTL );
628 nTopSize = nSplitPosY - nPosY;
629 nSplitPosY += nSplitSizeY;
630 nBottomSize = nSizeY - nTopSize - nSplitSizeY;
633 // ShowHide for pColOutline / pRowOutline happens in UpdateShow
635 if (bHOutline) // Outline-Controls
637 if (pColOutline[SC_SPLIT_LEFT])
639 pColOutline[SC_SPLIT_LEFT]->SetHeaderSize( nBarX );
640 lcl_SetPosSize( *pColOutline[SC_SPLIT_LEFT],
641 Point(nPosX-nBarX,nOutPosY), Size(nLeftSize+nBarX,nOutlineY), nTotalWidth, bLayoutRTL );
643 if (pColOutline[SC_SPLIT_RIGHT])
645 pColOutline[SC_SPLIT_RIGHT]->SetHeaderSize( 0 ); // always call to update RTL flag
646 lcl_SetPosSize( *pColOutline[SC_SPLIT_RIGHT],
647 Point(nSplitPosX,nOutPosY), Size(nRightSize,nOutlineY), nTotalWidth, bLayoutRTL );
650 if (bVOutline)
652 if (nTopSize)
654 if (pRowOutline[SC_SPLIT_TOP] && pRowOutline[SC_SPLIT_BOTTOM])
656 pRowOutline[SC_SPLIT_TOP]->SetHeaderSize( nBarY );
657 lcl_SetPosSize( *pRowOutline[SC_SPLIT_TOP],
658 Point(nOutPosX,nPosY-nBarY), Size(nOutlineX,nTopSize+nBarY), nTotalWidth, bLayoutRTL );
659 pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( 0 );
660 lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
661 Point(nOutPosX,nSplitPosY), Size(nOutlineX,nBottomSize), nTotalWidth, bLayoutRTL );
664 else if (pRowOutline[SC_SPLIT_BOTTOM])
666 pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( nBarY );
667 lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
668 Point(nOutPosX,nSplitPosY-nBarY), Size(nOutlineX,nBottomSize+nBarY), nTotalWidth, bLayoutRTL );
671 if (bHOutline && bVOutline)
673 lcl_SetPosSize( *aTopButton.get(), Point(nOutPosX,nOutPosY), Size(nOutlineX,nOutlineY), nTotalWidth, bLayoutRTL );
674 aTopButton->Show();
676 else
677 aTopButton->Hide();
679 if (bHeaders) // column/row header
681 lcl_SetPosSize( *pColBar[SC_SPLIT_LEFT],
682 Point(nPosX,nPosY-nBarY), Size(nLeftSize,nBarY), nTotalWidth, bLayoutRTL );
683 if (pColBar[SC_SPLIT_RIGHT])
684 lcl_SetPosSize( *pColBar[SC_SPLIT_RIGHT],
685 Point(nSplitPosX,nPosY-nBarY), Size(nRightSize,nBarY), nTotalWidth, bLayoutRTL );
687 if (pRowBar[SC_SPLIT_TOP])
688 lcl_SetPosSize( *pRowBar[SC_SPLIT_TOP],
689 Point(nPosX-nBarX,nPosY), Size(nBarX,nTopSize), nTotalWidth, bLayoutRTL );
690 lcl_SetPosSize( *pRowBar[SC_SPLIT_BOTTOM],
691 Point(nPosX-nBarX,nSplitPosY), Size(nBarX,nBottomSize), nTotalWidth, bLayoutRTL );
693 lcl_SetPosSize( *aCornerButton.get(), Point(nPosX-nBarX,nPosY-nBarY), Size(nBarX,nBarY), nTotalWidth, bLayoutRTL );
694 aCornerButton->Show();
695 pColBar[SC_SPLIT_LEFT]->Show();
696 pRowBar[SC_SPLIT_BOTTOM]->Show();
698 else
700 aCornerButton->Hide();
701 pColBar[SC_SPLIT_LEFT]->Hide(); // always here
702 pRowBar[SC_SPLIT_BOTTOM]->Hide();
705 // Grid-Windows
707 if (bInner)
709 long nInnerPosX = bLayoutRTL ? ( nTotalWidth - nPosX - nLeftSize ) : nPosX;
710 pGridWin[SC_SPLIT_BOTTOMLEFT]->SetPosPixel( Point(nInnerPosX,nSplitPosY) );
712 else
714 lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMLEFT],
715 Point(nPosX,nSplitPosY), Size(nLeftSize,nBottomSize), nTotalWidth, bLayoutRTL );
716 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
717 lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMRIGHT],
718 Point(nSplitPosX,nSplitPosY), Size(nRightSize,nBottomSize), nTotalWidth, bLayoutRTL );
719 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
720 lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPLEFT],
721 Point(nPosX,nPosY), Size(nLeftSize,nTopSize), nTotalWidth, bLayoutRTL );
722 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE && aViewData.GetVSplitMode() != SC_SPLIT_NONE )
723 lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPRIGHT],
724 Point(nSplitPosX,nPosY), Size(nRightSize,nTopSize), nTotalWidth, bLayoutRTL );
727 // update scroll bars
729 if (!bInUpdateHeader)
731 UpdateScrollBars(); // don't reset scroll bars when scrolling
732 UpdateHeaderWidth();
734 InterpretVisible(); // have everything calculated before painting
737 if (bHasHint)
738 TestHintWindow(); // reposition
740 UpdateVarZoom(); // update variable zoom types (after resizing GridWindows)
742 if (aViewData.GetViewShell()->HasAccessibilityObjects())
743 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_WINDOWRESIZED));
746 void ScTabView::UpdateVarZoom()
748 // update variable zoom types
750 SvxZoomType eZoomType = GetZoomType();
751 if ( eZoomType != SvxZoomType::PERCENT && !bInZoomUpdate )
753 bInZoomUpdate = true;
754 const Fraction& rOldX = GetViewData().GetZoomX();
755 const Fraction& rOldY = GetViewData().GetZoomY();
756 long nOldPercent = ( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator();
757 sal_uInt16 nNewZoom = CalcZoom( eZoomType, (sal_uInt16)nOldPercent );
758 Fraction aNew( nNewZoom, 100 );
760 if ( aNew != rOldX || aNew != rOldY )
762 SetZoom( aNew, aNew, false ); // always separately per sheet
763 PaintGrid();
764 PaintTop();
765 PaintLeft();
766 aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
767 aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
769 bInZoomUpdate = false;
773 void ScTabView::UpdateFixPos()
775 bool bResize = false;
776 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
777 if (aViewData.UpdateFixX())
778 bResize = true;
779 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
780 if (aViewData.UpdateFixY())
781 bResize = true;
782 if (bResize)
783 RepeatResize(false);
786 void ScTabView::RepeatResize( bool bUpdateFix )
788 if ( bUpdateFix )
790 ScSplitMode eHSplit = aViewData.GetHSplitMode();
791 ScSplitMode eVSplit = aViewData.GetVSplitMode();
793 // #i46796# UpdateFixX / UpdateFixY uses GetGridOffset, which requires the
794 // outline windows to be available. So UpdateShow has to be called before
795 // (also called from DoResize).
796 if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX )
797 UpdateShow();
799 if ( eHSplit == SC_SPLIT_FIX )
800 aViewData.UpdateFixX();
801 if ( eVSplit == SC_SPLIT_FIX )
802 aViewData.UpdateFixY();
805 DoResize( aBorderPos, aFrameSize );
807 //! border must be reset ???
810 void ScTabView::GetBorderSize( SvBorder& rBorder, const Size& /* rSize */ )
812 bool bScrollBars = aViewData.IsVScrollMode();
813 bool bHeaders = aViewData.IsHeaderMode();
814 bool bOutlMode = aViewData.IsOutlineMode();
815 bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
816 bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
817 bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
819 rBorder = SvBorder();
821 if (bScrollBars) // Scrollbars horizontal or vertical
823 rBorder.Right() += aVScrollBottom->GetSizePixel().Width();
824 rBorder.Bottom() += aHScrollLeft->GetSizePixel().Height();
827 // Outline-Controls
828 if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
829 rBorder.Left() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
830 if (bHOutline && pColOutline[SC_SPLIT_LEFT])
831 rBorder.Top() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
833 if (bHeaders) // column/row headers
835 rBorder.Left() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
836 rBorder.Top() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
839 if ( bLayoutRTL )
840 ::std::swap( rBorder.Left(), rBorder.Right() );
843 IMPL_LINK_NOARG_TYPED(ScTabView, TabBarResize, TabBar*, void)
845 if (aViewData.IsHScrollMode())
847 const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel();
848 long nSize = pTabControl->GetSplitSize();
850 if (aViewData.GetHSplitMode() != SC_SPLIT_FIX)
852 long nMax = pHSplitter->GetPosPixel().X();
853 if( pTabControl->IsEffectiveRTL() )
854 nMax = pFrameWin->GetSizePixel().Width() - nMax;
855 --nMax;
856 if (nSize>nMax) nSize = nMax;
859 if ( nSize != pTabControl->GetSizePixel().Width() )
861 pTabControl->SetSizePixel( Size( nSize+nOverlap,
862 pTabControl->GetSizePixel().Height() ) );
863 RepeatResize();
868 void ScTabView::SetTabBarWidth( long nNewWidth )
870 Size aSize = pTabControl->GetSizePixel();
872 if ( aSize.Width() != nNewWidth )
874 aSize.Width() = nNewWidth;
875 pTabControl->SetSizePixel( aSize );
879 void ScTabView::SetRelTabBarWidth( double fRelTabBarWidth )
881 if( (0.0 <= fRelTabBarWidth) && (fRelTabBarWidth <= 1.0) )
882 if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
883 SetTabBarWidth( static_cast< long >( fRelTabBarWidth * nFrameWidth + 0.5 ) );
886 void ScTabView::SetPendingRelTabBarWidth( double fRelTabBarWidth )
888 mfPendingTabBarWidth = fRelTabBarWidth;
889 SetRelTabBarWidth( fRelTabBarWidth );
892 long ScTabView::GetTabBarWidth() const
894 return pTabControl->GetSizePixel().Width();
897 double ScTabView::GetRelTabBarWidth() const
899 return 0.5;
902 ScGridWindow* ScTabView::GetActiveWin()
904 ScSplitPos ePos = aViewData.GetActivePart();
905 OSL_ENSURE(pGridWin[ePos],"no active window");
906 return pGridWin[ePos];
909 void ScTabView::SetActivePointer( const Pointer& rPointer )
911 for (VclPtr<ScGridWindow> & pWin : pGridWin)
912 if (pWin)
913 pWin->SetPointer( rPointer );
916 void ScTabView::ActiveGrabFocus()
918 ScSplitPos ePos = aViewData.GetActivePart();
919 if (pGridWin[ePos])
920 pGridWin[ePos]->GrabFocus();
923 ScSplitPos ScTabView::FindWindow( vcl::Window* pWindow ) const
925 ScSplitPos eVal = SC_SPLIT_BOTTOMLEFT; // Default
926 for (sal_uInt16 i=0; i<4; i++)
927 if ( pGridWin[i] == pWindow )
928 eVal = (ScSplitPos) i;
930 return eVal;
933 Point ScTabView::GetGridOffset() const
935 Point aPos;
937 // size as in DoResize
939 bool bHeaders = aViewData.IsHeaderMode();
940 bool bOutlMode = aViewData.IsOutlineMode();
941 bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
942 bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
944 // Outline-Controls
945 if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
946 aPos.X() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
947 if (bHOutline && pColOutline[SC_SPLIT_LEFT])
948 aPos.Y() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
950 if (bHeaders) // column/row headers
952 if (pRowBar[SC_SPLIT_BOTTOM])
953 aPos.X() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
954 if (pColBar[SC_SPLIT_LEFT])
955 aPos.Y() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
958 return aPos;
961 // --- Scroll-Bars --------------------------------------------------------
963 bool ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos )
965 HideNoteMarker();
967 bool bDone = false;
968 const CommandWheelData* pData = rCEvt.GetWheelData();
969 if ( pData && (pData->GetMode() == CommandWheelMode::ZOOM ||
970 pData->GetMode() == CommandWheelMode::ZOOM_SCALE ) )
972 if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() )
974 // for ole inplace editing, the scale is defined by the visarea and client size
975 // and can't be changed directly
977 const Fraction& rOldY = aViewData.GetZoomY();
978 long nOld = (long)(( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator());
979 long nNew;
980 if ( pData->GetMode() == CommandWheelMode::ZOOM_SCALE )
982 nNew = 100 * (long) ((nOld / 100.0) * (pData->GetDelta() / 100.0));
983 } else
985 if ( pData->GetDelta() < 0 )
986 nNew = std::max( (long) MINZOOM, basegfx::zoomtools::zoomOut( nOld ));
987 else
988 nNew = std::min( (long) MAXZOOM, basegfx::zoomtools::zoomIn( nOld ));
990 if ( nNew != nOld )
992 // scroll wheel doesn't set the AppOptions default
994 bool bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
995 SetZoomType( SvxZoomType::PERCENT, bSyncZoom );
996 Fraction aFract( nNew, 100 );
997 SetZoom( aFract, aFract, bSyncZoom );
998 PaintGrid();
999 PaintTop();
1000 PaintLeft();
1001 aViewData.GetBindings().Invalidate( SID_ATTR_ZOOM );
1002 aViewData.GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
1005 bDone = true;
1008 else
1010 ScHSplitPos eHPos = WhichH(ePos);
1011 ScVSplitPos eVPos = WhichV(ePos);
1012 ScrollBar* pHScroll = ( eHPos == SC_SPLIT_LEFT ) ? aHScrollLeft.get() : aHScrollRight.get();
1013 ScrollBar* pVScroll = ( eVPos == SC_SPLIT_TOP ) ? aVScrollTop.get() : aVScrollBottom.get();
1014 if ( pGridWin[ePos] )
1015 bDone = pGridWin[ePos]->HandleScrollCommand( rCEvt, pHScroll, pVScroll );
1017 return bDone;
1020 IMPL_LINK_NOARG_TYPED(ScTabView, EndScrollHdl, ScrollBar*, void)
1022 if ( bDragging )
1024 UpdateScrollBars();
1025 bDragging = false;
1029 IMPL_LINK_TYPED( ScTabView, ScrollHdl, ScrollBar*, pScroll, void )
1031 bool bHoriz = ( pScroll == aHScrollLeft.get() || pScroll == aHScrollRight.get() );
1032 long nViewPos;
1033 if ( bHoriz )
1034 nViewPos = aViewData.GetPosX( (pScroll == aHScrollLeft.get()) ?
1035 SC_SPLIT_LEFT : SC_SPLIT_RIGHT );
1036 else
1037 nViewPos = aViewData.GetPosY( (pScroll == aVScrollTop.get()) ?
1038 SC_SPLIT_TOP : SC_SPLIT_BOTTOM );
1040 bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1042 ScrollType eType = pScroll->GetType();
1043 if ( eType == SCROLL_DRAG )
1045 if (!bDragging)
1047 bDragging = true;
1048 nPrevDragPos = nViewPos;
1051 // show scroll position
1052 // (only QuickHelp, there is no entry for it in the status bar)
1054 if (Help::IsQuickHelpEnabled())
1056 Size aSize = pScroll->GetSizePixel();
1058 /* Convert scrollbar mouse position to screen position. If RTL
1059 mode of scrollbar differs from RTL mode of its parent, then the
1060 direct call to Window::OutputToNormalizedScreenPixel() will
1061 give unusable results, because calculation of screen position
1062 is based on parent orientation and expects equal orientation of
1063 the child position. Need to mirror mouse position before. */
1064 Point aMousePos = pScroll->GetPointerPosPixel();
1065 if( pScroll->IsRTLEnabled() != pScroll->GetParent()->IsRTLEnabled() )
1066 aMousePos.X() = aSize.Width() - aMousePos.X() - 1;
1067 aMousePos = pScroll->OutputToNormalizedScreenPixel( aMousePos );
1069 // convert top-left position of scrollbar to screen position
1070 Point aPos = pScroll->OutputToNormalizedScreenPixel( Point() );
1072 // get scrollbar scroll position for help text (row number/column name)
1073 long nScrollMin = 0; // simulate RangeMin
1074 if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == aHScrollRight.get() )
1075 nScrollMin = aViewData.GetFixPosX();
1076 if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == aVScrollBottom.get() )
1077 nScrollMin = aViewData.GetFixPosY();
1078 long nScrollPos = GetScrollBarPos( *pScroll ) + nScrollMin;
1080 OUString aHelpStr;
1081 Rectangle aRect;
1082 QuickHelpFlags nAlign;
1083 if (bHoriz)
1085 aHelpStr = ScGlobal::GetRscString(STR_COLUMN) +
1086 " " + ScColToAlpha((SCCOL) nScrollPos);
1088 aRect.Left() = aMousePos.X();
1089 aRect.Top() = aPos.Y() - 4;
1090 nAlign = QuickHelpFlags::Bottom|QuickHelpFlags::Center;
1092 else
1094 aHelpStr = ScGlobal::GetRscString(STR_ROW) +
1095 " " + OUString::number(nScrollPos + 1);
1097 // show quicktext always inside sheet area
1098 aRect.Left() = bLayoutRTL ? (aPos.X() + aSize.Width() + 8) : (aPos.X() - 8);
1099 aRect.Top() = aMousePos.Y();
1100 nAlign = (bLayoutRTL ? QuickHelpFlags::Left : QuickHelpFlags::Right) | QuickHelpFlags::VCenter;
1102 aRect.Right() = aRect.Left();
1103 aRect.Bottom() = aRect.Top();
1105 Help::ShowQuickHelp(pScroll->GetParent(), aRect, aHelpStr, nAlign);
1109 long nDelta = pScroll->GetDelta();
1110 switch ( eType )
1112 case SCROLL_LINEUP:
1113 nDelta = -1;
1114 break;
1115 case SCROLL_LINEDOWN:
1116 nDelta = 1;
1117 break;
1118 case SCROLL_PAGEUP:
1119 if ( pScroll == aHScrollLeft.get() ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_LEFT );
1120 if ( pScroll == aHScrollRight.get() ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_RIGHT );
1121 if ( pScroll == aVScrollTop.get() ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_TOP );
1122 if ( pScroll == aVScrollBottom.get() ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_BOTTOM );
1123 if (nDelta==0) nDelta=-1;
1124 break;
1125 case SCROLL_PAGEDOWN:
1126 if ( pScroll == aHScrollLeft.get() ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_LEFT );
1127 if ( pScroll == aHScrollRight.get() ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_RIGHT );
1128 if ( pScroll == aVScrollTop.get() ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_TOP );
1129 if ( pScroll == aVScrollBottom.get() ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM );
1130 if (nDelta==0) nDelta=1;
1131 break;
1132 case SCROLL_DRAG:
1134 // only scroll in the correct direction, do not jitter around hidden ranges
1135 long nScrollMin = 0; // simulate RangeMin
1136 if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == aHScrollRight.get() )
1137 nScrollMin = aViewData.GetFixPosX();
1138 if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == aVScrollBottom.get() )
1139 nScrollMin = aViewData.GetFixPosY();
1141 long nScrollPos = GetScrollBarPos( *pScroll ) + nScrollMin;
1142 nDelta = nScrollPos - nViewPos;
1143 if ( nScrollPos > nPrevDragPos )
1145 if (nDelta<0) nDelta=0;
1147 else if ( nScrollPos < nPrevDragPos )
1149 if (nDelta>0) nDelta=0;
1151 else
1152 nDelta = 0;
1153 nPrevDragPos = nScrollPos;
1155 break;
1156 default:
1158 // added to avoid warnings
1162 if (nDelta)
1164 bool bUpdate = ( eType != SCROLL_DRAG ); // don't alter the ranges while dragging
1165 if ( bHoriz )
1166 ScrollX( nDelta, (pScroll == aHScrollLeft.get()) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT, bUpdate );
1167 else
1168 ScrollY( nDelta, (pScroll == aVScrollTop.get()) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM, bUpdate );
1172 void ScTabView::ScrollX( long nDeltaX, ScHSplitPos eWhich, bool bUpdBars )
1174 SCCOL nOldX = aViewData.GetPosX(eWhich);
1175 SCsCOL nNewX = static_cast<SCsCOL>(nOldX) + static_cast<SCsCOL>(nDeltaX);
1176 if ( nNewX < 0 )
1178 nDeltaX -= nNewX;
1179 nNewX = 0;
1181 if ( nNewX > MAXCOL )
1183 nDeltaX -= nNewX - MAXCOL;
1184 nNewX = MAXCOL;
1187 SCsCOL nDir = ( nDeltaX > 0 ) ? 1 : -1;
1188 ScDocument* pDoc = aViewData.GetDocument();
1189 SCTAB nTab = aViewData.GetTabNo();
1190 while ( pDoc->ColHidden(nNewX, nTab) &&
1191 nNewX+nDir >= 0 && nNewX+nDir <= MAXCOL )
1192 nNewX = sal::static_int_cast<SCsCOL>( nNewX + nDir );
1194 // freeze
1196 if (aViewData.GetHSplitMode() == SC_SPLIT_FIX)
1198 if (eWhich == SC_SPLIT_LEFT)
1199 nNewX = static_cast<SCsCOL>(nOldX); // always keep the left part
1200 else
1202 SCsCOL nFixX = static_cast<SCsCOL>(aViewData.GetFixPosX());
1203 if (nNewX < nFixX)
1204 nNewX = nFixX;
1207 if (nNewX == static_cast<SCsCOL>(nOldX))
1208 return;
1210 HideAllCursors();
1212 if ( nNewX >= 0 && nNewX <= MAXCOL && nDeltaX )
1214 SCCOL nTrackX = std::max( nOldX, static_cast<SCCOL>(nNewX) );
1216 // with VCL Update() affects all windows at the moment, that is why
1217 // calling Update after scrolling of the GridWindow would possibly
1218 // already have painted the column/row bar with updated position. -
1219 // Therefore call Update once before on column/row bar
1220 if (pColBar[eWhich])
1221 pColBar[eWhich]->Update();
1223 long nOldPos = aViewData.GetScrPos( nTrackX, 0, eWhich ).X();
1224 aViewData.SetPosX( eWhich, static_cast<SCCOL>(nNewX) );
1225 long nDiff = aViewData.GetScrPos( nTrackX, 0, eWhich ).X() - nOldPos;
1227 if ( eWhich==SC_SPLIT_LEFT )
1229 pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( nDiff, 0 );
1230 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
1231 pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( nDiff, 0 );
1233 else
1235 pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( nDiff, 0 );
1236 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
1237 pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( nDiff, 0 );
1239 if (pColBar[eWhich]) { pColBar[eWhich]->Scroll( nDiff,0 ); pColBar[eWhich]->Update(); }
1240 if (pColOutline[eWhich]) pColOutline[eWhich]->ScrollPixel( nDiff );
1241 if (bUpdBars)
1242 UpdateScrollBars();
1245 if (nDeltaX==1 || nDeltaX==-1)
1246 pGridWin[aViewData.GetActivePart()]->Update();
1248 ShowAllCursors();
1250 SetNewVisArea(); // MapMode must already be set
1252 TestHintWindow();
1255 void ScTabView::ScrollY( long nDeltaY, ScVSplitPos eWhich, bool bUpdBars )
1257 SCROW nOldY = aViewData.GetPosY(eWhich);
1258 SCsROW nNewY = static_cast<SCsROW>(nOldY) + static_cast<SCsROW>(nDeltaY);
1259 if ( nNewY < 0 )
1261 nDeltaY -= nNewY;
1262 nNewY = 0;
1264 if ( nNewY > MAXROW )
1266 nDeltaY -= nNewY - MAXROW;
1267 nNewY = MAXROW;
1270 SCsROW nDir = ( nDeltaY > 0 ) ? 1 : -1;
1271 ScDocument* pDoc = aViewData.GetDocument();
1272 SCTAB nTab = aViewData.GetTabNo();
1273 while ( pDoc->RowHidden(nNewY, nTab) &&
1274 nNewY+nDir >= 0 && nNewY+nDir <= MAXROW )
1275 nNewY += nDir;
1277 // freeze
1279 if (aViewData.GetVSplitMode() == SC_SPLIT_FIX)
1281 if (eWhich == SC_SPLIT_TOP)
1282 nNewY = static_cast<SCsROW>(nOldY); // always keep the upper part
1283 else
1285 SCsROW nFixY = static_cast<SCsROW>(aViewData.GetFixPosY());
1286 if (nNewY < nFixY)
1287 nNewY = nFixY;
1290 if (nNewY == static_cast<SCsROW>(nOldY))
1291 return;
1293 HideAllCursors();
1295 if ( nNewY >= 0 && nNewY <= MAXROW && nDeltaY )
1297 SCROW nTrackY = std::max( nOldY, static_cast<SCROW>(nNewY) );
1299 // adjust row headers before the actual scrolling, so it does not get painted twice
1300 // PosY may then also not be set yet, pass on new value
1301 SCROW nUNew = static_cast<SCROW>(nNewY);
1302 UpdateHeaderWidth( &eWhich, &nUNew ); // adjust row headers
1304 if (pRowBar[eWhich])
1305 pRowBar[eWhich]->Update();
1307 long nOldPos = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y();
1308 aViewData.SetPosY( eWhich, static_cast<SCROW>(nNewY) );
1309 long nDiff = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y() - nOldPos;
1311 if ( eWhich==SC_SPLIT_TOP )
1313 pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( 0, nDiff );
1314 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
1315 pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( 0, nDiff );
1317 else
1319 pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( 0, nDiff );
1320 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
1321 pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( 0, nDiff );
1323 if (pRowBar[eWhich]) { pRowBar[eWhich]->Scroll( 0,nDiff ); pRowBar[eWhich]->Update(); }
1324 if (pRowOutline[eWhich]) pRowOutline[eWhich]->ScrollPixel( nDiff );
1325 if (bUpdBars)
1326 UpdateScrollBars();
1329 if (nDeltaY==1 || nDeltaY==-1)
1330 pGridWin[aViewData.GetActivePart()]->Update();
1332 ShowAllCursors();
1334 SetNewVisArea(); // MapMode must already be set
1336 TestHintWindow();
1339 void ScTabView::ScrollLines( long nDeltaX, long nDeltaY )
1341 ScSplitPos eWhich = aViewData.GetActivePart();
1342 if (nDeltaX)
1343 ScrollX(nDeltaX,WhichH(eWhich));
1344 if (nDeltaY)
1345 ScrollY(nDeltaY,WhichV(eWhich));
1348 namespace
1351 SCROW lcl_LastVisible( ScViewData& rViewData )
1353 // If many rows are hidden at end of the document (what kind of idiot does that?),
1354 // then there should not be a switch to wide row headers because of this
1355 //! as a member to the document???
1356 ScDocument* pDoc = rViewData.GetDocument();
1357 SCTAB nTab = rViewData.GetTabNo();
1359 SCROW nVis = MAXROW;
1360 while ( nVis > 0 && pDoc->GetRowHeight( nVis, nTab ) == 0 )
1361 --nVis;
1362 return nVis;
1365 } // anonymous namespace
1367 void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY )
1369 if ( !pRowBar[SC_SPLIT_BOTTOM] || MAXROW < 10000 )
1370 return;
1372 SCROW nEndPos = MAXROW;
1373 if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() )
1375 // for OLE Inplace always MAXROW
1377 if ( pWhich && *pWhich == SC_SPLIT_BOTTOM && pPosY )
1378 nEndPos = *pPosY;
1379 else
1380 nEndPos = aViewData.GetPosY( SC_SPLIT_BOTTOM );
1381 nEndPos += aViewData.CellsAtY( nEndPos, 1, SC_SPLIT_BOTTOM ); // VisibleCellsY
1382 if (nEndPos > MAXROW)
1383 nEndPos = lcl_LastVisible( aViewData );
1385 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
1387 SCROW nTopEnd;
1388 if ( pWhich && *pWhich == SC_SPLIT_TOP && pPosY )
1389 nTopEnd = *pPosY;
1390 else
1391 nTopEnd = aViewData.GetPosY( SC_SPLIT_TOP );
1392 nTopEnd += aViewData.CellsAtY( nTopEnd, 1, SC_SPLIT_TOP );// VisibleCellsY
1393 if (nTopEnd > MAXROW)
1394 nTopEnd = lcl_LastVisible( aViewData );
1396 if ( nTopEnd > nEndPos )
1397 nEndPos = nTopEnd;
1401 long nSmall = pRowBar[SC_SPLIT_BOTTOM]->GetSmallWidth();
1402 long nBig = pRowBar[SC_SPLIT_BOTTOM]->GetBigWidth();
1403 long nDiff = nBig - nSmall;
1405 if (nEndPos>10000)
1406 nEndPos = 10000;
1407 else if (nEndPos<1) // avoid extra step at 0 (when only one row is visible)
1408 nEndPos = 1;
1409 long nWidth = nBig - ( 10000 - nEndPos ) * nDiff / 10000;
1411 if ( nWidth != pRowBar[SC_SPLIT_BOTTOM]->GetWidth() && !bInUpdateHeader )
1413 bInUpdateHeader = true;
1415 pRowBar[SC_SPLIT_BOTTOM]->SetWidth( nWidth );
1416 if (pRowBar[SC_SPLIT_TOP])
1417 pRowBar[SC_SPLIT_TOP]->SetWidth( nWidth );
1419 RepeatResize();
1421 // on VCL there are endless updates (each Update is valid for all windows)
1422 //aCornerButton->Update(); // otherwise this never gets an Update
1424 bInUpdateHeader = false;
1428 inline void ShowHide( vcl::Window* pWin, bool bShow )
1430 OSL_ENSURE(pWin || !bShow, "window is not present");
1431 if (pWin)
1432 pWin->Show(bShow);
1435 void ScTabView::UpdateShow()
1437 bool bHScrollMode = aViewData.IsHScrollMode();
1438 bool bVScrollMode = aViewData.IsVScrollMode();
1439 bool bTabMode = aViewData.IsTabMode();
1440 bool bOutlMode = aViewData.IsOutlineMode();
1441 bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
1442 bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
1443 bool bHeader = aViewData.IsHeaderMode();
1445 bool bShowH = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE );
1446 bool bShowV = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE );
1448 if ( aViewData.GetDocShell()->IsPreview() )
1449 bHScrollMode = bVScrollMode = bTabMode = bHeader = bHOutline = bVOutline = false;
1451 // create Windows
1453 if (bShowH && !pGridWin[SC_SPLIT_BOTTOMRIGHT])
1455 pGridWin[SC_SPLIT_BOTTOMRIGHT] = VclPtr<ScGridWindow>::Create( pFrameWin, &aViewData, SC_SPLIT_BOTTOMRIGHT );
1456 DoAddWin( pGridWin[SC_SPLIT_BOTTOMRIGHT] );
1458 if (bShowV && !pGridWin[SC_SPLIT_TOPLEFT])
1460 pGridWin[SC_SPLIT_TOPLEFT] = VclPtr<ScGridWindow>::Create( pFrameWin, &aViewData, SC_SPLIT_TOPLEFT );
1461 DoAddWin( pGridWin[SC_SPLIT_TOPLEFT] );
1463 if (bShowH && bShowV && !pGridWin[SC_SPLIT_TOPRIGHT])
1465 pGridWin[SC_SPLIT_TOPRIGHT] = VclPtr<ScGridWindow>::Create( pFrameWin, &aViewData, SC_SPLIT_TOPRIGHT );
1466 DoAddWin( pGridWin[SC_SPLIT_TOPRIGHT] );
1469 if (bHOutline && !pColOutline[SC_SPLIT_LEFT])
1470 pColOutline[SC_SPLIT_LEFT] = VclPtr<ScOutlineWindow>::Create( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMLEFT );
1471 if (bShowH && bHOutline && !pColOutline[SC_SPLIT_RIGHT])
1472 pColOutline[SC_SPLIT_RIGHT] = VclPtr<ScOutlineWindow>::Create( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMRIGHT );
1474 if (bVOutline && !pRowOutline[SC_SPLIT_BOTTOM])
1475 pRowOutline[SC_SPLIT_BOTTOM] = VclPtr<ScOutlineWindow>::Create( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_BOTTOMLEFT );
1476 if (bShowV && bVOutline && !pRowOutline[SC_SPLIT_TOP])
1477 pRowOutline[SC_SPLIT_TOP] = VclPtr<ScOutlineWindow>::Create( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_TOPLEFT );
1479 if (bShowH && bHeader && !pColBar[SC_SPLIT_RIGHT])
1480 pColBar[SC_SPLIT_RIGHT] = VclPtr<ScColBar>::Create( pFrameWin, SC_SPLIT_RIGHT,
1481 &aHdrFunc, pHdrSelEng, this );
1482 if (bShowV && bHeader && !pRowBar[SC_SPLIT_TOP])
1483 pRowBar[SC_SPLIT_TOP] = VclPtr<ScRowBar>::Create( pFrameWin, SC_SPLIT_TOP,
1484 &aHdrFunc, pHdrSelEng, this );
1486 // show Windows
1488 ShowHide( aHScrollLeft.get(), bHScrollMode );
1489 ShowHide( aHScrollRight.get(), bShowH && bHScrollMode );
1490 ShowHide( aVScrollBottom.get(), bVScrollMode );
1491 ShowHide( aVScrollTop.get(), bShowV && bVScrollMode );
1492 ShowHide( aScrollBarBox.get(), bVScrollMode || bHScrollMode );
1494 ShowHide( pHSplitter, bHScrollMode || bShowH ); // always generated
1495 ShowHide( pVSplitter, bVScrollMode || bShowV );
1496 ShowHide( pTabControl, bTabMode );
1498 // from here dynamically generated
1500 ShowHide( pGridWin[SC_SPLIT_BOTTOMRIGHT], bShowH );
1501 ShowHide( pGridWin[SC_SPLIT_TOPLEFT], bShowV );
1502 ShowHide( pGridWin[SC_SPLIT_TOPRIGHT], bShowH && bShowV );
1504 ShowHide( pColOutline[SC_SPLIT_LEFT], bHOutline );
1505 ShowHide( pColOutline[SC_SPLIT_RIGHT], bShowH && bHOutline );
1507 ShowHide( pRowOutline[SC_SPLIT_BOTTOM], bVOutline );
1508 ShowHide( pRowOutline[SC_SPLIT_TOP], bShowV && bVOutline );
1510 ShowHide( pColBar[SC_SPLIT_RIGHT], bShowH && bHeader );
1511 ShowHide( pRowBar[SC_SPLIT_TOP], bShowV && bHeader );
1513 //! register new Gridwindows
1516 bool ScTabView::UpdateVisibleRange()
1518 bool bChanged = false;
1519 for (VclPtr<ScGridWindow> & pWin : pGridWin)
1521 if (!pWin || !pWin->IsVisible())
1522 continue;
1524 if (pWin->UpdateVisibleRange())
1525 bChanged = true;
1528 return bChanged;
1531 // --- Splitter --------------------------------------------------------
1533 IMPL_LINK_TYPED( ScTabView, SplitHdl, Splitter*, pSplitter, void )
1535 if ( pSplitter == pHSplitter )
1536 DoHSplit( pHSplitter->GetSplitPosPixel() );
1537 else
1538 DoVSplit( pVSplitter->GetSplitPosPixel() );
1540 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1541 FreezeSplitters( true );
1543 DoResize( aBorderPos, aFrameSize );
1546 void ScTabView::DoHSplit(long nSplitPos)
1548 // nSplitPos is the real pixel position on the frame window,
1549 // mirroring for RTL has to be done here.
1551 bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1552 if ( bLayoutRTL )
1553 nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
1555 long nMinPos;
1556 long nMaxPos;
1557 SCCOL nOldDelta;
1558 SCCOL nNewDelta;
1560 nMinPos = SPLIT_MARGIN;
1561 if ( pRowBar[SC_SPLIT_BOTTOM] && pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() >= nMinPos )
1562 nMinPos = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() + 1;
1563 nMaxPos = aFrameSize.Width() - SPLIT_MARGIN;
1565 ScSplitMode aOldMode = aViewData.GetHSplitMode();
1566 ScSplitMode aNewMode = SC_SPLIT_NORMAL;
1568 aViewData.SetHSplitPos( nSplitPos );
1569 if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
1570 aNewMode = SC_SPLIT_NONE;
1572 aViewData.SetHSplitMode( aNewMode );
1574 if ( aNewMode != aOldMode )
1576 UpdateShow(); // before ActivatePart !!
1578 if ( aNewMode == SC_SPLIT_NONE )
1580 if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
1581 ActivatePart( SC_SPLIT_TOPLEFT );
1582 if (aViewData.GetActivePart() == SC_SPLIT_BOTTOMRIGHT)
1583 ActivatePart( SC_SPLIT_BOTTOMLEFT );
1585 else
1587 nOldDelta = aViewData.GetPosX( SC_SPLIT_LEFT );
1588 long nLeftWidth = nSplitPos - pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
1589 if ( nLeftWidth < 0 ) nLeftWidth = 0;
1590 nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, SC_SPLIT_LEFT,
1591 (sal_uInt16) nLeftWidth );
1592 if ( nNewDelta > MAXCOL )
1593 nNewDelta = MAXCOL;
1594 aViewData.SetPosX( SC_SPLIT_RIGHT, nNewDelta );
1595 if ( nNewDelta > aViewData.GetCurX() )
1596 ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
1597 SC_SPLIT_BOTTOMLEFT : SC_SPLIT_TOPLEFT );
1598 else
1599 ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
1600 SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_TOPRIGHT );
1603 // Form Layer needs to know the visible part of all windows
1604 // that is why MapMode must already be correct here
1605 for (VclPtr<ScGridWindow> & pWin : pGridWin)
1606 if (pWin)
1607 pWin->SetMapMode( pWin->GetDrawMapMode() );
1608 SetNewVisArea();
1610 PaintGrid();
1611 PaintTop();
1613 InvalidateSplit();
1617 void ScTabView::DoVSplit(long nSplitPos)
1619 long nMinPos;
1620 long nMaxPos;
1621 SCROW nOldDelta;
1622 SCROW nNewDelta;
1624 nMinPos = SPLIT_MARGIN;
1625 if ( pColBar[SC_SPLIT_LEFT] && pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() >= nMinPos )
1626 nMinPos = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() + 1;
1627 nMaxPos = aFrameSize.Height() - SPLIT_MARGIN;
1629 ScSplitMode aOldMode = aViewData.GetVSplitMode();
1630 ScSplitMode aNewMode = SC_SPLIT_NORMAL;
1632 aViewData.SetVSplitPos( nSplitPos );
1633 if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
1634 aNewMode = SC_SPLIT_NONE;
1636 aViewData.SetVSplitMode( aNewMode );
1638 if ( aNewMode != aOldMode )
1640 UpdateShow(); // before ActivatePart !!
1642 if ( aNewMode == SC_SPLIT_NONE )
1644 nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
1645 aViewData.SetPosY( SC_SPLIT_BOTTOM, nOldDelta );
1647 if (aViewData.GetActivePart() == SC_SPLIT_TOPLEFT)
1648 ActivatePart( SC_SPLIT_BOTTOMLEFT );
1649 if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
1650 ActivatePart( SC_SPLIT_BOTTOMRIGHT );
1652 else
1654 if ( aOldMode == SC_SPLIT_NONE )
1655 nOldDelta = aViewData.GetPosY( SC_SPLIT_BOTTOM );
1656 else
1657 nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
1659 aViewData.SetPosY( SC_SPLIT_TOP, nOldDelta );
1660 long nTopHeight = nSplitPos - pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
1661 if ( nTopHeight < 0 ) nTopHeight = 0;
1662 nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, SC_SPLIT_TOP,
1663 (sal_uInt16) nTopHeight );
1664 if ( nNewDelta > MAXROW )
1665 nNewDelta = MAXROW;
1666 aViewData.SetPosY( SC_SPLIT_BOTTOM, nNewDelta );
1667 if ( nNewDelta > aViewData.GetCurY() )
1668 ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
1669 SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
1670 else
1671 ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
1672 SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
1675 // Form Layer needs to know the visible part of all windows
1676 // that is why MapMode must already be correct here
1677 for (VclPtr<ScGridWindow> & pWin : pGridWin)
1678 if (pWin)
1679 pWin->SetMapMode( pWin->GetDrawMapMode() );
1680 SetNewVisArea();
1682 PaintGrid();
1683 PaintLeft();
1685 InvalidateSplit();
1689 Point ScTabView::GetInsertPos()
1691 ScDocument* pDoc = aViewData.GetDocument();
1692 SCCOL nCol = aViewData.GetCurX();
1693 SCROW nRow = aViewData.GetCurY();
1694 SCTAB nTab = aViewData.GetTabNo();
1695 long nPosX = 0;
1696 for (SCCOL i=0; i<nCol; i++)
1697 nPosX += pDoc->GetColWidth(i,nTab);
1698 nPosX = (long)(nPosX * HMM_PER_TWIPS);
1699 if ( pDoc->IsNegativePage( nTab ) )
1700 nPosX = -nPosX;
1701 long nPosY = (long) pDoc->GetRowHeight( 0, nRow-1, nTab);
1702 nPosY = (long)(nPosY * HMM_PER_TWIPS);
1703 return Point(nPosX,nPosY);
1706 Point ScTabView::GetChartInsertPos( const Size& rSize, const ScRange& rCellRange )
1708 Point aInsertPos;
1709 const long nBorder = 100; // leave 1mm for border
1710 long nNeededWidth = rSize.Width() + 2 * nBorder;
1711 long nNeededHeight = rSize.Height() + 2 * nBorder;
1713 // use the active window, or lower/right if frozen (as in CalcZoom)
1714 ScSplitPos eUsedPart = aViewData.GetActivePart();
1715 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1716 eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
1717 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1718 eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1720 ScGridWindow* pWin = pGridWin[eUsedPart];
1721 OSL_ENSURE( pWin, "Window not found" );
1722 if (pWin)
1724 ActivatePart( eUsedPart );
1726 // get the visible rectangle in logic units
1728 MapMode aDrawMode = pWin->GetDrawMapMode();
1729 Rectangle aVisible( pWin->PixelToLogic( Rectangle( Point(0,0), pWin->GetOutputSizePixel() ), aDrawMode ) );
1731 ScDocument* pDoc = aViewData.GetDocument();
1732 SCTAB nTab = aViewData.GetTabNo();
1733 bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1734 long nLayoutSign = bLayoutRTL ? -1 : 1;
1736 long nDocX = (long)( (double) pDoc->GetColOffset( MAXCOL + 1, nTab ) * HMM_PER_TWIPS ) * nLayoutSign;
1737 long nDocY = (long)( (double) pDoc->GetRowOffset( MAXROW + 1, nTab ) * HMM_PER_TWIPS );
1739 if ( aVisible.Left() * nLayoutSign > nDocX * nLayoutSign )
1740 aVisible.Left() = nDocX;
1741 if ( aVisible.Right() * nLayoutSign > nDocX * nLayoutSign )
1742 aVisible.Right() = nDocX;
1743 if ( aVisible.Top() > nDocY )
1744 aVisible.Top() = nDocY;
1745 if ( aVisible.Bottom() > nDocY )
1746 aVisible.Bottom() = nDocY;
1748 // get the logic position of the selection
1750 Rectangle aSelection = pDoc->GetMMRect( rCellRange.aStart.Col(), rCellRange.aStart.Row(),
1751 rCellRange.aEnd.Col(), rCellRange.aEnd.Row(), nTab );
1753 long nLeftSpace = aSelection.Left() - aVisible.Left();
1754 long nRightSpace = aVisible.Right() - aSelection.Right();
1755 long nTopSpace = aSelection.Top() - aVisible.Top();
1756 long nBottomSpace = aVisible.Bottom() - aSelection.Bottom();
1758 bool bFitLeft = ( nLeftSpace >= nNeededWidth );
1759 bool bFitRight = ( nRightSpace >= nNeededWidth );
1761 if ( bFitLeft || bFitRight )
1763 // first preference: completely left or right of the selection
1765 // if both fit, prefer left in RTL mode, right otherwise
1766 bool bPutLeft = bFitLeft && ( bLayoutRTL || !bFitRight );
1768 if ( bPutLeft )
1769 aInsertPos.X() = aSelection.Left() - nNeededWidth;
1770 else
1771 aInsertPos.X() = aSelection.Right() + 1;
1773 // align with top of selection (is moved again if it doesn't fit)
1774 aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
1776 else if ( nTopSpace >= nNeededHeight || nBottomSpace >= nNeededHeight )
1778 // second preference: completely above or below the selection
1780 if ( nBottomSpace > nNeededHeight ) // bottom is preferred
1781 aInsertPos.Y() = aSelection.Bottom() + 1;
1782 else
1783 aInsertPos.Y() = aSelection.Top() - nNeededHeight;
1785 // align with (logic) left edge of selection (moved again if it doesn't fit)
1786 if ( bLayoutRTL )
1787 aInsertPos.X() = std::min( aSelection.Right(), aVisible.Right() ) - nNeededWidth + 1;
1788 else
1789 aInsertPos.X() = std::max( aSelection.Left(), aVisible.Left() );
1791 else
1793 // place to the (logic) right of the selection and move so it fits
1795 if ( bLayoutRTL )
1796 aInsertPos.X() = aSelection.Left() - nNeededWidth;
1797 else
1798 aInsertPos.X() = aSelection.Right() + 1;
1799 aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
1802 // move the position if the object doesn't fit in the screen
1804 Rectangle aCompareRect( aInsertPos, Size( nNeededWidth, nNeededHeight ) );
1805 if ( aCompareRect.Right() > aVisible.Right() )
1806 aInsertPos.X() -= aCompareRect.Right() - aVisible.Right();
1807 if ( aCompareRect.Bottom() > aVisible.Bottom() )
1808 aInsertPos.Y() -= aCompareRect.Bottom() - aVisible.Bottom();
1810 if ( aInsertPos.X() < aVisible.Left() )
1811 aInsertPos.X() = aVisible.Left();
1812 if ( aInsertPos.Y() < aVisible.Top() )
1813 aInsertPos.Y() = aVisible.Top();
1815 // nNeededWidth / nNeededHeight includes all borders - move aInsertPos to the
1816 // object position, inside the border
1818 aInsertPos.X() += nBorder;
1819 aInsertPos.Y() += nBorder;
1821 return aInsertPos;
1824 Point ScTabView::GetChartDialogPos( const Size& rDialogSize, const Rectangle& rLogicChart )
1826 // rDialogSize must be in pixels, rLogicChart in 1/100 mm. Return value is in pixels.
1828 Point aRet;
1830 // use the active window, or lower/right if frozen (as in CalcZoom)
1831 ScSplitPos eUsedPart = aViewData.GetActivePart();
1832 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1833 eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
1834 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1835 eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1837 ScGridWindow* pWin = pGridWin[eUsedPart];
1838 OSL_ENSURE( pWin, "Window not found" );
1839 if (pWin)
1841 MapMode aDrawMode = pWin->GetDrawMapMode();
1842 Rectangle aObjPixel = pWin->LogicToPixel( rLogicChart, aDrawMode );
1843 Rectangle aObjAbs( pWin->OutputToAbsoluteScreenPixel( aObjPixel.TopLeft() ),
1844 pWin->OutputToAbsoluteScreenPixel( aObjPixel.BottomRight() ) );
1846 Rectangle aDesktop = pWin->GetDesktopRectPixel();
1847 Size aSpace = pWin->LogicToPixel( Size( 8, 12 ), MAP_APPFONT );
1849 ScDocument* pDoc = aViewData.GetDocument();
1850 SCTAB nTab = aViewData.GetTabNo();
1851 bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1853 bool bCenterHor = false;
1855 if ( aDesktop.Bottom() - aObjAbs.Bottom() >= rDialogSize.Height() + aSpace.Height() )
1857 // first preference: below the chart
1859 aRet.Y() = aObjAbs.Bottom() + aSpace.Height();
1860 bCenterHor = true;
1862 else if ( aObjAbs.Top() - aDesktop.Top() >= rDialogSize.Height() + aSpace.Height() )
1864 // second preference: above the chart
1866 aRet.Y() = aObjAbs.Top() - rDialogSize.Height() - aSpace.Height();
1867 bCenterHor = true;
1869 else
1871 bool bFitLeft = ( aObjAbs.Left() - aDesktop.Left() >= rDialogSize.Width() + aSpace.Width() );
1872 bool bFitRight = ( aDesktop.Right() - aObjAbs.Right() >= rDialogSize.Width() + aSpace.Width() );
1874 if ( bFitLeft || bFitRight )
1876 // if both fit, prefer right in RTL mode, left otherwise
1877 bool bPutRight = bFitRight && ( bLayoutRTL || !bFitLeft );
1878 if ( bPutRight )
1879 aRet.X() = aObjAbs.Right() + aSpace.Width();
1880 else
1881 aRet.X() = aObjAbs.Left() - rDialogSize.Width() - aSpace.Width();
1883 // center vertically
1884 aRet.Y() = aObjAbs.Top() + ( aObjAbs.GetHeight() - rDialogSize.Height() ) / 2;
1886 else
1888 // doesn't fit on any edge - put at the bottom of the screen
1889 aRet.Y() = aDesktop.Bottom() - rDialogSize.Height();
1890 bCenterHor = true;
1893 if ( bCenterHor )
1894 aRet.X() = aObjAbs.Left() + ( aObjAbs.GetWidth() - rDialogSize.Width() ) / 2;
1896 // limit to screen (centering might lead to invalid positions)
1897 if ( aRet.X() + rDialogSize.Width() - 1 > aDesktop.Right() )
1898 aRet.X() = aDesktop.Right() - rDialogSize.Width() + 1;
1899 if ( aRet.X() < aDesktop.Left() )
1900 aRet.X() = aDesktop.Left();
1901 if ( aRet.Y() + rDialogSize.Height() - 1 > aDesktop.Bottom() )
1902 aRet.Y() = aDesktop.Bottom() - rDialogSize.Height() + 1;
1903 if ( aRet.Y() < aDesktop.Top() )
1904 aRet.Y() = aDesktop.Top();
1907 return aRet;
1910 void ScTabView::LockModifiers( sal_uInt16 nModifiers )
1912 pSelEngine->LockModifiers( nModifiers );
1913 pHdrSelEng->LockModifiers( nModifiers );
1916 sal_uInt16 ScTabView::GetLockedModifiers() const
1918 return pSelEngine->GetLockedModifiers();
1921 Point ScTabView::GetMousePosPixel()
1923 Point aPos;
1924 ScGridWindow* pWin = GetActiveWin();
1926 if ( pWin )
1927 aPos = pWin->GetMousePosPixel();
1929 return aPos;
1932 void ScTabView::FreezeSplitters( bool bFreeze, SplitMethod eSplitMetod)
1934 ScSplitMode eOldH = aViewData.GetHSplitMode();
1935 ScSplitMode eOldV = aViewData.GetVSplitMode();
1937 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
1938 if ( eOldV != SC_SPLIT_NONE )
1939 ePos = SC_SPLIT_TOPLEFT;
1940 vcl::Window* pWin = pGridWin[ePos];
1942 bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1944 if ( bFreeze )
1946 Point aWinStart = pWin->GetPosPixel();
1947 aViewData.GetDocShell()->SetDocumentModified();
1949 Point aSplit;
1950 SCsCOL nPosX = 1;
1951 SCsROW nPosY = 1;
1952 if (eOldV != SC_SPLIT_NONE || eOldH != SC_SPLIT_NONE)
1954 if ( eOldV != SC_SPLIT_NONE && (eSplitMetod == SC_SPLIT_METHOD_FIRST_ROW || eSplitMetod == SC_SPLIT_METHOD_CURSOR))
1955 aSplit.Y() = aViewData.GetVSplitPos() - aWinStart.Y();
1957 if ( eOldH != SC_SPLIT_NONE && (eSplitMetod == SC_SPLIT_METHOD_FIRST_COL || eSplitMetod == SC_SPLIT_METHOD_CURSOR))
1959 long nSplitPos = aViewData.GetHSplitPos();
1960 if ( bLayoutRTL )
1961 nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
1962 aSplit.X() = nSplitPos - aWinStart.X();
1965 aViewData.GetPosFromPixel( aSplit.X(), aSplit.Y(), ePos, nPosX, nPosY );
1966 bool bLeft;
1967 bool bTop;
1968 aViewData.GetMouseQuadrant( aSplit, ePos, nPosX, nPosY, bLeft, bTop );
1969 if (!bLeft)
1970 ++nPosX;
1971 if (!bTop)
1972 ++nPosY;
1974 else
1976 switch(eSplitMetod)
1978 case SC_SPLIT_METHOD_FIRST_ROW:
1980 nPosX = 0;
1981 nPosY = 1;
1983 break;
1984 case SC_SPLIT_METHOD_FIRST_COL:
1986 nPosX = 1;
1987 nPosY = 0;
1989 break;
1990 case SC_SPLIT_METHOD_CURSOR:
1992 nPosX = static_cast<SCsCOL>( aViewData.GetCurX());
1993 nPosY = static_cast<SCsROW>( aViewData.GetCurY());
1995 break;
1999 SCROW nTopPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
2000 SCROW nBottomPos = static_cast<SCROW>(nPosY);
2001 SCCOL nLeftPos = aViewData.GetPosX(SC_SPLIT_LEFT);
2002 SCCOL nRightPos = static_cast<SCCOL>(nPosX);
2004 if (eSplitMetod == SC_SPLIT_METHOD_FIRST_ROW || eSplitMetod == SC_SPLIT_METHOD_CURSOR)
2006 if (eOldV != SC_SPLIT_NONE)
2008 nTopPos = aViewData.GetPosY(SC_SPLIT_TOP);
2009 if (aViewData.GetPosY(SC_SPLIT_BOTTOM) > nBottomPos)
2010 nBottomPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
2012 aSplit = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, true );
2013 if (aSplit.Y() > 0)
2015 aViewData.SetVSplitMode( SC_SPLIT_FIX );
2016 aViewData.SetVSplitPos( aSplit.Y() + aWinStart.Y() );
2017 aViewData.SetFixPosY( nPosY );
2019 aViewData.SetPosY(SC_SPLIT_TOP, nTopPos);
2020 aViewData.SetPosY(SC_SPLIT_BOTTOM, nBottomPos);
2022 else
2023 aViewData.SetVSplitMode( SC_SPLIT_NONE );
2026 if (eSplitMetod == SC_SPLIT_METHOD_FIRST_COL || eSplitMetod == SC_SPLIT_METHOD_CURSOR)
2028 if (eOldH != SC_SPLIT_NONE)
2030 if (aViewData.GetPosX(SC_SPLIT_RIGHT) > nRightPos)
2031 nRightPos = aViewData.GetPosX(SC_SPLIT_RIGHT);
2033 aSplit = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, true );
2034 if (nPosX > aViewData.GetPosX(SC_SPLIT_LEFT)) // (aSplit.X() > 0) doesn't work for RTL
2036 long nSplitPos = aSplit.X() + aWinStart.X();
2037 if ( bLayoutRTL )
2038 nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
2040 aViewData.SetHSplitMode( SC_SPLIT_FIX );
2041 aViewData.SetHSplitPos( nSplitPos );
2042 aViewData.SetFixPosX( nPosX );
2044 aViewData.SetPosX(SC_SPLIT_LEFT, nLeftPos);
2045 aViewData.SetPosX(SC_SPLIT_RIGHT, nRightPos);
2047 else
2048 aViewData.SetHSplitMode( SC_SPLIT_NONE );
2051 else // unfreeze
2053 if ( eOldH == SC_SPLIT_FIX )
2054 aViewData.SetHSplitMode( SC_SPLIT_NORMAL );
2055 if ( eOldV == SC_SPLIT_FIX )
2056 aViewData.SetVSplitMode( SC_SPLIT_NORMAL );
2059 // Form Layer needs to know the visible part of all windows
2060 // that is why MapMode must already be correct here
2061 for (VclPtr<ScGridWindow> & p : pGridWin)
2062 if (p)
2063 p->SetMapMode( p->GetDrawMapMode() );
2064 SetNewVisArea();
2066 RepeatResize(false);
2068 UpdateShow();
2069 PaintLeft();
2070 PaintTop();
2071 PaintGrid();
2073 // SC_FOLLOW_NONE: only update active part
2074 AlignToCursor( aViewData.GetCurX(), aViewData.GetCurY(), SC_FOLLOW_NONE );
2075 UpdateAutoFillMark();
2077 InvalidateSplit();
2080 void ScTabView::RemoveSplit()
2082 DoHSplit( 0 );
2083 DoVSplit( 0 );
2084 RepeatResize();
2087 void ScTabView::SplitAtCursor()
2089 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
2090 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
2091 ePos = SC_SPLIT_TOPLEFT;
2092 vcl::Window* pWin = pGridWin[ePos];
2093 Point aWinStart = pWin->GetPosPixel();
2095 SCCOL nPosX = aViewData.GetCurX();
2096 SCROW nPosY = aViewData.GetCurY();
2097 Point aSplit = aViewData.GetScrPos( nPosX, nPosY, ePos, true );
2098 if ( nPosX > 0 )
2099 DoHSplit( aSplit.X() + aWinStart.X() );
2100 else
2101 DoHSplit( 0 );
2102 if ( nPosY > 0 )
2103 DoVSplit( aSplit.Y() + aWinStart.Y() );
2104 else
2105 DoVSplit( 0 );
2106 RepeatResize();
2109 void ScTabView::SplitAtPixel( const Point& rPixel )
2111 // pixel is relative to the entire View, not to the first GridWin
2113 if ( rPixel.X() > 0 )
2114 DoHSplit( rPixel.X() );
2115 else
2116 DoHSplit( 0 );
2117 if ( rPixel.Y() > 0 )
2118 DoVSplit( rPixel.Y() );
2119 else
2120 DoVSplit( 0 );
2121 RepeatResize();
2124 void ScTabView::InvalidateSplit()
2126 SfxBindings& rBindings = aViewData.GetBindings();
2127 rBindings.Invalidate( SID_WINDOW_SPLIT );
2128 rBindings.Invalidate( SID_WINDOW_FIX );
2129 rBindings.Invalidate( SID_WINDOW_FIX_COL );
2130 rBindings.Invalidate( SID_WINDOW_FIX_ROW );
2132 pHSplitter->SetFixed( aViewData.GetHSplitMode() == SC_SPLIT_FIX );
2133 pVSplitter->SetFixed( aViewData.GetVSplitMode() == SC_SPLIT_FIX );
2136 void ScTabView::SetNewVisArea()
2138 // Draw-MapMode must be set for Controls when VisAreaChanged
2139 // (also when Edit-MapMode is set instead)
2140 MapMode aOldMode[4];
2141 MapMode aDrawMode[4];
2142 sal_uInt16 i;
2143 for (i=0; i<4; i++)
2144 if (pGridWin[i])
2146 aOldMode[i] = pGridWin[i]->GetMapMode();
2147 aDrawMode[i] = pGridWin[i]->GetDrawMapMode();
2148 if (aDrawMode[i] != aOldMode[i])
2149 pGridWin[i]->SetMapMode(aDrawMode[i]);
2152 vcl::Window* pActive = pGridWin[aViewData.GetActivePart()];
2153 if (pActive)
2154 aViewData.GetViewShell()->VisAreaChanged(
2155 pActive->PixelToLogic(Rectangle(Point(),pActive->GetOutputSizePixel())) );
2156 if (pDrawView)
2157 pDrawView->VisAreaChanged(); // no window passed on -> for all windows
2159 UpdateAllOverlays(); // #i79909# with drawing MapMode set
2161 for (i=0; i<4; i++)
2162 if (pGridWin[i] && aDrawMode[i] != aOldMode[i])
2164 pGridWin[i]->flushOverlayManager(); // #i79909# flush overlays before switching to edit MapMode
2165 pGridWin[i]->SetMapMode(aOldMode[i]);
2168 SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
2169 if (pViewFrame)
2171 SfxFrame& rFrame = pViewFrame->GetFrame();
2172 css::uno::Reference<css::frame::XController> xController = rFrame.GetController();
2173 if (xController.is())
2175 ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
2176 if (pImp)
2177 pImp->VisAreaChanged();
2180 if (aViewData.GetViewShell()->HasAccessibilityObjects())
2181 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_VISAREACHANGED));
2184 bool ScTabView::HasPageFieldDataAtCursor() const
2186 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2187 SCCOL nCol = aViewData.GetCurX();
2188 SCROW nRow = aViewData.GetCurY();
2189 if (pWin)
2190 return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE;
2192 return false;
2195 void ScTabView::StartDataSelect()
2197 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2198 SCCOL nCol = aViewData.GetCurX();
2199 SCROW nRow = aViewData.GetCurY();
2201 if (!pWin)
2202 return;
2204 switch (pWin->GetDPFieldOrientation(nCol, nRow))
2206 case sheet::DataPilotFieldOrientation_PAGE:
2207 // #i36598# If the cursor is on a page field's data cell,
2208 // no meaningful input is possible anyway, so this function
2209 // can be used to select a page field entry.
2210 pWin->LaunchPageFieldMenu( nCol, nRow );
2211 return;
2212 case sheet::DataPilotFieldOrientation_COLUMN:
2213 case sheet::DataPilotFieldOrientation_ROW:
2214 pWin->LaunchDPFieldMenu( nCol, nRow );
2215 return;
2216 default:
2220 // Do autofilter if the current cell has autofilter button. Otherwise do
2221 // a normal data select popup.
2222 const ScMergeFlagAttr* pAttr = static_cast<const ScMergeFlagAttr*>(
2223 aViewData.GetDocument()->GetAttr(
2224 nCol, nRow, aViewData.GetTabNo(), ATTR_MERGE_FLAG));
2226 if (pAttr->HasAutoFilter())
2227 pWin->LaunchAutoFilterMenu(nCol, nRow);
2228 else
2229 pWin->LaunchDataSelectMenu(nCol, nRow);
2232 void ScTabView::EnableRefInput(bool bFlag)
2234 aHScrollLeft->EnableInput(bFlag);
2235 aHScrollRight->EnableInput(bFlag);
2236 aVScrollBottom->EnableInput(bFlag);
2237 aVScrollTop->EnableInput(bFlag);
2238 aScrollBarBox->EnableInput(bFlag);
2240 // from here on dynamically created ones
2242 if(pTabControl!=nullptr) pTabControl->EnableInput(bFlag);
2244 if(pGridWin[SC_SPLIT_BOTTOMLEFT]!=nullptr)
2245 pGridWin[SC_SPLIT_BOTTOMLEFT]->EnableInput(bFlag,false);
2246 if(pGridWin[SC_SPLIT_BOTTOMRIGHT]!=nullptr)
2247 pGridWin[SC_SPLIT_BOTTOMRIGHT]->EnableInput(bFlag,false);
2248 if(pGridWin[SC_SPLIT_TOPLEFT]!=nullptr)
2249 pGridWin[SC_SPLIT_TOPLEFT]->EnableInput(bFlag,false);
2250 if(pGridWin[SC_SPLIT_TOPRIGHT]!=nullptr)
2251 pGridWin[SC_SPLIT_TOPRIGHT]->EnableInput(bFlag,false);
2252 if(pColBar[SC_SPLIT_RIGHT]!=nullptr)
2253 pColBar[SC_SPLIT_RIGHT]->EnableInput(bFlag,false);
2254 if(pRowBar[SC_SPLIT_TOP]!=nullptr)
2255 pRowBar[SC_SPLIT_TOP]->EnableInput(bFlag,false);
2258 bool ScTabView::ContinueOnlineSpelling()
2260 bool bChanged = false;
2261 for (VclPtr<ScGridWindow> & pWin : pGridWin)
2263 if (!pWin || !pWin->IsVisible())
2264 continue;
2266 if (pWin->ContinueOnlineSpelling())
2267 bChanged = true;
2270 return bChanged;
2273 void ScTabView::EnableAutoSpell( bool bEnable )
2275 for (VclPtr<ScGridWindow> & pWin : pGridWin)
2277 if (!pWin)
2278 continue;
2280 pWin->EnableAutoSpell(bEnable);
2284 void ScTabView::ResetAutoSpell()
2286 for (VclPtr<ScGridWindow> & pWin : pGridWin)
2288 if (!pWin)
2289 continue;
2291 pWin->ResetAutoSpell();
2295 void ScTabView::SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges )
2297 for (VclPtr<ScGridWindow> & pWin: pGridWin)
2299 if (!pWin)
2300 continue;
2302 pWin->SetAutoSpellData(nPosX, nPosY, pRanges);
2306 OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle)
2308 ScDocument* pDoc = aViewData.GetDocument();
2309 if (!pDoc)
2310 return OUString();
2312 SCCOL nEndCol = 0;
2313 SCROW nEndRow = 0;
2314 pDoc->GetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow);
2316 boost::property_tree::ptree aRows;
2317 long nTotal = 0;
2318 long nTotalPixels = 0;
2319 for (SCROW nRow = 0; nRow <= nEndRow; ++nRow)
2321 // nSize will be 0 for hidden rows.
2322 sal_uInt16 nSize = pDoc->GetRowHeight(nRow, aViewData.GetTabNo());
2323 long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTY());
2324 OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow);
2326 bool bSkip = false;
2327 if (!rRectangle.IsEmpty())
2329 long nTop = std::max(rRectangle.Top(), nTotal);
2330 long nBottom = std::min(rRectangle.Bottom(), nTotal + nSize);
2331 if (nBottom < nTop)
2332 // They do not intersect.
2333 bSkip = true;
2335 if (!bSkip)
2337 boost::property_tree::ptree aRow;
2338 aRow.put("size", OString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTY()).getStr());
2339 aRow.put("text", aText.toUtf8().getStr());
2340 aRows.push_back(std::make_pair("", aRow));
2342 nTotal += nSize;
2343 nTotalPixels += nSizePixels;
2346 boost::property_tree::ptree aCols;
2347 nTotal = 0;
2348 nTotalPixels = 0;
2349 for (SCCOL nCol = 0; nCol <= nEndCol; ++nCol)
2351 sal_uInt16 nSize = pDoc->GetColWidth(nCol, aViewData.GetTabNo());
2352 long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTX());
2353 OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol);
2355 bool bSkip = false;
2356 if (!rRectangle.IsEmpty())
2358 long nLeft = std::max(rRectangle.Left(), nTotal);
2359 long nRight = std::min(rRectangle.Right(), nTotal + nSize);
2360 if (nRight < nLeft)
2361 // They do not intersect.
2362 bSkip = true;
2364 if (!bSkip)
2366 boost::property_tree::ptree aCol;
2367 aCol.put("size", OString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTX()).getStr());
2368 aCol.put("text", aText.toUtf8().getStr());
2369 aCols.push_back(std::make_pair("", aCol));
2371 nTotal += nSize;
2372 nTotalPixels += nSizePixels;
2375 boost::property_tree::ptree aTree;
2376 aTree.put("commandName", ".uno:ViewRowColumnHeaders");
2377 aTree.add_child("rows", aRows);
2378 aTree.add_child("columns", aCols);
2379 std::stringstream aStream;
2380 boost::property_tree::write_json(aStream, aTree);
2381 return OUString::fromUtf8(aStream.str().c_str());
2384 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */