Line data Source code
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 <vcl/svapp.hxx>
21 :
22 : #include "scitems.hxx"
23 : #include <sfx2/viewfrm.hxx>
24 : #include <sfx2/bindings.hxx>
25 : #include <vcl/help.hxx>
26 : #include <vcl/settings.hxx>
27 :
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"
48 :
49 : #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
50 :
51 : #include <string>
52 : #include <algorithm>
53 :
54 : #include <basegfx/tools/zoomtools.hxx>
55 :
56 : #define SPLIT_MARGIN 30
57 : #define SPLIT_HANDLE_SIZE 5
58 : #define WIDTH_MARGIN 5
59 :
60 : #define SC_ICONSIZE 36
61 :
62 : #define SC_SCROLLBAR_MIN 30
63 : #define SC_TABBAR_MIN 6
64 :
65 : using namespace ::com::sun::star;
66 :
67 : // Corner-Button
68 :
69 696 : ScCornerButton::ScCornerButton( vcl::Window* pParent, ScViewData* pData, bool bAdditional ) :
70 : Window( pParent, WinBits( 0 ) ),
71 : pViewData( pData ),
72 696 : bAdd( bAdditional )
73 : {
74 696 : EnableRTL( false );
75 696 : }
76 :
77 1380 : ScCornerButton::~ScCornerButton()
78 : {
79 1380 : }
80 :
81 222 : void ScCornerButton::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
82 : {
83 222 : const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
84 222 : SetBackground(rStyleSettings.GetFaceColor());
85 :
86 222 : Size aSize = rRenderContext.GetOutputSizePixel();
87 222 : long nPosX = aSize.Width() - 1;
88 222 : long nPosY = aSize.Height() - 1;
89 :
90 :
91 222 : Window::Paint(rRenderContext, rRect);
92 :
93 222 : bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
94 222 : long nDarkX = bLayoutRTL ? 0 : nPosX;
95 :
96 222 : if (!bAdd)
97 : {
98 : // match the shaded look of column/row headers
99 :
100 222 : Color aFace(rStyleSettings.GetFaceColor());
101 222 : Color aWhite(COL_WHITE);
102 222 : Color aCenter(aFace);
103 222 : aCenter.Merge(aWhite, 0xd0); // lighten up a bit
104 222 : Color aOuter(aFace );
105 222 : aOuter.Merge(aWhite, 0xa0); // lighten up more
106 :
107 222 : long nCenterX = (aSize.Width() / 2) - 1;
108 222 : long nCenterY = (aSize.Height() / 2) - 1;
109 :
110 222 : rRenderContext.SetLineColor();
111 222 : rRenderContext.SetFillColor(aCenter);
112 222 : rRenderContext.DrawRect(Rectangle(nCenterX, nCenterY, nCenterX, nPosY));
113 222 : rRenderContext.DrawRect(Rectangle(nCenterX, nCenterY, nDarkX, nCenterY));
114 222 : rRenderContext.SetFillColor(aOuter);
115 222 : rRenderContext.DrawRect(Rectangle(0, 0, nPosX, nCenterY - 1));
116 222 : if (bLayoutRTL)
117 1 : rRenderContext.DrawRect(Rectangle(nCenterX + 1, nCenterY, nPosX, nPosY));
118 : else
119 221 : rRenderContext.DrawRect(Rectangle(0, nCenterY, nCenterX - 1, nPosY));
120 : }
121 :
122 : // both buttons have the same look now - only dark right/bottom lines
123 222 : rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
124 222 : rRenderContext.DrawLine(Point(0, nPosY), Point(nPosX, nPosY));
125 222 : rRenderContext.DrawLine(Point(nDarkX, 0), Point(nDarkX, nPosY));
126 222 : }
127 :
128 1509 : void ScCornerButton::StateChanged( StateChangedType nType )
129 : {
130 1509 : Window::StateChanged( nType );
131 :
132 1509 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
133 1509 : SetBackground( rStyleSettings.GetFaceColor() );
134 1509 : Invalidate();
135 1509 : }
136 :
137 52 : void ScCornerButton::DataChanged( const DataChangedEvent& rDCEvt )
138 : {
139 52 : Window::DataChanged( rDCEvt );
140 :
141 52 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
142 52 : SetBackground( rStyleSettings.GetFaceColor() );
143 52 : Invalidate();
144 52 : }
145 :
146 715 : void ScCornerButton::Resize()
147 : {
148 715 : Invalidate();
149 715 : }
150 :
151 0 : void ScCornerButton::MouseButtonDown( const MouseEvent& rMEvt )
152 : {
153 0 : ScModule* pScMod = SC_MOD();
154 0 : bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
155 0 : if (!bDisable)
156 : {
157 0 : ScTabViewShell* pViewSh = pViewData->GetViewShell();
158 0 : pViewSh->SetActive(); // Appear und SetViewFrame
159 0 : pViewSh->ActiveGrabFocus();
160 :
161 0 : bool bControl = rMEvt.IsMod1();
162 0 : pViewSh->SelectAll( bControl );
163 : }
164 0 : }
165 : namespace
166 : {
167 :
168 6616 : bool lcl_HasColOutline( const ScViewData& rViewData )
169 : {
170 6616 : const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
171 6616 : if (pTable)
172 : {
173 1490 : const ScOutlineArray& rArray = pTable->GetColArray();
174 1490 : if ( rArray.GetDepth() > 0 )
175 24 : return true;
176 : }
177 6592 : return false;
178 : }
179 :
180 6616 : bool lcl_HasRowOutline( const ScViewData& rViewData )
181 : {
182 6616 : const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
183 6616 : if (pTable)
184 : {
185 1490 : const ScOutlineArray& rArray = pTable->GetRowArray();
186 1490 : if ( rArray.GetDepth() > 0 )
187 63 : return true;
188 : }
189 6553 : return false;
190 : }
191 :
192 : } // anonymous namespace
193 :
194 348 : ScTabView::ScTabView( vcl::Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
195 : pFrameWin( pParent ),
196 : aViewData( &rDocSh, pViewShell ),
197 : pSelEngine( NULL ),
198 : aFunctionSet( &aViewData ),
199 : pHdrSelEng( NULL ),
200 : aHdrFunc( &aViewData ),
201 : pDrawView( NULL ),
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( NULL ),
210 : pPageBreakData( NULL ),
211 : pBrushDocument( NULL ),
212 : pDrawBrushSet( NULL ),
213 : pTimerWindow( NULL ),
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 348 : mbInlineWithScrollbar( false )
240 : {
241 348 : Init();
242 348 : }
243 :
244 1392 : void ScTabView::InitScrollBar( ScrollBar& rScrollBar, long nMaxVal )
245 : {
246 1392 : rScrollBar.SetRange( Range( 0, nMaxVal ) );
247 1392 : rScrollBar.SetLineSize( 1 );
248 1392 : rScrollBar.SetPageSize( 1 ); // wird getrennt abgefragt
249 1392 : rScrollBar.SetVisibleSize( 10 ); // wird bei Resize neu gesetzt
250 :
251 1392 : rScrollBar.SetScrollHdl( LINK(this, ScTabView, ScrollHdl) );
252 1392 : rScrollBar.SetEndScrollHdl( LINK(this, ScTabView, EndScrollHdl) );
253 :
254 1392 : rScrollBar.EnableRTL( aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ) );
255 1392 : }
256 :
257 : // Scroll-Timer
258 :
259 0 : void ScTabView::SetTimer( ScGridWindow* pWin, const MouseEvent& rMEvt )
260 : {
261 0 : pTimerWindow = pWin;
262 0 : aTimerMEvt = rMEvt;
263 0 : aScrollTimer.Start();
264 0 : }
265 :
266 0 : void ScTabView::ResetTimer()
267 : {
268 0 : aScrollTimer.Stop();
269 0 : pTimerWindow = NULL;
270 0 : }
271 :
272 0 : IMPL_LINK_NOARG_TYPED(ScTabView, TimerHdl, Timer *, void)
273 : {
274 0 : if (pTimerWindow)
275 0 : pTimerWindow->MouseMove( aTimerMEvt );
276 0 : }
277 :
278 : // --- Resize ---------------------------------------------------------------------
279 :
280 22344 : static void lcl_SetPosSize( vcl::Window& rWindow, const Point& rPos, const Size& rSize,
281 : long nTotalWidth, bool bLayoutRTL )
282 : {
283 22344 : Point aNewPos = rPos;
284 22344 : if ( bLayoutRTL )
285 : {
286 12 : aNewPos.X() = nTotalWidth - rPos.X() - rSize.Width();
287 12 : if ( aNewPos == rWindow.GetPosPixel() && rSize.Width() != rWindow.GetSizePixel().Width() )
288 : {
289 : // Document windows are manually painted right-to-left, so they need to
290 : // be repainted if the size changes.
291 0 : rWindow.Invalidate();
292 : }
293 : }
294 22344 : rWindow.SetPosSizePixel( aNewPos, rSize );
295 22344 : }
296 :
297 2272 : void ScTabView::DoResize( const Point& rOffset, const Size& rSize, bool bInner )
298 : {
299 2272 : HideListBox();
300 :
301 2272 : bool bHasHint = HasHintWindow();
302 2272 : if (bHasHint)
303 0 : RemoveHintWindow();
304 :
305 2272 : bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
306 2272 : long nTotalWidth = rSize.Width();
307 2272 : if ( bLayoutRTL )
308 1 : nTotalWidth += 2*rOffset.X();
309 :
310 2272 : bool bVScroll = aViewData.IsVScrollMode();
311 2272 : bool bHScroll = aViewData.IsHScrollMode();
312 2272 : bool bTabControl = aViewData.IsTabMode();
313 2272 : bool bHeaders = aViewData.IsHeaderMode();
314 2272 : bool bOutlMode = aViewData.IsOutlineMode();
315 2272 : bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
316 2272 : bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
317 :
318 2272 : if ( aViewData.GetDocShell()->IsPreview() )
319 0 : bHScroll = bVScroll = bTabControl = bHeaders = bOutlMode = bHOutline = bVOutline = false;
320 :
321 2272 : long nBarX = 0;
322 2272 : long nBarY = 0;
323 2272 : long nOutlineX = 0;
324 2272 : long nOutlineY = 0;
325 : long nOutPosX;
326 : long nOutPosY;
327 :
328 2272 : long nPosX = rOffset.X();
329 2272 : long nPosY = rOffset.Y();
330 2272 : long nSizeX = rSize.Width();
331 2272 : long nSizeY = rSize.Height();
332 :
333 2272 : bMinimized = ( nSizeX<=SC_ICONSIZE || nSizeY<=SC_ICONSIZE );
334 2272 : if ( bMinimized )
335 2677 : return;
336 :
337 1867 : sal_Int32 aScaleFactor = pFrameWin->GetDPIScaleFactor();
338 :
339 1867 : long nSplitSizeX = SPLIT_HANDLE_SIZE * aScaleFactor;
340 1867 : if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
341 1 : nSplitSizeX = 1;
342 1867 : long nSplitSizeY = SPLIT_HANDLE_SIZE * aScaleFactor;
343 1867 : if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
344 2 : nSplitSizeY = 1;
345 :
346 1867 : aBorderPos = rOffset;
347 1867 : aFrameSize = rSize;
348 :
349 1867 : const StyleSettings& rStyleSettings = pFrameWin->GetSettings().GetStyleSettings();
350 :
351 1867 : sal_Int32 nTabWidth = pFrameWin->GetFont().GetHeight() + WIDTH_MARGIN;
352 :
353 1867 : if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
354 : {
355 6 : if ( aViewData.GetHSplitPos() > nSizeX - SPLIT_MARGIN )
356 : {
357 0 : aViewData.SetHSplitMode( SC_SPLIT_NONE );
358 0 : if ( WhichH( aViewData.GetActivePart() ) == SC_SPLIT_RIGHT )
359 0 : ActivatePart( SC_SPLIT_BOTTOMLEFT );
360 0 : InvalidateSplit();
361 : }
362 : }
363 1867 : if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
364 : {
365 10 : if ( aViewData.GetVSplitPos() > nSizeY - SPLIT_MARGIN )
366 : {
367 0 : aViewData.SetVSplitMode( SC_SPLIT_NONE );
368 0 : if ( WhichV( aViewData.GetActivePart() ) == SC_SPLIT_TOP )
369 0 : ActivatePart( SC_SPLIT_BOTTOMLEFT );
370 0 : InvalidateSplit();
371 : }
372 : }
373 :
374 1867 : UpdateShow();
375 :
376 1867 : if (bHScroll || bVScroll) // Scrollbars horizontal oder vertikal
377 : {
378 1866 : long nScrollBarSize = rStyleSettings.GetScrollBarSize();
379 1866 : if (bVScroll)
380 : {
381 1804 : nBarX = nScrollBarSize;
382 1804 : nSizeX -= nBarX;
383 : }
384 1866 : if (bHScroll)
385 : {
386 1866 : nBarY = nTabWidth;
387 :
388 1866 : if (!mbInlineWithScrollbar)
389 1866 : nBarY += nScrollBarSize;
390 :
391 1866 : nSizeY -= nBarY;
392 : }
393 :
394 : // window at the bottom right
395 1866 : lcl_SetPosSize( *aScrollBarBox.get(), Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
396 3732 : nTotalWidth, bLayoutRTL );
397 :
398 1866 : if (bHScroll) // Scrollbars horizontal
399 : {
400 1866 : long nSizeLt = 0; // left scroll bar
401 1866 : long nSizeRt = 0; // right scroll bar
402 1866 : long nSizeSp = 0; // splitter
403 :
404 1866 : switch (aViewData.GetHSplitMode())
405 : {
406 : case SC_SPLIT_NONE:
407 1860 : nSizeSp = nSplitSizeX;
408 1860 : nSizeLt = nSizeX - nSizeSp; // Covert the corner
409 1860 : break;
410 : case SC_SPLIT_NORMAL:
411 5 : nSizeSp = nSplitSizeX;
412 5 : nSizeLt = aViewData.GetHSplitPos();
413 5 : break;
414 : case SC_SPLIT_FIX:
415 1 : nSizeSp = 0;
416 1 : nSizeLt = 0;
417 1 : break;
418 : }
419 1866 : nSizeRt = nSizeX - nSizeLt - nSizeSp;
420 :
421 1866 : long nTabSize = 0;
422 :
423 1866 : if (bTabControl)
424 : {
425 : // pending relative tab bar width from extended document options
426 1865 : if( mfPendingTabBarWidth >= 0.0 )
427 : {
428 96 : SetRelTabBarWidth( mfPendingTabBarWidth );
429 96 : mfPendingTabBarWidth = -1.0;
430 : }
431 :
432 1865 : if (mbInlineWithScrollbar)
433 : {
434 0 : nTabSize = pTabControl->GetSizePixel().Width();
435 :
436 0 : if ( aViewData.GetHSplitMode() != SC_SPLIT_FIX ) // left Scrollbar
437 : {
438 0 : if (nTabSize > nSizeLt-SC_SCROLLBAR_MIN)
439 0 : nTabSize = nSizeLt-SC_SCROLLBAR_MIN;
440 0 : if (nTabSize < SC_TABBAR_MIN)
441 0 : nTabSize = SC_TABBAR_MIN;
442 0 : nSizeLt -= nTabSize;
443 : }
444 : else // right Scrollbar
445 : {
446 0 : if (nTabSize > nSizeRt-SC_SCROLLBAR_MIN)
447 0 : nTabSize = nSizeRt-SC_SCROLLBAR_MIN;
448 0 : if (nTabSize < SC_TABBAR_MIN)
449 0 : nTabSize = SC_TABBAR_MIN;
450 0 : nSizeRt -= nTabSize;
451 : }
452 : }
453 : }
454 :
455 1866 : if (mbInlineWithScrollbar)
456 : {
457 0 : Point aTabPoint(nPosX, nPosY + nSizeY);
458 0 : Size aTabSize(nTabSize, nBarY);
459 0 : lcl_SetPosSize(*pTabControl.get(), aTabPoint, aTabSize, nTotalWidth, bLayoutRTL);
460 0 : pTabControl->SetSheetLayoutRTL(bLayoutRTL);
461 :
462 0 : Point aHScrollLeftPoint(nPosX + nTabSize, nPosY + nSizeY);
463 0 : Size aHScrollLeftSize(nSizeLt, nBarY);
464 0 : lcl_SetPosSize(*aHScrollLeft.get(), aHScrollLeftPoint, aHScrollLeftSize, nTotalWidth, bLayoutRTL);
465 :
466 0 : Point aHSplitterPoint(nPosX + nTabSize + nSizeLt, nPosY + nSizeY);
467 0 : Size aHSplitterSize(nSizeSp, nBarY);
468 0 : lcl_SetPosSize(*pHSplitter.get(), aHSplitterPoint, aHSplitterSize, nTotalWidth, bLayoutRTL);
469 :
470 0 : Point aHScrollRightPoint(nPosX + nTabSize + nSizeLt + nSizeSp, nPosY + nSizeY);
471 0 : Size aHScrollRightSize(nSizeRt, nBarY);
472 0 : lcl_SetPosSize(*aHScrollRight.get(), aHScrollRightPoint, aHScrollRightSize, nTotalWidth, bLayoutRTL);
473 : }
474 : else
475 : {
476 1866 : Point aTabPoint(nPosX, nPosY + nSizeY + nScrollBarSize);
477 1866 : Size aTabSize(nSizeX, nTabWidth);
478 1866 : lcl_SetPosSize(*pTabControl.get(), aTabPoint, aTabSize, nTotalWidth, bLayoutRTL);
479 1866 : pTabControl->SetSheetLayoutRTL(bLayoutRTL);
480 :
481 1866 : Point aHScrollLeftPoint(nPosX, nPosY + nSizeY);
482 1866 : Size aHScrollLeftSize(nSizeLt, nScrollBarSize);
483 1866 : lcl_SetPosSize(*aHScrollLeft.get(), aHScrollLeftPoint, aHScrollLeftSize, nTotalWidth, bLayoutRTL);
484 :
485 1866 : Point aHSplitterPoint(nPosX + nSizeLt, nPosY + nSizeY);
486 1866 : Size aHSplitterSize(nSizeSp, nScrollBarSize);
487 1866 : lcl_SetPosSize(*pHSplitter.get(), aHSplitterPoint, aHSplitterSize, nTotalWidth, bLayoutRTL);
488 :
489 1866 : Point aHScrollRightPoint(nPosX + nSizeLt + nSizeSp, nPosY + nSizeY);
490 1866 : Size aHScrollRightSize(nSizeRt, nScrollBarSize);
491 1866 : lcl_SetPosSize(*aHScrollRight.get(), aHScrollRightPoint, aHScrollRightSize, nTotalWidth, bLayoutRTL);
492 : }
493 : // SetDragRectPixel is done below
494 : }
495 :
496 1866 : if (bVScroll)
497 : {
498 1804 : long nSizeUp = 0; // upper scroll bar
499 1804 : long nSizeSp = 0; // splitter
500 : long nSizeDn; // unterer Scrollbar
501 :
502 1804 : switch (aViewData.GetVSplitMode())
503 : {
504 : case SC_SPLIT_NONE:
505 1794 : nSizeUp = 0;
506 1794 : nSizeSp = nSplitSizeY;
507 1794 : break;
508 : case SC_SPLIT_NORMAL:
509 8 : nSizeUp = aViewData.GetVSplitPos();
510 8 : nSizeSp = nSplitSizeY;
511 8 : break;
512 : case SC_SPLIT_FIX:
513 2 : nSizeUp = 0;
514 2 : nSizeSp = 0;
515 2 : break;
516 : }
517 1804 : nSizeDn = nSizeY - nSizeUp - nSizeSp;
518 :
519 1804 : lcl_SetPosSize( *aVScrollTop.get(), Point(nPosX + nSizeX, nPosY),
520 3608 : Size(nBarX, nSizeUp), nTotalWidth, bLayoutRTL );
521 1804 : lcl_SetPosSize( *pVSplitter, Point( nPosX + nSizeX, nPosY+nSizeUp ),
522 3608 : Size( nBarX, nSizeSp ), nTotalWidth, bLayoutRTL );
523 1804 : lcl_SetPosSize( *aVScrollBottom.get(), Point(nPosX + nSizeX,
524 1804 : nPosY + nSizeUp + nSizeSp),
525 5412 : Size(nBarX, nSizeDn), nTotalWidth, bLayoutRTL );
526 :
527 : // SetDragRectPixel is done below
528 : }
529 : }
530 :
531 : // SetDragRectPixel auch ohne Scrollbars etc., wenn schon gesplittet ist
532 1867 : if ( bHScroll || aViewData.GetHSplitMode() != SC_SPLIT_NONE )
533 1866 : pHSplitter->SetDragRectPixel(
534 3732 : Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
535 1867 : if ( bVScroll || aViewData.GetVSplitMode() != SC_SPLIT_NONE )
536 1804 : pVSplitter->SetDragRectPixel(
537 3608 : Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
538 :
539 1867 : if (bTabControl && ! bHScroll )
540 : {
541 1 : nBarY = aHScrollLeft->GetSizePixel().Height();
542 1 : nBarX = aVScrollBottom->GetSizePixel().Width();
543 :
544 1 : long nSize1 = nSizeX;
545 :
546 1 : long nTabSize = nSize1;
547 1 : if (nTabSize < 0) nTabSize = 0;
548 :
549 2 : lcl_SetPosSize( *pTabControl.get(), Point(nPosX, nPosY+nSizeY-nBarY),
550 3 : Size(nTabSize, nBarY), nTotalWidth, bLayoutRTL );
551 1 : nSizeY -= nBarY;
552 1 : lcl_SetPosSize( *aScrollBarBox.get(), Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
553 2 : nTotalWidth, bLayoutRTL );
554 :
555 1 : if( bVScroll )
556 : {
557 0 : Size aVScrSize = aVScrollBottom->GetSizePixel();
558 0 : aVScrSize.Height() -= nBarY;
559 0 : aVScrollBottom->SetSizePixel( aVScrSize );
560 : }
561 : }
562 :
563 1867 : nOutPosX = nPosX;
564 1867 : nOutPosY = nPosY;
565 :
566 : // Outline-Controls
567 1867 : if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
568 : {
569 23 : nOutlineX = pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
570 23 : nSizeX -= nOutlineX;
571 23 : nPosX += nOutlineX;
572 : }
573 1867 : if (bHOutline && pColOutline[SC_SPLIT_LEFT])
574 : {
575 8 : nOutlineY = pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
576 8 : nSizeY -= nOutlineY;
577 8 : nPosY += nOutlineY;
578 : }
579 :
580 1867 : if (bHeaders) // Spalten/Zeilen-Header
581 : {
582 1865 : nBarX = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
583 1865 : nBarY = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
584 1865 : nSizeX -= nBarX;
585 1865 : nSizeY -= nBarY;
586 1865 : nPosX += nBarX;
587 1865 : nPosY += nBarY;
588 : }
589 : else
590 2 : nBarX = nBarY = 0;
591 :
592 : // Splitter auswerten
593 :
594 1867 : long nLeftSize = nSizeX;
595 1867 : long nRightSize = 0;
596 1867 : long nTopSize = 0;
597 1867 : long nBottomSize = nSizeY;
598 1867 : long nSplitPosX = nPosX;
599 1867 : long nSplitPosY = nPosY;
600 :
601 1867 : if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
602 : {
603 6 : long nSplitHeight = rSize.Height();
604 6 : if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
605 : {
606 : // Fixier-Splitter nicht mit Scrollbar/TabBar ueberlappen lassen
607 1 : if ( bHScroll )
608 1 : nSplitHeight -= aHScrollLeft->GetSizePixel().Height();
609 0 : else if ( bTabControl && pTabControl )
610 0 : nSplitHeight -= pTabControl->GetSizePixel().Height();
611 : }
612 6 : nSplitPosX = aViewData.GetHSplitPos();
613 6 : lcl_SetPosSize( *pHSplitter,
614 : Point(nSplitPosX, nOutPosY),
615 12 : Size( nSplitSizeX, nSplitHeight - nTabWidth ), nTotalWidth, bLayoutRTL );
616 6 : nLeftSize = nSplitPosX - nPosX;
617 6 : nSplitPosX += nSplitSizeX;
618 6 : nRightSize = nSizeX - nLeftSize - nSplitSizeX;
619 : }
620 1867 : if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
621 : {
622 10 : long nSplitWidth = rSize.Width();
623 10 : if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && bVScroll )
624 2 : nSplitWidth -= aVScrollBottom->GetSizePixel().Width();
625 10 : nSplitPosY = aViewData.GetVSplitPos();
626 10 : lcl_SetPosSize( *pVSplitter,
627 20 : Point( nOutPosX, nSplitPosY ), Size( nSplitWidth, nSplitSizeY ), nTotalWidth, bLayoutRTL );
628 10 : nTopSize = nSplitPosY - nPosY;
629 10 : nSplitPosY += nSplitSizeY;
630 10 : nBottomSize = nSizeY - nTopSize - nSplitSizeY;
631 : }
632 :
633 : // ShowHide fuer pColOutline / pRowOutline passiert in UpdateShow
634 :
635 1867 : if (bHOutline) // Outline-Controls
636 : {
637 8 : if (pColOutline[SC_SPLIT_LEFT])
638 : {
639 8 : pColOutline[SC_SPLIT_LEFT]->SetHeaderSize( nBarX );
640 8 : lcl_SetPosSize( *pColOutline[SC_SPLIT_LEFT],
641 16 : Point(nPosX-nBarX,nOutPosY), Size(nLeftSize+nBarX,nOutlineY), nTotalWidth, bLayoutRTL );
642 : }
643 8 : if (pColOutline[SC_SPLIT_RIGHT])
644 : {
645 0 : pColOutline[SC_SPLIT_RIGHT]->SetHeaderSize( 0 ); // always call to update RTL flag
646 0 : lcl_SetPosSize( *pColOutline[SC_SPLIT_RIGHT],
647 0 : Point(nSplitPosX,nOutPosY), Size(nRightSize,nOutlineY), nTotalWidth, bLayoutRTL );
648 : }
649 : }
650 1867 : if (bVOutline)
651 : {
652 23 : if (nTopSize)
653 : {
654 0 : if (pRowOutline[SC_SPLIT_TOP] && pRowOutline[SC_SPLIT_BOTTOM])
655 : {
656 0 : pRowOutline[SC_SPLIT_TOP]->SetHeaderSize( nBarY );
657 0 : lcl_SetPosSize( *pRowOutline[SC_SPLIT_TOP],
658 0 : Point(nOutPosX,nPosY-nBarY), Size(nOutlineX,nTopSize+nBarY), nTotalWidth, bLayoutRTL );
659 0 : pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( 0 );
660 0 : lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
661 0 : Point(nOutPosX,nSplitPosY), Size(nOutlineX,nBottomSize), nTotalWidth, bLayoutRTL );
662 : }
663 : }
664 23 : else if (pRowOutline[SC_SPLIT_BOTTOM])
665 : {
666 23 : pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( nBarY );
667 23 : lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
668 46 : Point(nOutPosX,nSplitPosY-nBarY), Size(nOutlineX,nBottomSize+nBarY), nTotalWidth, bLayoutRTL );
669 : }
670 : }
671 1867 : if (bHOutline && bVOutline)
672 : {
673 8 : lcl_SetPosSize( *aTopButton.get(), Point(nOutPosX,nOutPosY), Size(nOutlineX,nOutlineY), nTotalWidth, bLayoutRTL );
674 8 : aTopButton->Show();
675 : }
676 : else
677 1859 : aTopButton->Hide();
678 :
679 1867 : if (bHeaders) // Spalten/Zeilen-Header
680 : {
681 1865 : lcl_SetPosSize( *pColBar[SC_SPLIT_LEFT],
682 3730 : Point(nPosX,nPosY-nBarY), Size(nLeftSize,nBarY), nTotalWidth, bLayoutRTL );
683 1865 : if (pColBar[SC_SPLIT_RIGHT])
684 30 : lcl_SetPosSize( *pColBar[SC_SPLIT_RIGHT],
685 60 : Point(nSplitPosX,nPosY-nBarY), Size(nRightSize,nBarY), nTotalWidth, bLayoutRTL );
686 :
687 1865 : if (pRowBar[SC_SPLIT_TOP])
688 33 : lcl_SetPosSize( *pRowBar[SC_SPLIT_TOP],
689 66 : Point(nPosX-nBarX,nPosY), Size(nBarX,nTopSize), nTotalWidth, bLayoutRTL );
690 1865 : lcl_SetPosSize( *pRowBar[SC_SPLIT_BOTTOM],
691 3730 : Point(nPosX-nBarX,nSplitPosY), Size(nBarX,nBottomSize), nTotalWidth, bLayoutRTL );
692 :
693 1865 : lcl_SetPosSize( *aCornerButton.get(), Point(nPosX-nBarX,nPosY-nBarY), Size(nBarX,nBarY), nTotalWidth, bLayoutRTL );
694 1865 : aCornerButton->Show();
695 1865 : pColBar[SC_SPLIT_LEFT]->Show();
696 1865 : pRowBar[SC_SPLIT_BOTTOM]->Show();
697 : }
698 : else
699 : {
700 2 : aCornerButton->Hide();
701 2 : pColBar[SC_SPLIT_LEFT]->Hide(); // immer da
702 2 : pRowBar[SC_SPLIT_BOTTOM]->Hide();
703 : }
704 :
705 : // Grid-Windows
706 :
707 1867 : if (bInner)
708 : {
709 0 : long nInnerPosX = bLayoutRTL ? ( nTotalWidth - nPosX - nLeftSize ) : nPosX;
710 0 : pGridWin[SC_SPLIT_BOTTOMLEFT]->SetPosPixel( Point(nInnerPosX,nSplitPosY) );
711 : }
712 : else
713 : {
714 1867 : lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMLEFT],
715 3734 : Point(nPosX,nSplitPosY), Size(nLeftSize,nBottomSize), nTotalWidth, bLayoutRTL );
716 1867 : if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
717 6 : lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMRIGHT],
718 12 : Point(nSplitPosX,nSplitPosY), Size(nRightSize,nBottomSize), nTotalWidth, bLayoutRTL );
719 1867 : if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
720 10 : lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPLEFT],
721 20 : Point(nPosX,nPosY), Size(nLeftSize,nTopSize), nTotalWidth, bLayoutRTL );
722 1867 : if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE && aViewData.GetVSplitMode() != SC_SPLIT_NONE )
723 4 : lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPRIGHT],
724 8 : Point(nSplitPosX,nPosY), Size(nRightSize,nTopSize), nTotalWidth, bLayoutRTL );
725 : }
726 :
727 : // Scrollbars updaten
728 :
729 1867 : if (!bInUpdateHeader)
730 : {
731 1490 : UpdateScrollBars(); // Scrollbars nicht beim Scrollen neu setzen
732 1490 : UpdateHeaderWidth();
733 :
734 1490 : InterpretVisible(); // have everything calculated before painting
735 : }
736 :
737 1867 : if (bHasHint)
738 0 : TestHintWindow(); // neu positionieren
739 :
740 1867 : UpdateVarZoom(); // update variable zoom types (after resizing GridWindows)
741 :
742 1867 : if (aViewData.GetViewShell()->HasAccessibilityObjects())
743 2 : aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_WINDOWRESIZED));
744 : }
745 :
746 2464 : void ScTabView::UpdateVarZoom()
747 : {
748 : // update variable zoom types
749 :
750 2464 : SvxZoomType eZoomType = GetZoomType();
751 2464 : if ( eZoomType != SvxZoomType::PERCENT && !bInZoomUpdate )
752 : {
753 0 : bInZoomUpdate = true;
754 0 : const Fraction& rOldX = GetViewData().GetZoomX();
755 0 : const Fraction& rOldY = GetViewData().GetZoomY();
756 0 : long nOldPercent = ( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator();
757 0 : sal_uInt16 nNewZoom = CalcZoom( eZoomType, (sal_uInt16)nOldPercent );
758 0 : Fraction aNew( nNewZoom, 100 );
759 :
760 0 : if ( aNew != rOldX || aNew != rOldY )
761 : {
762 0 : SetZoom( aNew, aNew, false ); // always separately per sheet
763 0 : PaintGrid();
764 0 : PaintTop();
765 0 : PaintLeft();
766 0 : aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
767 0 : aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
768 : }
769 0 : bInZoomUpdate = false;
770 : }
771 2464 : }
772 :
773 1312 : void ScTabView::UpdateFixPos()
774 : {
775 1312 : bool bResize = false;
776 1312 : if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
777 0 : if (aViewData.UpdateFixX())
778 0 : bResize = true;
779 1312 : if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
780 0 : if (aViewData.UpdateFixY())
781 0 : bResize = true;
782 1312 : if (bResize)
783 0 : RepeatResize(false);
784 1312 : }
785 :
786 520 : void ScTabView::RepeatResize( bool bUpdateFix )
787 : {
788 520 : if ( bUpdateFix )
789 : {
790 508 : ScSplitMode eHSplit = aViewData.GetHSplitMode();
791 508 : ScSplitMode eVSplit = aViewData.GetVSplitMode();
792 :
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 508 : if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX )
797 0 : UpdateShow();
798 :
799 508 : if ( eHSplit == SC_SPLIT_FIX )
800 0 : aViewData.UpdateFixX();
801 508 : if ( eVSplit == SC_SPLIT_FIX )
802 0 : aViewData.UpdateFixY();
803 : }
804 :
805 520 : DoResize( aBorderPos, aFrameSize );
806 :
807 : //! Border muss neu gesetzt werden ???
808 520 : }
809 :
810 1851 : void ScTabView::GetBorderSize( SvBorder& rBorder, const Size& /* rSize */ )
811 : {
812 1851 : bool bScrollBars = aViewData.IsVScrollMode();
813 1851 : bool bHeaders = aViewData.IsHeaderMode();
814 1851 : bool bOutlMode = aViewData.IsOutlineMode();
815 1851 : bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
816 1851 : bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
817 1851 : bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
818 :
819 1851 : rBorder = SvBorder();
820 :
821 1851 : if (bScrollBars) // Scrollbars horizontal oder vertikal
822 : {
823 1812 : rBorder.Right() += aVScrollBottom->GetSizePixel().Width();
824 1812 : rBorder.Bottom() += aHScrollLeft->GetSizePixel().Height();
825 : }
826 :
827 : // Outline-Controls
828 1851 : if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
829 8 : rBorder.Left() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
830 1851 : if (bHOutline && pColOutline[SC_SPLIT_LEFT])
831 4 : rBorder.Top() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
832 :
833 1851 : if (bHeaders) // Spalten/Zeilen-Header
834 : {
835 1849 : rBorder.Left() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
836 1849 : rBorder.Top() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
837 : }
838 :
839 1851 : if ( bLayoutRTL )
840 0 : ::std::swap( rBorder.Left(), rBorder.Right() );
841 1851 : }
842 :
843 0 : IMPL_LINK_NOARG(ScTabView, TabBarResize)
844 : {
845 0 : if (aViewData.IsHScrollMode())
846 : {
847 0 : const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel();
848 0 : long nSize = pTabControl->GetSplitSize();
849 :
850 0 : if (aViewData.GetHSplitMode() != SC_SPLIT_FIX)
851 : {
852 0 : long nMax = pHSplitter->GetPosPixel().X();
853 0 : if( pTabControl->IsEffectiveRTL() )
854 0 : nMax = pFrameWin->GetSizePixel().Width() - nMax;
855 0 : --nMax;
856 0 : if (nSize>nMax) nSize = nMax;
857 : }
858 :
859 0 : if ( nSize != pTabControl->GetSizePixel().Width() )
860 : {
861 0 : pTabControl->SetSizePixel( Size( nSize+nOverlap,
862 0 : pTabControl->GetSizePixel().Height() ) );
863 0 : RepeatResize();
864 : }
865 : }
866 :
867 0 : return 0;
868 : }
869 :
870 471 : void ScTabView::SetTabBarWidth( long nNewWidth )
871 : {
872 471 : Size aSize = pTabControl->GetSizePixel();
873 :
874 471 : if ( aSize.Width() != nNewWidth )
875 : {
876 129 : aSize.Width() = nNewWidth;
877 129 : pTabControl->SetSizePixel( aSize );
878 : }
879 471 : }
880 :
881 193 : void ScTabView::SetRelTabBarWidth( double fRelTabBarWidth )
882 : {
883 193 : if( (0.0 <= fRelTabBarWidth) && (fRelTabBarWidth <= 1.0) )
884 193 : if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
885 192 : SetTabBarWidth( static_cast< long >( fRelTabBarWidth * nFrameWidth + 0.5 ) );
886 193 : }
887 :
888 97 : void ScTabView::SetPendingRelTabBarWidth( double fRelTabBarWidth )
889 : {
890 97 : mfPendingTabBarWidth = fRelTabBarWidth;
891 97 : SetRelTabBarWidth( fRelTabBarWidth );
892 97 : }
893 :
894 262 : long ScTabView::GetTabBarWidth() const
895 : {
896 262 : return pTabControl->GetSizePixel().Width();
897 : }
898 :
899 25 : double ScTabView::GetRelTabBarWidth() const
900 : {
901 25 : if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
902 25 : return static_cast< double >( GetTabBarWidth() ) / nFrameWidth;
903 0 : return 0.0;
904 : }
905 :
906 3663 : ScGridWindow* ScTabView::GetActiveWin()
907 : {
908 3663 : ScSplitPos ePos = aViewData.GetActivePart();
909 : OSL_ENSURE(pGridWin[ePos],"kein aktives Fenster");
910 3663 : return pGridWin[ePos];
911 : }
912 :
913 0 : void ScTabView::SetActivePointer( const Pointer& rPointer )
914 : {
915 0 : for (sal_uInt16 i=0; i<4; i++)
916 0 : if (pGridWin[i])
917 0 : pGridWin[i]->SetPointer( rPointer );
918 0 : }
919 :
920 0 : void ScTabView::ActiveGrabFocus()
921 : {
922 0 : ScSplitPos ePos = aViewData.GetActivePart();
923 0 : if (pGridWin[ePos])
924 0 : pGridWin[ePos]->GrabFocus();
925 0 : }
926 :
927 0 : ScSplitPos ScTabView::FindWindow( vcl::Window* pWindow ) const
928 : {
929 0 : ScSplitPos eVal = SC_SPLIT_BOTTOMLEFT; // Default
930 0 : for (sal_uInt16 i=0; i<4; i++)
931 0 : if ( pGridWin[i] == pWindow )
932 0 : eVal = (ScSplitPos) i;
933 :
934 0 : return eVal;
935 : }
936 :
937 0 : Point ScTabView::GetGridOffset() const
938 : {
939 0 : Point aPos;
940 :
941 : // Groessen hier wie in DoResize
942 :
943 0 : bool bHeaders = aViewData.IsHeaderMode();
944 0 : bool bOutlMode = aViewData.IsOutlineMode();
945 0 : bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
946 0 : bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
947 :
948 : // Outline-Controls
949 0 : if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
950 0 : aPos.X() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
951 0 : if (bHOutline && pColOutline[SC_SPLIT_LEFT])
952 0 : aPos.Y() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
953 :
954 0 : if (bHeaders) // Spalten/Zeilen-Header
955 : {
956 0 : if (pRowBar[SC_SPLIT_BOTTOM])
957 0 : aPos.X() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
958 0 : if (pColBar[SC_SPLIT_LEFT])
959 0 : aPos.Y() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
960 : }
961 :
962 0 : return aPos;
963 : }
964 :
965 : // --- Scroll-Bars --------------------------------------------------------
966 :
967 0 : bool ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos )
968 : {
969 0 : HideNoteMarker();
970 :
971 0 : bool bDone = false;
972 0 : const CommandWheelData* pData = rCEvt.GetWheelData();
973 0 : if ( pData && (pData->GetMode() == CommandWheelMode::ZOOM ||
974 0 : pData->GetMode() == CommandWheelMode::ZOOM_SCALE ) )
975 : {
976 0 : if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() )
977 : {
978 : // for ole inplace editing, the scale is defined by the visarea and client size
979 : // and can't be changed directly
980 :
981 0 : const Fraction& rOldY = aViewData.GetZoomY();
982 0 : long nOld = (long)(( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator());
983 0 : long nNew = nOld;
984 0 : if ( pData->GetMode() == CommandWheelMode::ZOOM_SCALE )
985 : {
986 0 : nNew = 100 * (long) ((nOld / 100.0) * (pData->GetDelta() / 100.0));
987 : } else
988 : {
989 0 : if ( pData->GetDelta() < 0 )
990 0 : nNew = std::max( (long) MINZOOM, basegfx::zoomtools::zoomOut( nOld ));
991 : else
992 0 : nNew = std::min( (long) MAXZOOM, basegfx::zoomtools::zoomIn( nOld ));
993 : }
994 0 : if ( nNew != nOld )
995 : {
996 : // scroll wheel doesn't set the AppOptions default
997 :
998 0 : bool bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
999 0 : SetZoomType( SvxZoomType::PERCENT, bSyncZoom );
1000 0 : Fraction aFract( nNew, 100 );
1001 0 : SetZoom( aFract, aFract, bSyncZoom );
1002 0 : PaintGrid();
1003 0 : PaintTop();
1004 0 : PaintLeft();
1005 0 : aViewData.GetBindings().Invalidate( SID_ATTR_ZOOM );
1006 0 : aViewData.GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
1007 : }
1008 :
1009 0 : bDone = true;
1010 : }
1011 : }
1012 : else
1013 : {
1014 0 : ScHSplitPos eHPos = WhichH(ePos);
1015 0 : ScVSplitPos eVPos = WhichV(ePos);
1016 0 : ScrollBar* pHScroll = ( eHPos == SC_SPLIT_LEFT ) ? aHScrollLeft.get() : aHScrollRight.get();
1017 0 : ScrollBar* pVScroll = ( eVPos == SC_SPLIT_TOP ) ? aVScrollTop.get() : aVScrollBottom.get();
1018 0 : if ( pGridWin[ePos] )
1019 0 : bDone = pGridWin[ePos]->HandleScrollCommand( rCEvt, pHScroll, pVScroll );
1020 : }
1021 0 : return bDone;
1022 : }
1023 :
1024 0 : IMPL_LINK_NOARG(ScTabView, EndScrollHdl)
1025 : {
1026 0 : if ( bDragging )
1027 : {
1028 0 : UpdateScrollBars();
1029 0 : bDragging = false;
1030 : }
1031 0 : return 0;
1032 : }
1033 :
1034 0 : IMPL_LINK( ScTabView, ScrollHdl, ScrollBar*, pScroll )
1035 : {
1036 0 : bool bHoriz = ( pScroll == aHScrollLeft.get() || pScroll == aHScrollRight.get() );
1037 : long nViewPos;
1038 0 : if ( bHoriz )
1039 0 : nViewPos = aViewData.GetPosX( (pScroll == aHScrollLeft.get()) ?
1040 0 : SC_SPLIT_LEFT : SC_SPLIT_RIGHT );
1041 : else
1042 0 : nViewPos = aViewData.GetPosY( (pScroll == aVScrollTop.get()) ?
1043 0 : SC_SPLIT_TOP : SC_SPLIT_BOTTOM );
1044 :
1045 0 : bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1046 :
1047 0 : ScrollType eType = pScroll->GetType();
1048 0 : if ( eType == SCROLL_DRAG )
1049 : {
1050 0 : if (!bDragging)
1051 : {
1052 0 : bDragging = true;
1053 0 : nPrevDragPos = nViewPos;
1054 : }
1055 :
1056 : // Scroll-Position anzeigen
1057 : // (nur QuickHelp, in der Statuszeile gibt es keinen Eintrag dafuer)
1058 :
1059 0 : if (Help::IsQuickHelpEnabled())
1060 : {
1061 0 : Size aSize = pScroll->GetSizePixel();
1062 :
1063 : /* Convert scrollbar mouse position to screen position. If RTL
1064 : mode of scrollbar differs from RTL mode of its parent, then the
1065 : direct call to Window::OutputToNormalizedScreenPixel() will
1066 : give unusable results, because calcualtion of screen position
1067 : is based on parent orientation and expects equal orientation of
1068 : the child position. Need to mirror mouse position before. */
1069 0 : Point aMousePos = pScroll->GetPointerPosPixel();
1070 0 : if( pScroll->IsRTLEnabled() != pScroll->GetParent()->IsRTLEnabled() )
1071 0 : aMousePos.X() = aSize.Width() - aMousePos.X() - 1;
1072 0 : aMousePos = pScroll->OutputToNormalizedScreenPixel( aMousePos );
1073 :
1074 : // convert top-left position of scrollbar to screen position
1075 0 : Point aPos = pScroll->OutputToNormalizedScreenPixel( Point() );
1076 :
1077 : // get scrollbar scroll position for help text (row number/column name)
1078 0 : long nScrollMin = 0; // RangeMin simulieren
1079 0 : if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == aHScrollRight.get() )
1080 0 : nScrollMin = aViewData.GetFixPosX();
1081 0 : if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == aVScrollBottom.get() )
1082 0 : nScrollMin = aViewData.GetFixPosY();
1083 0 : long nScrollPos = GetScrollBarPos( *pScroll ) + nScrollMin;
1084 :
1085 0 : OUString aHelpStr;
1086 0 : Rectangle aRect;
1087 : QuickHelpFlags nAlign;
1088 0 : if (bHoriz)
1089 : {
1090 0 : aHelpStr = ScGlobal::GetRscString(STR_COLUMN) +
1091 0 : " " + ScColToAlpha((SCCOL) nScrollPos);
1092 :
1093 0 : aRect.Left() = aMousePos.X();
1094 0 : aRect.Top() = aPos.Y() - 4;
1095 0 : nAlign = QuickHelpFlags::Bottom|QuickHelpFlags::Center;
1096 : }
1097 : else
1098 : {
1099 0 : aHelpStr = ScGlobal::GetRscString(STR_ROW) +
1100 0 : " " + OUString::number(nScrollPos + 1);
1101 :
1102 : // show quicktext always inside sheet area
1103 0 : aRect.Left() = bLayoutRTL ? (aPos.X() + aSize.Width() + 8) : (aPos.X() - 8);
1104 0 : aRect.Top() = aMousePos.Y();
1105 0 : nAlign = (bLayoutRTL ? QuickHelpFlags::Left : QuickHelpFlags::Right) | QuickHelpFlags::VCenter;
1106 : }
1107 0 : aRect.Right() = aRect.Left();
1108 0 : aRect.Bottom() = aRect.Top();
1109 :
1110 0 : Help::ShowQuickHelp(pScroll->GetParent(), aRect, aHelpStr, nAlign);
1111 : }
1112 : }
1113 :
1114 0 : long nDelta = pScroll->GetDelta();
1115 0 : switch ( eType )
1116 : {
1117 : case SCROLL_LINEUP:
1118 0 : nDelta = -1;
1119 0 : break;
1120 : case SCROLL_LINEDOWN:
1121 0 : nDelta = 1;
1122 0 : break;
1123 : case SCROLL_PAGEUP:
1124 0 : if ( pScroll == aHScrollLeft.get() ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_LEFT );
1125 0 : if ( pScroll == aHScrollRight.get() ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_RIGHT );
1126 0 : if ( pScroll == aVScrollTop.get() ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_TOP );
1127 0 : if ( pScroll == aVScrollBottom.get() ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_BOTTOM );
1128 0 : if (nDelta==0) nDelta=-1;
1129 0 : break;
1130 : case SCROLL_PAGEDOWN:
1131 0 : if ( pScroll == aHScrollLeft.get() ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_LEFT );
1132 0 : if ( pScroll == aHScrollRight.get() ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_RIGHT );
1133 0 : if ( pScroll == aVScrollTop.get() ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_TOP );
1134 0 : if ( pScroll == aVScrollBottom.get() ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM );
1135 0 : if (nDelta==0) nDelta=1;
1136 0 : break;
1137 : case SCROLL_DRAG:
1138 : {
1139 : // nur in die richtige Richtung scrollen, nicht um ausgeblendete
1140 : // Bereiche herumzittern
1141 :
1142 0 : long nScrollMin = 0; // RangeMin simulieren
1143 0 : if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == aHScrollRight.get() )
1144 0 : nScrollMin = aViewData.GetFixPosX();
1145 0 : if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == aVScrollBottom.get() )
1146 0 : nScrollMin = aViewData.GetFixPosY();
1147 :
1148 0 : long nScrollPos = GetScrollBarPos( *pScroll ) + nScrollMin;
1149 0 : nDelta = nScrollPos - nViewPos;
1150 0 : if ( nScrollPos > nPrevDragPos )
1151 : {
1152 0 : if (nDelta<0) nDelta=0;
1153 : }
1154 0 : else if ( nScrollPos < nPrevDragPos )
1155 : {
1156 0 : if (nDelta>0) nDelta=0;
1157 : }
1158 : else
1159 0 : nDelta = 0;
1160 0 : nPrevDragPos = nScrollPos;
1161 : }
1162 0 : break;
1163 : default:
1164 : {
1165 : // added to avoid warnings
1166 : }
1167 : }
1168 :
1169 0 : if (nDelta)
1170 : {
1171 0 : bool bUpdate = ( eType != SCROLL_DRAG ); // bei Drag die Ranges nicht aendern
1172 0 : if ( bHoriz )
1173 0 : ScrollX( nDelta, (pScroll == aHScrollLeft.get()) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT, bUpdate );
1174 : else
1175 0 : ScrollY( nDelta, (pScroll == aVScrollTop.get()) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM, bUpdate );
1176 : }
1177 :
1178 0 : return 0;
1179 : }
1180 :
1181 55 : void ScTabView::ScrollX( long nDeltaX, ScHSplitPos eWhich, bool bUpdBars )
1182 : {
1183 55 : SCCOL nOldX = aViewData.GetPosX(eWhich);
1184 55 : SCsCOL nNewX = static_cast<SCsCOL>(nOldX) + static_cast<SCsCOL>(nDeltaX);
1185 55 : if ( nNewX < 0 )
1186 : {
1187 0 : nDeltaX -= nNewX;
1188 0 : nNewX = 0;
1189 : }
1190 55 : if ( nNewX > MAXCOL )
1191 : {
1192 0 : nDeltaX -= nNewX - MAXCOL;
1193 0 : nNewX = MAXCOL;
1194 : }
1195 :
1196 55 : SCsCOL nDir = ( nDeltaX > 0 ) ? 1 : -1;
1197 55 : ScDocument* pDoc = aViewData.GetDocument();
1198 55 : SCTAB nTab = aViewData.GetTabNo();
1199 165 : while ( pDoc->ColHidden(nNewX, nTab) &&
1200 55 : nNewX+nDir >= 0 && nNewX+nDir <= MAXCOL )
1201 0 : nNewX = sal::static_int_cast<SCsCOL>( nNewX + nDir );
1202 :
1203 : // Fixierung
1204 :
1205 55 : if (aViewData.GetHSplitMode() == SC_SPLIT_FIX)
1206 : {
1207 0 : if (eWhich == SC_SPLIT_LEFT)
1208 0 : nNewX = static_cast<SCsCOL>(nOldX); // links immer stehenlassen
1209 : else
1210 : {
1211 0 : SCsCOL nFixX = static_cast<SCsCOL>(aViewData.GetFixPosX());
1212 0 : if (nNewX < nFixX)
1213 0 : nNewX = nFixX;
1214 : }
1215 : }
1216 55 : if (nNewX == static_cast<SCsCOL>(nOldX))
1217 59 : return;
1218 :
1219 51 : HideAllCursors();
1220 :
1221 51 : if ( nNewX >= 0 && nNewX <= MAXCOL && nDeltaX )
1222 : {
1223 51 : SCCOL nTrackX = std::max( nOldX, static_cast<SCCOL>(nNewX) );
1224 :
1225 : // Mit VCL wirkt Update() im Moment immer auf alle Fenster, beim Update
1226 : // nach dem Scrollen des GridWindow's wuerde darum der Col-/RowBar evtl.
1227 : // mit schon geaenderter Pos. gepainted werden -
1228 : // darum vorher einmal Update am Col-/RowBar
1229 :
1230 51 : if (pColBar[eWhich])
1231 51 : pColBar[eWhich]->Update();
1232 :
1233 51 : long nOldPos = aViewData.GetScrPos( nTrackX, 0, eWhich ).X();
1234 51 : aViewData.SetPosX( eWhich, static_cast<SCCOL>(nNewX) );
1235 51 : long nDiff = aViewData.GetScrPos( nTrackX, 0, eWhich ).X() - nOldPos;
1236 :
1237 51 : if ( eWhich==SC_SPLIT_LEFT )
1238 : {
1239 51 : pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( nDiff, 0 );
1240 51 : if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
1241 1 : pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( nDiff, 0 );
1242 : }
1243 : else
1244 : {
1245 0 : pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( nDiff, 0 );
1246 0 : if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
1247 0 : pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( nDiff, 0 );
1248 : }
1249 51 : if (pColBar[eWhich]) { pColBar[eWhich]->Scroll( nDiff,0 ); pColBar[eWhich]->Update(); }
1250 51 : if (pColOutline[eWhich]) pColOutline[eWhich]->ScrollPixel( nDiff );
1251 51 : if (bUpdBars)
1252 51 : UpdateScrollBars();
1253 : }
1254 :
1255 51 : if (nDeltaX==1 || nDeltaX==-1)
1256 0 : pGridWin[aViewData.GetActivePart()]->Update();
1257 :
1258 51 : ShowAllCursors();
1259 :
1260 51 : SetNewVisArea(); // MapMode muss schon gesetzt sein
1261 :
1262 51 : TestHintWindow();
1263 : }
1264 :
1265 65 : void ScTabView::ScrollY( long nDeltaY, ScVSplitPos eWhich, bool bUpdBars )
1266 : {
1267 65 : SCROW nOldY = aViewData.GetPosY(eWhich);
1268 65 : SCsROW nNewY = static_cast<SCsROW>(nOldY) + static_cast<SCsROW>(nDeltaY);
1269 65 : if ( nNewY < 0 )
1270 : {
1271 0 : nDeltaY -= nNewY;
1272 0 : nNewY = 0;
1273 : }
1274 65 : if ( nNewY > MAXROW )
1275 : {
1276 0 : nDeltaY -= nNewY - MAXROW;
1277 0 : nNewY = MAXROW;
1278 : }
1279 :
1280 65 : SCsROW nDir = ( nDeltaY > 0 ) ? 1 : -1;
1281 65 : ScDocument* pDoc = aViewData.GetDocument();
1282 65 : SCTAB nTab = aViewData.GetTabNo();
1283 195 : while ( pDoc->RowHidden(nNewY, nTab) &&
1284 65 : nNewY+nDir >= 0 && nNewY+nDir <= MAXROW )
1285 0 : nNewY += nDir;
1286 :
1287 : // Fixierung
1288 :
1289 65 : if (aViewData.GetVSplitMode() == SC_SPLIT_FIX)
1290 : {
1291 0 : if (eWhich == SC_SPLIT_TOP)
1292 0 : nNewY = static_cast<SCsROW>(nOldY); // oben immer stehenlassen
1293 : else
1294 : {
1295 0 : SCsROW nFixY = static_cast<SCsROW>(aViewData.GetFixPosY());
1296 0 : if (nNewY < nFixY)
1297 0 : nNewY = nFixY;
1298 : }
1299 : }
1300 65 : if (nNewY == static_cast<SCsROW>(nOldY))
1301 73 : return;
1302 :
1303 57 : HideAllCursors();
1304 :
1305 57 : if ( nNewY >= 0 && nNewY <= MAXROW && nDeltaY )
1306 : {
1307 57 : SCROW nTrackY = std::max( nOldY, static_cast<SCROW>(nNewY) );
1308 :
1309 : // Zeilenkoepfe anpassen vor dem eigentlichen Scrolling, damit nicht
1310 : // doppelt gepainted werden muss
1311 : // PosY darf dann auch noch nicht umgesetzt sein, neuen Wert uebergeben
1312 57 : SCROW nUNew = static_cast<SCROW>(nNewY);
1313 57 : UpdateHeaderWidth( &eWhich, &nUNew ); // Zeilenkoepfe anpassen
1314 :
1315 57 : if (pRowBar[eWhich])
1316 57 : pRowBar[eWhich]->Update();
1317 :
1318 57 : long nOldPos = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y();
1319 57 : aViewData.SetPosY( eWhich, static_cast<SCROW>(nNewY) );
1320 57 : long nDiff = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y() - nOldPos;
1321 :
1322 57 : if ( eWhich==SC_SPLIT_TOP )
1323 : {
1324 0 : pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( 0, nDiff );
1325 0 : if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
1326 0 : pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( 0, nDiff );
1327 : }
1328 : else
1329 : {
1330 57 : pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( 0, nDiff );
1331 57 : if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
1332 0 : pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( 0, nDiff );
1333 : }
1334 57 : if (pRowBar[eWhich]) { pRowBar[eWhich]->Scroll( 0,nDiff ); pRowBar[eWhich]->Update(); }
1335 57 : if (pRowOutline[eWhich]) pRowOutline[eWhich]->ScrollPixel( nDiff );
1336 57 : if (bUpdBars)
1337 57 : UpdateScrollBars();
1338 : }
1339 :
1340 57 : if (nDeltaY==1 || nDeltaY==-1)
1341 0 : pGridWin[aViewData.GetActivePart()]->Update();
1342 :
1343 57 : ShowAllCursors();
1344 :
1345 57 : SetNewVisArea(); // MapMode muss schon gesetzt sein
1346 :
1347 57 : TestHintWindow();
1348 : }
1349 :
1350 6 : void ScTabView::ScrollLines( long nDeltaX, long nDeltaY )
1351 : {
1352 6 : ScSplitPos eWhich = aViewData.GetActivePart();
1353 6 : if (nDeltaX)
1354 3 : ScrollX(nDeltaX,WhichH(eWhich));
1355 6 : if (nDeltaY)
1356 3 : ScrollY(nDeltaY,WhichV(eWhich));
1357 6 : }
1358 :
1359 : namespace
1360 : {
1361 :
1362 8 : SCROW lcl_LastVisible( ScViewData& rViewData )
1363 : {
1364 : // wenn am Dokumentende viele Zeilen ausgeblendet sind (welcher Trottel macht sowas?),
1365 : // soll dadurch nicht auf breite Zeilenkoepfe geschaltet werden
1366 : //! als Member ans Dokument ???
1367 :
1368 8 : ScDocument* pDoc = rViewData.GetDocument();
1369 8 : SCTAB nTab = rViewData.GetTabNo();
1370 :
1371 8 : SCROW nVis = MAXROW;
1372 16 : while ( nVis > 0 && pDoc->GetRowHeight( nVis, nTab ) == 0 )
1373 0 : --nVis;
1374 8 : return nVis;
1375 : }
1376 :
1377 : } // anonymous namespace
1378 :
1379 9036 : void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY )
1380 : {
1381 9036 : if ( !pRowBar[SC_SPLIT_BOTTOM] || MAXROW < 10000 )
1382 9036 : return;
1383 :
1384 9036 : SCROW nEndPos = MAXROW;
1385 9036 : if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() )
1386 : {
1387 : // fuer OLE Inplace immer MAXROW
1388 :
1389 9036 : if ( pWhich && *pWhich == SC_SPLIT_BOTTOM && pPosY )
1390 57 : nEndPos = *pPosY;
1391 : else
1392 8979 : nEndPos = aViewData.GetPosY( SC_SPLIT_BOTTOM );
1393 9036 : nEndPos += aViewData.CellsAtY( nEndPos, 1, SC_SPLIT_BOTTOM, SC_SIZE_NONE ); // VisibleCellsY
1394 9036 : if (nEndPos > MAXROW)
1395 8 : nEndPos = lcl_LastVisible( aViewData );
1396 :
1397 9036 : if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
1398 : {
1399 : SCROW nTopEnd;
1400 13 : if ( pWhich && *pWhich == SC_SPLIT_TOP && pPosY )
1401 0 : nTopEnd = *pPosY;
1402 : else
1403 13 : nTopEnd = aViewData.GetPosY( SC_SPLIT_TOP );
1404 13 : nTopEnd += aViewData.CellsAtY( nTopEnd, 1, SC_SPLIT_TOP, SC_SIZE_NONE );// VisibleCellsY
1405 13 : if (nTopEnd > MAXROW)
1406 0 : nTopEnd = lcl_LastVisible( aViewData );
1407 :
1408 13 : if ( nTopEnd > nEndPos )
1409 2 : nEndPos = nTopEnd;
1410 : }
1411 : }
1412 :
1413 9036 : long nSmall = pRowBar[SC_SPLIT_BOTTOM]->GetSmallWidth();
1414 9036 : long nBig = pRowBar[SC_SPLIT_BOTTOM]->GetBigWidth();
1415 9036 : long nDiff = nBig - nSmall;
1416 :
1417 9036 : if (nEndPos>10000)
1418 20 : nEndPos = 10000;
1419 9016 : else if (nEndPos<1) // avoid extra step at 0 (when only one row is visible)
1420 1 : nEndPos = 1;
1421 9036 : long nWidth = nBig - ( 10000 - nEndPos ) * nDiff / 10000;
1422 :
1423 9036 : if ( nWidth != pRowBar[SC_SPLIT_BOTTOM]->GetWidth() && !bInUpdateHeader )
1424 : {
1425 378 : bInUpdateHeader = true;
1426 :
1427 378 : pRowBar[SC_SPLIT_BOTTOM]->SetWidth( nWidth );
1428 378 : if (pRowBar[SC_SPLIT_TOP])
1429 0 : pRowBar[SC_SPLIT_TOP]->SetWidth( nWidth );
1430 :
1431 378 : RepeatResize();
1432 :
1433 : // auf VCL gibt's Update ohne Ende (jedes Update gilt fuer alle Fenster)
1434 : //aCornerButton->Update(); // der bekommt sonst nie ein Update
1435 :
1436 378 : bInUpdateHeader = false;
1437 : }
1438 : }
1439 :
1440 42432 : inline void ShowHide( vcl::Window* pWin, bool bShow )
1441 : {
1442 : OSL_ENSURE(pWin || !bShow, "Fenster ist nicht da");
1443 42432 : if (pWin)
1444 20319 : pWin->Show(bShow);
1445 42432 : }
1446 :
1447 2496 : void ScTabView::UpdateShow()
1448 : {
1449 2496 : bool bHScrollMode = aViewData.IsHScrollMode();
1450 2496 : bool bVScrollMode = aViewData.IsVScrollMode();
1451 2496 : bool bTabMode = aViewData.IsTabMode();
1452 2496 : bool bOutlMode = aViewData.IsOutlineMode();
1453 2496 : bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
1454 2496 : bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
1455 2496 : bool bHeader = aViewData.IsHeaderMode();
1456 :
1457 2496 : bool bShowH = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE );
1458 2496 : bool bShowV = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE );
1459 :
1460 2496 : if ( aViewData.GetDocShell()->IsPreview() )
1461 0 : bHScrollMode = bVScrollMode = bTabMode = bHeader = bOutlMode = bHOutline = bVOutline = false;
1462 :
1463 : // Windows anlegen
1464 :
1465 2496 : if (bShowH && !pGridWin[SC_SPLIT_BOTTOMRIGHT])
1466 : {
1467 1 : pGridWin[SC_SPLIT_BOTTOMRIGHT] = VclPtr<ScGridWindow>::Create( pFrameWin, &aViewData, SC_SPLIT_BOTTOMRIGHT );
1468 1 : DoAddWin( pGridWin[SC_SPLIT_BOTTOMRIGHT] );
1469 : }
1470 2496 : if (bShowV && !pGridWin[SC_SPLIT_TOPLEFT])
1471 : {
1472 1 : pGridWin[SC_SPLIT_TOPLEFT] = VclPtr<ScGridWindow>::Create( pFrameWin, &aViewData, SC_SPLIT_TOPLEFT );
1473 1 : DoAddWin( pGridWin[SC_SPLIT_TOPLEFT] );
1474 : }
1475 2496 : if (bShowH && bShowV && !pGridWin[SC_SPLIT_TOPRIGHT])
1476 : {
1477 1 : pGridWin[SC_SPLIT_TOPRIGHT] = VclPtr<ScGridWindow>::Create( pFrameWin, &aViewData, SC_SPLIT_TOPRIGHT );
1478 1 : DoAddWin( pGridWin[SC_SPLIT_TOPRIGHT] );
1479 : }
1480 :
1481 2496 : if (bHOutline && !pColOutline[SC_SPLIT_LEFT])
1482 1 : pColOutline[SC_SPLIT_LEFT] = VclPtr<ScOutlineWindow>::Create( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMLEFT );
1483 2496 : if (bShowH && bHOutline && !pColOutline[SC_SPLIT_RIGHT])
1484 0 : pColOutline[SC_SPLIT_RIGHT] = VclPtr<ScOutlineWindow>::Create( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMRIGHT );
1485 :
1486 2496 : if (bVOutline && !pRowOutline[SC_SPLIT_BOTTOM])
1487 4 : pRowOutline[SC_SPLIT_BOTTOM] = VclPtr<ScOutlineWindow>::Create( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_BOTTOMLEFT );
1488 2496 : if (bShowV && bVOutline && !pRowOutline[SC_SPLIT_TOP])
1489 0 : pRowOutline[SC_SPLIT_TOP] = VclPtr<ScOutlineWindow>::Create( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_TOPLEFT );
1490 :
1491 2496 : if (bShowH && bHeader && !pColBar[SC_SPLIT_RIGHT])
1492 2 : pColBar[SC_SPLIT_RIGHT] = VclPtr<ScColBar>::Create( pFrameWin, &aViewData, SC_SPLIT_RIGHT,
1493 1 : &aHdrFunc, pHdrSelEng );
1494 2496 : if (bShowV && bHeader && !pRowBar[SC_SPLIT_TOP])
1495 2 : pRowBar[SC_SPLIT_TOP] = VclPtr<ScRowBar>::Create( pFrameWin, &aViewData, SC_SPLIT_TOP,
1496 1 : &aHdrFunc, pHdrSelEng );
1497 :
1498 : // Windows anzeigen
1499 :
1500 2496 : ShowHide( aHScrollLeft.get(), bHScrollMode );
1501 2496 : ShowHide( aHScrollRight.get(), bShowH && bHScrollMode );
1502 2496 : ShowHide( aVScrollBottom.get(), bVScrollMode );
1503 2496 : ShowHide( aVScrollTop.get(), bShowV && bVScrollMode );
1504 2496 : ShowHide( aScrollBarBox.get(), bVScrollMode || bHScrollMode );
1505 :
1506 2496 : ShowHide( pHSplitter, bHScrollMode || bShowH ); // immer angelegt
1507 2496 : ShowHide( pVSplitter, bVScrollMode || bShowV );
1508 2496 : ShowHide( pTabControl, bTabMode );
1509 :
1510 : // ab hier dynamisch angelegte
1511 :
1512 2496 : ShowHide( pGridWin[SC_SPLIT_BOTTOMRIGHT], bShowH );
1513 2496 : ShowHide( pGridWin[SC_SPLIT_TOPLEFT], bShowV );
1514 2496 : ShowHide( pGridWin[SC_SPLIT_TOPRIGHT], bShowH && bShowV );
1515 :
1516 2496 : ShowHide( pColOutline[SC_SPLIT_LEFT], bHOutline );
1517 2496 : ShowHide( pColOutline[SC_SPLIT_RIGHT], bShowH && bHOutline );
1518 :
1519 2496 : ShowHide( pRowOutline[SC_SPLIT_BOTTOM], bVOutline );
1520 2496 : ShowHide( pRowOutline[SC_SPLIT_TOP], bShowV && bVOutline );
1521 :
1522 2496 : ShowHide( pColBar[SC_SPLIT_RIGHT], bShowH && bHeader );
1523 2496 : ShowHide( pRowBar[SC_SPLIT_TOP], bShowV && bHeader );
1524 :
1525 : //! neue Gridwindows eintragen
1526 2496 : }
1527 :
1528 3492 : bool ScTabView::UpdateVisibleRange()
1529 : {
1530 3492 : bool bChanged = false;
1531 17460 : for (int i = 0; i < 4; ++i)
1532 : {
1533 13968 : if (!pGridWin[i] || !pGridWin[i]->IsVisible())
1534 10802 : continue;
1535 :
1536 3166 : if (pGridWin[i]->UpdateVisibleRange())
1537 1241 : bChanged = true;
1538 : }
1539 :
1540 3492 : return bChanged;
1541 : }
1542 :
1543 : // --- Splitter --------------------------------------------------------
1544 :
1545 0 : IMPL_LINK( ScTabView, SplitHdl, Splitter*, pSplitter )
1546 : {
1547 0 : if ( pSplitter == pHSplitter )
1548 0 : DoHSplit( pHSplitter->GetSplitPosPixel() );
1549 : else
1550 0 : DoVSplit( pVSplitter->GetSplitPosPixel() );
1551 :
1552 0 : if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1553 0 : FreezeSplitters( true );
1554 :
1555 0 : DoResize( aBorderPos, aFrameSize );
1556 :
1557 0 : return 0;
1558 : }
1559 :
1560 18 : void ScTabView::DoHSplit(long nSplitPos)
1561 : {
1562 : // nSplitPos is the real pixel position on the frame window,
1563 : // mirroring for RTL has to be done here.
1564 :
1565 18 : bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1566 18 : if ( bLayoutRTL )
1567 0 : nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
1568 :
1569 : long nMinPos;
1570 : long nMaxPos;
1571 : SCCOL nOldDelta;
1572 : SCCOL nNewDelta;
1573 :
1574 18 : nMinPos = SPLIT_MARGIN;
1575 18 : if ( pRowBar[SC_SPLIT_BOTTOM] && pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() >= nMinPos )
1576 18 : nMinPos = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() + 1;
1577 18 : nMaxPos = aFrameSize.Width() - SPLIT_MARGIN;
1578 :
1579 18 : ScSplitMode aOldMode = aViewData.GetHSplitMode();
1580 18 : ScSplitMode aNewMode = SC_SPLIT_NORMAL;
1581 :
1582 18 : aViewData.SetHSplitPos( nSplitPos );
1583 18 : if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
1584 14 : aNewMode = SC_SPLIT_NONE;
1585 :
1586 18 : aViewData.SetHSplitMode( aNewMode );
1587 :
1588 18 : if ( aNewMode != aOldMode )
1589 : {
1590 8 : UpdateShow(); // vor ActivatePart !!
1591 :
1592 8 : if ( aNewMode == SC_SPLIT_NONE )
1593 : {
1594 4 : if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
1595 0 : ActivatePart( SC_SPLIT_TOPLEFT );
1596 4 : if (aViewData.GetActivePart() == SC_SPLIT_BOTTOMRIGHT)
1597 3 : ActivatePart( SC_SPLIT_BOTTOMLEFT );
1598 : }
1599 : else
1600 : {
1601 4 : nOldDelta = aViewData.GetPosX( SC_SPLIT_LEFT );
1602 4 : long nLeftWidth = nSplitPos - pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
1603 4 : if ( nLeftWidth < 0 ) nLeftWidth = 0;
1604 : nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, SC_SPLIT_LEFT,
1605 4 : (sal_uInt16) nLeftWidth );
1606 4 : if ( nNewDelta > MAXCOL )
1607 0 : nNewDelta = MAXCOL;
1608 4 : aViewData.SetPosX( SC_SPLIT_RIGHT, nNewDelta );
1609 4 : if ( nNewDelta > aViewData.GetCurX() )
1610 1 : ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
1611 1 : SC_SPLIT_BOTTOMLEFT : SC_SPLIT_TOPLEFT );
1612 : else
1613 3 : ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
1614 3 : SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_TOPRIGHT );
1615 : }
1616 :
1617 : // Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
1618 : // dafuer muss hier schon der MapMode stimmen
1619 40 : for (sal_uInt16 i=0; i<4; i++)
1620 32 : if (pGridWin[i])
1621 32 : pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
1622 8 : SetNewVisArea();
1623 :
1624 8 : PaintGrid();
1625 8 : PaintTop();
1626 :
1627 8 : InvalidateSplit();
1628 : }
1629 18 : }
1630 :
1631 18 : void ScTabView::DoVSplit(long nSplitPos)
1632 : {
1633 : long nMinPos;
1634 : long nMaxPos;
1635 : SCROW nOldDelta;
1636 : SCROW nNewDelta;
1637 :
1638 18 : nMinPos = SPLIT_MARGIN;
1639 18 : if ( pColBar[SC_SPLIT_LEFT] && pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() >= nMinPos )
1640 0 : nMinPos = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() + 1;
1641 18 : nMaxPos = aFrameSize.Height() - SPLIT_MARGIN;
1642 :
1643 18 : ScSplitMode aOldMode = aViewData.GetVSplitMode();
1644 18 : ScSplitMode aNewMode = SC_SPLIT_NORMAL;
1645 :
1646 18 : aViewData.SetVSplitPos( nSplitPos );
1647 18 : if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
1648 11 : aNewMode = SC_SPLIT_NONE;
1649 :
1650 18 : aViewData.SetVSplitMode( aNewMode );
1651 :
1652 18 : if ( aNewMode != aOldMode )
1653 : {
1654 12 : UpdateShow(); // vor ActivatePart !!
1655 :
1656 12 : if ( aNewMode == SC_SPLIT_NONE )
1657 : {
1658 6 : nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
1659 6 : aViewData.SetPosY( SC_SPLIT_BOTTOM, nOldDelta );
1660 :
1661 6 : if (aViewData.GetActivePart() == SC_SPLIT_TOPLEFT)
1662 1 : ActivatePart( SC_SPLIT_BOTTOMLEFT );
1663 6 : if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
1664 0 : ActivatePart( SC_SPLIT_BOTTOMRIGHT );
1665 : }
1666 : else
1667 : {
1668 6 : if ( aOldMode == SC_SPLIT_NONE )
1669 6 : nOldDelta = aViewData.GetPosY( SC_SPLIT_BOTTOM );
1670 : else
1671 0 : nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
1672 :
1673 6 : aViewData.SetPosY( SC_SPLIT_TOP, nOldDelta );
1674 6 : long nTopHeight = nSplitPos - pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
1675 6 : if ( nTopHeight < 0 ) nTopHeight = 0;
1676 : nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, SC_SPLIT_TOP,
1677 6 : (sal_uInt16) nTopHeight );
1678 6 : if ( nNewDelta > MAXROW )
1679 0 : nNewDelta = MAXROW;
1680 6 : aViewData.SetPosY( SC_SPLIT_BOTTOM, nNewDelta );
1681 6 : if ( nNewDelta > aViewData.GetCurY() )
1682 1 : ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
1683 1 : SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
1684 : else
1685 5 : ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
1686 5 : SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
1687 : }
1688 :
1689 : // Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
1690 : // dafuer muss hier schon der MapMode stimmen
1691 60 : for (sal_uInt16 i=0; i<4; i++)
1692 48 : if (pGridWin[i])
1693 46 : pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
1694 12 : SetNewVisArea();
1695 :
1696 12 : PaintGrid();
1697 12 : PaintLeft();
1698 :
1699 12 : InvalidateSplit();
1700 : }
1701 18 : }
1702 :
1703 0 : Point ScTabView::GetInsertPos()
1704 : {
1705 0 : ScDocument* pDoc = aViewData.GetDocument();
1706 0 : SCCOL nCol = aViewData.GetCurX();
1707 0 : SCROW nRow = aViewData.GetCurY();
1708 0 : SCTAB nTab = aViewData.GetTabNo();
1709 0 : long nPosX = 0;
1710 0 : for (SCCOL i=0; i<nCol; i++)
1711 0 : nPosX += pDoc->GetColWidth(i,nTab);
1712 0 : nPosX = (long)(nPosX * HMM_PER_TWIPS);
1713 0 : if ( pDoc->IsNegativePage( nTab ) )
1714 0 : nPosX = -nPosX;
1715 0 : long nPosY = (long) pDoc->GetRowHeight( 0, nRow-1, nTab);
1716 0 : nPosY = (long)(nPosY * HMM_PER_TWIPS);
1717 0 : return Point(nPosX,nPosY);
1718 : }
1719 :
1720 0 : Point ScTabView::GetChartInsertPos( const Size& rSize, const ScRange& rCellRange )
1721 : {
1722 0 : Point aInsertPos;
1723 0 : const long nBorder = 100; // leave 1mm for border
1724 0 : long nNeededWidth = rSize.Width() + 2 * nBorder;
1725 0 : long nNeededHeight = rSize.Height() + 2 * nBorder;
1726 :
1727 : // use the active window, or lower/right if frozen (as in CalcZoom)
1728 0 : ScSplitPos eUsedPart = aViewData.GetActivePart();
1729 0 : if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1730 0 : eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
1731 0 : if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1732 0 : eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1733 :
1734 0 : ScGridWindow* pWin = pGridWin[eUsedPart];
1735 : OSL_ENSURE( pWin, "Window not found" );
1736 0 : if (pWin)
1737 : {
1738 0 : ActivatePart( eUsedPart );
1739 :
1740 : // get the visible rectangle in logic units
1741 :
1742 0 : MapMode aDrawMode = pWin->GetDrawMapMode();
1743 0 : Rectangle aVisible( pWin->PixelToLogic( Rectangle( Point(0,0), pWin->GetOutputSizePixel() ), aDrawMode ) );
1744 :
1745 0 : ScDocument* pDoc = aViewData.GetDocument();
1746 0 : SCTAB nTab = aViewData.GetTabNo();
1747 0 : bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1748 0 : long nLayoutSign = bLayoutRTL ? -1 : 1;
1749 :
1750 0 : long nDocX = (long)( (double) pDoc->GetColOffset( MAXCOL + 1, nTab ) * HMM_PER_TWIPS ) * nLayoutSign;
1751 0 : long nDocY = (long)( (double) pDoc->GetRowOffset( MAXROW + 1, nTab ) * HMM_PER_TWIPS );
1752 :
1753 0 : if ( aVisible.Left() * nLayoutSign > nDocX * nLayoutSign )
1754 0 : aVisible.Left() = nDocX;
1755 0 : if ( aVisible.Right() * nLayoutSign > nDocX * nLayoutSign )
1756 0 : aVisible.Right() = nDocX;
1757 0 : if ( aVisible.Top() > nDocY )
1758 0 : aVisible.Top() = nDocY;
1759 0 : if ( aVisible.Bottom() > nDocY )
1760 0 : aVisible.Bottom() = nDocY;
1761 :
1762 : // get the logic position of the selection
1763 :
1764 0 : Rectangle aSelection = pDoc->GetMMRect( rCellRange.aStart.Col(), rCellRange.aStart.Row(),
1765 0 : rCellRange.aEnd.Col(), rCellRange.aEnd.Row(), nTab );
1766 :
1767 0 : long nLeftSpace = aSelection.Left() - aVisible.Left();
1768 0 : long nRightSpace = aVisible.Right() - aSelection.Right();
1769 0 : long nTopSpace = aSelection.Top() - aVisible.Top();
1770 0 : long nBottomSpace = aVisible.Bottom() - aSelection.Bottom();
1771 :
1772 0 : bool bFitLeft = ( nLeftSpace >= nNeededWidth );
1773 0 : bool bFitRight = ( nRightSpace >= nNeededWidth );
1774 :
1775 0 : if ( bFitLeft || bFitRight )
1776 : {
1777 : // first preference: completely left or right of the selection
1778 :
1779 : // if both fit, prefer left in RTL mode, right otherwise
1780 0 : bool bPutLeft = bFitLeft && ( bLayoutRTL || !bFitRight );
1781 :
1782 0 : if ( bPutLeft )
1783 0 : aInsertPos.X() = aSelection.Left() - nNeededWidth;
1784 : else
1785 0 : aInsertPos.X() = aSelection.Right() + 1;
1786 :
1787 : // align with top of selection (is moved again if it doesn't fit)
1788 0 : aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
1789 : }
1790 0 : else if ( nTopSpace >= nNeededHeight || nBottomSpace >= nNeededHeight )
1791 : {
1792 : // second preference: completely above or below the selection
1793 :
1794 0 : if ( nBottomSpace > nNeededHeight ) // bottom is preferred
1795 0 : aInsertPos.Y() = aSelection.Bottom() + 1;
1796 : else
1797 0 : aInsertPos.Y() = aSelection.Top() - nNeededHeight;
1798 :
1799 : // align with (logic) left edge of selection (moved again if it doesn't fit)
1800 0 : if ( bLayoutRTL )
1801 0 : aInsertPos.X() = std::min( aSelection.Right(), aVisible.Right() ) - nNeededWidth + 1;
1802 : else
1803 0 : aInsertPos.X() = std::max( aSelection.Left(), aVisible.Left() );
1804 : }
1805 : else
1806 : {
1807 : // place to the (logic) right of the selection and move so it fits
1808 :
1809 0 : if ( bLayoutRTL )
1810 0 : aInsertPos.X() = aSelection.Left() - nNeededWidth;
1811 : else
1812 0 : aInsertPos.X() = aSelection.Right() + 1;
1813 0 : aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
1814 : }
1815 :
1816 : // move the position if the object doesn't fit in the screen
1817 :
1818 0 : Rectangle aCompareRect( aInsertPos, Size( nNeededWidth, nNeededHeight ) );
1819 0 : if ( aCompareRect.Right() > aVisible.Right() )
1820 0 : aInsertPos.X() -= aCompareRect.Right() - aVisible.Right();
1821 0 : if ( aCompareRect.Bottom() > aVisible.Bottom() )
1822 0 : aInsertPos.Y() -= aCompareRect.Bottom() - aVisible.Bottom();
1823 :
1824 0 : if ( aInsertPos.X() < aVisible.Left() )
1825 0 : aInsertPos.X() = aVisible.Left();
1826 0 : if ( aInsertPos.Y() < aVisible.Top() )
1827 0 : aInsertPos.Y() = aVisible.Top();
1828 :
1829 : // nNeededWidth / nNeededHeight includes all borders - move aInsertPos to the
1830 : // object position, inside the border
1831 :
1832 0 : aInsertPos.X() += nBorder;
1833 0 : aInsertPos.Y() += nBorder;
1834 : }
1835 0 : return aInsertPos;
1836 : }
1837 :
1838 0 : Point ScTabView::GetChartDialogPos( const Size& rDialogSize, const Rectangle& rLogicChart )
1839 : {
1840 : // rDialogSize must be in pixels, rLogicChart in 1/100 mm. Return value is in pixels.
1841 :
1842 0 : Point aRet;
1843 :
1844 : // use the active window, or lower/right if frozen (as in CalcZoom)
1845 0 : ScSplitPos eUsedPart = aViewData.GetActivePart();
1846 0 : if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1847 0 : eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
1848 0 : if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1849 0 : eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1850 :
1851 0 : ScGridWindow* pWin = pGridWin[eUsedPart];
1852 : OSL_ENSURE( pWin, "Window not found" );
1853 0 : if (pWin)
1854 : {
1855 0 : MapMode aDrawMode = pWin->GetDrawMapMode();
1856 0 : Rectangle aObjPixel = pWin->LogicToPixel( rLogicChart, aDrawMode );
1857 0 : Rectangle aObjAbs( pWin->OutputToAbsoluteScreenPixel( aObjPixel.TopLeft() ),
1858 0 : pWin->OutputToAbsoluteScreenPixel( aObjPixel.BottomRight() ) );
1859 :
1860 0 : Rectangle aDesktop = pWin->GetDesktopRectPixel();
1861 0 : Size aSpace = pWin->LogicToPixel( Size( 8, 12 ), MAP_APPFONT );
1862 :
1863 0 : ScDocument* pDoc = aViewData.GetDocument();
1864 0 : SCTAB nTab = aViewData.GetTabNo();
1865 0 : bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1866 :
1867 0 : bool bCenterHor = false;
1868 :
1869 0 : if ( aDesktop.Bottom() - aObjAbs.Bottom() >= rDialogSize.Height() + aSpace.Height() )
1870 : {
1871 : // first preference: below the chart
1872 :
1873 0 : aRet.Y() = aObjAbs.Bottom() + aSpace.Height();
1874 0 : bCenterHor = true;
1875 : }
1876 0 : else if ( aObjAbs.Top() - aDesktop.Top() >= rDialogSize.Height() + aSpace.Height() )
1877 : {
1878 : // second preference: above the chart
1879 :
1880 0 : aRet.Y() = aObjAbs.Top() - rDialogSize.Height() - aSpace.Height();
1881 0 : bCenterHor = true;
1882 : }
1883 : else
1884 : {
1885 0 : bool bFitLeft = ( aObjAbs.Left() - aDesktop.Left() >= rDialogSize.Width() + aSpace.Width() );
1886 0 : bool bFitRight = ( aDesktop.Right() - aObjAbs.Right() >= rDialogSize.Width() + aSpace.Width() );
1887 :
1888 0 : if ( bFitLeft || bFitRight )
1889 : {
1890 : // if both fit, prefer right in RTL mode, left otherwise
1891 0 : bool bPutRight = bFitRight && ( bLayoutRTL || !bFitLeft );
1892 0 : if ( bPutRight )
1893 0 : aRet.X() = aObjAbs.Right() + aSpace.Width();
1894 : else
1895 0 : aRet.X() = aObjAbs.Left() - rDialogSize.Width() - aSpace.Width();
1896 :
1897 : // center vertically
1898 0 : aRet.Y() = aObjAbs.Top() + ( aObjAbs.GetHeight() - rDialogSize.Height() ) / 2;
1899 : }
1900 : else
1901 : {
1902 : // doesn't fit on any edge - put at the bottom of the screen
1903 0 : aRet.Y() = aDesktop.Bottom() - rDialogSize.Height();
1904 0 : bCenterHor = true;
1905 : }
1906 : }
1907 0 : if ( bCenterHor )
1908 0 : aRet.X() = aObjAbs.Left() + ( aObjAbs.GetWidth() - rDialogSize.Width() ) / 2;
1909 :
1910 : // limit to screen (centering might lead to invalid positions)
1911 0 : if ( aRet.X() + rDialogSize.Width() - 1 > aDesktop.Right() )
1912 0 : aRet.X() = aDesktop.Right() - rDialogSize.Width() + 1;
1913 0 : if ( aRet.X() < aDesktop.Left() )
1914 0 : aRet.X() = aDesktop.Left();
1915 0 : if ( aRet.Y() + rDialogSize.Height() - 1 > aDesktop.Bottom() )
1916 0 : aRet.Y() = aDesktop.Bottom() - rDialogSize.Height() + 1;
1917 0 : if ( aRet.Y() < aDesktop.Top() )
1918 0 : aRet.Y() = aDesktop.Top();
1919 : }
1920 :
1921 0 : return aRet;
1922 : }
1923 :
1924 0 : void ScTabView::LockModifiers( sal_uInt16 nModifiers )
1925 : {
1926 0 : pSelEngine->LockModifiers( nModifiers );
1927 0 : pHdrSelEng->LockModifiers( nModifiers );
1928 0 : }
1929 :
1930 185 : sal_uInt16 ScTabView::GetLockedModifiers() const
1931 : {
1932 185 : return pSelEngine->GetLockedModifiers();
1933 : }
1934 :
1935 0 : Point ScTabView::GetMousePosPixel()
1936 : {
1937 0 : Point aPos;
1938 0 : ScGridWindow* pWin = GetActiveWin();
1939 :
1940 0 : if ( pWin )
1941 0 : aPos = pWin->GetMousePosPixel();
1942 :
1943 0 : return aPos;
1944 : }
1945 :
1946 12 : void ScTabView::FreezeSplitters( bool bFreeze )
1947 : {
1948 12 : ScSplitMode eOldH = aViewData.GetHSplitMode();
1949 12 : ScSplitMode eOldV = aViewData.GetVSplitMode();
1950 :
1951 12 : ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
1952 12 : if ( eOldV != SC_SPLIT_NONE )
1953 3 : ePos = SC_SPLIT_TOPLEFT;
1954 12 : vcl::Window* pWin = pGridWin[ePos];
1955 :
1956 12 : bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1957 :
1958 12 : if ( bFreeze )
1959 : {
1960 2 : Point aWinStart = pWin->GetPosPixel();
1961 2 : aViewData.GetDocShell()->SetDocumentModified();
1962 :
1963 2 : Point aSplit;
1964 : SCsCOL nPosX;
1965 : SCsROW nPosY;
1966 2 : if (eOldH != SC_SPLIT_NONE || eOldV != SC_SPLIT_NONE)
1967 : {
1968 2 : if (eOldH != SC_SPLIT_NONE)
1969 : {
1970 1 : long nSplitPos = aViewData.GetHSplitPos();
1971 1 : if ( bLayoutRTL )
1972 0 : nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
1973 1 : aSplit.X() = nSplitPos - aWinStart.X();
1974 : }
1975 2 : if (eOldV != SC_SPLIT_NONE)
1976 2 : aSplit.Y() = aViewData.GetVSplitPos() - aWinStart.Y();
1977 :
1978 2 : aViewData.GetPosFromPixel( aSplit.X(), aSplit.Y(), ePos, nPosX, nPosY );
1979 : bool bLeft;
1980 : bool bTop;
1981 2 : aViewData.GetMouseQuadrant( aSplit, ePos, nPosX, nPosY, bLeft, bTop );
1982 2 : if (!bLeft)
1983 0 : ++nPosX;
1984 2 : if (!bTop)
1985 0 : ++nPosY;
1986 : }
1987 : else
1988 : {
1989 0 : nPosX = static_cast<SCsCOL>( aViewData.GetCurX());
1990 0 : nPosY = static_cast<SCsROW>( aViewData.GetCurY());
1991 : }
1992 :
1993 2 : SCCOL nLeftPos = aViewData.GetPosX(SC_SPLIT_LEFT);
1994 2 : SCROW nTopPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
1995 2 : SCCOL nRightPos = static_cast<SCCOL>(nPosX);
1996 2 : SCROW nBottomPos = static_cast<SCROW>(nPosY);
1997 2 : if (eOldH != SC_SPLIT_NONE)
1998 1 : if (aViewData.GetPosX(SC_SPLIT_RIGHT) > nRightPos)
1999 0 : nRightPos = aViewData.GetPosX(SC_SPLIT_RIGHT);
2000 2 : if (eOldV != SC_SPLIT_NONE)
2001 : {
2002 2 : nTopPos = aViewData.GetPosY(SC_SPLIT_TOP);
2003 2 : if (aViewData.GetPosY(SC_SPLIT_BOTTOM) > nBottomPos)
2004 0 : nBottomPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
2005 : }
2006 :
2007 2 : aSplit = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, true );
2008 2 : if (nPosX > aViewData.GetPosX(SC_SPLIT_LEFT)) // (aSplit.X() > 0) doesn't work for RTL
2009 : {
2010 1 : long nSplitPos = aSplit.X() + aWinStart.X();
2011 1 : if ( bLayoutRTL )
2012 0 : nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
2013 :
2014 1 : aViewData.SetHSplitMode( SC_SPLIT_FIX );
2015 1 : aViewData.SetHSplitPos( nSplitPos );
2016 1 : aViewData.SetFixPosX( nPosX );
2017 :
2018 1 : aViewData.SetPosX(SC_SPLIT_LEFT, nLeftPos);
2019 1 : aViewData.SetPosX(SC_SPLIT_RIGHT, nRightPos);
2020 : }
2021 : else
2022 1 : aViewData.SetHSplitMode( SC_SPLIT_NONE );
2023 2 : if (aSplit.Y() > 0)
2024 : {
2025 2 : aViewData.SetVSplitMode( SC_SPLIT_FIX );
2026 2 : aViewData.SetVSplitPos( aSplit.Y() + aWinStart.Y() );
2027 2 : aViewData.SetFixPosY( nPosY );
2028 :
2029 2 : aViewData.SetPosY(SC_SPLIT_TOP, nTopPos);
2030 2 : aViewData.SetPosY(SC_SPLIT_BOTTOM, nBottomPos);
2031 : }
2032 : else
2033 0 : aViewData.SetVSplitMode( SC_SPLIT_NONE );
2034 : }
2035 : else // Fixierung aufheben
2036 : {
2037 10 : if ( eOldH == SC_SPLIT_FIX )
2038 0 : aViewData.SetHSplitMode( SC_SPLIT_NORMAL );
2039 10 : if ( eOldV == SC_SPLIT_FIX )
2040 0 : aViewData.SetVSplitMode( SC_SPLIT_NORMAL );
2041 : }
2042 :
2043 : // Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
2044 : // dafuer muss hier schon der MapMode stimmen
2045 60 : for (sal_uInt16 i=0; i<4; i++)
2046 48 : if (pGridWin[i])
2047 43 : pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
2048 12 : SetNewVisArea();
2049 :
2050 12 : RepeatResize(false);
2051 :
2052 12 : UpdateShow();
2053 12 : PaintLeft();
2054 12 : PaintTop();
2055 12 : PaintGrid();
2056 :
2057 : // SC_FOLLOW_NONE: only update active part
2058 12 : AlignToCursor( aViewData.GetCurX(), aViewData.GetCurY(), SC_FOLLOW_NONE );
2059 12 : UpdateAutoFillMark();
2060 :
2061 12 : InvalidateSplit();
2062 12 : }
2063 :
2064 2 : void ScTabView::RemoveSplit()
2065 : {
2066 2 : DoHSplit( 0 );
2067 2 : DoVSplit( 0 );
2068 2 : RepeatResize();
2069 2 : }
2070 :
2071 4 : void ScTabView::SplitAtCursor()
2072 : {
2073 4 : ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
2074 4 : if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
2075 0 : ePos = SC_SPLIT_TOPLEFT;
2076 4 : vcl::Window* pWin = pGridWin[ePos];
2077 4 : Point aWinStart = pWin->GetPosPixel();
2078 :
2079 4 : SCCOL nPosX = aViewData.GetCurX();
2080 4 : SCROW nPosY = aViewData.GetCurY();
2081 4 : Point aSplit = aViewData.GetScrPos( nPosX, nPosY, ePos, true );
2082 4 : if ( nPosX > 0 )
2083 3 : DoHSplit( aSplit.X() + aWinStart.X() );
2084 : else
2085 1 : DoHSplit( 0 );
2086 4 : if ( nPosY > 0 )
2087 4 : DoVSplit( aSplit.Y() + aWinStart.Y() );
2088 : else
2089 0 : DoVSplit( 0 );
2090 4 : RepeatResize();
2091 4 : }
2092 :
2093 12 : void ScTabView::SplitAtPixel( const Point& rPixel, bool bHor, bool bVer )
2094 : {
2095 : // Pixel ist auf die ganze View bezogen, nicht auf das erste GridWin
2096 :
2097 12 : if (bHor)
2098 : {
2099 12 : if ( rPixel.X() > 0 )
2100 3 : DoHSplit( rPixel.X() );
2101 : else
2102 9 : DoHSplit( 0 );
2103 : }
2104 12 : if (bVer)
2105 : {
2106 12 : if ( rPixel.Y() > 0 )
2107 3 : DoVSplit( rPixel.Y() );
2108 : else
2109 9 : DoVSplit( 0 );
2110 : }
2111 12 : RepeatResize();
2112 12 : }
2113 :
2114 645 : void ScTabView::InvalidateSplit()
2115 : {
2116 645 : SfxBindings& rBindings = aViewData.GetBindings();
2117 645 : rBindings.Invalidate( SID_WINDOW_SPLIT );
2118 645 : rBindings.Invalidate( SID_WINDOW_FIX );
2119 :
2120 645 : pHSplitter->SetFixed( aViewData.GetHSplitMode() == SC_SPLIT_FIX );
2121 645 : pVSplitter->SetFixed( aViewData.GetVSplitMode() == SC_SPLIT_FIX );
2122 645 : }
2123 :
2124 2033 : void ScTabView::SetNewVisArea()
2125 : {
2126 : // fuer die Controls muss bei VisAreaChanged der Draw-MapMode eingestellt sein
2127 : // (auch wenn ansonsten der Edit-MapMode gesetzt ist)
2128 10165 : MapMode aOldMode[4];
2129 4066 : MapMode aDrawMode[4];
2130 : sal_uInt16 i;
2131 10165 : for (i=0; i<4; i++)
2132 8132 : if (pGridWin[i])
2133 : {
2134 2142 : aOldMode[i] = pGridWin[i]->GetMapMode();
2135 2142 : aDrawMode[i] = pGridWin[i]->GetDrawMapMode();
2136 2142 : if (aDrawMode[i] != aOldMode[i])
2137 2 : pGridWin[i]->SetMapMode(aDrawMode[i]);
2138 : }
2139 :
2140 2033 : vcl::Window* pActive = pGridWin[aViewData.GetActivePart()];
2141 2033 : if (pActive)
2142 2033 : aViewData.GetViewShell()->VisAreaChanged(
2143 4066 : pActive->PixelToLogic(Rectangle(Point(),pActive->GetOutputSizePixel())) );
2144 2033 : if (pDrawView)
2145 1820 : pDrawView->VisAreaChanged(); // kein Window uebergeben -> alle Fenster
2146 :
2147 2033 : UpdateAllOverlays(); // #i79909# with drawing MapMode set
2148 :
2149 10165 : for (i=0; i<4; i++)
2150 8132 : if (pGridWin[i] && aDrawMode[i] != aOldMode[i])
2151 : {
2152 2 : pGridWin[i]->flushOverlayManager(); // #i79909# flush overlays before switching to edit MapMode
2153 2 : pGridWin[i]->SetMapMode(aOldMode[i]);
2154 : }
2155 :
2156 2033 : SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
2157 2033 : if (pViewFrame)
2158 : {
2159 2033 : SfxFrame& rFrame = pViewFrame->GetFrame();
2160 2033 : com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = rFrame.GetController();
2161 2033 : if (xController.is())
2162 : {
2163 1685 : ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
2164 1685 : if (pImp)
2165 1685 : pImp->VisAreaChanged();
2166 2033 : }
2167 : }
2168 2033 : if (aViewData.GetViewShell()->HasAccessibilityObjects())
2169 10165 : aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_VISAREACHANGED));
2170 2033 : }
2171 :
2172 0 : bool ScTabView::HasPageFieldDataAtCursor() const
2173 : {
2174 0 : ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2175 0 : SCCOL nCol = aViewData.GetCurX();
2176 0 : SCROW nRow = aViewData.GetCurY();
2177 0 : if (pWin)
2178 0 : return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE;
2179 :
2180 0 : return false;
2181 : }
2182 :
2183 0 : void ScTabView::StartDataSelect()
2184 : {
2185 0 : ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2186 0 : SCCOL nCol = aViewData.GetCurX();
2187 0 : SCROW nRow = aViewData.GetCurY();
2188 :
2189 0 : if (!pWin)
2190 0 : return;
2191 :
2192 0 : switch (pWin->GetDPFieldOrientation(nCol, nRow))
2193 : {
2194 : case sheet::DataPilotFieldOrientation_PAGE:
2195 : // #i36598# If the cursor is on a page field's data cell,
2196 : // no meaningful input is possible anyway, so this function
2197 : // can be used to select a page field entry.
2198 0 : pWin->LaunchPageFieldMenu( nCol, nRow );
2199 0 : return;
2200 : case sheet::DataPilotFieldOrientation_COLUMN:
2201 : case sheet::DataPilotFieldOrientation_ROW:
2202 0 : pWin->LaunchDPFieldMenu( nCol, nRow );
2203 0 : return;
2204 : default:
2205 : ;
2206 : }
2207 :
2208 : // Do autofilter if the current cell has autofilter button. Otherwise do
2209 : // a normal data select popup.
2210 : const ScMergeFlagAttr* pAttr = static_cast<const ScMergeFlagAttr*>(
2211 : aViewData.GetDocument()->GetAttr(
2212 0 : nCol, nRow, aViewData.GetTabNo(), ATTR_MERGE_FLAG));
2213 :
2214 0 : if (pAttr->HasAutoFilter())
2215 0 : pWin->LaunchAutoFilterMenu(nCol, nRow);
2216 : else
2217 0 : pWin->LaunchDataSelectMenu(nCol, nRow, true);
2218 : }
2219 :
2220 0 : void ScTabView::EnableRefInput(bool bFlag)
2221 : {
2222 0 : aHScrollLeft->EnableInput(bFlag);
2223 0 : aHScrollRight->EnableInput(bFlag);
2224 0 : aVScrollBottom->EnableInput(bFlag);
2225 0 : aVScrollTop->EnableInput(bFlag);
2226 0 : aScrollBarBox->EnableInput(bFlag);
2227 :
2228 : // ab hier dynamisch angelegte
2229 :
2230 0 : if(pTabControl!=nullptr) pTabControl->EnableInput(bFlag,true);
2231 :
2232 0 : if(pGridWin[SC_SPLIT_BOTTOMLEFT]!=nullptr)
2233 0 : pGridWin[SC_SPLIT_BOTTOMLEFT]->EnableInput(bFlag,false);
2234 0 : if(pGridWin[SC_SPLIT_BOTTOMRIGHT]!=nullptr)
2235 0 : pGridWin[SC_SPLIT_BOTTOMRIGHT]->EnableInput(bFlag,false);
2236 0 : if(pGridWin[SC_SPLIT_TOPLEFT]!=nullptr)
2237 0 : pGridWin[SC_SPLIT_TOPLEFT]->EnableInput(bFlag,false);
2238 0 : if(pGridWin[SC_SPLIT_TOPRIGHT]!=nullptr)
2239 0 : pGridWin[SC_SPLIT_TOPRIGHT]->EnableInput(bFlag,false);
2240 0 : if(pColBar[SC_SPLIT_RIGHT]!=nullptr)
2241 0 : pColBar[SC_SPLIT_RIGHT]->EnableInput(bFlag,false);
2242 0 : if(pRowBar[SC_SPLIT_TOP]!=nullptr)
2243 0 : pRowBar[SC_SPLIT_TOP]->EnableInput(bFlag,false);
2244 0 : }
2245 :
2246 2219 : bool ScTabView::ContinueOnlineSpelling()
2247 : {
2248 2219 : bool bChanged = false;
2249 11095 : for (int i = 0; i < 4; ++i)
2250 : {
2251 8876 : if (!pGridWin[i] || !pGridWin[i]->IsVisible())
2252 6652 : continue;
2253 :
2254 2224 : if (pGridWin[i]->ContinueOnlineSpelling())
2255 578 : bChanged = true;
2256 : }
2257 :
2258 2219 : return bChanged;
2259 : }
2260 :
2261 348 : void ScTabView::EnableAutoSpell( bool bEnable )
2262 : {
2263 1740 : for (int i = 0; i < 4; ++i)
2264 : {
2265 1392 : if (!pGridWin[i])
2266 1044 : continue;
2267 :
2268 348 : pGridWin[i]->EnableAutoSpell(bEnable);
2269 : }
2270 348 : }
2271 :
2272 17 : void ScTabView::ResetAutoSpell()
2273 : {
2274 85 : for (int i = 0; i < 4; ++i)
2275 : {
2276 68 : if (!pGridWin[i])
2277 51 : continue;
2278 :
2279 17 : pGridWin[i]->ResetAutoSpell();
2280 : }
2281 17 : }
2282 :
2283 0 : void ScTabView::SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges )
2284 : {
2285 0 : for (int i = 0; i < 4; ++i)
2286 : {
2287 0 : if (!pGridWin[i])
2288 0 : continue;
2289 :
2290 0 : pGridWin[i]->SetAutoSpellData(nPosX, nPosY, pRanges);
2291 : }
2292 156 : }
2293 :
2294 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|