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