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