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