Update ooo320-m1
[ooovba.git] / sc / source / ui / view / tabview.cxx
blobeb6908b4fe3763e64fd3b6ffb3b087e66e8a1b26
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tabview.cxx,v $
10 * $Revision: 1.37 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
35 //------------------------------------------------------------------
37 #if 0
38 #define _MACRODLG_HXX
39 #define _BIGINT_HXX
40 #define _SVCONTNR_HXX
41 #define BASIC_NODIALOGS
42 #define _SFXMNUITEM_HXX
43 #define _SVDXOUT_HXX
44 #define _SVDATTR_HXX
45 #define _SFXMNUITEM_HXX
46 #define _DLGCFG_HXX
47 #define _SFXMNUMGR_HXX
48 #define _SFXBASIC_HXX
49 #define _MODALDLG_HXX
50 #define _SFX_TEMPLDLG_HXX
51 #define _SFXSTBMGR_HXX
52 #define _SFXTBXMGR_HXX
53 #define _BASE_DLGS_HXX
54 #define _SFXIMGMGR_HXX
55 #define _SFXMNUMGR_HXX
56 #define _SFXSTBITEM_HXX
57 #define _SFXTBXCTRL_HXX
58 #define _PASSWD_HXX
59 //#define _SFXFILEDLG_HXX
60 //#define _SFXREQUEST_HXX
61 #define _SFXOBJFACE_HXX
63 #define _SDR_NOTRANSFORM
64 #define _SVDXOUT_HXX
65 #endif
66 #include <vcl/svapp.hxx>
68 ///////////////////////////////////////////////////////////////////////////
69 // NODRAW.HXX
70 // Erweiterte Konstanten, um CLOKs mit SVDRAW.HXX zu vermeiden
71 // Die u.a. Aenderungen nehmen vorgeschlagene Konstante vorweg
72 ///////////////////////////////////////////////////////////////////////////
74 #if 0
75 #define _SDR_NOTRANSFORM // Transformationen, selten verwendet
76 #define _SDR_NOTOUCH // Hit-Tests, selten verwendet
78 #define _SDR_NOUNDO // Undo-Objekte
79 #define _SDR_NOPAGEOBJ // SdrPageObj
80 #define _SDR_NOVIRTOBJ // SdrVirtObj
81 #define _SDR_NOGROUPOBJ // SdrGroupObj
82 #define _SDR_NOTEXTOBJ // SdrTextObj
83 #define _SDR_NOPATHOBJ // SdrPathObj
84 #define _SDR_NOEDGEOBJ // SdrEdgeObj
85 #define _SDR_NORECTOBJ // SdrRectObj
86 #define _SDR_NOCAPTIONOBJ // SdrCaptionObj
87 #define _SDR_NOCIRCLEOBJ // SdrCircleObj
88 #define _SDR_NOGRAFOBJ // SdrGrafObj
89 #define _SDR_NOOLE2OBJ // SdrOle2Obj
90 #endif
92 // Dieses define entfernt die VCControls aus SI.HXX
94 #define _SI_HXX // VCControls
96 ////////////////////// Umsetzen der Standard-Defines //////////////////////
98 //#define _SVDDRAG_HXX // SdrDragStat
99 #define _SVDPAGE_HXX // SdrPage
101 #ifdef _SDR_NOSURROGATEOBJ
102 #undef _SDR_NOSURROGATEOBJ
103 #define _SVDSURO_HXX
104 #endif
106 #ifdef _SDR_NOPAGEOBJ
107 #undef _SDR_NOPAGEOBJ
108 #define _SVDOPAGE_HXX
109 #endif
111 #ifdef _SDR_NOVIRTOBJ
112 #undef _SDR_NOVIRTOBJ
113 #define _SVDOVIRT_HXX
114 #endif
116 #ifdef _SDR_NOGROUPOBJ
117 #undef _SDR_NOGROUPOBJ
118 #define _SVDOGRP_HXX
119 #endif
121 #ifdef _SDR_NOTEXTOBJ
122 #undef _SDR_NOTEXTOBJ
123 #define _SVDOTEXT_HXX
124 #endif
126 #ifdef _SDR_NOPATHOBJ
127 #undef _SDR_NOPATHOBJ
128 #define _SVDOPATH_HXX
129 #endif
131 #ifdef _SDR_NOEDGEOBJ
132 #undef _SDR_NOEDGEOBJ
133 #define _SVDOEDGE_HXX
134 #endif
136 #ifdef _SDR_NORECTOBJ
137 #undef _SDR_NORECTOBJ
138 #define _SVDORECT_HXX
139 #else
140 #undef _SDVOTEXT_OBJ
141 #endif
143 #ifdef _SDR_NOCAPTIONOBJ
144 #undef _SDR_NOCAPTIONOBJ
145 #define _SVDCAPT_HXX
146 #endif
148 #ifdef _SDR_NOCIRCLEOBJ
149 #undef _SDR_NOCIRCLEOBJ
150 #define _SVDOCIRC_HXX
151 #endif
153 #ifdef _SDR_NOGRAFOBJ
154 #undef _SDR_NOGRAFOBJ
155 #define _SVDOGRAF_HXX
156 #else
157 #undef _SVDOTEXT_HXX
158 #undef _SVDORECT_HXX
159 #endif
161 #ifdef _SDR_NOOLE2OBJ
162 #undef _SDR_NOOLE2OBJ
163 #define _SVDOOLE2_HXX
164 #else
165 #undef _SVDOTEXT_HXX
166 #undef _SVDORECT_HXX
167 #endif
169 //#ifdef _SDR_NOVIEWS
170 // #define _SVDDRAG_HXX
171 //#endif
173 ////////////////////// Ende der SVDRAW-Modifikationen /////////////////////
176 // INCLUDE ---------------------------------------------------------------
178 #include "scitems.hxx"
179 #include <sfx2/viewfrm.hxx>
180 #include <sfx2/bindings.hxx>
181 #include <vcl/help.hxx>
182 #include <rtl/logfile.hxx>
184 #include "tabview.hxx"
185 #include "tabvwsh.hxx"
186 #include "document.hxx"
187 #include "gridwin.hxx"
188 #include "olinewin.hxx"
189 #include "olinetab.hxx"
190 #include "tabsplit.hxx"
191 #include "colrowba.hxx"
192 #include "tabcont.hxx"
193 #include "scmod.hxx"
194 #include "sc.hrc"
195 #include "viewutil.hxx"
196 #include "globstr.hrc"
197 #include "drawview.hxx"
198 #include "docsh.hxx"
199 #include "viewuno.hxx"
200 #include "AccessibilityHints.hxx"
201 #include "appoptio.hxx"
203 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
205 #include <string>
206 #include <algorithm>
208 #define SPLIT_MARGIN 30
209 #define SC_ICONSIZE 36
211 #define SC_SCROLLBAR_MIN 30
212 #define SC_TABBAR_MIN 6
214 // fuer Rad-Maus
215 #define SC_DELTA_ZOOM 10
217 using namespace ::com::sun::star;
219 // STATIC DATA -----------------------------------------------------------
222 //==================================================================
224 // Corner-Button
226 ScCornerButton::ScCornerButton( Window* pParent, ScViewData* pData, BOOL bAdditional ) :
227 Window( pParent, WinBits( 0 ) ),
228 pViewData( pData ),
229 bAdd( bAdditional )
231 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
232 SetBackground( rStyleSettings.GetFaceColor() );
233 EnableRTL( FALSE );
236 __EXPORT ScCornerButton::~ScCornerButton()
240 void __EXPORT ScCornerButton::Paint( const Rectangle& rRect )
242 Size aSize = GetOutputSizePixel();
243 long nPosX = aSize.Width()-1;
244 long nPosY = aSize.Height()-1;
246 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
248 Window::Paint(rRect);
250 BOOL bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
251 long nDarkX = bLayoutRTL ? 0 : nPosX;
253 if ( !bAdd && !rStyleSettings.GetHighContrastMode() )
255 // match the shaded look of column/row headers
257 Color aFace( rStyleSettings.GetFaceColor() );
258 Color aWhite( COL_WHITE );
259 Color aCenter( aFace );
260 aCenter.Merge( aWhite, 0xd0 ); // lighten up a bit
261 Color aOuter( aFace );
262 aOuter.Merge( aWhite, 0xa0 ); // lighten up more
264 long nCenterX = (aSize.Width() / 2) - 1;
265 long nCenterY = (aSize.Height() / 2) - 1;
267 SetLineColor();
268 SetFillColor(aCenter);
269 DrawRect( Rectangle( nCenterX, nCenterY, nCenterX, nPosY ) );
270 DrawRect( Rectangle( nCenterX, nCenterY, nDarkX, nCenterY ) );
271 SetFillColor(aOuter);
272 DrawRect( Rectangle( 0, 0, nPosX, nCenterY-1 ) );
273 if ( bLayoutRTL )
274 DrawRect( Rectangle( nCenterX+1, nCenterY, nPosX, nPosY ) );
275 else
276 DrawRect( Rectangle( 0, nCenterY, nCenterX-1, nPosY ) );
279 // both buttons have the same look now - only dark right/bottom lines
280 SetLineColor( rStyleSettings.GetDarkShadowColor() );
281 DrawLine( Point(0,nPosY), Point(nPosX,nPosY) );
282 DrawLine( Point(nDarkX,0), Point(nDarkX,nPosY) );
285 void ScCornerButton::StateChanged( StateChangedType nType )
287 Window::StateChanged( nType );
289 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
290 SetBackground( rStyleSettings.GetFaceColor() );
291 Invalidate();
294 // -----------------------------------------------------------------------
296 void ScCornerButton::DataChanged( const DataChangedEvent& rDCEvt )
298 Window::DataChanged( rDCEvt );
300 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
301 SetBackground( rStyleSettings.GetFaceColor() );
302 Invalidate();
306 void __EXPORT ScCornerButton::Resize()
308 Invalidate();
311 void __EXPORT ScCornerButton::MouseButtonDown( const MouseEvent& rMEvt )
313 ScModule* pScMod = SC_MOD();
314 BOOL bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
315 if (!bDisable)
317 ScTabViewShell* pViewSh = pViewData->GetViewShell();
318 pViewSh->SetActive(); // Appear und SetViewFrame
319 pViewSh->ActiveGrabFocus();
321 BOOL bControl = rMEvt.IsMod1();
322 pViewSh->SelectAll( bControl );
326 //==================================================================
328 BOOL lcl_HasColOutline( const ScViewData& rViewData )
330 const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
331 if (pTable)
333 const ScOutlineArray* pArray = pTable->GetColArray();
334 if ( pArray->GetDepth() > 0 )
335 return TRUE;
337 return FALSE;
340 BOOL lcl_HasRowOutline( const ScViewData& rViewData )
342 const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
343 if (pTable)
345 const ScOutlineArray* pArray = pTable->GetRowArray();
346 if ( pArray->GetDepth() > 0 )
347 return TRUE;
349 return FALSE;
352 //==================================================================
354 // Init und Konstruktoren
355 // ScTabView::Init() in tabview5.cxx wegen out of keys
358 #define TABVIEW_INIT \
359 pSelEngine( NULL ), \
360 aFunctionSet( &aViewData ), \
361 pHdrSelEng( NULL ), \
362 aHdrFunc( &aViewData ), \
363 pDrawView( NULL ), \
364 bDrawSelMode( FALSE ), \
365 aVScrollTop( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ), \
366 aVScrollBottom( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ), \
367 aHScrollLeft( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ), \
368 aHScrollRight( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ), \
369 aCornerButton( pFrameWin, &aViewData, FALSE ), \
370 aTopButton( pFrameWin, &aViewData, TRUE ), \
371 aScrollBarBox( pFrameWin, WB_SIZEABLE ), \
372 pInputHintWindow( NULL ), \
373 pPageBreakData( NULL ), \
374 pHighlightRanges( NULL ), \
375 pBrushDocument( NULL ), \
376 pDrawBrushSet( NULL ), \
377 bLockPaintBrush( FALSE ), \
378 pTimerWindow( NULL ), \
379 nTipVisible( 0 ), \
380 bDragging( FALSE ), \
381 bIsBlockMode( FALSE ), \
382 bBlockNeg( FALSE ), \
383 bBlockCols( FALSE ), \
384 bBlockRows( FALSE ), \
385 mfPendingTabBarWidth( -1.0 ), \
386 bMinimized( FALSE ), \
387 bInUpdateHeader( FALSE ), \
388 bInActivatePart( FALSE ), \
389 bInZoomUpdate( FALSE ), \
390 bMoveIsShift( FALSE )
393 ScTabView::ScTabView( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
394 pFrameWin( pParent ),
395 aViewData( &rDocSh, pViewShell ),
396 TABVIEW_INIT
398 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" );
400 Init();
403 //UNUSED2009-05 ScTabView::ScTabView( Window* pParent, const ScTabView& rScTabView, ScTabViewShell* pViewShell ) :
404 //UNUSED2009-05 pFrameWin( pParent ),
405 //UNUSED2009-05 aViewData( rScTabView.aViewData ),
406 //UNUSED2009-05 TABVIEW_INIT
407 //UNUSED2009-05 {
408 //UNUSED2009-05 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" );
409 //UNUSED2009-05
410 //UNUSED2009-05 aViewData.SetViewShell( pViewShell );
411 //UNUSED2009-05 Init();
412 //UNUSED2009-05
413 //UNUSED2009-05 UpdateShow();
414 //UNUSED2009-05 if ( aViewData.GetActivePart() != SC_SPLIT_BOTTOMLEFT )
415 //UNUSED2009-05 pGridWin[SC_SPLIT_BOTTOMLEFT]->Show();
416 //UNUSED2009-05
417 //UNUSED2009-05 InvalidateSplit();
418 //UNUSED2009-05 }
420 void ScTabView::InitScrollBar( ScrollBar& rScrollBar, long nMaxVal )
422 rScrollBar.SetRange( Range( 0, nMaxVal ) );
423 rScrollBar.SetLineSize( 1 );
424 rScrollBar.SetPageSize( 1 ); // wird getrennt abgefragt
425 rScrollBar.SetVisibleSize( 10 ); // wird bei Resize neu gesetzt
427 rScrollBar.SetScrollHdl( LINK(this, ScTabView, ScrollHdl) );
428 rScrollBar.SetEndScrollHdl( LINK(this, ScTabView, EndScrollHdl) );
431 // Scroll-Timer
433 void ScTabView::SetTimer( ScGridWindow* pWin, const MouseEvent& rMEvt )
435 pTimerWindow = pWin;
436 aTimerMEvt = rMEvt;
437 aScrollTimer.Start();
440 void ScTabView::ResetTimer()
442 aScrollTimer.Stop();
443 pTimerWindow = NULL;
446 IMPL_LINK( ScTabView, TimerHdl, Timer*, EMPTYARG )
448 // aScrollTimer.Stop();
449 if (pTimerWindow)
450 pTimerWindow->MouseMove( aTimerMEvt );
452 return 0;
455 // --- Resize ---------------------------------------------------------------------
457 void lcl_SetPosSize( Window& rWindow, const Point& rPos, const Size& rSize,
458 long nTotalWidth, BOOL bLayoutRTL )
460 Point aNewPos = rPos;
461 if ( bLayoutRTL )
463 aNewPos.X() = nTotalWidth - rPos.X() - rSize.Width();
464 if ( aNewPos == rWindow.GetPosPixel() && rSize.Width() != rWindow.GetSizePixel().Width() )
466 // Document windows are manually painted right-to-left, so they need to
467 // be repainted if the size changes.
468 rWindow.Invalidate();
471 rWindow.SetPosSizePixel( aNewPos, rSize );
474 void ScTabView::DoResize( const Point& rOffset, const Size& rSize, BOOL bInner )
476 HideListBox();
478 BOOL bHasHint = ( pInputHintWindow != NULL );
479 if (bHasHint)
480 RemoveHintWindow();
482 BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
483 long nTotalWidth = rSize.Width();
484 if ( bLayoutRTL )
485 nTotalWidth += 2*rOffset.X();
487 BOOL bVScroll = aViewData.IsVScrollMode();
488 BOOL bHScroll = aViewData.IsHScrollMode();
489 BOOL bTabControl = aViewData.IsTabMode();
490 BOOL bHeaders = aViewData.IsHeaderMode();
491 BOOL bOutlMode = aViewData.IsOutlineMode();
492 BOOL bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
493 BOOL bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
495 // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
496 SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
497 if ( eMode == SCROLLING_NO )
498 bHScroll = bVScroll = FALSE;
499 else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ???
500 bHScroll = bVScroll = TRUE;
502 if ( aViewData.GetDocShell()->IsPreview() )
503 bHScroll = bVScroll = bTabControl = bHeaders = bOutlMode = bHOutline = bVOutline = FALSE;
505 long nBarX = 0;
506 long nBarY = 0;
507 long nOutlineX = 0;
508 long nOutlineY = 0;
509 long nOutPosX;
510 long nOutPosY;
512 long nPosX = rOffset.X();
513 long nPosY = rOffset.Y();
514 long nSizeX = rSize.Width();
515 long nSizeY = rSize.Height();
516 long nSize1;
518 bMinimized = ( nSizeX<=SC_ICONSIZE || nSizeY<=SC_ICONSIZE );
519 if ( bMinimized )
520 return;
522 long nSplitSizeX = SPLIT_HANDLE_SIZE;
523 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
524 nSplitSizeX = 1;
525 long nSplitSizeY = SPLIT_HANDLE_SIZE;
526 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
527 nSplitSizeY = 1;
529 const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel();
531 aBorderPos = rOffset;
532 aFrameSize = rSize;
534 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
535 if ( aViewData.GetHSplitPos() > nSizeX - SPLIT_MARGIN )
537 aViewData.SetHSplitMode( SC_SPLIT_NONE );
538 if ( WhichH( aViewData.GetActivePart() ) == SC_SPLIT_RIGHT )
539 ActivatePart( SC_SPLIT_BOTTOMLEFT );
540 InvalidateSplit();
541 // UpdateShow();
543 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
544 if ( aViewData.GetVSplitPos() > nSizeY - SPLIT_MARGIN )
546 aViewData.SetVSplitMode( SC_SPLIT_NONE );
547 if ( WhichV( aViewData.GetActivePart() ) == SC_SPLIT_TOP )
548 ActivatePart( SC_SPLIT_BOTTOMLEFT );
549 InvalidateSplit();
550 // UpdateShow();
553 UpdateShow();
555 if (bHScroll || bVScroll) // Scrollbars horizontal oder vertikal
557 long nScrollBarSize = pFrameWin->GetSettings().GetStyleSettings().GetScrollBarSize();
558 if (bVScroll)
560 // nBarX = aVScrollBottom.GetSizePixel().Width();
561 nBarX = nScrollBarSize;
562 nSizeX -= nBarX - nOverlap;
564 if (bHScroll)
566 // nBarY = aHScrollLeft.GetSizePixel().Height();
567 nBarY = nScrollBarSize;
568 nSizeY -= nBarY - nOverlap;
571 // window at the bottom right
572 lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
573 nTotalWidth, bLayoutRTL );
575 if (bHScroll) // Scrollbars horizontal
577 long nSizeLt = 0; // left scroll bar
578 long nSizeRt = 0; // right scroll bar
579 long nSizeSp = 0; // splitter
581 switch (aViewData.GetHSplitMode())
583 case SC_SPLIT_NONE:
584 nSizeSp = nSplitSizeX;
585 nSizeLt = nSizeX - nSizeSp + nOverlap; // Ecke ueberdecken
586 break;
587 case SC_SPLIT_NORMAL:
588 nSizeSp = nSplitSizeX;
589 nSizeLt = aViewData.GetHSplitPos();
590 break;
591 case SC_SPLIT_FIX:
592 nSizeSp = 0;
593 nSizeLt = 0;
594 break;
596 nSizeRt = nSizeX - nSizeLt - nSizeSp;
598 long nTabSize = 0;
599 if (bTabControl)
601 // pending relative tab bar width from extended document options
602 if( mfPendingTabBarWidth >= 0.0 )
604 SetRelTabBarWidth( mfPendingTabBarWidth );
605 mfPendingTabBarWidth = -1.0;
608 nTabSize = pTabControl->GetSizePixel().Width()-nOverlap;
610 if ( aViewData.GetHSplitMode() != SC_SPLIT_FIX ) // bei linkem Scrollbar
612 if (nTabSize > nSizeLt-SC_SCROLLBAR_MIN) nTabSize = nSizeLt-SC_SCROLLBAR_MIN;
613 if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN;
614 nSizeLt -= nTabSize;
616 else // bei rechtem Scrollbar
618 if (nTabSize > nSizeRt-SC_SCROLLBAR_MIN) nTabSize = nSizeRt-SC_SCROLLBAR_MIN;
619 if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN;
620 nSizeRt -= nTabSize;
624 lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY),
625 Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL );
626 pTabControl->SetSheetLayoutRTL( bLayoutRTL );
628 lcl_SetPosSize( aHScrollLeft, Point(nPosX+nTabSize-nOverlap, nPosY+nSizeY),
629 Size(nSizeLt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL );
630 lcl_SetPosSize( *pHSplitter, Point( nPosX+nTabSize+nSizeLt, nPosY+nSizeY ),
631 Size( nSizeSp, nBarY ), nTotalWidth, bLayoutRTL );
632 lcl_SetPosSize( aHScrollRight, Point(nPosX+nTabSize+nSizeLt+nSizeSp-nOverlap,
633 nPosY+nSizeY),
634 Size(nSizeRt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL );
636 // SetDragRectPixel is done below
639 if (bVScroll) // Scrollbars vertikal
641 long nSizeUp = 0; // upper scroll bar
642 long nSizeSp = 0; // splitter
643 long nSizeDn; // unterer Scrollbar
645 switch (aViewData.GetVSplitMode())
647 case SC_SPLIT_NONE:
648 nSizeUp = 0;
649 nSizeSp = nSplitSizeY;
650 break;
651 case SC_SPLIT_NORMAL:
652 nSizeUp = aViewData.GetVSplitPos();
653 nSizeSp = nSplitSizeY;
654 break;
655 case SC_SPLIT_FIX:
656 nSizeUp = 0;
657 nSizeSp = 0;
658 break;
660 nSizeDn = nSizeY - nSizeUp - nSizeSp;
662 lcl_SetPosSize( aVScrollTop, Point(nPosX+nSizeX, nPosY-nOverlap),
663 Size(nBarX,nSizeUp+2*nOverlap), nTotalWidth, bLayoutRTL );
664 lcl_SetPosSize( *pVSplitter, Point( nPosX+nSizeX, nPosY+nSizeUp ),
665 Size( nBarX, nSizeSp ), nTotalWidth, bLayoutRTL );
666 lcl_SetPosSize( aVScrollBottom, Point(nPosX+nSizeX,
667 nPosY+nSizeUp+nSizeSp-nOverlap),
668 Size(nBarX, nSizeDn+2*nOverlap), nTotalWidth, bLayoutRTL );
670 // SetDragRectPixel is done below
674 // SetDragRectPixel auch ohne Scrollbars etc., wenn schon gesplittet ist
675 if ( bHScroll || aViewData.GetHSplitMode() != SC_SPLIT_NONE )
676 pHSplitter->SetDragRectPixel(
677 Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
678 if ( bVScroll || aViewData.GetVSplitMode() != SC_SPLIT_NONE )
679 pVSplitter->SetDragRectPixel(
680 Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
682 if (bTabControl && ! bHScroll )
684 nBarY = aHScrollLeft.GetSizePixel().Height();
685 nBarX = aVScrollBottom.GetSizePixel().Width();
687 nSize1 = nSizeX + nOverlap;
689 long nTabSize = nSize1;
690 if (nTabSize < 0) nTabSize = 0;
692 lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY-nBarY),
693 Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL );
694 nSizeY -= nBarY - nOverlap;
695 lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
696 nTotalWidth, bLayoutRTL );
698 if( bVScroll )
700 Size aVScrSize = aVScrollBottom.GetSizePixel();
701 aVScrSize.Height() -= nBarY;
702 aVScrollBottom.SetSizePixel( aVScrSize );
706 nOutPosX = nPosX;
707 nOutPosY = nPosY;
709 // Outline-Controls
710 if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
712 nOutlineX = pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
713 nSizeX -= nOutlineX;
714 nPosX += nOutlineX;
716 if (bHOutline && pColOutline[SC_SPLIT_LEFT])
718 nOutlineY = pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
719 nSizeY -= nOutlineY;
720 nPosY += nOutlineY;
723 if (bHeaders) // Spalten/Zeilen-Header
725 nBarX = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
726 nBarY = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
727 nSizeX -= nBarX;
728 nSizeY -= nBarY;
729 nPosX += nBarX;
730 nPosY += nBarY;
732 else
733 nBarX = nBarY = 0;
736 // Splitter auswerten
739 long nLeftSize = nSizeX;
740 long nRightSize = 0;
741 long nTopSize = 0;
742 long nBottomSize = nSizeY;
743 long nSplitPosX = nPosX;
744 long nSplitPosY = nPosY;
746 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
748 long nSplitHeight = rSize.Height();
749 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
751 // Fixier-Splitter nicht mit Scrollbar/TabBar ueberlappen lassen
752 if ( bHScroll )
753 nSplitHeight -= aHScrollLeft.GetSizePixel().Height();
754 else if ( bTabControl && pTabControl )
755 nSplitHeight -= pTabControl->GetSizePixel().Height();
757 nSplitPosX = aViewData.GetHSplitPos();
758 lcl_SetPosSize( *pHSplitter,
759 Point( nSplitPosX, nOutPosY ), Size( nSplitSizeX, nSplitHeight ), nTotalWidth, bLayoutRTL );
760 nLeftSize = nSplitPosX - nPosX;
761 nSplitPosX += nSplitSizeX;
762 nRightSize = nSizeX - nLeftSize - nSplitSizeX;
764 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
766 long nSplitWidth = rSize.Width();
767 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && bVScroll )
768 nSplitWidth -= aVScrollBottom.GetSizePixel().Width();
769 nSplitPosY = aViewData.GetVSplitPos();
770 lcl_SetPosSize( *pVSplitter,
771 Point( nOutPosX, nSplitPosY ), Size( nSplitWidth, nSplitSizeY ), nTotalWidth, bLayoutRTL );
772 nTopSize = nSplitPosY - nPosY;
773 nSplitPosY += nSplitSizeY;
774 nBottomSize = nSizeY - nTopSize - nSplitSizeY;
777 // ShowHide fuer pColOutline / pRowOutline passiert in UpdateShow
779 if (bHOutline) // Outline-Controls
781 if (pColOutline[SC_SPLIT_LEFT])
783 pColOutline[SC_SPLIT_LEFT]->SetHeaderSize( nBarX );
784 lcl_SetPosSize( *pColOutline[SC_SPLIT_LEFT],
785 Point(nPosX-nBarX,nOutPosY), Size(nLeftSize+nBarX,nOutlineY), nTotalWidth, bLayoutRTL );
787 if (pColOutline[SC_SPLIT_RIGHT])
789 pColOutline[SC_SPLIT_RIGHT]->SetHeaderSize( 0 ); // always call to update RTL flag
790 lcl_SetPosSize( *pColOutline[SC_SPLIT_RIGHT],
791 Point(nSplitPosX,nOutPosY), Size(nRightSize,nOutlineY), nTotalWidth, bLayoutRTL );
794 if (bVOutline)
796 if (nTopSize)
798 if (pRowOutline[SC_SPLIT_TOP] && pRowOutline[SC_SPLIT_BOTTOM])
800 pRowOutline[SC_SPLIT_TOP]->SetHeaderSize( nBarY );
801 lcl_SetPosSize( *pRowOutline[SC_SPLIT_TOP],
802 Point(nOutPosX,nPosY-nBarY), Size(nOutlineX,nTopSize+nBarY), nTotalWidth, bLayoutRTL );
803 pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( 0 );
804 lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
805 Point(nOutPosX,nSplitPosY), Size(nOutlineX,nBottomSize), nTotalWidth, bLayoutRTL );
808 else if (pRowOutline[SC_SPLIT_BOTTOM])
810 pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( nBarY );
811 lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
812 Point(nOutPosX,nSplitPosY-nBarY), Size(nOutlineX,nBottomSize+nBarY), nTotalWidth, bLayoutRTL );
815 if (bHOutline && bVOutline)
817 lcl_SetPosSize( aTopButton, Point(nOutPosX,nOutPosY), Size(nOutlineX,nOutlineY), nTotalWidth, bLayoutRTL );
818 aTopButton.Show();
820 else
821 aTopButton.Hide();
823 if (bHeaders) // Spalten/Zeilen-Header
825 lcl_SetPosSize( *pColBar[SC_SPLIT_LEFT],
826 Point(nPosX,nPosY-nBarY), Size(nLeftSize,nBarY), nTotalWidth, bLayoutRTL );
827 if (pColBar[SC_SPLIT_RIGHT])
828 lcl_SetPosSize( *pColBar[SC_SPLIT_RIGHT],
829 Point(nSplitPosX,nPosY-nBarY), Size(nRightSize,nBarY), nTotalWidth, bLayoutRTL );
831 if (pRowBar[SC_SPLIT_TOP])
832 lcl_SetPosSize( *pRowBar[SC_SPLIT_TOP],
833 Point(nPosX-nBarX,nPosY), Size(nBarX,nTopSize), nTotalWidth, bLayoutRTL );
834 lcl_SetPosSize( *pRowBar[SC_SPLIT_BOTTOM],
835 Point(nPosX-nBarX,nSplitPosY), Size(nBarX,nBottomSize), nTotalWidth, bLayoutRTL );
837 lcl_SetPosSize( aCornerButton, Point(nPosX-nBarX,nPosY-nBarY), Size(nBarX,nBarY), nTotalWidth, bLayoutRTL );
838 aCornerButton.Show();
839 pColBar[SC_SPLIT_LEFT]->Show();
840 pRowBar[SC_SPLIT_BOTTOM]->Show();
842 else
844 aCornerButton.Hide();
845 pColBar[SC_SPLIT_LEFT]->Hide(); // immer da
846 pRowBar[SC_SPLIT_BOTTOM]->Hide();
850 // Grid-Windows
852 if (bInner)
854 long nInnerPosX = bLayoutRTL ? ( nTotalWidth - nPosX - nLeftSize ) : nPosX;
855 pGridWin[SC_SPLIT_BOTTOMLEFT]->SetPosPixel( Point(nInnerPosX,nSplitPosY) );
857 else
859 lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMLEFT],
860 Point(nPosX,nSplitPosY), Size(nLeftSize,nBottomSize), nTotalWidth, bLayoutRTL );
861 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
862 lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMRIGHT],
863 Point(nSplitPosX,nSplitPosY), Size(nRightSize,nBottomSize), nTotalWidth, bLayoutRTL );
864 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
865 lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPLEFT],
866 Point(nPosX,nPosY), Size(nLeftSize,nTopSize), nTotalWidth, bLayoutRTL );
867 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE && aViewData.GetVSplitMode() != SC_SPLIT_NONE )
868 lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPRIGHT],
869 Point(nSplitPosX,nPosY), Size(nRightSize,nTopSize), nTotalWidth, bLayoutRTL );
873 // Scrollbars updaten
876 if (!bInUpdateHeader)
878 UpdateScrollBars(); // Scrollbars nicht beim Scrollen neu setzen
879 UpdateHeaderWidth();
881 InterpretVisible(); // #69343# have everything calculated before painting
884 if (bHasHint)
885 TestHintWindow(); // neu positionieren
887 UpdateVarZoom(); // update variable zoom types (after resizing GridWindows)
889 if (aViewData.GetViewShell()->HasAccessibilityObjects())
890 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_WINDOWRESIZED));
893 void ScTabView::UpdateVarZoom()
895 // update variable zoom types
897 SvxZoomType eZoomType = GetZoomType();
898 if ( eZoomType != SVX_ZOOM_PERCENT && !bInZoomUpdate )
900 bInZoomUpdate = TRUE;
901 const Fraction& rOldX = GetViewData()->GetZoomX();
902 const Fraction& rOldY = GetViewData()->GetZoomY();
903 long nOldPercent = ( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator();
904 USHORT nNewZoom = CalcZoom( eZoomType, (USHORT)nOldPercent );
905 Fraction aNew( nNewZoom, 100 );
907 if ( aNew != rOldX || aNew != rOldY )
909 SetZoom( aNew, aNew, FALSE ); // always separately per sheet
910 PaintGrid();
911 PaintTop();
912 PaintLeft();
913 aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
914 aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
916 bInZoomUpdate = FALSE;
920 void ScTabView::UpdateFixPos()
922 BOOL bResize = FALSE;
923 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
924 if (aViewData.UpdateFixX())
925 bResize = TRUE;
926 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
927 if (aViewData.UpdateFixY())
928 bResize = TRUE;
929 if (bResize)
930 RepeatResize(FALSE);
933 void ScTabView::RepeatResize( BOOL bUpdateFix )
935 if ( bUpdateFix )
937 ScSplitMode eHSplit = aViewData.GetHSplitMode();
938 ScSplitMode eVSplit = aViewData.GetVSplitMode();
940 // #i46796# UpdateFixX / UpdateFixY uses GetGridOffset, which requires the
941 // outline windows to be available. So UpdateShow has to be called before
942 // (also called from DoResize).
943 if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX )
944 UpdateShow();
946 if ( eHSplit == SC_SPLIT_FIX )
947 aViewData.UpdateFixX();
948 if ( eVSplit == SC_SPLIT_FIX )
949 aViewData.UpdateFixY();
952 DoResize( aBorderPos, aFrameSize );
954 //! Border muss neu gesetzt werden ???
957 void ScTabView::GetBorderSize( SvBorder& rBorder, const Size& /* rSize */ )
959 BOOL bScrollBars = aViewData.IsVScrollMode();
960 BOOL bHeaders = aViewData.IsHeaderMode();
961 BOOL bOutlMode = aViewData.IsOutlineMode();
962 BOOL bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
963 BOOL bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
964 BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
966 rBorder = SvBorder();
968 if (bScrollBars) // Scrollbars horizontal oder vertikal
970 rBorder.Right() += aVScrollBottom.GetSizePixel().Width();
971 rBorder.Bottom() += aHScrollLeft.GetSizePixel().Height();
974 // Outline-Controls
975 if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
976 rBorder.Left() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
977 if (bHOutline && pColOutline[SC_SPLIT_LEFT])
978 rBorder.Top() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
980 if (bHeaders) // Spalten/Zeilen-Header
982 rBorder.Left() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
983 rBorder.Top() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
986 if ( bLayoutRTL )
987 ::std::swap( rBorder.Left(), rBorder.Right() );
990 IMPL_LINK( ScTabView, TabBarResize, void*, EMPTYARG )
992 BOOL bHScrollMode = aViewData.IsHScrollMode();
994 // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
995 SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
996 if ( eMode == SCROLLING_NO )
997 bHScrollMode = FALSE;
998 else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ???
999 bHScrollMode = TRUE;
1001 if( bHScrollMode )
1003 const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel();
1004 long nSize = pTabControl->GetSplitSize();
1006 if (aViewData.GetHSplitMode() != SC_SPLIT_FIX)
1008 long nMax = pHSplitter->GetPosPixel().X();
1009 if( pTabControl->IsEffectiveRTL() )
1010 nMax = pFrameWin->GetSizePixel().Width() - nMax;
1011 --nMax;
1012 if (nSize>nMax) nSize = nMax;
1015 if ( nSize != pTabControl->GetSizePixel().Width() )
1017 pTabControl->SetSizePixel( Size( nSize+nOverlap,
1018 pTabControl->GetSizePixel().Height() ) );
1019 RepeatResize();
1023 return 0;
1026 void ScTabView::SetTabBarWidth( long nNewWidth )
1028 Size aSize = pTabControl->GetSizePixel();
1030 if ( aSize.Width() != nNewWidth )
1032 aSize.Width() = nNewWidth;
1033 pTabControl->SetSizePixel( aSize );
1037 void ScTabView::SetRelTabBarWidth( double fRelTabBarWidth )
1039 if( (0.0 <= fRelTabBarWidth) && (fRelTabBarWidth <= 1.0) )
1040 if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
1041 SetTabBarWidth( static_cast< long >( fRelTabBarWidth * nFrameWidth + 0.5 ) );
1044 void ScTabView::SetPendingRelTabBarWidth( double fRelTabBarWidth )
1046 mfPendingTabBarWidth = fRelTabBarWidth;
1047 SetRelTabBarWidth( fRelTabBarWidth );
1050 long ScTabView::GetTabBarWidth() const
1052 return pTabControl->GetSizePixel().Width();
1055 double ScTabView::GetRelTabBarWidth() const
1057 if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
1058 return static_cast< double >( GetTabBarWidth() ) / nFrameWidth;
1059 return 0.0;
1062 double ScTabView::GetPendingRelTabBarWidth() const
1064 return mfPendingTabBarWidth;
1067 Window* ScTabView::GetActiveWin()
1069 ScSplitPos ePos = aViewData.GetActivePart();
1070 DBG_ASSERT(pGridWin[ePos],"kein aktives Fenster");
1071 return pGridWin[ePos];
1074 Window* ScTabView::GetWindowByPos( ScSplitPos ePos )
1076 return pGridWin[ePos];
1079 void ScTabView::SetActivePointer( const Pointer& rPointer )
1081 for (USHORT i=0; i<4; i++)
1082 if (pGridWin[i])
1083 pGridWin[i]->SetPointer( rPointer );
1085 /* ScSplitPos ePos = aViewData.GetActivePart();
1086 if (pGridWin[ePos])
1087 pGridWin[ePos]->SetPointer( rPointer );
1091 //UNUSED2008-05 void ScTabView::SetActivePointer( const ResId& )
1092 //UNUSED2008-05 {
1093 //UNUSED2008-05 DBG_ERRORFILE( "keine Pointer mit ResId!" );
1094 //UNUSED2008-05 }
1096 void ScTabView::ActiveGrabFocus()
1098 ScSplitPos ePos = aViewData.GetActivePart();
1099 if (pGridWin[ePos])
1100 pGridWin[ePos]->GrabFocus();
1103 //UNUSED2008-05 void ScTabView::ActiveCaptureMouse()
1104 //UNUSED2008-05 {
1105 //UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart();
1106 //UNUSED2008-05 if (pGridWin[ePos])
1107 //UNUSED2008-05 pGridWin[ePos]->CaptureMouse();
1108 //UNUSED2008-05 }
1109 //UNUSED2008-05
1110 //UNUSED2008-05 void ScTabView::ActiveReleaseMouse()
1111 //UNUSED2008-05 {
1112 //UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart();
1113 //UNUSED2008-05 if (pGridWin[ePos])
1114 //UNUSED2008-05 pGridWin[ePos]->ReleaseMouse();
1115 //UNUSED2008-05 }
1116 //UNUSED2008-05
1117 //UNUSED2008-05 Point ScTabView::ActivePixelToLogic( const Point& rDevicePoint )
1118 //UNUSED2008-05 {
1119 //UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart();
1120 //UNUSED2008-05 if (pGridWin[ePos])
1121 //UNUSED2008-05 return pGridWin[ePos]->PixelToLogic(rDevicePoint);
1122 //UNUSED2008-05 else
1123 //UNUSED2008-05 return Point();
1124 //UNUSED2008-05 }
1126 ScSplitPos ScTabView::FindWindow( Window* pWindow ) const
1128 ScSplitPos eVal = SC_SPLIT_BOTTOMLEFT; // Default
1129 for (USHORT i=0; i<4; i++)
1130 if ( pGridWin[i] == pWindow )
1131 eVal = (ScSplitPos) i;
1133 return eVal;
1136 Point ScTabView::GetGridOffset() const
1138 Point aPos;
1140 // Groessen hier wie in DoResize
1142 BOOL bHeaders = aViewData.IsHeaderMode();
1143 BOOL bOutlMode = aViewData.IsOutlineMode();
1144 BOOL bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
1145 BOOL bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
1147 // Outline-Controls
1148 if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
1149 aPos.X() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
1150 if (bHOutline && pColOutline[SC_SPLIT_LEFT])
1151 aPos.Y() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
1153 if (bHeaders) // Spalten/Zeilen-Header
1155 if (pRowBar[SC_SPLIT_BOTTOM])
1156 aPos.X() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
1157 if (pColBar[SC_SPLIT_LEFT])
1158 aPos.Y() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
1161 return aPos;
1164 // --- Scroll-Bars --------------------------------------------------------
1166 BOOL ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos )
1168 HideNoteMarker();
1170 BOOL bDone = FALSE;
1171 const CommandWheelData* pData = rCEvt.GetWheelData();
1172 if ( pData && pData->GetMode() == COMMAND_WHEEL_ZOOM )
1174 if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame()->IsInPlace() )
1176 // for ole inplace editing, the scale is defined by the visarea and client size
1177 // and can't be changed directly
1179 const Fraction& rOldY = aViewData.GetZoomY();
1180 long nOld = (long)(( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator());
1181 long nNew = nOld;
1182 if ( pData->GetDelta() < 0 )
1183 nNew = Max( (long) MINZOOM, (long)( nOld - SC_DELTA_ZOOM ) );
1184 else
1185 nNew = Min( (long) MAXZOOM, (long)( nOld + SC_DELTA_ZOOM ) );
1187 if ( nNew != nOld )
1189 // scroll wheel doesn't set the AppOptions default
1191 BOOL bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
1192 SetZoomType( SVX_ZOOM_PERCENT, bSyncZoom );
1193 Fraction aFract( nNew, 100 );
1194 SetZoom( aFract, aFract, bSyncZoom );
1195 PaintGrid();
1196 PaintTop();
1197 PaintLeft();
1198 aViewData.GetBindings().Invalidate( SID_ATTR_ZOOM );
1199 aViewData.GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
1202 bDone = TRUE;
1205 else
1207 ScHSplitPos eHPos = WhichH(ePos);
1208 ScVSplitPos eVPos = WhichV(ePos);
1209 ScrollBar* pHScroll = ( eHPos == SC_SPLIT_LEFT ) ? &aHScrollLeft : &aHScrollRight;
1210 ScrollBar* pVScroll = ( eVPos == SC_SPLIT_TOP ) ? &aVScrollTop : &aVScrollBottom;
1211 if ( pGridWin[ePos] )
1212 bDone = pGridWin[ePos]->HandleScrollCommand( rCEvt, pHScroll, pVScroll );
1214 return bDone;
1217 IMPL_LINK( ScTabView, EndScrollHdl, ScrollBar*, pScroll )
1219 BOOL bOnlineScroll = TRUE; //! Optionen
1221 if ( bDragging )
1223 if ( bOnlineScroll ) // nur Ranges aktualisieren
1224 UpdateScrollBars();
1225 else
1227 long nScrollMin = 0; // RangeMin simulieren
1228 if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
1229 nScrollMin = aViewData.GetFixPosX();
1230 if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
1231 nScrollMin = aViewData.GetFixPosY();
1233 if ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight )
1235 BOOL bMirror = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ) != Application::GetSettings().GetLayoutRTL();
1236 ScHSplitPos eWhich = (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT;
1237 long nDelta = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin - aViewData.GetPosX(eWhich);
1238 if (nDelta) ScrollX( nDelta, eWhich );
1240 else // VScroll...
1242 ScVSplitPos eWhich = (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM;
1243 long nDelta = GetScrollBarPos( *pScroll, FALSE ) + nScrollMin - aViewData.GetPosY(eWhich);
1244 if (nDelta) ScrollY( nDelta, eWhich );
1247 bDragging = FALSE;
1249 return 0;
1252 IMPL_LINK( ScTabView, ScrollHdl, ScrollBar*, pScroll )
1254 BOOL bOnlineScroll = TRUE; //! Optionen
1256 BOOL bHoriz = ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight );
1257 long nViewPos;
1258 if ( bHoriz )
1259 nViewPos = aViewData.GetPosX( (pScroll == &aHScrollLeft) ?
1260 SC_SPLIT_LEFT : SC_SPLIT_RIGHT );
1261 else
1262 nViewPos = aViewData.GetPosY( (pScroll == &aVScrollTop) ?
1263 SC_SPLIT_TOP : SC_SPLIT_BOTTOM );
1265 BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1266 BOOL bMirror = bHoriz && (bLayoutRTL != Application::GetSettings().GetLayoutRTL());
1268 ScrollType eType = pScroll->GetType();
1269 if ( eType == SCROLL_DRAG )
1271 if (!bDragging)
1273 bDragging = TRUE;
1274 nPrevDragPos = nViewPos;
1277 // Scroll-Position anzeigen
1278 // (nur QuickHelp, in der Statuszeile gibt es keinen Eintrag dafuer)
1280 if (Help::IsQuickHelpEnabled())
1282 Size aSize = pScroll->GetSizePixel();
1284 /* Convert scrollbar mouse position to screen position. If RTL
1285 mode of scrollbar differs from RTL mode of its parent, then the
1286 direct call to Window::OutputToNormalizedScreenPixel() will
1287 give unusable results, because calcualtion of screen position
1288 is based on parent orientation and expects equal orientation of
1289 the child position. Need to mirror mouse position before. */
1290 Point aMousePos = pScroll->GetPointerPosPixel();
1291 if( pScroll->IsRTLEnabled() != pScroll->GetParent()->IsRTLEnabled() )
1292 aMousePos.X() = aSize.Width() - aMousePos.X() - 1;
1293 aMousePos = pScroll->OutputToNormalizedScreenPixel( aMousePos );
1295 // convert top-left position of scrollbar to screen position
1296 Point aPos = pScroll->OutputToNormalizedScreenPixel( Point() );
1298 // get scrollbar scroll position for help text (row number/column name)
1299 long nScrollMin = 0; // RangeMin simulieren
1300 if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
1301 nScrollMin = aViewData.GetFixPosX();
1302 if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
1303 nScrollMin = aViewData.GetFixPosY();
1304 long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin;
1306 String aHelpStr;
1307 Rectangle aRect;
1308 USHORT nAlign;
1309 if (bHoriz)
1311 aHelpStr = ScGlobal::GetRscString(STR_COLUMN);
1312 aHelpStr += ' ';
1313 aHelpStr += ScColToAlpha((SCCOL) nScrollPos);
1315 aRect.Left() = aMousePos.X();
1316 aRect.Top() = aPos.Y() - 4;
1317 nAlign = QUICKHELP_BOTTOM|QUICKHELP_CENTER;
1319 else
1321 aHelpStr = ScGlobal::GetRscString(STR_ROW);
1322 aHelpStr += ' ';
1323 aHelpStr += String::CreateFromInt32(nScrollPos + 1);
1325 // show quicktext always inside sheet area
1326 aRect.Left() = bLayoutRTL ? (aPos.X() + aSize.Width() + 8) : (aPos.X() - 8);
1327 aRect.Top() = aMousePos.Y();
1328 nAlign = (bLayoutRTL ? QUICKHELP_LEFT : QUICKHELP_RIGHT) | QUICKHELP_VCENTER;
1330 aRect.Right() = aRect.Left();
1331 aRect.Bottom() = aRect.Top();
1333 Help::ShowQuickHelp(pScroll->GetParent(), aRect, aHelpStr, nAlign);
1337 if ( bOnlineScroll || eType != SCROLL_DRAG )
1339 if ( bMirror )
1341 // change scroll type so visible/previous cells calculation below remains the same
1342 switch ( eType )
1344 case SCROLL_LINEUP: eType = SCROLL_LINEDOWN; break;
1345 case SCROLL_LINEDOWN: eType = SCROLL_LINEUP; break;
1346 case SCROLL_PAGEUP: eType = SCROLL_PAGEDOWN; break;
1347 case SCROLL_PAGEDOWN: eType = SCROLL_PAGEUP; break;
1348 default:
1350 // added to avoid warnings
1354 long nDelta = pScroll->GetDelta();
1355 switch ( eType )
1357 case SCROLL_LINEUP:
1358 nDelta = -1;
1359 break;
1360 case SCROLL_LINEDOWN:
1361 nDelta = 1;
1362 break;
1363 case SCROLL_PAGEUP:
1364 if ( pScroll == &aHScrollLeft ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_LEFT );
1365 if ( pScroll == &aHScrollRight ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_RIGHT );
1366 if ( pScroll == &aVScrollTop ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_TOP );
1367 if ( pScroll == &aVScrollBottom ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_BOTTOM );
1368 if (nDelta==0) nDelta=-1;
1369 break;
1370 case SCROLL_PAGEDOWN:
1371 if ( pScroll == &aHScrollLeft ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_LEFT );
1372 if ( pScroll == &aHScrollRight ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_RIGHT );
1373 if ( pScroll == &aVScrollTop ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_TOP );
1374 if ( pScroll == &aVScrollBottom ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM );
1375 if (nDelta==0) nDelta=1;
1376 break;
1377 case SCROLL_DRAG:
1379 // nur in die richtige Richtung scrollen, nicht um ausgeblendete
1380 // Bereiche herumzittern
1382 long nScrollMin = 0; // RangeMin simulieren
1383 if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
1384 nScrollMin = aViewData.GetFixPosX();
1385 if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
1386 nScrollMin = aViewData.GetFixPosY();
1388 long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin;
1389 nDelta = nScrollPos - nViewPos;
1390 if ( nScrollPos > nPrevDragPos )
1392 if (nDelta<0) nDelta=0;
1394 else if ( nScrollPos < nPrevDragPos )
1396 if (nDelta>0) nDelta=0;
1398 else
1399 nDelta = 0;
1400 nPrevDragPos = nScrollPos;
1402 break;
1403 default:
1405 // added to avoid warnings
1409 if (nDelta)
1411 BOOL bUpdate = ( eType != SCROLL_DRAG ); // bei Drag die Ranges nicht aendern
1412 if ( bHoriz )
1413 ScrollX( nDelta, (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT, bUpdate );
1414 else
1415 ScrollY( nDelta, (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM, bUpdate );
1419 return 0;
1422 void ScTabView::ScrollX( long nDeltaX, ScHSplitPos eWhich, BOOL bUpdBars )
1424 BOOL bHasHint = ( pInputHintWindow != NULL );
1425 if (bHasHint)
1426 RemoveHintWindow();
1428 SCCOL nOldX = aViewData.GetPosX(eWhich);
1429 SCsCOL nNewX = static_cast<SCsCOL>(nOldX) + static_cast<SCsCOL>(nDeltaX);
1430 if ( nNewX < 0 )
1432 nDeltaX -= nNewX;
1433 nNewX = 0;
1435 if ( nNewX > MAXCOL )
1437 nDeltaX -= nNewX - MAXCOL;
1438 nNewX = MAXCOL;
1441 SCsCOL nDir = ( nDeltaX > 0 ) ? 1 : -1;
1442 ScDocument* pDoc = aViewData.GetDocument();
1443 SCTAB nTab = aViewData.GetTabNo();
1444 while ( pDoc->ColHidden(nNewX, nTab) &&
1445 nNewX+nDir >= 0 && nNewX+nDir <= MAXCOL )
1446 nNewX = sal::static_int_cast<SCsCOL>( nNewX + nDir );
1448 // Fixierung
1450 if (aViewData.GetHSplitMode() == SC_SPLIT_FIX)
1452 if (eWhich == SC_SPLIT_LEFT)
1453 nNewX = static_cast<SCsCOL>(nOldX); // links immer stehenlassen
1454 else
1456 SCsCOL nFixX = static_cast<SCsCOL>(aViewData.GetFixPosX());
1457 if (nNewX < nFixX)
1458 nNewX = nFixX;
1461 if (nNewX == static_cast<SCsCOL>(nOldX))
1462 return;
1464 HideAllCursors();
1466 if ( nNewX >= 0 && nNewX <= MAXCOL && nDeltaX )
1468 SCCOL nTrackX = std::max( nOldX, static_cast<SCCOL>(nNewX) );
1470 // Mit VCL wirkt Update() im Moment immer auf alle Fenster, beim Update
1471 // nach dem Scrollen des GridWindow's wuerde darum der Col-/RowBar evtl.
1472 // mit schon geaenderter Pos. gepainted werden -
1473 // darum vorher einmal Update am Col-/RowBar
1475 if (pColBar[eWhich])
1476 pColBar[eWhich]->Update();
1478 long nOldPos = aViewData.GetScrPos( nTrackX, 0, eWhich ).X();
1479 aViewData.SetPosX( eWhich, static_cast<SCCOL>(nNewX) );
1480 long nDiff = aViewData.GetScrPos( nTrackX, 0, eWhich ).X() - nOldPos;
1482 if ( eWhich==SC_SPLIT_LEFT )
1484 pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( nDiff, 0 );
1485 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
1486 pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( nDiff, 0 );
1488 else
1490 pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( nDiff, 0 );
1491 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
1492 pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( nDiff, 0 );
1494 if (pColBar[eWhich]) { pColBar[eWhich]->Scroll( nDiff,0 ); pColBar[eWhich]->Update(); }
1495 if (pColOutline[eWhich]) pColOutline[eWhich]->ScrollPixel( nDiff );
1496 if (bUpdBars)
1497 UpdateScrollBars();
1500 if (nDeltaX==1 || nDeltaX==-1)
1501 pGridWin[aViewData.GetActivePart()]->Update();
1503 ShowAllCursors();
1505 SetNewVisArea(); // MapMode muss schon gesetzt sein
1507 if (bHasHint)
1508 TestHintWindow(); // neu positionieren
1511 void ScTabView::ScrollY( long nDeltaY, ScVSplitPos eWhich, BOOL bUpdBars )
1513 BOOL bHasHint = ( pInputHintWindow != NULL );
1514 if (bHasHint)
1515 RemoveHintWindow();
1517 SCROW nOldY = aViewData.GetPosY(eWhich);
1518 SCsROW nNewY = static_cast<SCsROW>(nOldY) + static_cast<SCsROW>(nDeltaY);
1519 if ( nNewY < 0 )
1521 nDeltaY -= nNewY;
1522 nNewY = 0;
1524 if ( nNewY > MAXROW )
1526 nDeltaY -= nNewY - MAXROW;
1527 nNewY = MAXROW;
1530 SCsROW nDir = ( nDeltaY > 0 ) ? 1 : -1;
1531 ScDocument* pDoc = aViewData.GetDocument();
1532 SCTAB nTab = aViewData.GetTabNo();
1533 while ( pDoc->RowHidden(nNewY, nTab) &&
1534 nNewY+nDir >= 0 && nNewY+nDir <= MAXROW )
1535 nNewY += nDir;
1537 // Fixierung
1539 if (aViewData.GetVSplitMode() == SC_SPLIT_FIX)
1541 if (eWhich == SC_SPLIT_TOP)
1542 nNewY = static_cast<SCsROW>(nOldY); // oben immer stehenlassen
1543 else
1545 SCsROW nFixY = static_cast<SCsROW>(aViewData.GetFixPosY());
1546 if (nNewY < nFixY)
1547 nNewY = nFixY;
1550 if (nNewY == static_cast<SCsROW>(nOldY))
1551 return;
1553 HideAllCursors();
1555 if ( nNewY >= 0 && nNewY <= MAXROW && nDeltaY )
1557 SCROW nTrackY = std::max( nOldY, static_cast<SCROW>(nNewY) );
1559 // Zeilenkoepfe anpassen vor dem eigentlichen Scrolling, damit nicht
1560 // doppelt gepainted werden muss
1561 // PosY darf dann auch noch nicht umgesetzt sein, neuen Wert uebergeben
1562 SCROW nUNew = static_cast<SCROW>(nNewY);
1563 UpdateHeaderWidth( &eWhich, &nUNew ); // Zeilenkoepfe anpassen
1565 if (pRowBar[eWhich])
1566 pRowBar[eWhich]->Update();
1568 long nOldPos = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y();
1569 aViewData.SetPosY( eWhich, static_cast<SCROW>(nNewY) );
1570 long nDiff = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y() - nOldPos;
1572 if ( eWhich==SC_SPLIT_TOP )
1574 pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( 0, nDiff );
1575 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
1576 pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( 0, nDiff );
1578 else
1580 pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( 0, nDiff );
1581 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
1582 pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( 0, nDiff );
1584 if (pRowBar[eWhich]) { pRowBar[eWhich]->Scroll( 0,nDiff ); pRowBar[eWhich]->Update(); }
1585 if (pRowOutline[eWhich]) pRowOutline[eWhich]->ScrollPixel( nDiff );
1586 if (bUpdBars)
1587 UpdateScrollBars();
1590 if (nDeltaY==1 || nDeltaY==-1)
1591 pGridWin[aViewData.GetActivePart()]->Update();
1593 ShowAllCursors();
1595 SetNewVisArea(); // MapMode muss schon gesetzt sein
1597 if (bHasHint)
1598 TestHintWindow(); // neu positionieren
1601 void ScTabView::ScrollLines( long nDeltaX, long nDeltaY )
1603 ScSplitPos eWhich = aViewData.GetActivePart();
1604 if (nDeltaX)
1605 ScrollX(nDeltaX,WhichH(eWhich));
1606 if (nDeltaY)
1607 ScrollY(nDeltaY,WhichV(eWhich));
1610 SCROW lcl_LastVisible( ScViewData& rViewData )
1612 // wenn am Dokumentende viele Zeilen ausgeblendet sind (welcher Trottel macht sowas?),
1613 // soll dadurch nicht auf breite Zeilenkoepfe geschaltet werden
1614 //! als Member ans Dokument ???
1616 ScDocument* pDoc = rViewData.GetDocument();
1617 SCTAB nTab = rViewData.GetTabNo();
1619 SCROW nVis = MAXROW;
1620 while ( nVis > 0 && pDoc->FastGetRowHeight( nVis, nTab ) == 0 )
1621 --nVis;
1622 return nVis;
1625 void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY )
1627 if ( !pRowBar[SC_SPLIT_BOTTOM] || MAXROW < 10000 )
1628 return;
1630 SCROW nEndPos = MAXROW;
1631 if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame()->IsInPlace() )
1633 // fuer OLE Inplace immer MAXROW
1635 if ( pWhich && *pWhich == SC_SPLIT_BOTTOM && pPosY )
1636 nEndPos = *pPosY;
1637 else
1638 nEndPos = aViewData.GetPosY( SC_SPLIT_BOTTOM );
1639 nEndPos += aViewData.CellsAtY( nEndPos, 1, SC_SPLIT_BOTTOM, SC_SIZE_NONE ); // VisibleCellsY
1640 if (nEndPos > MAXROW)
1641 nEndPos = lcl_LastVisible( aViewData );
1643 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
1645 SCROW nTopEnd;
1646 if ( pWhich && *pWhich == SC_SPLIT_TOP && pPosY )
1647 nTopEnd = *pPosY;
1648 else
1649 nTopEnd = aViewData.GetPosY( SC_SPLIT_TOP );
1650 nTopEnd += aViewData.CellsAtY( nTopEnd, 1, SC_SPLIT_TOP, SC_SIZE_NONE );// VisibleCellsY
1651 if (nTopEnd > MAXROW)
1652 nTopEnd = lcl_LastVisible( aViewData );
1654 if ( nTopEnd > nEndPos )
1655 nEndPos = nTopEnd;
1659 long nSmall = pRowBar[SC_SPLIT_BOTTOM]->GetSmallWidth();
1660 long nBig = pRowBar[SC_SPLIT_BOTTOM]->GetBigWidth();
1661 long nDiff = nBig - nSmall;
1663 if (nEndPos>10000)
1664 nEndPos = 10000;
1665 else if (nEndPos<1) // avoid extra step at 0 (when only one row is visible)
1666 nEndPos = 1;
1667 long nWidth = nBig - ( 10000 - nEndPos ) * nDiff / 10000;
1669 if ( nWidth != pRowBar[SC_SPLIT_BOTTOM]->GetWidth() && !bInUpdateHeader )
1671 bInUpdateHeader = TRUE;
1673 pRowBar[SC_SPLIT_BOTTOM]->SetWidth( nWidth );
1674 if (pRowBar[SC_SPLIT_TOP])
1675 pRowBar[SC_SPLIT_TOP]->SetWidth( nWidth );
1677 RepeatResize();
1679 // auf VCL gibt's Update ohne Ende (jedes Update gilt fuer alle Fenster)
1680 //aCornerButton.Update(); // der bekommt sonst nie ein Update
1682 bInUpdateHeader = FALSE;
1686 inline void ShowHide( Window* pWin, BOOL bShow )
1688 DBG_ASSERT(pWin || !bShow, "Fenster ist nicht da");
1689 if (pWin)
1690 pWin->Show(bShow);
1693 void ScTabView::UpdateShow()
1695 BOOL bHScrollMode = aViewData.IsHScrollMode();
1696 BOOL bVScrollMode = aViewData.IsVScrollMode();
1697 BOOL bTabMode = aViewData.IsTabMode();
1698 BOOL bOutlMode = aViewData.IsOutlineMode();
1699 BOOL bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
1700 BOOL bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
1701 BOOL bHeader = aViewData.IsHeaderMode();
1703 BOOL bShowH = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE );
1704 BOOL bShowV = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE );
1706 // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
1707 SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
1708 if ( eMode == SCROLLING_NO )
1709 bHScrollMode = bVScrollMode = FALSE;
1710 else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ???
1711 bHScrollMode = bVScrollMode = TRUE;
1713 if ( aViewData.GetDocShell()->IsPreview() )
1714 bHScrollMode = bVScrollMode = bTabMode = bHeader = bOutlMode = bHOutline = bVOutline = FALSE;
1717 // Windows anlegen
1720 if (bShowH && !pGridWin[SC_SPLIT_BOTTOMRIGHT])
1722 pGridWin[SC_SPLIT_BOTTOMRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_BOTTOMRIGHT );
1723 DoAddWin( pGridWin[SC_SPLIT_BOTTOMRIGHT] );
1725 if (bShowV && !pGridWin[SC_SPLIT_TOPLEFT])
1727 pGridWin[SC_SPLIT_TOPLEFT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPLEFT );
1728 DoAddWin( pGridWin[SC_SPLIT_TOPLEFT] );
1730 if (bShowH && bShowV && !pGridWin[SC_SPLIT_TOPRIGHT])
1732 pGridWin[SC_SPLIT_TOPRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPRIGHT );
1733 DoAddWin( pGridWin[SC_SPLIT_TOPRIGHT] );
1736 if (bHOutline && !pColOutline[SC_SPLIT_LEFT])
1737 pColOutline[SC_SPLIT_LEFT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMLEFT );
1738 if (bShowH && bHOutline && !pColOutline[SC_SPLIT_RIGHT])
1739 pColOutline[SC_SPLIT_RIGHT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMRIGHT );
1741 if (bVOutline && !pRowOutline[SC_SPLIT_BOTTOM])
1742 pRowOutline[SC_SPLIT_BOTTOM] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_BOTTOMLEFT );
1743 if (bShowV && bVOutline && !pRowOutline[SC_SPLIT_TOP])
1744 pRowOutline[SC_SPLIT_TOP] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_TOPLEFT );
1746 if (bShowH && bHeader && !pColBar[SC_SPLIT_RIGHT])
1747 pColBar[SC_SPLIT_RIGHT] = new ScColBar( pFrameWin, &aViewData, SC_SPLIT_RIGHT,
1748 &aHdrFunc, pHdrSelEng );
1749 if (bShowV && bHeader && !pRowBar[SC_SPLIT_TOP])
1750 pRowBar[SC_SPLIT_TOP] = new ScRowBar( pFrameWin, &aViewData, SC_SPLIT_TOP,
1751 &aHdrFunc, pHdrSelEng );
1754 // Windows anzeigen
1757 ShowHide( &aHScrollLeft, bHScrollMode );
1758 ShowHide( &aHScrollRight, bShowH && bHScrollMode );
1759 ShowHide( &aVScrollBottom, bVScrollMode );
1760 ShowHide( &aVScrollTop, bShowV && bVScrollMode );
1761 ShowHide( &aScrollBarBox, bVScrollMode || bHScrollMode );
1763 ShowHide( pHSplitter, bHScrollMode || bShowH ); // immer angelegt
1764 ShowHide( pVSplitter, bVScrollMode || bShowV );
1765 ShowHide( pTabControl, bTabMode );
1767 // ab hier dynamisch angelegte
1769 ShowHide( pGridWin[SC_SPLIT_BOTTOMRIGHT], bShowH );
1770 ShowHide( pGridWin[SC_SPLIT_TOPLEFT], bShowV );
1771 ShowHide( pGridWin[SC_SPLIT_TOPRIGHT], bShowH && bShowV );
1773 ShowHide( pColOutline[SC_SPLIT_LEFT], bHOutline );
1774 ShowHide( pColOutline[SC_SPLIT_RIGHT], bShowH && bHOutline );
1776 ShowHide( pRowOutline[SC_SPLIT_BOTTOM], bVOutline );
1777 ShowHide( pRowOutline[SC_SPLIT_TOP], bShowV && bVOutline );
1779 ShowHide( pColBar[SC_SPLIT_RIGHT], bShowH && bHeader );
1780 ShowHide( pRowBar[SC_SPLIT_TOP], bShowV && bHeader );
1783 //! neue Gridwindows eintragen
1786 // --- Splitter --------------------------------------------------------
1788 IMPL_LINK( ScTabView, SplitHdl, Splitter*, pSplitter )
1790 if ( pSplitter == pHSplitter )
1791 DoHSplit( pHSplitter->GetSplitPosPixel() );
1792 else
1793 DoVSplit( pVSplitter->GetSplitPosPixel() );
1795 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1796 FreezeSplitters( TRUE );
1798 DoResize( aBorderPos, aFrameSize );
1800 return 0;
1803 void ScTabView::DoHSplit(long nSplitPos)
1805 // nSplitPos is the real pixel position on the frame window,
1806 // mirroring for RTL has to be done here.
1808 BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1809 if ( bLayoutRTL )
1810 nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
1812 long nMinPos;
1813 long nMaxPos;
1814 SCCOL nOldDelta;
1815 SCCOL nNewDelta;
1817 nMinPos = SPLIT_MARGIN;
1818 if ( pRowBar[SC_SPLIT_BOTTOM] && pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() >= nMinPos )
1819 nMinPos = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() + 1;
1820 nMaxPos = aFrameSize.Width() - SPLIT_MARGIN;
1822 ScSplitMode aOldMode = aViewData.GetHSplitMode();
1823 ScSplitMode aNewMode = SC_SPLIT_NORMAL;
1825 aViewData.SetHSplitPos( nSplitPos );
1826 if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
1827 aNewMode = SC_SPLIT_NONE;
1829 aViewData.SetHSplitMode( aNewMode );
1831 if ( aNewMode != aOldMode )
1833 UpdateShow(); // vor ActivatePart !!
1835 if ( aNewMode == SC_SPLIT_NONE )
1837 if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
1838 ActivatePart( SC_SPLIT_TOPLEFT );
1839 if (aViewData.GetActivePart() == SC_SPLIT_BOTTOMRIGHT)
1840 ActivatePart( SC_SPLIT_BOTTOMLEFT );
1842 else
1844 nOldDelta = aViewData.GetPosX( SC_SPLIT_LEFT );
1845 // aViewData.SetPosX( SC_SPLIT_LEFT, nOldDelta );
1846 long nLeftWidth = nSplitPos - pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
1847 if ( nLeftWidth < 0 ) nLeftWidth = 0;
1848 nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, SC_SPLIT_LEFT,
1849 (USHORT) nLeftWidth );
1850 if ( nNewDelta > MAXCOL )
1851 nNewDelta = MAXCOL;
1852 aViewData.SetPosX( SC_SPLIT_RIGHT, nNewDelta );
1853 if ( nNewDelta > aViewData.GetCurX() )
1854 ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
1855 SC_SPLIT_BOTTOMLEFT : SC_SPLIT_TOPLEFT );
1856 else
1857 ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
1858 SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_TOPRIGHT );
1861 // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
1862 // dafuer muss hier schon der MapMode stimmen
1863 for (USHORT i=0; i<4; i++)
1864 if (pGridWin[i])
1865 pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
1866 SetNewVisArea();
1868 PaintGrid();
1869 PaintTop();
1871 InvalidateSplit();
1875 void ScTabView::DoVSplit(long nSplitPos)
1877 long nMinPos;
1878 long nMaxPos;
1879 SCROW nOldDelta;
1880 SCROW nNewDelta;
1882 nMinPos = SPLIT_MARGIN;
1883 if ( pColBar[SC_SPLIT_LEFT] && pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() >= nMinPos )
1884 nMinPos = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() + 1;
1885 nMaxPos = aFrameSize.Height() - SPLIT_MARGIN;
1887 ScSplitMode aOldMode = aViewData.GetVSplitMode();
1888 ScSplitMode aNewMode = SC_SPLIT_NORMAL;
1890 aViewData.SetVSplitPos( nSplitPos );
1891 if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
1892 aNewMode = SC_SPLIT_NONE;
1894 aViewData.SetVSplitMode( aNewMode );
1896 if ( aNewMode != aOldMode )
1898 UpdateShow(); // vor ActivatePart !!
1900 if ( aNewMode == SC_SPLIT_NONE )
1902 nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
1903 aViewData.SetPosY( SC_SPLIT_BOTTOM, nOldDelta );
1905 if (aViewData.GetActivePart() == SC_SPLIT_TOPLEFT)
1906 ActivatePart( SC_SPLIT_BOTTOMLEFT );
1907 if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
1908 ActivatePart( SC_SPLIT_BOTTOMRIGHT );
1910 else
1912 if ( aOldMode == SC_SPLIT_NONE )
1913 nOldDelta = aViewData.GetPosY( SC_SPLIT_BOTTOM );
1914 else
1915 nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
1917 aViewData.SetPosY( SC_SPLIT_TOP, nOldDelta );
1918 long nTopHeight = nSplitPos - pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
1919 if ( nTopHeight < 0 ) nTopHeight = 0;
1920 nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, SC_SPLIT_TOP,
1921 (USHORT) nTopHeight );
1922 if ( nNewDelta > MAXROW )
1923 nNewDelta = MAXROW;
1924 aViewData.SetPosY( SC_SPLIT_BOTTOM, nNewDelta );
1925 if ( nNewDelta > aViewData.GetCurY() )
1926 ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
1927 SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
1928 else
1929 ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
1930 SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
1933 // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
1934 // dafuer muss hier schon der MapMode stimmen
1935 for (USHORT i=0; i<4; i++)
1936 if (pGridWin[i])
1937 pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
1938 SetNewVisArea();
1940 PaintGrid();
1941 PaintLeft();
1943 InvalidateSplit();
1947 Point ScTabView::GetInsertPos()
1949 ScDocument* pDoc = aViewData.GetDocument();
1950 SCCOL nCol = aViewData.GetCurX();
1951 SCROW nRow = aViewData.GetCurY();
1952 SCTAB nTab = aViewData.GetTabNo();
1953 long nPosX = 0;
1954 for (SCCOL i=0; i<nCol; i++)
1955 nPosX += pDoc->GetColWidth(i,nTab);
1956 nPosX = (long)(nPosX * HMM_PER_TWIPS);
1957 if ( pDoc->IsNegativePage( nTab ) )
1958 nPosX = -nPosX;
1959 long nPosY = (long) pDoc->GetRowHeight( 0, nRow-1, nTab);
1960 nPosY = (long)(nPosY * HMM_PER_TWIPS);
1961 return Point(nPosX,nPosY);
1964 Point ScTabView::GetChartInsertPos( const Size& rSize, const ScRange& rCellRange )
1966 Point aInsertPos;
1967 const long nBorder = 100; // leave 1mm for border
1968 long nNeededWidth = rSize.Width() + 2 * nBorder;
1969 long nNeededHeight = rSize.Height() + 2 * nBorder;
1971 // use the active window, or lower/right if frozen (as in CalcZoom)
1972 ScSplitPos eUsedPart = aViewData.GetActivePart();
1973 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1974 eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
1975 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1976 eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1978 ScGridWindow* pWin = pGridWin[eUsedPart];
1979 DBG_ASSERT( pWin, "Window not found" );
1980 if (pWin)
1982 ActivatePart( eUsedPart );
1984 // get the visible rectangle in logic units
1986 MapMode aDrawMode = pWin->GetDrawMapMode();
1987 Rectangle aVisible( pWin->PixelToLogic( Rectangle( Point(0,0), pWin->GetOutputSizePixel() ), aDrawMode ) );
1989 ScDocument* pDoc = aViewData.GetDocument();
1990 SCTAB nTab = aViewData.GetTabNo();
1991 BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1992 long nLayoutSign = bLayoutRTL ? -1 : 1;
1994 long nDocX = (long)( (double) pDoc->GetColOffset( MAXCOL + 1, nTab ) * HMM_PER_TWIPS ) * nLayoutSign;
1995 long nDocY = (long)( (double) pDoc->GetRowOffset( MAXROW + 1, nTab ) * HMM_PER_TWIPS );
1997 if ( aVisible.Left() * nLayoutSign > nDocX * nLayoutSign )
1998 aVisible.Left() = nDocX;
1999 if ( aVisible.Right() * nLayoutSign > nDocX * nLayoutSign )
2000 aVisible.Right() = nDocX;
2001 if ( aVisible.Top() > nDocY )
2002 aVisible.Top() = nDocY;
2003 if ( aVisible.Bottom() > nDocY )
2004 aVisible.Bottom() = nDocY;
2006 // get the logic position of the selection
2008 Rectangle aSelection = pDoc->GetMMRect( rCellRange.aStart.Col(), rCellRange.aStart.Row(),
2009 rCellRange.aEnd.Col(), rCellRange.aEnd.Row(), nTab );
2011 long nLeftSpace = aSelection.Left() - aVisible.Left();
2012 long nRightSpace = aVisible.Right() - aSelection.Right();
2013 long nTopSpace = aSelection.Top() - aVisible.Top();
2014 long nBottomSpace = aVisible.Bottom() - aSelection.Bottom();
2016 bool bFitLeft = ( nLeftSpace >= nNeededWidth );
2017 bool bFitRight = ( nRightSpace >= nNeededWidth );
2019 if ( bFitLeft || bFitRight )
2021 // first preference: completely left or right of the selection
2023 // if both fit, prefer left in RTL mode, right otherwise
2024 bool bPutLeft = bFitLeft && ( bLayoutRTL || !bFitRight );
2026 if ( bPutLeft )
2027 aInsertPos.X() = aSelection.Left() - nNeededWidth;
2028 else
2029 aInsertPos.X() = aSelection.Right() + 1;
2031 // align with top of selection (is moved again if it doesn't fit)
2032 aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
2034 else if ( nTopSpace >= nNeededHeight || nBottomSpace >= nNeededHeight )
2036 // second preference: completely above or below the selection
2038 if ( nBottomSpace > nNeededHeight ) // bottom is preferred
2039 aInsertPos.Y() = aSelection.Bottom() + 1;
2040 else
2041 aInsertPos.Y() = aSelection.Top() - nNeededHeight;
2043 // align with (logic) left edge of selection (moved again if it doesn't fit)
2044 if ( bLayoutRTL )
2045 aInsertPos.X() = std::min( aSelection.Right(), aVisible.Right() ) - nNeededWidth + 1;
2046 else
2047 aInsertPos.X() = std::max( aSelection.Left(), aVisible.Left() );
2049 else
2051 // place to the (logic) right of the selection and move so it fits
2053 if ( bLayoutRTL )
2054 aInsertPos.X() = aSelection.Left() - nNeededWidth;
2055 else
2056 aInsertPos.X() = aSelection.Right() + 1;
2057 aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
2060 // move the position if the object doesn't fit in the screen
2062 Rectangle aCompareRect( aInsertPos, Size( nNeededWidth, nNeededHeight ) );
2063 if ( aCompareRect.Right() > aVisible.Right() )
2064 aInsertPos.X() -= aCompareRect.Right() - aVisible.Right();
2065 if ( aCompareRect.Bottom() > aVisible.Bottom() )
2066 aInsertPos.Y() -= aCompareRect.Bottom() - aVisible.Bottom();
2068 if ( aInsertPos.X() < aVisible.Left() )
2069 aInsertPos.X() = aVisible.Left();
2070 if ( aInsertPos.Y() < aVisible.Top() )
2071 aInsertPos.Y() = aVisible.Top();
2073 // nNeededWidth / nNeededHeight includes all borders - move aInsertPos to the
2074 // object position, inside the border
2076 aInsertPos.X() += nBorder;
2077 aInsertPos.Y() += nBorder;
2079 return aInsertPos;
2082 Point ScTabView::GetChartDialogPos( const Size& rDialogSize, const Rectangle& rLogicChart )
2084 // rDialogSize must be in pixels, rLogicChart in 1/100 mm. Return value is in pixels.
2086 Point aRet;
2088 // use the active window, or lower/right if frozen (as in CalcZoom)
2089 ScSplitPos eUsedPart = aViewData.GetActivePart();
2090 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
2091 eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
2092 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
2093 eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
2095 ScGridWindow* pWin = pGridWin[eUsedPart];
2096 DBG_ASSERT( pWin, "Window not found" );
2097 if (pWin)
2099 MapMode aDrawMode = pWin->GetDrawMapMode();
2100 Rectangle aObjPixel = pWin->LogicToPixel( rLogicChart, aDrawMode );
2101 Rectangle aObjAbs( pWin->OutputToAbsoluteScreenPixel( aObjPixel.TopLeft() ),
2102 pWin->OutputToAbsoluteScreenPixel( aObjPixel.BottomRight() ) );
2104 Rectangle aDesktop = pWin->GetDesktopRectPixel();
2105 Size aSpace = pWin->LogicToPixel( Size( 8, 12 ), MAP_APPFONT );
2107 ScDocument* pDoc = aViewData.GetDocument();
2108 SCTAB nTab = aViewData.GetTabNo();
2109 BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
2111 bool bCenterHor = false;
2113 if ( aDesktop.Bottom() - aObjAbs.Bottom() >= rDialogSize.Height() + aSpace.Height() )
2115 // first preference: below the chart
2117 aRet.Y() = aObjAbs.Bottom() + aSpace.Height();
2118 bCenterHor = true;
2120 else if ( aObjAbs.Top() - aDesktop.Top() >= rDialogSize.Height() + aSpace.Height() )
2122 // second preference: above the chart
2124 aRet.Y() = aObjAbs.Top() - rDialogSize.Height() - aSpace.Height();
2125 bCenterHor = true;
2127 else
2129 bool bFitLeft = ( aObjAbs.Left() - aDesktop.Left() >= rDialogSize.Width() + aSpace.Width() );
2130 bool bFitRight = ( aDesktop.Right() - aObjAbs.Right() >= rDialogSize.Width() + aSpace.Width() );
2132 if ( bFitLeft || bFitRight )
2134 // if both fit, prefer right in RTL mode, left otherwise
2135 bool bPutRight = bFitRight && ( bLayoutRTL || !bFitLeft );
2136 if ( bPutRight )
2137 aRet.X() = aObjAbs.Right() + aSpace.Width();
2138 else
2139 aRet.X() = aObjAbs.Left() - rDialogSize.Width() - aSpace.Width();
2141 // center vertically
2142 aRet.Y() = aObjAbs.Top() + ( aObjAbs.GetHeight() - rDialogSize.Height() ) / 2;
2144 else
2146 // doesn't fit on any edge - put at the bottom of the screen
2147 aRet.Y() = aDesktop.Bottom() - rDialogSize.Height();
2148 bCenterHor = true;
2151 if ( bCenterHor )
2152 aRet.X() = aObjAbs.Left() + ( aObjAbs.GetWidth() - rDialogSize.Width() ) / 2;
2154 // limit to screen (centering might lead to invalid positions)
2155 if ( aRet.X() + rDialogSize.Width() - 1 > aDesktop.Right() )
2156 aRet.X() = aDesktop.Right() - rDialogSize.Width() + 1;
2157 if ( aRet.X() < aDesktop.Left() )
2158 aRet.X() = aDesktop.Left();
2159 if ( aRet.Y() + rDialogSize.Height() - 1 > aDesktop.Bottom() )
2160 aRet.Y() = aDesktop.Bottom() - rDialogSize.Height() + 1;
2161 if ( aRet.Y() < aDesktop.Top() )
2162 aRet.Y() = aDesktop.Top();
2165 return aRet;
2168 void ScTabView::LockModifiers( USHORT nModifiers )
2170 pSelEngine->LockModifiers( nModifiers );
2171 pHdrSelEng->LockModifiers( nModifiers );
2174 USHORT ScTabView::GetLockedModifiers() const
2176 return pSelEngine->GetLockedModifiers();
2179 Point ScTabView::GetMousePosPixel()
2181 Point aPos;
2182 ScGridWindow* pWin = (ScGridWindow*)GetActiveWin();
2184 if ( pWin )
2185 aPos = pWin->GetMousePosPixel();
2187 return aPos;
2190 BOOL lcl_MouseIsOverWin( const Point& rScreenPosPixel, Window* pWin )
2192 if (pWin)
2194 // SPLIT_HANDLE_SIZE draufaddieren, damit das Einrasten genau
2195 // auf dem Splitter nicht aussetzt
2197 Point aRel = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel );
2198 Size aWinSize = pWin->GetOutputSizePixel();
2199 if ( aRel.X() >= 0 && aRel.X() < aWinSize.Width() + SPLIT_HANDLE_SIZE &&
2200 aRel.Y() >= 0 && aRel.Y() < aWinSize.Height() + SPLIT_HANDLE_SIZE )
2201 return TRUE;
2203 return FALSE;
2206 void ScTabView::SnapSplitPos( Point& rScreenPosPixel )
2208 BOOL bOverWin = FALSE;
2209 USHORT i;
2210 for (i=0; i<4; i++)
2211 if (lcl_MouseIsOverWin(rScreenPosPixel,pGridWin[i]))
2212 bOverWin = TRUE;
2214 if (!bOverWin)
2215 return;
2217 // #74761# don't snap to cells if the scale will be modified afterwards
2218 if ( GetZoomType() != SVX_ZOOM_PERCENT )
2219 return;
2221 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
2222 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
2223 ePos = SC_SPLIT_TOPLEFT;
2225 Window* pWin = pGridWin[ePos];
2226 if (!pWin)
2228 DBG_ERROR("Window NULL");
2229 return;
2232 Point aMouse = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel );
2233 SCsCOL nPosX;
2234 SCsROW nPosY;
2235 // #52949# bNextIfLarge=FALSE: nicht auf naechste Zelle, wenn ausserhalb des Fensters
2236 aViewData.GetPosFromPixel( aMouse.X(), aMouse.Y(), ePos, nPosX, nPosY, TRUE, FALSE, FALSE );
2237 BOOL bLeft;
2238 BOOL bTop;
2239 aViewData.GetMouseQuadrant( aMouse, ePos, nPosX, nPosY, bLeft, bTop );
2240 if (!bLeft)
2241 ++nPosX;
2242 if (!bTop)
2243 ++nPosY;
2244 aMouse = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, TRUE );
2245 rScreenPosPixel = pWin->OutputToNormalizedScreenPixel( aMouse );
2248 void ScTabView::FreezeSplitters( BOOL bFreeze )
2250 ScSplitMode eOldH = aViewData.GetHSplitMode();
2251 ScSplitMode eOldV = aViewData.GetVSplitMode();
2253 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
2254 if ( eOldV != SC_SPLIT_NONE )
2255 ePos = SC_SPLIT_TOPLEFT;
2256 Window* pWin = pGridWin[ePos];
2258 BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
2260 if ( bFreeze )
2262 Point aWinStart = pWin->GetPosPixel();
2264 Point aSplit;
2265 SCsCOL nPosX;
2266 SCsROW nPosY;
2267 if (eOldH != SC_SPLIT_NONE || eOldV != SC_SPLIT_NONE)
2269 if (eOldH != SC_SPLIT_NONE)
2271 long nSplitPos = aViewData.GetHSplitPos();
2272 if ( bLayoutRTL )
2273 nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
2274 aSplit.X() = nSplitPos - aWinStart.X();
2276 if (eOldV != SC_SPLIT_NONE)
2277 aSplit.Y() = aViewData.GetVSplitPos() - aWinStart.Y();
2279 aViewData.GetPosFromPixel( aSplit.X(), aSplit.Y(), ePos, nPosX, nPosY );
2280 BOOL bLeft;
2281 BOOL bTop;
2282 aViewData.GetMouseQuadrant( aSplit, ePos, nPosX, nPosY, bLeft, bTop );
2283 if (!bLeft)
2284 ++nPosX;
2285 if (!bTop)
2286 ++nPosY;
2288 else
2290 nPosX = static_cast<SCsCOL>( aViewData.GetCurX());
2291 nPosY = static_cast<SCsROW>( aViewData.GetCurY());
2294 SCCOL nLeftPos = aViewData.GetPosX(SC_SPLIT_LEFT);
2295 SCROW nTopPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
2296 SCCOL nRightPos = static_cast<SCCOL>(nPosX);
2297 SCROW nBottomPos = static_cast<SCROW>(nPosY);
2298 if (eOldH != SC_SPLIT_NONE)
2299 if (aViewData.GetPosX(SC_SPLIT_RIGHT) > nRightPos)
2300 nRightPos = aViewData.GetPosX(SC_SPLIT_RIGHT);
2301 if (eOldV != SC_SPLIT_NONE)
2303 nTopPos = aViewData.GetPosY(SC_SPLIT_TOP);
2304 if (aViewData.GetPosY(SC_SPLIT_BOTTOM) > nBottomPos)
2305 nBottomPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
2308 aSplit = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, TRUE );
2309 if (nPosX > aViewData.GetPosX(SC_SPLIT_LEFT)) // (aSplit.X() > 0) doesn't work for RTL
2311 long nSplitPos = aSplit.X() + aWinStart.X();
2312 if ( bLayoutRTL )
2313 nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
2315 aViewData.SetHSplitMode( SC_SPLIT_FIX );
2316 aViewData.SetHSplitPos( nSplitPos );
2317 aViewData.SetFixPosX( nPosX );
2319 aViewData.SetPosX(SC_SPLIT_LEFT, nLeftPos);
2320 aViewData.SetPosX(SC_SPLIT_RIGHT, nRightPos);
2322 else
2323 aViewData.SetHSplitMode( SC_SPLIT_NONE );
2324 if (aSplit.Y() > 0)
2326 aViewData.SetVSplitMode( SC_SPLIT_FIX );
2327 aViewData.SetVSplitPos( aSplit.Y() + aWinStart.Y() );
2328 aViewData.SetFixPosY( nPosY );
2330 aViewData.SetPosY(SC_SPLIT_TOP, nTopPos);
2331 aViewData.SetPosY(SC_SPLIT_BOTTOM, nBottomPos);
2333 else
2334 aViewData.SetVSplitMode( SC_SPLIT_NONE );
2336 else // Fixierung aufheben
2338 if ( eOldH == SC_SPLIT_FIX )
2339 aViewData.SetHSplitMode( SC_SPLIT_NORMAL );
2340 if ( eOldV == SC_SPLIT_FIX )
2341 aViewData.SetVSplitMode( SC_SPLIT_NORMAL );
2344 // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
2345 // dafuer muss hier schon der MapMode stimmen
2346 for (USHORT i=0; i<4; i++)
2347 if (pGridWin[i])
2348 pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
2349 SetNewVisArea();
2351 RepeatResize(FALSE);
2353 UpdateShow();
2354 PaintLeft();
2355 PaintTop();
2356 PaintGrid();
2358 // SC_FOLLOW_NONE: only update active part
2359 AlignToCursor( aViewData.GetCurX(), aViewData.GetCurY(), SC_FOLLOW_NONE );
2360 UpdateAutoFillMark();
2362 InvalidateSplit();
2365 void ScTabView::RemoveSplit()
2367 DoHSplit( 0 );
2368 DoVSplit( 0 );
2369 RepeatResize();
2372 void ScTabView::SplitAtCursor()
2374 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
2375 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
2376 ePos = SC_SPLIT_TOPLEFT;
2377 Window* pWin = pGridWin[ePos];
2378 Point aWinStart = pWin->GetPosPixel();
2380 SCCOL nPosX = aViewData.GetCurX();
2381 SCROW nPosY = aViewData.GetCurY();
2382 Point aSplit = aViewData.GetScrPos( nPosX, nPosY, ePos, TRUE );
2383 if ( nPosX > 0 )
2384 DoHSplit( aSplit.X() + aWinStart.X() );
2385 else
2386 DoHSplit( 0 );
2387 if ( nPosY > 0 )
2388 DoVSplit( aSplit.Y() + aWinStart.Y() );
2389 else
2390 DoVSplit( 0 );
2391 RepeatResize();
2394 void ScTabView::SplitAtPixel( const Point& rPixel, BOOL bHor, BOOL bVer ) // fuer API
2396 // Pixel ist auf die ganze View bezogen, nicht auf das erste GridWin
2398 if (bHor)
2400 if ( rPixel.X() > 0 )
2401 DoHSplit( rPixel.X() );
2402 else
2403 DoHSplit( 0 );
2405 if (bVer)
2407 if ( rPixel.Y() > 0 )
2408 DoVSplit( rPixel.Y() );
2409 else
2410 DoVSplit( 0 );
2412 RepeatResize();
2415 void ScTabView::InvalidateSplit()
2417 SfxBindings& rBindings = aViewData.GetBindings();
2418 rBindings.Invalidate( SID_WINDOW_SPLIT );
2419 rBindings.Invalidate( SID_WINDOW_FIX );
2421 pHSplitter->SetFixed( aViewData.GetHSplitMode() == SC_SPLIT_FIX );
2422 pVSplitter->SetFixed( aViewData.GetVSplitMode() == SC_SPLIT_FIX );
2425 void ScTabView::SetNewVisArea()
2427 // #63854# fuer die Controls muss bei VisAreaChanged der Draw-MapMode eingestellt sein
2428 // (auch wenn ansonsten der Edit-MapMode gesetzt ist)
2429 MapMode aOldMode[4];
2430 MapMode aDrawMode[4];
2431 USHORT i;
2432 for (i=0; i<4; i++)
2433 if (pGridWin[i])
2435 aOldMode[i] = pGridWin[i]->GetMapMode();
2436 aDrawMode[i] = pGridWin[i]->GetDrawMapMode();
2437 if (aDrawMode[i] != aOldMode[i])
2438 pGridWin[i]->SetMapMode(aDrawMode[i]);
2441 Window* pActive = pGridWin[aViewData.GetActivePart()];
2442 if (pActive)
2443 aViewData.GetViewShell()->VisAreaChanged(
2444 pActive->PixelToLogic(Rectangle(Point(),pActive->GetOutputSizePixel())) );
2445 if (pDrawView)
2446 pDrawView->VisAreaChanged(); // kein Window uebergeben -> alle Fenster
2448 UpdateAllOverlays(); // #i79909# with drawing MapMode set
2450 for (i=0; i<4; i++)
2451 if (pGridWin[i] && aDrawMode[i] != aOldMode[i])
2453 pGridWin[i]->flushOverlayManager(); // #i79909# flush overlays before switching to edit MapMode
2454 pGridWin[i]->SetMapMode(aOldMode[i]);
2457 SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
2458 if (pViewFrame)
2460 SfxFrame* pFrame = pViewFrame->GetFrame();
2461 if (pFrame)
2463 com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pFrame->GetController();
2464 if (xController.is())
2466 ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
2467 if (pImp)
2468 pImp->VisAreaChanged();
2472 if (aViewData.GetViewShell()->HasAccessibilityObjects())
2473 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_VISAREACHANGED));
2476 sal_Bool ScTabView::HasPageFieldDataAtCursor() const
2478 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2479 SCCOL nCol = aViewData.GetCurX();
2480 SCROW nRow = aViewData.GetCurY();
2481 if (pWin)
2482 return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE;
2484 return sal_False;
2487 void ScTabView::StartDataSelect()
2489 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2490 SCCOL nCol = aViewData.GetCurX();
2491 SCROW nRow = aViewData.GetCurY();
2493 if (!pWin)
2494 return;
2496 switch (pWin->GetDPFieldOrientation(nCol, nRow))
2498 case sheet::DataPilotFieldOrientation_PAGE:
2499 // #i36598# If the cursor is on a page field's data cell,
2500 // no meaningful input is possible anyway, so this function
2501 // can be used to select a page field entry.
2502 pWin->LaunchPageFieldMenu( nCol, nRow );
2503 break;
2504 case sheet::DataPilotFieldOrientation_COLUMN:
2505 case sheet::DataPilotFieldOrientation_ROW:
2506 pWin->LaunchDPFieldMenu( nCol, nRow );
2507 break;
2508 default:
2509 pWin->DoAutoFilterMenue( nCol, nRow, TRUE );
2513 void ScTabView::EnableRefInput(BOOL bFlag)
2515 aHScrollLeft.EnableInput(bFlag);
2516 aHScrollRight.EnableInput(bFlag);
2517 aVScrollBottom.EnableInput(bFlag);
2518 aVScrollTop.EnableInput(bFlag);
2519 aScrollBarBox.EnableInput(bFlag);
2521 // ab hier dynamisch angelegte
2523 if(pTabControl!=NULL) pTabControl->EnableInput(bFlag,TRUE);
2525 if(pGridWin[SC_SPLIT_BOTTOMLEFT]!=NULL)
2526 pGridWin[SC_SPLIT_BOTTOMLEFT]->EnableInput(bFlag,FALSE);
2527 if(pGridWin[SC_SPLIT_BOTTOMRIGHT]!=NULL)
2528 pGridWin[SC_SPLIT_BOTTOMRIGHT]->EnableInput(bFlag,FALSE);
2529 if(pGridWin[SC_SPLIT_TOPLEFT]!=NULL)
2530 pGridWin[SC_SPLIT_TOPLEFT]->EnableInput(bFlag,FALSE);
2531 if(pGridWin[SC_SPLIT_TOPRIGHT]!=NULL)
2532 pGridWin[SC_SPLIT_TOPRIGHT]->EnableInput(bFlag,FALSE);
2533 if(pColBar[SC_SPLIT_RIGHT]!=NULL)
2534 pColBar[SC_SPLIT_RIGHT]->EnableInput(bFlag,FALSE);
2535 if(pRowBar[SC_SPLIT_TOP]!=NULL)
2536 pRowBar[SC_SPLIT_TOP]->EnableInput(bFlag,FALSE);