diff options
Diffstat (limited to 'sc/source/ui/view/tabview.cxx')
-rw-r--r-- | sc/source/ui/view/tabview.cxx | 2429 |
1 files changed, 2429 insertions, 0 deletions
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx new file mode 100644 index 000000000000..9fe099ebf327 --- /dev/null +++ b/sc/source/ui/view/tabview.cxx @@ -0,0 +1,2429 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + +//------------------------------------------------------------------ +#include <vcl/svapp.hxx> + +/////////////////////////////////////////////////////////////////////////// +// NODRAW.HXX +// Erweiterte Konstanten, um CLOKs mit SVDRAW.HXX zu vermeiden +// Die u.a. Aenderungen nehmen vorgeschlagene Konstante vorweg +/////////////////////////////////////////////////////////////////////////// + +// Dieses define entfernt die VCControls aus SI.HXX + +#define _SI_HXX // VCControls + +////////////////////// Umsetzen der Standard-Defines ////////////////////// + +#define _SVDPAGE_HXX // SdrPage + +#ifdef _SDR_NOSURROGATEOBJ + #undef _SDR_NOSURROGATEOBJ + #define _SVDSURO_HXX +#endif + +#ifdef _SDR_NOPAGEOBJ + #undef _SDR_NOPAGEOBJ + #define _SVDOPAGE_HXX +#endif + +#ifdef _SDR_NOVIRTOBJ + #undef _SDR_NOVIRTOBJ + #define _SVDOVIRT_HXX +#endif + +#ifdef _SDR_NOGROUPOBJ + #undef _SDR_NOGROUPOBJ + #define _SVDOGRP_HXX +#endif + +#ifdef _SDR_NOTEXTOBJ + #undef _SDR_NOTEXTOBJ + #define _SVDOTEXT_HXX +#endif + +#ifdef _SDR_NOPATHOBJ + #undef _SDR_NOPATHOBJ + #define _SVDOPATH_HXX +#endif + +#ifdef _SDR_NOEDGEOBJ + #undef _SDR_NOEDGEOBJ + #define _SVDOEDGE_HXX +#endif + +#ifdef _SDR_NORECTOBJ + #undef _SDR_NORECTOBJ + #define _SVDORECT_HXX +#else + #undef _SDVOTEXT_OBJ +#endif + +#ifdef _SDR_NOCAPTIONOBJ + #undef _SDR_NOCAPTIONOBJ + #define _SVDCAPT_HXX +#endif + +#ifdef _SDR_NOCIRCLEOBJ + #undef _SDR_NOCIRCLEOBJ + #define _SVDOCIRC_HXX +#endif + +#ifdef _SDR_NOGRAFOBJ + #undef _SDR_NOGRAFOBJ + #define _SVDOGRAF_HXX +#else + #undef _SVDOTEXT_HXX + #undef _SVDORECT_HXX +#endif + +#ifdef _SDR_NOOLE2OBJ + #undef _SDR_NOOLE2OBJ + #define _SVDOOLE2_HXX +#else + #undef _SVDOTEXT_HXX + #undef _SVDORECT_HXX +#endif + +////////////////////// Ende der SVDRAW-Modifikationen ///////////////////// + +// INCLUDE --------------------------------------------------------------- + +#include "scitems.hxx" +#include <sfx2/viewfrm.hxx> +#include <sfx2/bindings.hxx> +#include <vcl/help.hxx> +#include <rtl/logfile.hxx> + +#include "tabview.hxx" +#include "tabvwsh.hxx" +#include "document.hxx" +#include "gridwin.hxx" +#include "olinewin.hxx" +#include "olinetab.hxx" +#include "tabsplit.hxx" +#include "colrowba.hxx" +#include "tabcont.hxx" +#include "scmod.hxx" +#include "sc.hrc" +#include "viewutil.hxx" +#include "globstr.hrc" +#include "drawview.hxx" +#include "docsh.hxx" +#include "viewuno.hxx" +#include "AccessibilityHints.hxx" +#include "appoptio.hxx" + +#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> + +#include <string> +#include <algorithm> + +#define SPLIT_MARGIN 30 +#define SC_ICONSIZE 36 + +#define SC_SCROLLBAR_MIN 30 +#define SC_TABBAR_MIN 6 + +// fuer Rad-Maus +#define SC_DELTA_ZOOM 10 + +using namespace ::com::sun::star; + +// STATIC DATA ----------------------------------------------------------- + + +//================================================================== + +// Corner-Button + +ScCornerButton::ScCornerButton( Window* pParent, ScViewData* pData, BOOL bAdditional ) : + Window( pParent, WinBits( 0 ) ), + pViewData( pData ), + bAdd( bAdditional ) +{ + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + SetBackground( rStyleSettings.GetFaceColor() ); + EnableRTL( FALSE ); +} + +__EXPORT ScCornerButton::~ScCornerButton() +{ +} + +void __EXPORT ScCornerButton::Paint( const Rectangle& rRect ) +{ + Size aSize = GetOutputSizePixel(); + long nPosX = aSize.Width()-1; + long nPosY = aSize.Height()-1; + + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + + Window::Paint(rRect); + + BOOL bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() ); + long nDarkX = bLayoutRTL ? 0 : nPosX; + + if ( !bAdd ) + { + // match the shaded look of column/row headers + + Color aFace( rStyleSettings.GetFaceColor() ); + Color aWhite( COL_WHITE ); + Color aCenter( aFace ); + aCenter.Merge( aWhite, 0xd0 ); // lighten up a bit + Color aOuter( aFace ); + aOuter.Merge( aWhite, 0xa0 ); // lighten up more + + long nCenterX = (aSize.Width() / 2) - 1; + long nCenterY = (aSize.Height() / 2) - 1; + + SetLineColor(); + SetFillColor(aCenter); + DrawRect( Rectangle( nCenterX, nCenterY, nCenterX, nPosY ) ); + DrawRect( Rectangle( nCenterX, nCenterY, nDarkX, nCenterY ) ); + SetFillColor(aOuter); + DrawRect( Rectangle( 0, 0, nPosX, nCenterY-1 ) ); + if ( bLayoutRTL ) + DrawRect( Rectangle( nCenterX+1, nCenterY, nPosX, nPosY ) ); + else + DrawRect( Rectangle( 0, nCenterY, nCenterX-1, nPosY ) ); + } + + // both buttons have the same look now - only dark right/bottom lines + SetLineColor( rStyleSettings.GetDarkShadowColor() ); + DrawLine( Point(0,nPosY), Point(nPosX,nPosY) ); + DrawLine( Point(nDarkX,0), Point(nDarkX,nPosY) ); +} + +void ScCornerButton::StateChanged( StateChangedType nType ) +{ + Window::StateChanged( nType ); + + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + SetBackground( rStyleSettings.GetFaceColor() ); + Invalidate(); +} + +// ----------------------------------------------------------------------- + +void ScCornerButton::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Window::DataChanged( rDCEvt ); + + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + SetBackground( rStyleSettings.GetFaceColor() ); + Invalidate(); +} + + +void __EXPORT ScCornerButton::Resize() +{ + Invalidate(); +} + +void __EXPORT ScCornerButton::MouseButtonDown( const MouseEvent& rMEvt ) +{ + ScModule* pScMod = SC_MOD(); + BOOL bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode(); + if (!bDisable) + { + ScTabViewShell* pViewSh = pViewData->GetViewShell(); + pViewSh->SetActive(); // Appear und SetViewFrame + pViewSh->ActiveGrabFocus(); + + BOOL bControl = rMEvt.IsMod1(); + pViewSh->SelectAll( bControl ); + } +} + +//================================================================== + +BOOL lcl_HasColOutline( const ScViewData& rViewData ) +{ + const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo()); + if (pTable) + { + const ScOutlineArray* pArray = pTable->GetColArray(); + if ( pArray->GetDepth() > 0 ) + return TRUE; + } + return FALSE; +} + +BOOL lcl_HasRowOutline( const ScViewData& rViewData ) +{ + const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo()); + if (pTable) + { + const ScOutlineArray* pArray = pTable->GetRowArray(); + if ( pArray->GetDepth() > 0 ) + return TRUE; + } + return FALSE; +} + +//================================================================== + +// Init und Konstruktoren +// ScTabView::Init() in tabview5.cxx wegen out of keys + + +#define TABVIEW_INIT \ + pSelEngine( NULL ), \ + aFunctionSet( &aViewData ), \ + pHdrSelEng( NULL ), \ + aHdrFunc( &aViewData ), \ + pDrawView( NULL ), \ + bDrawSelMode( FALSE ), \ + aVScrollTop( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ), \ + aVScrollBottom( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ), \ + aHScrollLeft( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ), \ + aHScrollRight( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ), \ + aCornerButton( pFrameWin, &aViewData, FALSE ), \ + aTopButton( pFrameWin, &aViewData, TRUE ), \ + aScrollBarBox( pFrameWin, WB_SIZEABLE ), \ + pInputHintWindow( NULL ), \ + pPageBreakData( NULL ), \ + pHighlightRanges( NULL ), \ + pBrushDocument( NULL ), \ + pDrawBrushSet( NULL ), \ + bLockPaintBrush( FALSE ), \ + pTimerWindow( NULL ), \ + nTipVisible( 0 ), \ + bDragging( FALSE ), \ + bIsBlockMode( FALSE ), \ + bBlockNeg( FALSE ), \ + bBlockCols( FALSE ), \ + bBlockRows( FALSE ), \ + mfPendingTabBarWidth( -1.0 ), \ + bMinimized( FALSE ), \ + bInUpdateHeader( FALSE ), \ + bInActivatePart( FALSE ), \ + bInZoomUpdate( FALSE ), \ + bMoveIsShift( FALSE ) + + +ScTabView::ScTabView( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) : + pFrameWin( pParent ), + aViewData( &rDocSh, pViewShell ), + TABVIEW_INIT +{ + RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" ); + + Init(); +} + + +void ScTabView::InitScrollBar( ScrollBar& rScrollBar, long nMaxVal ) +{ + rScrollBar.SetRange( Range( 0, nMaxVal ) ); + rScrollBar.SetLineSize( 1 ); + rScrollBar.SetPageSize( 1 ); // wird getrennt abgefragt + rScrollBar.SetVisibleSize( 10 ); // wird bei Resize neu gesetzt + + rScrollBar.SetScrollHdl( LINK(this, ScTabView, ScrollHdl) ); + rScrollBar.SetEndScrollHdl( LINK(this, ScTabView, EndScrollHdl) ); +} + +// Scroll-Timer + +void ScTabView::SetTimer( ScGridWindow* pWin, const MouseEvent& rMEvt ) +{ + pTimerWindow = pWin; + aTimerMEvt = rMEvt; + aScrollTimer.Start(); +} + +void ScTabView::ResetTimer() +{ + aScrollTimer.Stop(); + pTimerWindow = NULL; +} + +IMPL_LINK( ScTabView, TimerHdl, Timer*, EMPTYARG ) +{ +// aScrollTimer.Stop(); + if (pTimerWindow) + pTimerWindow->MouseMove( aTimerMEvt ); + + return 0; +} + +// --- Resize --------------------------------------------------------------------- + +void lcl_SetPosSize( Window& rWindow, const Point& rPos, const Size& rSize, + long nTotalWidth, BOOL bLayoutRTL ) +{ + Point aNewPos = rPos; + if ( bLayoutRTL ) + { + aNewPos.X() = nTotalWidth - rPos.X() - rSize.Width(); + if ( aNewPos == rWindow.GetPosPixel() && rSize.Width() != rWindow.GetSizePixel().Width() ) + { + // Document windows are manually painted right-to-left, so they need to + // be repainted if the size changes. + rWindow.Invalidate(); + } + } + rWindow.SetPosSizePixel( aNewPos, rSize ); +} + +void ScTabView::DoResize( const Point& rOffset, const Size& rSize, BOOL bInner ) +{ + HideListBox(); + + BOOL bHasHint = ( pInputHintWindow != NULL ); + if (bHasHint) + RemoveHintWindow(); + + BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ); + long nTotalWidth = rSize.Width(); + if ( bLayoutRTL ) + nTotalWidth += 2*rOffset.X(); + + BOOL bVScroll = aViewData.IsVScrollMode(); + BOOL bHScroll = aViewData.IsHScrollMode(); + BOOL bTabControl = aViewData.IsTabMode(); + BOOL bHeaders = aViewData.IsHeaderMode(); + BOOL bOutlMode = aViewData.IsOutlineMode(); + BOOL bHOutline = bOutlMode && lcl_HasColOutline(aViewData); + BOOL bVOutline = bOutlMode && lcl_HasRowOutline(aViewData); + + // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden: + SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode(); + if ( eMode == SCROLLING_NO ) + bHScroll = bVScroll = FALSE; + else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ??? + bHScroll = bVScroll = TRUE; + + if ( aViewData.GetDocShell()->IsPreview() ) + bHScroll = bVScroll = bTabControl = bHeaders = bOutlMode = bHOutline = bVOutline = FALSE; + + long nBarX = 0; + long nBarY = 0; + long nOutlineX = 0; + long nOutlineY = 0; + long nOutPosX; + long nOutPosY; + + long nPosX = rOffset.X(); + long nPosY = rOffset.Y(); + long nSizeX = rSize.Width(); + long nSizeY = rSize.Height(); + long nSize1; + + bMinimized = ( nSizeX<=SC_ICONSIZE || nSizeY<=SC_ICONSIZE ); + if ( bMinimized ) + return; + + long nSplitSizeX = SPLIT_HANDLE_SIZE; + if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX ) + nSplitSizeX = 1; + long nSplitSizeY = SPLIT_HANDLE_SIZE; + if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX ) + nSplitSizeY = 1; + + const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel(); + + aBorderPos = rOffset; + aFrameSize = rSize; + + if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE ) + if ( aViewData.GetHSplitPos() > nSizeX - SPLIT_MARGIN ) + { + aViewData.SetHSplitMode( SC_SPLIT_NONE ); + if ( WhichH( aViewData.GetActivePart() ) == SC_SPLIT_RIGHT ) + ActivatePart( SC_SPLIT_BOTTOMLEFT ); + InvalidateSplit(); + } + if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) + if ( aViewData.GetVSplitPos() > nSizeY - SPLIT_MARGIN ) + { + aViewData.SetVSplitMode( SC_SPLIT_NONE ); + if ( WhichV( aViewData.GetActivePart() ) == SC_SPLIT_TOP ) + ActivatePart( SC_SPLIT_BOTTOMLEFT ); + InvalidateSplit(); + } + + UpdateShow(); + + if (bHScroll || bVScroll) // Scrollbars horizontal oder vertikal + { + long nScrollBarSize = pFrameWin->GetSettings().GetStyleSettings().GetScrollBarSize(); + if (bVScroll) + { + nBarX = nScrollBarSize; + nSizeX -= nBarX - nOverlap; + } + if (bHScroll) + { + nBarY = nScrollBarSize; + nSizeY -= nBarY - nOverlap; + } + + // window at the bottom right + lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ), + nTotalWidth, bLayoutRTL ); + + if (bHScroll) // Scrollbars horizontal + { + long nSizeLt = 0; // left scroll bar + long nSizeRt = 0; // right scroll bar + long nSizeSp = 0; // splitter + + switch (aViewData.GetHSplitMode()) + { + case SC_SPLIT_NONE: + nSizeSp = nSplitSizeX; + nSizeLt = nSizeX - nSizeSp + nOverlap; // Ecke ueberdecken + break; + case SC_SPLIT_NORMAL: + nSizeSp = nSplitSizeX; + nSizeLt = aViewData.GetHSplitPos(); + break; + case SC_SPLIT_FIX: + nSizeSp = 0; + nSizeLt = 0; + break; + } + nSizeRt = nSizeX - nSizeLt - nSizeSp; + + long nTabSize = 0; + if (bTabControl) + { + // pending relative tab bar width from extended document options + if( mfPendingTabBarWidth >= 0.0 ) + { + SetRelTabBarWidth( mfPendingTabBarWidth ); + mfPendingTabBarWidth = -1.0; + } + + nTabSize = pTabControl->GetSizePixel().Width()-nOverlap; + + if ( aViewData.GetHSplitMode() != SC_SPLIT_FIX ) // bei linkem Scrollbar + { + if (nTabSize > nSizeLt-SC_SCROLLBAR_MIN) nTabSize = nSizeLt-SC_SCROLLBAR_MIN; + if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN; + nSizeLt -= nTabSize; + } + else // bei rechtem Scrollbar + { + if (nTabSize > nSizeRt-SC_SCROLLBAR_MIN) nTabSize = nSizeRt-SC_SCROLLBAR_MIN; + if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN; + nSizeRt -= nTabSize; + } + } + + lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY), + Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL ); + pTabControl->SetSheetLayoutRTL( bLayoutRTL ); + + lcl_SetPosSize( aHScrollLeft, Point(nPosX+nTabSize-nOverlap, nPosY+nSizeY), + Size(nSizeLt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL ); + lcl_SetPosSize( *pHSplitter, Point( nPosX+nTabSize+nSizeLt, nPosY+nSizeY ), + Size( nSizeSp, nBarY ), nTotalWidth, bLayoutRTL ); + lcl_SetPosSize( aHScrollRight, Point(nPosX+nTabSize+nSizeLt+nSizeSp-nOverlap, + nPosY+nSizeY), + Size(nSizeRt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL ); + + // SetDragRectPixel is done below + } + + if (bVScroll) // Scrollbars vertikal + { + long nSizeUp = 0; // upper scroll bar + long nSizeSp = 0; // splitter + long nSizeDn; // unterer Scrollbar + + switch (aViewData.GetVSplitMode()) + { + case SC_SPLIT_NONE: + nSizeUp = 0; + nSizeSp = nSplitSizeY; + break; + case SC_SPLIT_NORMAL: + nSizeUp = aViewData.GetVSplitPos(); + nSizeSp = nSplitSizeY; + break; + case SC_SPLIT_FIX: + nSizeUp = 0; + nSizeSp = 0; + break; + } + nSizeDn = nSizeY - nSizeUp - nSizeSp; + + lcl_SetPosSize( aVScrollTop, Point(nPosX+nSizeX, nPosY-nOverlap), + Size(nBarX,nSizeUp+2*nOverlap), nTotalWidth, bLayoutRTL ); + lcl_SetPosSize( *pVSplitter, Point( nPosX+nSizeX, nPosY+nSizeUp ), + Size( nBarX, nSizeSp ), nTotalWidth, bLayoutRTL ); + lcl_SetPosSize( aVScrollBottom, Point(nPosX+nSizeX, + nPosY+nSizeUp+nSizeSp-nOverlap), + Size(nBarX, nSizeDn+2*nOverlap), nTotalWidth, bLayoutRTL ); + + // SetDragRectPixel is done below + } + } + + // SetDragRectPixel auch ohne Scrollbars etc., wenn schon gesplittet ist + if ( bHScroll || aViewData.GetHSplitMode() != SC_SPLIT_NONE ) + pHSplitter->SetDragRectPixel( + Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin ); + if ( bVScroll || aViewData.GetVSplitMode() != SC_SPLIT_NONE ) + pVSplitter->SetDragRectPixel( + Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin ); + + if (bTabControl && ! bHScroll ) + { + nBarY = aHScrollLeft.GetSizePixel().Height(); + nBarX = aVScrollBottom.GetSizePixel().Width(); + + nSize1 = nSizeX + nOverlap; + + long nTabSize = nSize1; + if (nTabSize < 0) nTabSize = 0; + + lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY-nBarY), + Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL ); + nSizeY -= nBarY - nOverlap; + lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ), + nTotalWidth, bLayoutRTL ); + + if( bVScroll ) + { + Size aVScrSize = aVScrollBottom.GetSizePixel(); + aVScrSize.Height() -= nBarY; + aVScrollBottom.SetSizePixel( aVScrSize ); + } + } + + nOutPosX = nPosX; + nOutPosY = nPosY; + + // Outline-Controls + if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM]) + { + nOutlineX = pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize(); + nSizeX -= nOutlineX; + nPosX += nOutlineX; + } + if (bHOutline && pColOutline[SC_SPLIT_LEFT]) + { + nOutlineY = pColOutline[SC_SPLIT_LEFT]->GetDepthSize(); + nSizeY -= nOutlineY; + nPosY += nOutlineY; + } + + if (bHeaders) // Spalten/Zeilen-Header + { + nBarX = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width(); + nBarY = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height(); + nSizeX -= nBarX; + nSizeY -= nBarY; + nPosX += nBarX; + nPosY += nBarY; + } + else + nBarX = nBarY = 0; + + // + // Splitter auswerten + // + + long nLeftSize = nSizeX; + long nRightSize = 0; + long nTopSize = 0; + long nBottomSize = nSizeY; + long nSplitPosX = nPosX; + long nSplitPosY = nPosY; + + if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE ) + { + long nSplitHeight = rSize.Height(); + if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX ) + { + // Fixier-Splitter nicht mit Scrollbar/TabBar ueberlappen lassen + if ( bHScroll ) + nSplitHeight -= aHScrollLeft.GetSizePixel().Height(); + else if ( bTabControl && pTabControl ) + nSplitHeight -= pTabControl->GetSizePixel().Height(); + } + nSplitPosX = aViewData.GetHSplitPos(); + lcl_SetPosSize( *pHSplitter, + Point( nSplitPosX, nOutPosY ), Size( nSplitSizeX, nSplitHeight ), nTotalWidth, bLayoutRTL ); + nLeftSize = nSplitPosX - nPosX; + nSplitPosX += nSplitSizeX; + nRightSize = nSizeX - nLeftSize - nSplitSizeX; + } + if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) + { + long nSplitWidth = rSize.Width(); + if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && bVScroll ) + nSplitWidth -= aVScrollBottom.GetSizePixel().Width(); + nSplitPosY = aViewData.GetVSplitPos(); + lcl_SetPosSize( *pVSplitter, + Point( nOutPosX, nSplitPosY ), Size( nSplitWidth, nSplitSizeY ), nTotalWidth, bLayoutRTL ); + nTopSize = nSplitPosY - nPosY; + nSplitPosY += nSplitSizeY; + nBottomSize = nSizeY - nTopSize - nSplitSizeY; + } + + // ShowHide fuer pColOutline / pRowOutline passiert in UpdateShow + + if (bHOutline) // Outline-Controls + { + if (pColOutline[SC_SPLIT_LEFT]) + { + pColOutline[SC_SPLIT_LEFT]->SetHeaderSize( nBarX ); + lcl_SetPosSize( *pColOutline[SC_SPLIT_LEFT], + Point(nPosX-nBarX,nOutPosY), Size(nLeftSize+nBarX,nOutlineY), nTotalWidth, bLayoutRTL ); + } + if (pColOutline[SC_SPLIT_RIGHT]) + { + pColOutline[SC_SPLIT_RIGHT]->SetHeaderSize( 0 ); // always call to update RTL flag + lcl_SetPosSize( *pColOutline[SC_SPLIT_RIGHT], + Point(nSplitPosX,nOutPosY), Size(nRightSize,nOutlineY), nTotalWidth, bLayoutRTL ); + } + } + if (bVOutline) + { + if (nTopSize) + { + if (pRowOutline[SC_SPLIT_TOP] && pRowOutline[SC_SPLIT_BOTTOM]) + { + pRowOutline[SC_SPLIT_TOP]->SetHeaderSize( nBarY ); + lcl_SetPosSize( *pRowOutline[SC_SPLIT_TOP], + Point(nOutPosX,nPosY-nBarY), Size(nOutlineX,nTopSize+nBarY), nTotalWidth, bLayoutRTL ); + pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( 0 ); + lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM], + Point(nOutPosX,nSplitPosY), Size(nOutlineX,nBottomSize), nTotalWidth, bLayoutRTL ); + } + } + else if (pRowOutline[SC_SPLIT_BOTTOM]) + { + pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( nBarY ); + lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM], + Point(nOutPosX,nSplitPosY-nBarY), Size(nOutlineX,nBottomSize+nBarY), nTotalWidth, bLayoutRTL ); + } + } + if (bHOutline && bVOutline) + { + lcl_SetPosSize( aTopButton, Point(nOutPosX,nOutPosY), Size(nOutlineX,nOutlineY), nTotalWidth, bLayoutRTL ); + aTopButton.Show(); + } + else + aTopButton.Hide(); + + if (bHeaders) // Spalten/Zeilen-Header + { + lcl_SetPosSize( *pColBar[SC_SPLIT_LEFT], + Point(nPosX,nPosY-nBarY), Size(nLeftSize,nBarY), nTotalWidth, bLayoutRTL ); + if (pColBar[SC_SPLIT_RIGHT]) + lcl_SetPosSize( *pColBar[SC_SPLIT_RIGHT], + Point(nSplitPosX,nPosY-nBarY), Size(nRightSize,nBarY), nTotalWidth, bLayoutRTL ); + + if (pRowBar[SC_SPLIT_TOP]) + lcl_SetPosSize( *pRowBar[SC_SPLIT_TOP], + Point(nPosX-nBarX,nPosY), Size(nBarX,nTopSize), nTotalWidth, bLayoutRTL ); + lcl_SetPosSize( *pRowBar[SC_SPLIT_BOTTOM], + Point(nPosX-nBarX,nSplitPosY), Size(nBarX,nBottomSize), nTotalWidth, bLayoutRTL ); + + lcl_SetPosSize( aCornerButton, Point(nPosX-nBarX,nPosY-nBarY), Size(nBarX,nBarY), nTotalWidth, bLayoutRTL ); + aCornerButton.Show(); + pColBar[SC_SPLIT_LEFT]->Show(); + pRowBar[SC_SPLIT_BOTTOM]->Show(); + } + else + { + aCornerButton.Hide(); + pColBar[SC_SPLIT_LEFT]->Hide(); // immer da + pRowBar[SC_SPLIT_BOTTOM]->Hide(); + } + + + // Grid-Windows + + if (bInner) + { + long nInnerPosX = bLayoutRTL ? ( nTotalWidth - nPosX - nLeftSize ) : nPosX; + pGridWin[SC_SPLIT_BOTTOMLEFT]->SetPosPixel( Point(nInnerPosX,nSplitPosY) ); + } + else + { + lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMLEFT], + Point(nPosX,nSplitPosY), Size(nLeftSize,nBottomSize), nTotalWidth, bLayoutRTL ); + if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE ) + lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMRIGHT], + Point(nSplitPosX,nSplitPosY), Size(nRightSize,nBottomSize), nTotalWidth, bLayoutRTL ); + if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) + lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPLEFT], + Point(nPosX,nPosY), Size(nLeftSize,nTopSize), nTotalWidth, bLayoutRTL ); + if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE && aViewData.GetVSplitMode() != SC_SPLIT_NONE ) + lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPRIGHT], + Point(nSplitPosX,nPosY), Size(nRightSize,nTopSize), nTotalWidth, bLayoutRTL ); + } + + // + // Scrollbars updaten + // + + if (!bInUpdateHeader) + { + UpdateScrollBars(); // Scrollbars nicht beim Scrollen neu setzen + UpdateHeaderWidth(); + + InterpretVisible(); // #69343# have everything calculated before painting + } + + if (bHasHint) + TestHintWindow(); // neu positionieren + + UpdateVarZoom(); // update variable zoom types (after resizing GridWindows) + + if (aViewData.GetViewShell()->HasAccessibilityObjects()) + aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_WINDOWRESIZED)); +} + +void ScTabView::UpdateVarZoom() +{ + // update variable zoom types + + SvxZoomType eZoomType = GetZoomType(); + if ( eZoomType != SVX_ZOOM_PERCENT && !bInZoomUpdate ) + { + bInZoomUpdate = TRUE; + const Fraction& rOldX = GetViewData()->GetZoomX(); + const Fraction& rOldY = GetViewData()->GetZoomY(); + long nOldPercent = ( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator(); + USHORT nNewZoom = CalcZoom( eZoomType, (USHORT)nOldPercent ); + Fraction aNew( nNewZoom, 100 ); + + if ( aNew != rOldX || aNew != rOldY ) + { + SetZoom( aNew, aNew, FALSE ); // always separately per sheet + PaintGrid(); + PaintTop(); + PaintLeft(); + aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM ); + aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER ); + } + bInZoomUpdate = FALSE; + } +} + +void ScTabView::UpdateFixPos() +{ + BOOL bResize = FALSE; + if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX ) + if (aViewData.UpdateFixX()) + bResize = TRUE; + if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX ) + if (aViewData.UpdateFixY()) + bResize = TRUE; + if (bResize) + RepeatResize(FALSE); +} + +void ScTabView::RepeatResize( BOOL bUpdateFix ) +{ + if ( bUpdateFix ) + { + ScSplitMode eHSplit = aViewData.GetHSplitMode(); + ScSplitMode eVSplit = aViewData.GetVSplitMode(); + + // #i46796# UpdateFixX / UpdateFixY uses GetGridOffset, which requires the + // outline windows to be available. So UpdateShow has to be called before + // (also called from DoResize). + if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX ) + UpdateShow(); + + if ( eHSplit == SC_SPLIT_FIX ) + aViewData.UpdateFixX(); + if ( eVSplit == SC_SPLIT_FIX ) + aViewData.UpdateFixY(); + } + + DoResize( aBorderPos, aFrameSize ); + + //! Border muss neu gesetzt werden ??? +} + +void ScTabView::GetBorderSize( SvBorder& rBorder, const Size& /* rSize */ ) +{ + BOOL bScrollBars = aViewData.IsVScrollMode(); + BOOL bHeaders = aViewData.IsHeaderMode(); + BOOL bOutlMode = aViewData.IsOutlineMode(); + BOOL bHOutline = bOutlMode && lcl_HasColOutline(aViewData); + BOOL bVOutline = bOutlMode && lcl_HasRowOutline(aViewData); + BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ); + + rBorder = SvBorder(); + + if (bScrollBars) // Scrollbars horizontal oder vertikal + { + rBorder.Right() += aVScrollBottom.GetSizePixel().Width(); + rBorder.Bottom() += aHScrollLeft.GetSizePixel().Height(); + } + + // Outline-Controls + if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM]) + rBorder.Left() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize(); + if (bHOutline && pColOutline[SC_SPLIT_LEFT]) + rBorder.Top() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize(); + + if (bHeaders) // Spalten/Zeilen-Header + { + rBorder.Left() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width(); + rBorder.Top() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height(); + } + + if ( bLayoutRTL ) + ::std::swap( rBorder.Left(), rBorder.Right() ); +} + +IMPL_LINK( ScTabView, TabBarResize, void*, EMPTYARG ) +{ + BOOL bHScrollMode = aViewData.IsHScrollMode(); + + // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden: + SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode(); + if ( eMode == SCROLLING_NO ) + bHScrollMode = FALSE; + else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ??? + bHScrollMode = TRUE; + + if( bHScrollMode ) + { + const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel(); + long nSize = pTabControl->GetSplitSize(); + + if (aViewData.GetHSplitMode() != SC_SPLIT_FIX) + { + long nMax = pHSplitter->GetPosPixel().X(); + if( pTabControl->IsEffectiveRTL() ) + nMax = pFrameWin->GetSizePixel().Width() - nMax; + --nMax; + if (nSize>nMax) nSize = nMax; + } + + if ( nSize != pTabControl->GetSizePixel().Width() ) + { + pTabControl->SetSizePixel( Size( nSize+nOverlap, + pTabControl->GetSizePixel().Height() ) ); + RepeatResize(); + } + } + + return 0; +} + +void ScTabView::SetTabBarWidth( long nNewWidth ) +{ + Size aSize = pTabControl->GetSizePixel(); + + if ( aSize.Width() != nNewWidth ) + { + aSize.Width() = nNewWidth; + pTabControl->SetSizePixel( aSize ); + } +} + +void ScTabView::SetRelTabBarWidth( double fRelTabBarWidth ) +{ + if( (0.0 <= fRelTabBarWidth) && (fRelTabBarWidth <= 1.0) ) + if( long nFrameWidth = pFrameWin->GetSizePixel().Width() ) + SetTabBarWidth( static_cast< long >( fRelTabBarWidth * nFrameWidth + 0.5 ) ); +} + +void ScTabView::SetPendingRelTabBarWidth( double fRelTabBarWidth ) +{ + mfPendingTabBarWidth = fRelTabBarWidth; + SetRelTabBarWidth( fRelTabBarWidth ); +} + +long ScTabView::GetTabBarWidth() const +{ + return pTabControl->GetSizePixel().Width(); +} + +double ScTabView::GetRelTabBarWidth() const +{ + if( long nFrameWidth = pFrameWin->GetSizePixel().Width() ) + return static_cast< double >( GetTabBarWidth() ) / nFrameWidth; + return 0.0; +} + +double ScTabView::GetPendingRelTabBarWidth() const +{ + return mfPendingTabBarWidth; +} + +Window* ScTabView::GetActiveWin() +{ + ScSplitPos ePos = aViewData.GetActivePart(); + DBG_ASSERT(pGridWin[ePos],"kein aktives Fenster"); + return pGridWin[ePos]; +} + +Window* ScTabView::GetWindowByPos( ScSplitPos ePos ) +{ + return pGridWin[ePos]; +} + +void ScTabView::SetActivePointer( const Pointer& rPointer ) +{ + for (USHORT i=0; i<4; i++) + if (pGridWin[i]) + pGridWin[i]->SetPointer( rPointer ); +} + + +void ScTabView::ActiveGrabFocus() +{ + ScSplitPos ePos = aViewData.GetActivePart(); + if (pGridWin[ePos]) + pGridWin[ePos]->GrabFocus(); +} + + +ScSplitPos ScTabView::FindWindow( Window* pWindow ) const +{ + ScSplitPos eVal = SC_SPLIT_BOTTOMLEFT; // Default + for (USHORT i=0; i<4; i++) + if ( pGridWin[i] == pWindow ) + eVal = (ScSplitPos) i; + + return eVal; +} + +Point ScTabView::GetGridOffset() const +{ + Point aPos; + + // Groessen hier wie in DoResize + + BOOL bHeaders = aViewData.IsHeaderMode(); + BOOL bOutlMode = aViewData.IsOutlineMode(); + BOOL bHOutline = bOutlMode && lcl_HasColOutline(aViewData); + BOOL bVOutline = bOutlMode && lcl_HasRowOutline(aViewData); + + // Outline-Controls + if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM]) + aPos.X() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize(); + if (bHOutline && pColOutline[SC_SPLIT_LEFT]) + aPos.Y() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize(); + + if (bHeaders) // Spalten/Zeilen-Header + { + if (pRowBar[SC_SPLIT_BOTTOM]) + aPos.X() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width(); + if (pColBar[SC_SPLIT_LEFT]) + aPos.Y() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height(); + } + + return aPos; +} + +// --- Scroll-Bars -------------------------------------------------------- + +BOOL ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos ) +{ + HideNoteMarker(); + + BOOL bDone = FALSE; + const CommandWheelData* pData = rCEvt.GetWheelData(); + if ( pData && pData->GetMode() == COMMAND_WHEEL_ZOOM ) + { + if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() ) + { + // for ole inplace editing, the scale is defined by the visarea and client size + // and can't be changed directly + + const Fraction& rOldY = aViewData.GetZoomY(); + long nOld = (long)(( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator()); + long nNew = nOld; + if ( pData->GetDelta() < 0 ) + nNew = Max( (long) MINZOOM, (long)( nOld - SC_DELTA_ZOOM ) ); + else + nNew = Min( (long) MAXZOOM, (long)( nOld + SC_DELTA_ZOOM ) ); + + if ( nNew != nOld ) + { + // scroll wheel doesn't set the AppOptions default + + BOOL bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom(); + SetZoomType( SVX_ZOOM_PERCENT, bSyncZoom ); + Fraction aFract( nNew, 100 ); + SetZoom( aFract, aFract, bSyncZoom ); + PaintGrid(); + PaintTop(); + PaintLeft(); + aViewData.GetBindings().Invalidate( SID_ATTR_ZOOM ); + aViewData.GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER ); + } + + bDone = TRUE; + } + } + else + { + ScHSplitPos eHPos = WhichH(ePos); + ScVSplitPos eVPos = WhichV(ePos); + ScrollBar* pHScroll = ( eHPos == SC_SPLIT_LEFT ) ? &aHScrollLeft : &aHScrollRight; + ScrollBar* pVScroll = ( eVPos == SC_SPLIT_TOP ) ? &aVScrollTop : &aVScrollBottom; + if ( pGridWin[ePos] ) + bDone = pGridWin[ePos]->HandleScrollCommand( rCEvt, pHScroll, pVScroll ); + } + return bDone; +} + +IMPL_LINK( ScTabView, EndScrollHdl, ScrollBar*, pScroll ) +{ + BOOL bOnlineScroll = TRUE; //! Optionen + + if ( bDragging ) + { + if ( bOnlineScroll ) // nur Ranges aktualisieren + UpdateScrollBars(); + else + { + long nScrollMin = 0; // RangeMin simulieren + if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight ) + nScrollMin = aViewData.GetFixPosX(); + if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom ) + nScrollMin = aViewData.GetFixPosY(); + + if ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight ) + { + BOOL bMirror = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ) != Application::GetSettings().GetLayoutRTL(); + ScHSplitPos eWhich = (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT; + long nDelta = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin - aViewData.GetPosX(eWhich); + if (nDelta) ScrollX( nDelta, eWhich ); + } + else // VScroll... + { + ScVSplitPos eWhich = (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM; + long nDelta = GetScrollBarPos( *pScroll, FALSE ) + nScrollMin - aViewData.GetPosY(eWhich); + if (nDelta) ScrollY( nDelta, eWhich ); + } + } + bDragging = FALSE; + } + return 0; +} + +IMPL_LINK( ScTabView, ScrollHdl, ScrollBar*, pScroll ) +{ + BOOL bOnlineScroll = TRUE; //! Optionen + + BOOL bHoriz = ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight ); + long nViewPos; + if ( bHoriz ) + nViewPos = aViewData.GetPosX( (pScroll == &aHScrollLeft) ? + SC_SPLIT_LEFT : SC_SPLIT_RIGHT ); + else + nViewPos = aViewData.GetPosY( (pScroll == &aVScrollTop) ? + SC_SPLIT_TOP : SC_SPLIT_BOTTOM ); + + BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ); + BOOL bMirror = bHoriz && (bLayoutRTL != Application::GetSettings().GetLayoutRTL()); + + ScrollType eType = pScroll->GetType(); + if ( eType == SCROLL_DRAG ) + { + if (!bDragging) + { + bDragging = TRUE; + nPrevDragPos = nViewPos; + } + + // Scroll-Position anzeigen + // (nur QuickHelp, in der Statuszeile gibt es keinen Eintrag dafuer) + + if (Help::IsQuickHelpEnabled()) + { + Size aSize = pScroll->GetSizePixel(); + + /* Convert scrollbar mouse position to screen position. If RTL + mode of scrollbar differs from RTL mode of its parent, then the + direct call to Window::OutputToNormalizedScreenPixel() will + give unusable results, because calcualtion of screen position + is based on parent orientation and expects equal orientation of + the child position. Need to mirror mouse position before. */ + Point aMousePos = pScroll->GetPointerPosPixel(); + if( pScroll->IsRTLEnabled() != pScroll->GetParent()->IsRTLEnabled() ) + aMousePos.X() = aSize.Width() - aMousePos.X() - 1; + aMousePos = pScroll->OutputToNormalizedScreenPixel( aMousePos ); + + // convert top-left position of scrollbar to screen position + Point aPos = pScroll->OutputToNormalizedScreenPixel( Point() ); + + // get scrollbar scroll position for help text (row number/column name) + long nScrollMin = 0; // RangeMin simulieren + if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight ) + nScrollMin = aViewData.GetFixPosX(); + if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom ) + nScrollMin = aViewData.GetFixPosY(); + long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin; + + String aHelpStr; + Rectangle aRect; + USHORT nAlign; + if (bHoriz) + { + aHelpStr = ScGlobal::GetRscString(STR_COLUMN); + aHelpStr += ' '; + aHelpStr += ScColToAlpha((SCCOL) nScrollPos); + + aRect.Left() = aMousePos.X(); + aRect.Top() = aPos.Y() - 4; + nAlign = QUICKHELP_BOTTOM|QUICKHELP_CENTER; + } + else + { + aHelpStr = ScGlobal::GetRscString(STR_ROW); + aHelpStr += ' '; + aHelpStr += String::CreateFromInt32(nScrollPos + 1); + + // show quicktext always inside sheet area + aRect.Left() = bLayoutRTL ? (aPos.X() + aSize.Width() + 8) : (aPos.X() - 8); + aRect.Top() = aMousePos.Y(); + nAlign = (bLayoutRTL ? QUICKHELP_LEFT : QUICKHELP_RIGHT) | QUICKHELP_VCENTER; + } + aRect.Right() = aRect.Left(); + aRect.Bottom() = aRect.Top(); + + Help::ShowQuickHelp(pScroll->GetParent(), aRect, aHelpStr, nAlign); + } + } + + if ( bOnlineScroll || eType != SCROLL_DRAG ) + { + if ( bMirror ) + { + // change scroll type so visible/previous cells calculation below remains the same + switch ( eType ) + { + case SCROLL_LINEUP: eType = SCROLL_LINEDOWN; break; + case SCROLL_LINEDOWN: eType = SCROLL_LINEUP; break; + case SCROLL_PAGEUP: eType = SCROLL_PAGEDOWN; break; + case SCROLL_PAGEDOWN: eType = SCROLL_PAGEUP; break; + default: + { + // added to avoid warnings + } + } + } + long nDelta = pScroll->GetDelta(); + switch ( eType ) + { + case SCROLL_LINEUP: + nDelta = -1; + break; + case SCROLL_LINEDOWN: + nDelta = 1; + break; + case SCROLL_PAGEUP: + if ( pScroll == &aHScrollLeft ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_LEFT ); + if ( pScroll == &aHScrollRight ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_RIGHT ); + if ( pScroll == &aVScrollTop ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_TOP ); + if ( pScroll == &aVScrollBottom ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_BOTTOM ); + if (nDelta==0) nDelta=-1; + break; + case SCROLL_PAGEDOWN: + if ( pScroll == &aHScrollLeft ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_LEFT ); + if ( pScroll == &aHScrollRight ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_RIGHT ); + if ( pScroll == &aVScrollTop ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_TOP ); + if ( pScroll == &aVScrollBottom ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM ); + if (nDelta==0) nDelta=1; + break; + case SCROLL_DRAG: + { + // nur in die richtige Richtung scrollen, nicht um ausgeblendete + // Bereiche herumzittern + + long nScrollMin = 0; // RangeMin simulieren + if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight ) + nScrollMin = aViewData.GetFixPosX(); + if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom ) + nScrollMin = aViewData.GetFixPosY(); + + long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin; + nDelta = nScrollPos - nViewPos; + if ( nScrollPos > nPrevDragPos ) + { + if (nDelta<0) nDelta=0; + } + else if ( nScrollPos < nPrevDragPos ) + { + if (nDelta>0) nDelta=0; + } + else + nDelta = 0; + nPrevDragPos = nScrollPos; + } + break; + default: + { + // added to avoid warnings + } + } + + if (nDelta) + { + BOOL bUpdate = ( eType != SCROLL_DRAG ); // bei Drag die Ranges nicht aendern + if ( bHoriz ) + ScrollX( nDelta, (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT, bUpdate ); + else + ScrollY( nDelta, (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM, bUpdate ); + } + } + + return 0; +} + +void ScTabView::ScrollX( long nDeltaX, ScHSplitPos eWhich, BOOL bUpdBars ) +{ + BOOL bHasHint = ( pInputHintWindow != NULL ); + if (bHasHint) + RemoveHintWindow(); + + SCCOL nOldX = aViewData.GetPosX(eWhich); + SCsCOL nNewX = static_cast<SCsCOL>(nOldX) + static_cast<SCsCOL>(nDeltaX); + if ( nNewX < 0 ) + { + nDeltaX -= nNewX; + nNewX = 0; + } + if ( nNewX > MAXCOL ) + { + nDeltaX -= nNewX - MAXCOL; + nNewX = MAXCOL; + } + + SCsCOL nDir = ( nDeltaX > 0 ) ? 1 : -1; + ScDocument* pDoc = aViewData.GetDocument(); + SCTAB nTab = aViewData.GetTabNo(); + while ( pDoc->ColHidden(nNewX, nTab) && + nNewX+nDir >= 0 && nNewX+nDir <= MAXCOL ) + nNewX = sal::static_int_cast<SCsCOL>( nNewX + nDir ); + + // Fixierung + + if (aViewData.GetHSplitMode() == SC_SPLIT_FIX) + { + if (eWhich == SC_SPLIT_LEFT) + nNewX = static_cast<SCsCOL>(nOldX); // links immer stehenlassen + else + { + SCsCOL nFixX = static_cast<SCsCOL>(aViewData.GetFixPosX()); + if (nNewX < nFixX) + nNewX = nFixX; + } + } + if (nNewX == static_cast<SCsCOL>(nOldX)) + return; + + HideAllCursors(); + + if ( nNewX >= 0 && nNewX <= MAXCOL && nDeltaX ) + { + SCCOL nTrackX = std::max( nOldX, static_cast<SCCOL>(nNewX) ); + + // Mit VCL wirkt Update() im Moment immer auf alle Fenster, beim Update + // nach dem Scrollen des GridWindow's wuerde darum der Col-/RowBar evtl. + // mit schon geaenderter Pos. gepainted werden - + // darum vorher einmal Update am Col-/RowBar + + if (pColBar[eWhich]) + pColBar[eWhich]->Update(); + + long nOldPos = aViewData.GetScrPos( nTrackX, 0, eWhich ).X(); + aViewData.SetPosX( eWhich, static_cast<SCCOL>(nNewX) ); + long nDiff = aViewData.GetScrPos( nTrackX, 0, eWhich ).X() - nOldPos; + + if ( eWhich==SC_SPLIT_LEFT ) + { + pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( nDiff, 0 ); + if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) + pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( nDiff, 0 ); + } + else + { + pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( nDiff, 0 ); + if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) + pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( nDiff, 0 ); + } + if (pColBar[eWhich]) { pColBar[eWhich]->Scroll( nDiff,0 ); pColBar[eWhich]->Update(); } + if (pColOutline[eWhich]) pColOutline[eWhich]->ScrollPixel( nDiff ); + if (bUpdBars) + UpdateScrollBars(); + } + + if (nDeltaX==1 || nDeltaX==-1) + pGridWin[aViewData.GetActivePart()]->Update(); + + ShowAllCursors(); + + SetNewVisArea(); // MapMode muss schon gesetzt sein + + if (bHasHint) + TestHintWindow(); // neu positionieren +} + +void ScTabView::ScrollY( long nDeltaY, ScVSplitPos eWhich, BOOL bUpdBars ) +{ + BOOL bHasHint = ( pInputHintWindow != NULL ); + if (bHasHint) + RemoveHintWindow(); + + SCROW nOldY = aViewData.GetPosY(eWhich); + SCsROW nNewY = static_cast<SCsROW>(nOldY) + static_cast<SCsROW>(nDeltaY); + if ( nNewY < 0 ) + { + nDeltaY -= nNewY; + nNewY = 0; + } + if ( nNewY > MAXROW ) + { + nDeltaY -= nNewY - MAXROW; + nNewY = MAXROW; + } + + SCsROW nDir = ( nDeltaY > 0 ) ? 1 : -1; + ScDocument* pDoc = aViewData.GetDocument(); + SCTAB nTab = aViewData.GetTabNo(); + while ( pDoc->RowHidden(nNewY, nTab) && + nNewY+nDir >= 0 && nNewY+nDir <= MAXROW ) + nNewY += nDir; + + // Fixierung + + if (aViewData.GetVSplitMode() == SC_SPLIT_FIX) + { + if (eWhich == SC_SPLIT_TOP) + nNewY = static_cast<SCsROW>(nOldY); // oben immer stehenlassen + else + { + SCsROW nFixY = static_cast<SCsROW>(aViewData.GetFixPosY()); + if (nNewY < nFixY) + nNewY = nFixY; + } + } + if (nNewY == static_cast<SCsROW>(nOldY)) + return; + + HideAllCursors(); + + if ( nNewY >= 0 && nNewY <= MAXROW && nDeltaY ) + { + SCROW nTrackY = std::max( nOldY, static_cast<SCROW>(nNewY) ); + + // Zeilenkoepfe anpassen vor dem eigentlichen Scrolling, damit nicht + // doppelt gepainted werden muss + // PosY darf dann auch noch nicht umgesetzt sein, neuen Wert uebergeben + SCROW nUNew = static_cast<SCROW>(nNewY); + UpdateHeaderWidth( &eWhich, &nUNew ); // Zeilenkoepfe anpassen + + if (pRowBar[eWhich]) + pRowBar[eWhich]->Update(); + + long nOldPos = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y(); + aViewData.SetPosY( eWhich, static_cast<SCROW>(nNewY) ); + long nDiff = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y() - nOldPos; + + if ( eWhich==SC_SPLIT_TOP ) + { + pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( 0, nDiff ); + if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE ) + pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( 0, nDiff ); + } + else + { + pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( 0, nDiff ); + if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE ) + pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( 0, nDiff ); + } + if (pRowBar[eWhich]) { pRowBar[eWhich]->Scroll( 0,nDiff ); pRowBar[eWhich]->Update(); } + if (pRowOutline[eWhich]) pRowOutline[eWhich]->ScrollPixel( nDiff ); + if (bUpdBars) + UpdateScrollBars(); + } + + if (nDeltaY==1 || nDeltaY==-1) + pGridWin[aViewData.GetActivePart()]->Update(); + + ShowAllCursors(); + + SetNewVisArea(); // MapMode muss schon gesetzt sein + + if (bHasHint) + TestHintWindow(); // neu positionieren +} + +void ScTabView::ScrollLines( long nDeltaX, long nDeltaY ) +{ + ScSplitPos eWhich = aViewData.GetActivePart(); + if (nDeltaX) + ScrollX(nDeltaX,WhichH(eWhich)); + if (nDeltaY) + ScrollY(nDeltaY,WhichV(eWhich)); +} + +SCROW lcl_LastVisible( ScViewData& rViewData ) +{ + // wenn am Dokumentende viele Zeilen ausgeblendet sind (welcher Trottel macht sowas?), + // soll dadurch nicht auf breite Zeilenkoepfe geschaltet werden + //! als Member ans Dokument ??? + + ScDocument* pDoc = rViewData.GetDocument(); + SCTAB nTab = rViewData.GetTabNo(); + + SCROW nVis = MAXROW; + while ( nVis > 0 && pDoc->GetRowHeight( nVis, nTab ) == 0 ) + --nVis; + return nVis; +} + +void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY ) +{ + if ( !pRowBar[SC_SPLIT_BOTTOM] || MAXROW < 10000 ) + return; + + SCROW nEndPos = MAXROW; + if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() ) + { + // fuer OLE Inplace immer MAXROW + + if ( pWhich && *pWhich == SC_SPLIT_BOTTOM && pPosY ) + nEndPos = *pPosY; + else + nEndPos = aViewData.GetPosY( SC_SPLIT_BOTTOM ); + nEndPos += aViewData.CellsAtY( nEndPos, 1, SC_SPLIT_BOTTOM, SC_SIZE_NONE ); // VisibleCellsY + if (nEndPos > MAXROW) + nEndPos = lcl_LastVisible( aViewData ); + + if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) + { + SCROW nTopEnd; + if ( pWhich && *pWhich == SC_SPLIT_TOP && pPosY ) + nTopEnd = *pPosY; + else + nTopEnd = aViewData.GetPosY( SC_SPLIT_TOP ); + nTopEnd += aViewData.CellsAtY( nTopEnd, 1, SC_SPLIT_TOP, SC_SIZE_NONE );// VisibleCellsY + if (nTopEnd > MAXROW) + nTopEnd = lcl_LastVisible( aViewData ); + + if ( nTopEnd > nEndPos ) + nEndPos = nTopEnd; + } + } + + long nSmall = pRowBar[SC_SPLIT_BOTTOM]->GetSmallWidth(); + long nBig = pRowBar[SC_SPLIT_BOTTOM]->GetBigWidth(); + long nDiff = nBig - nSmall; + + if (nEndPos>10000) + nEndPos = 10000; + else if (nEndPos<1) // avoid extra step at 0 (when only one row is visible) + nEndPos = 1; + long nWidth = nBig - ( 10000 - nEndPos ) * nDiff / 10000; + + if ( nWidth != pRowBar[SC_SPLIT_BOTTOM]->GetWidth() && !bInUpdateHeader ) + { + bInUpdateHeader = TRUE; + + pRowBar[SC_SPLIT_BOTTOM]->SetWidth( nWidth ); + if (pRowBar[SC_SPLIT_TOP]) + pRowBar[SC_SPLIT_TOP]->SetWidth( nWidth ); + + RepeatResize(); + + // auf VCL gibt's Update ohne Ende (jedes Update gilt fuer alle Fenster) + //aCornerButton.Update(); // der bekommt sonst nie ein Update + + bInUpdateHeader = FALSE; + } +} + +inline void ShowHide( Window* pWin, BOOL bShow ) +{ + DBG_ASSERT(pWin || !bShow, "Fenster ist nicht da"); + if (pWin) + pWin->Show(bShow); +} + +void ScTabView::UpdateShow() +{ + BOOL bHScrollMode = aViewData.IsHScrollMode(); + BOOL bVScrollMode = aViewData.IsVScrollMode(); + BOOL bTabMode = aViewData.IsTabMode(); + BOOL bOutlMode = aViewData.IsOutlineMode(); + BOOL bHOutline = bOutlMode && lcl_HasColOutline(aViewData); + BOOL bVOutline = bOutlMode && lcl_HasRowOutline(aViewData); + BOOL bHeader = aViewData.IsHeaderMode(); + + BOOL bShowH = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE ); + BOOL bShowV = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ); + + // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden: + SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode(); + if ( eMode == SCROLLING_NO ) + bHScrollMode = bVScrollMode = FALSE; + else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ??? + bHScrollMode = bVScrollMode = TRUE; + + if ( aViewData.GetDocShell()->IsPreview() ) + bHScrollMode = bVScrollMode = bTabMode = bHeader = bOutlMode = bHOutline = bVOutline = FALSE; + + // + // Windows anlegen + // + + if (bShowH && !pGridWin[SC_SPLIT_BOTTOMRIGHT]) + { + pGridWin[SC_SPLIT_BOTTOMRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_BOTTOMRIGHT ); + DoAddWin( pGridWin[SC_SPLIT_BOTTOMRIGHT] ); + } + if (bShowV && !pGridWin[SC_SPLIT_TOPLEFT]) + { + pGridWin[SC_SPLIT_TOPLEFT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPLEFT ); + DoAddWin( pGridWin[SC_SPLIT_TOPLEFT] ); + } + if (bShowH && bShowV && !pGridWin[SC_SPLIT_TOPRIGHT]) + { + pGridWin[SC_SPLIT_TOPRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPRIGHT ); + DoAddWin( pGridWin[SC_SPLIT_TOPRIGHT] ); + } + + if (bHOutline && !pColOutline[SC_SPLIT_LEFT]) + pColOutline[SC_SPLIT_LEFT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMLEFT ); + if (bShowH && bHOutline && !pColOutline[SC_SPLIT_RIGHT]) + pColOutline[SC_SPLIT_RIGHT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMRIGHT ); + + if (bVOutline && !pRowOutline[SC_SPLIT_BOTTOM]) + pRowOutline[SC_SPLIT_BOTTOM] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_BOTTOMLEFT ); + if (bShowV && bVOutline && !pRowOutline[SC_SPLIT_TOP]) + pRowOutline[SC_SPLIT_TOP] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_TOPLEFT ); + + if (bShowH && bHeader && !pColBar[SC_SPLIT_RIGHT]) + pColBar[SC_SPLIT_RIGHT] = new ScColBar( pFrameWin, &aViewData, SC_SPLIT_RIGHT, + &aHdrFunc, pHdrSelEng ); + if (bShowV && bHeader && !pRowBar[SC_SPLIT_TOP]) + pRowBar[SC_SPLIT_TOP] = new ScRowBar( pFrameWin, &aViewData, SC_SPLIT_TOP, + &aHdrFunc, pHdrSelEng ); + + // + // Windows anzeigen + // + + ShowHide( &aHScrollLeft, bHScrollMode ); + ShowHide( &aHScrollRight, bShowH && bHScrollMode ); + ShowHide( &aVScrollBottom, bVScrollMode ); + ShowHide( &aVScrollTop, bShowV && bVScrollMode ); + ShowHide( &aScrollBarBox, bVScrollMode || bHScrollMode ); + + ShowHide( pHSplitter, bHScrollMode || bShowH ); // immer angelegt + ShowHide( pVSplitter, bVScrollMode || bShowV ); + ShowHide( pTabControl, bTabMode ); + + // ab hier dynamisch angelegte + + ShowHide( pGridWin[SC_SPLIT_BOTTOMRIGHT], bShowH ); + ShowHide( pGridWin[SC_SPLIT_TOPLEFT], bShowV ); + ShowHide( pGridWin[SC_SPLIT_TOPRIGHT], bShowH && bShowV ); + + ShowHide( pColOutline[SC_SPLIT_LEFT], bHOutline ); + ShowHide( pColOutline[SC_SPLIT_RIGHT], bShowH && bHOutline ); + + ShowHide( pRowOutline[SC_SPLIT_BOTTOM], bVOutline ); + ShowHide( pRowOutline[SC_SPLIT_TOP], bShowV && bVOutline ); + + ShowHide( pColBar[SC_SPLIT_RIGHT], bShowH && bHeader ); + ShowHide( pRowBar[SC_SPLIT_TOP], bShowV && bHeader ); + + + //! neue Gridwindows eintragen +} + +// --- Splitter -------------------------------------------------------- + +IMPL_LINK( ScTabView, SplitHdl, Splitter*, pSplitter ) +{ + if ( pSplitter == pHSplitter ) + DoHSplit( pHSplitter->GetSplitPosPixel() ); + else + DoVSplit( pVSplitter->GetSplitPosPixel() ); + + if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX ) + FreezeSplitters( TRUE ); + + DoResize( aBorderPos, aFrameSize ); + + return 0; +} + +void ScTabView::DoHSplit(long nSplitPos) +{ + // nSplitPos is the real pixel position on the frame window, + // mirroring for RTL has to be done here. + + BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ); + if ( bLayoutRTL ) + nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1; + + long nMinPos; + long nMaxPos; + SCCOL nOldDelta; + SCCOL nNewDelta; + + nMinPos = SPLIT_MARGIN; + if ( pRowBar[SC_SPLIT_BOTTOM] && pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() >= nMinPos ) + nMinPos = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() + 1; + nMaxPos = aFrameSize.Width() - SPLIT_MARGIN; + + ScSplitMode aOldMode = aViewData.GetHSplitMode(); + ScSplitMode aNewMode = SC_SPLIT_NORMAL; + + aViewData.SetHSplitPos( nSplitPos ); + if ( nSplitPos < nMinPos || nSplitPos > nMaxPos ) + aNewMode = SC_SPLIT_NONE; + + aViewData.SetHSplitMode( aNewMode ); + + if ( aNewMode != aOldMode ) + { + UpdateShow(); // vor ActivatePart !! + + if ( aNewMode == SC_SPLIT_NONE ) + { + if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT) + ActivatePart( SC_SPLIT_TOPLEFT ); + if (aViewData.GetActivePart() == SC_SPLIT_BOTTOMRIGHT) + ActivatePart( SC_SPLIT_BOTTOMLEFT ); + } + else + { + nOldDelta = aViewData.GetPosX( SC_SPLIT_LEFT ); + long nLeftWidth = nSplitPos - pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width(); + if ( nLeftWidth < 0 ) nLeftWidth = 0; + nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, SC_SPLIT_LEFT, + (USHORT) nLeftWidth ); + if ( nNewDelta > MAXCOL ) + nNewDelta = MAXCOL; + aViewData.SetPosX( SC_SPLIT_RIGHT, nNewDelta ); + if ( nNewDelta > aViewData.GetCurX() ) + ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ? + SC_SPLIT_BOTTOMLEFT : SC_SPLIT_TOPLEFT ); + else + ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ? + SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_TOPRIGHT ); + } + + // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen + // dafuer muss hier schon der MapMode stimmen + for (USHORT i=0; i<4; i++) + if (pGridWin[i]) + pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() ); + SetNewVisArea(); + + PaintGrid(); + PaintTop(); + + InvalidateSplit(); + } +} + +void ScTabView::DoVSplit(long nSplitPos) +{ + long nMinPos; + long nMaxPos; + SCROW nOldDelta; + SCROW nNewDelta; + + nMinPos = SPLIT_MARGIN; + if ( pColBar[SC_SPLIT_LEFT] && pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() >= nMinPos ) + nMinPos = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() + 1; + nMaxPos = aFrameSize.Height() - SPLIT_MARGIN; + + ScSplitMode aOldMode = aViewData.GetVSplitMode(); + ScSplitMode aNewMode = SC_SPLIT_NORMAL; + + aViewData.SetVSplitPos( nSplitPos ); + if ( nSplitPos < nMinPos || nSplitPos > nMaxPos ) + aNewMode = SC_SPLIT_NONE; + + aViewData.SetVSplitMode( aNewMode ); + + if ( aNewMode != aOldMode ) + { + UpdateShow(); // vor ActivatePart !! + + if ( aNewMode == SC_SPLIT_NONE ) + { + nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP ); + aViewData.SetPosY( SC_SPLIT_BOTTOM, nOldDelta ); + + if (aViewData.GetActivePart() == SC_SPLIT_TOPLEFT) + ActivatePart( SC_SPLIT_BOTTOMLEFT ); + if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT) + ActivatePart( SC_SPLIT_BOTTOMRIGHT ); + } + else + { + if ( aOldMode == SC_SPLIT_NONE ) + nOldDelta = aViewData.GetPosY( SC_SPLIT_BOTTOM ); + else + nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP ); + + aViewData.SetPosY( SC_SPLIT_TOP, nOldDelta ); + long nTopHeight = nSplitPos - pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height(); + if ( nTopHeight < 0 ) nTopHeight = 0; + nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, SC_SPLIT_TOP, + (USHORT) nTopHeight ); + if ( nNewDelta > MAXROW ) + nNewDelta = MAXROW; + aViewData.SetPosY( SC_SPLIT_BOTTOM, nNewDelta ); + if ( nNewDelta > aViewData.GetCurY() ) + ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ? + SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT ); + else + ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ? + SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT ); + } + + // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen + // dafuer muss hier schon der MapMode stimmen + for (USHORT i=0; i<4; i++) + if (pGridWin[i]) + pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() ); + SetNewVisArea(); + + PaintGrid(); + PaintLeft(); + + InvalidateSplit(); + } +} + +Point ScTabView::GetInsertPos() +{ + ScDocument* pDoc = aViewData.GetDocument(); + SCCOL nCol = aViewData.GetCurX(); + SCROW nRow = aViewData.GetCurY(); + SCTAB nTab = aViewData.GetTabNo(); + long nPosX = 0; + for (SCCOL i=0; i<nCol; i++) + nPosX += pDoc->GetColWidth(i,nTab); + nPosX = (long)(nPosX * HMM_PER_TWIPS); + if ( pDoc->IsNegativePage( nTab ) ) + nPosX = -nPosX; + long nPosY = (long) pDoc->GetRowHeight( 0, nRow-1, nTab); + nPosY = (long)(nPosY * HMM_PER_TWIPS); + return Point(nPosX,nPosY); +} + +Point ScTabView::GetChartInsertPos( const Size& rSize, const ScRange& rCellRange ) +{ + Point aInsertPos; + const long nBorder = 100; // leave 1mm for border + long nNeededWidth = rSize.Width() + 2 * nBorder; + long nNeededHeight = rSize.Height() + 2 * nBorder; + + // use the active window, or lower/right if frozen (as in CalcZoom) + ScSplitPos eUsedPart = aViewData.GetActivePart(); + if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX ) + eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT; + if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX ) + eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT; + + ScGridWindow* pWin = pGridWin[eUsedPart]; + DBG_ASSERT( pWin, "Window not found" ); + if (pWin) + { + ActivatePart( eUsedPart ); + + // get the visible rectangle in logic units + + MapMode aDrawMode = pWin->GetDrawMapMode(); + Rectangle aVisible( pWin->PixelToLogic( Rectangle( Point(0,0), pWin->GetOutputSizePixel() ), aDrawMode ) ); + + ScDocument* pDoc = aViewData.GetDocument(); + SCTAB nTab = aViewData.GetTabNo(); + BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab ); + long nLayoutSign = bLayoutRTL ? -1 : 1; + + long nDocX = (long)( (double) pDoc->GetColOffset( MAXCOL + 1, nTab ) * HMM_PER_TWIPS ) * nLayoutSign; + long nDocY = (long)( (double) pDoc->GetRowOffset( MAXROW + 1, nTab ) * HMM_PER_TWIPS ); + + if ( aVisible.Left() * nLayoutSign > nDocX * nLayoutSign ) + aVisible.Left() = nDocX; + if ( aVisible.Right() * nLayoutSign > nDocX * nLayoutSign ) + aVisible.Right() = nDocX; + if ( aVisible.Top() > nDocY ) + aVisible.Top() = nDocY; + if ( aVisible.Bottom() > nDocY ) + aVisible.Bottom() = nDocY; + + // get the logic position of the selection + + Rectangle aSelection = pDoc->GetMMRect( rCellRange.aStart.Col(), rCellRange.aStart.Row(), + rCellRange.aEnd.Col(), rCellRange.aEnd.Row(), nTab ); + + long nLeftSpace = aSelection.Left() - aVisible.Left(); + long nRightSpace = aVisible.Right() - aSelection.Right(); + long nTopSpace = aSelection.Top() - aVisible.Top(); + long nBottomSpace = aVisible.Bottom() - aSelection.Bottom(); + + bool bFitLeft = ( nLeftSpace >= nNeededWidth ); + bool bFitRight = ( nRightSpace >= nNeededWidth ); + + if ( bFitLeft || bFitRight ) + { + // first preference: completely left or right of the selection + + // if both fit, prefer left in RTL mode, right otherwise + bool bPutLeft = bFitLeft && ( bLayoutRTL || !bFitRight ); + + if ( bPutLeft ) + aInsertPos.X() = aSelection.Left() - nNeededWidth; + else + aInsertPos.X() = aSelection.Right() + 1; + + // align with top of selection (is moved again if it doesn't fit) + aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() ); + } + else if ( nTopSpace >= nNeededHeight || nBottomSpace >= nNeededHeight ) + { + // second preference: completely above or below the selection + + if ( nBottomSpace > nNeededHeight ) // bottom is preferred + aInsertPos.Y() = aSelection.Bottom() + 1; + else + aInsertPos.Y() = aSelection.Top() - nNeededHeight; + + // align with (logic) left edge of selection (moved again if it doesn't fit) + if ( bLayoutRTL ) + aInsertPos.X() = std::min( aSelection.Right(), aVisible.Right() ) - nNeededWidth + 1; + else + aInsertPos.X() = std::max( aSelection.Left(), aVisible.Left() ); + } + else + { + // place to the (logic) right of the selection and move so it fits + + if ( bLayoutRTL ) + aInsertPos.X() = aSelection.Left() - nNeededWidth; + else + aInsertPos.X() = aSelection.Right() + 1; + aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() ); + } + + // move the position if the object doesn't fit in the screen + + Rectangle aCompareRect( aInsertPos, Size( nNeededWidth, nNeededHeight ) ); + if ( aCompareRect.Right() > aVisible.Right() ) + aInsertPos.X() -= aCompareRect.Right() - aVisible.Right(); + if ( aCompareRect.Bottom() > aVisible.Bottom() ) + aInsertPos.Y() -= aCompareRect.Bottom() - aVisible.Bottom(); + + if ( aInsertPos.X() < aVisible.Left() ) + aInsertPos.X() = aVisible.Left(); + if ( aInsertPos.Y() < aVisible.Top() ) + aInsertPos.Y() = aVisible.Top(); + + // nNeededWidth / nNeededHeight includes all borders - move aInsertPos to the + // object position, inside the border + + aInsertPos.X() += nBorder; + aInsertPos.Y() += nBorder; + } + return aInsertPos; +} + +Point ScTabView::GetChartDialogPos( const Size& rDialogSize, const Rectangle& rLogicChart ) +{ + // rDialogSize must be in pixels, rLogicChart in 1/100 mm. Return value is in pixels. + + Point aRet; + + // use the active window, or lower/right if frozen (as in CalcZoom) + ScSplitPos eUsedPart = aViewData.GetActivePart(); + if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX ) + eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT; + if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX ) + eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT; + + ScGridWindow* pWin = pGridWin[eUsedPart]; + DBG_ASSERT( pWin, "Window not found" ); + if (pWin) + { + MapMode aDrawMode = pWin->GetDrawMapMode(); + Rectangle aObjPixel = pWin->LogicToPixel( rLogicChart, aDrawMode ); + Rectangle aObjAbs( pWin->OutputToAbsoluteScreenPixel( aObjPixel.TopLeft() ), + pWin->OutputToAbsoluteScreenPixel( aObjPixel.BottomRight() ) ); + + Rectangle aDesktop = pWin->GetDesktopRectPixel(); + Size aSpace = pWin->LogicToPixel( Size( 8, 12 ), MAP_APPFONT ); + + ScDocument* pDoc = aViewData.GetDocument(); + SCTAB nTab = aViewData.GetTabNo(); + BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab ); + + bool bCenterHor = false; + + if ( aDesktop.Bottom() - aObjAbs.Bottom() >= rDialogSize.Height() + aSpace.Height() ) + { + // first preference: below the chart + + aRet.Y() = aObjAbs.Bottom() + aSpace.Height(); + bCenterHor = true; + } + else if ( aObjAbs.Top() - aDesktop.Top() >= rDialogSize.Height() + aSpace.Height() ) + { + // second preference: above the chart + + aRet.Y() = aObjAbs.Top() - rDialogSize.Height() - aSpace.Height(); + bCenterHor = true; + } + else + { + bool bFitLeft = ( aObjAbs.Left() - aDesktop.Left() >= rDialogSize.Width() + aSpace.Width() ); + bool bFitRight = ( aDesktop.Right() - aObjAbs.Right() >= rDialogSize.Width() + aSpace.Width() ); + + if ( bFitLeft || bFitRight ) + { + // if both fit, prefer right in RTL mode, left otherwise + bool bPutRight = bFitRight && ( bLayoutRTL || !bFitLeft ); + if ( bPutRight ) + aRet.X() = aObjAbs.Right() + aSpace.Width(); + else + aRet.X() = aObjAbs.Left() - rDialogSize.Width() - aSpace.Width(); + + // center vertically + aRet.Y() = aObjAbs.Top() + ( aObjAbs.GetHeight() - rDialogSize.Height() ) / 2; + } + else + { + // doesn't fit on any edge - put at the bottom of the screen + aRet.Y() = aDesktop.Bottom() - rDialogSize.Height(); + bCenterHor = true; + } + } + if ( bCenterHor ) + aRet.X() = aObjAbs.Left() + ( aObjAbs.GetWidth() - rDialogSize.Width() ) / 2; + + // limit to screen (centering might lead to invalid positions) + if ( aRet.X() + rDialogSize.Width() - 1 > aDesktop.Right() ) + aRet.X() = aDesktop.Right() - rDialogSize.Width() + 1; + if ( aRet.X() < aDesktop.Left() ) + aRet.X() = aDesktop.Left(); + if ( aRet.Y() + rDialogSize.Height() - 1 > aDesktop.Bottom() ) + aRet.Y() = aDesktop.Bottom() - rDialogSize.Height() + 1; + if ( aRet.Y() < aDesktop.Top() ) + aRet.Y() = aDesktop.Top(); + } + + return aRet; +} + +void ScTabView::LockModifiers( USHORT nModifiers ) +{ + pSelEngine->LockModifiers( nModifiers ); + pHdrSelEng->LockModifiers( nModifiers ); +} + +USHORT ScTabView::GetLockedModifiers() const +{ + return pSelEngine->GetLockedModifiers(); +} + +Point ScTabView::GetMousePosPixel() +{ + Point aPos; + ScGridWindow* pWin = (ScGridWindow*)GetActiveWin(); + + if ( pWin ) + aPos = pWin->GetMousePosPixel(); + + return aPos; +} + +BOOL lcl_MouseIsOverWin( const Point& rScreenPosPixel, Window* pWin ) +{ + if (pWin) + { + // SPLIT_HANDLE_SIZE draufaddieren, damit das Einrasten genau + // auf dem Splitter nicht aussetzt + + Point aRel = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel ); + Size aWinSize = pWin->GetOutputSizePixel(); + if ( aRel.X() >= 0 && aRel.X() < aWinSize.Width() + SPLIT_HANDLE_SIZE && + aRel.Y() >= 0 && aRel.Y() < aWinSize.Height() + SPLIT_HANDLE_SIZE ) + return TRUE; + } + return FALSE; +} + +void ScTabView::SnapSplitPos( Point& rScreenPosPixel ) +{ + BOOL bOverWin = FALSE; + USHORT i; + for (i=0; i<4; i++) + if (lcl_MouseIsOverWin(rScreenPosPixel,pGridWin[i])) + bOverWin = TRUE; + + if (!bOverWin) + return; + + // #74761# don't snap to cells if the scale will be modified afterwards + if ( GetZoomType() != SVX_ZOOM_PERCENT ) + return; + + ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT; + if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) + ePos = SC_SPLIT_TOPLEFT; + + Window* pWin = pGridWin[ePos]; + if (!pWin) + { + DBG_ERROR("Window NULL"); + return; + } + + Point aMouse = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel ); + SCsCOL nPosX; + SCsROW nPosY; + // #52949# bNextIfLarge=FALSE: nicht auf naechste Zelle, wenn ausserhalb des Fensters + aViewData.GetPosFromPixel( aMouse.X(), aMouse.Y(), ePos, nPosX, nPosY, TRUE, FALSE, FALSE ); + BOOL bLeft; + BOOL bTop; + aViewData.GetMouseQuadrant( aMouse, ePos, nPosX, nPosY, bLeft, bTop ); + if (!bLeft) + ++nPosX; + if (!bTop) + ++nPosY; + aMouse = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, TRUE ); + rScreenPosPixel = pWin->OutputToNormalizedScreenPixel( aMouse ); +} + +void ScTabView::FreezeSplitters( BOOL bFreeze ) +{ + ScSplitMode eOldH = aViewData.GetHSplitMode(); + ScSplitMode eOldV = aViewData.GetVSplitMode(); + + ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT; + if ( eOldV != SC_SPLIT_NONE ) + ePos = SC_SPLIT_TOPLEFT; + Window* pWin = pGridWin[ePos]; + + BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ); + + if ( bFreeze ) + { + Point aWinStart = pWin->GetPosPixel(); + + Point aSplit; + SCsCOL nPosX; + SCsROW nPosY; + if (eOldH != SC_SPLIT_NONE || eOldV != SC_SPLIT_NONE) + { + if (eOldH != SC_SPLIT_NONE) + { + long nSplitPos = aViewData.GetHSplitPos(); + if ( bLayoutRTL ) + nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1; + aSplit.X() = nSplitPos - aWinStart.X(); + } + if (eOldV != SC_SPLIT_NONE) + aSplit.Y() = aViewData.GetVSplitPos() - aWinStart.Y(); + + aViewData.GetPosFromPixel( aSplit.X(), aSplit.Y(), ePos, nPosX, nPosY ); + BOOL bLeft; + BOOL bTop; + aViewData.GetMouseQuadrant( aSplit, ePos, nPosX, nPosY, bLeft, bTop ); + if (!bLeft) + ++nPosX; + if (!bTop) + ++nPosY; + } + else + { + nPosX = static_cast<SCsCOL>( aViewData.GetCurX()); + nPosY = static_cast<SCsROW>( aViewData.GetCurY()); + } + + SCCOL nLeftPos = aViewData.GetPosX(SC_SPLIT_LEFT); + SCROW nTopPos = aViewData.GetPosY(SC_SPLIT_BOTTOM); + SCCOL nRightPos = static_cast<SCCOL>(nPosX); + SCROW nBottomPos = static_cast<SCROW>(nPosY); + if (eOldH != SC_SPLIT_NONE) + if (aViewData.GetPosX(SC_SPLIT_RIGHT) > nRightPos) + nRightPos = aViewData.GetPosX(SC_SPLIT_RIGHT); + if (eOldV != SC_SPLIT_NONE) + { + nTopPos = aViewData.GetPosY(SC_SPLIT_TOP); + if (aViewData.GetPosY(SC_SPLIT_BOTTOM) > nBottomPos) + nBottomPos = aViewData.GetPosY(SC_SPLIT_BOTTOM); + } + + aSplit = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, TRUE ); + if (nPosX > aViewData.GetPosX(SC_SPLIT_LEFT)) // (aSplit.X() > 0) doesn't work for RTL + { + long nSplitPos = aSplit.X() + aWinStart.X(); + if ( bLayoutRTL ) + nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1; + + aViewData.SetHSplitMode( SC_SPLIT_FIX ); + aViewData.SetHSplitPos( nSplitPos ); + aViewData.SetFixPosX( nPosX ); + + aViewData.SetPosX(SC_SPLIT_LEFT, nLeftPos); + aViewData.SetPosX(SC_SPLIT_RIGHT, nRightPos); + } + else + aViewData.SetHSplitMode( SC_SPLIT_NONE ); + if (aSplit.Y() > 0) + { + aViewData.SetVSplitMode( SC_SPLIT_FIX ); + aViewData.SetVSplitPos( aSplit.Y() + aWinStart.Y() ); + aViewData.SetFixPosY( nPosY ); + + aViewData.SetPosY(SC_SPLIT_TOP, nTopPos); + aViewData.SetPosY(SC_SPLIT_BOTTOM, nBottomPos); + } + else + aViewData.SetVSplitMode( SC_SPLIT_NONE ); + } + else // Fixierung aufheben + { + if ( eOldH == SC_SPLIT_FIX ) + aViewData.SetHSplitMode( SC_SPLIT_NORMAL ); + if ( eOldV == SC_SPLIT_FIX ) + aViewData.SetVSplitMode( SC_SPLIT_NORMAL ); + } + + // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen + // dafuer muss hier schon der MapMode stimmen + for (USHORT i=0; i<4; i++) + if (pGridWin[i]) + pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() ); + SetNewVisArea(); + + RepeatResize(FALSE); + + UpdateShow(); + PaintLeft(); + PaintTop(); + PaintGrid(); + + // SC_FOLLOW_NONE: only update active part + AlignToCursor( aViewData.GetCurX(), aViewData.GetCurY(), SC_FOLLOW_NONE ); + UpdateAutoFillMark(); + + InvalidateSplit(); +} + +void ScTabView::RemoveSplit() +{ + DoHSplit( 0 ); + DoVSplit( 0 ); + RepeatResize(); +} + +void ScTabView::SplitAtCursor() +{ + ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT; + if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE ) + ePos = SC_SPLIT_TOPLEFT; + Window* pWin = pGridWin[ePos]; + Point aWinStart = pWin->GetPosPixel(); + + SCCOL nPosX = aViewData.GetCurX(); + SCROW nPosY = aViewData.GetCurY(); + Point aSplit = aViewData.GetScrPos( nPosX, nPosY, ePos, TRUE ); + if ( nPosX > 0 ) + DoHSplit( aSplit.X() + aWinStart.X() ); + else + DoHSplit( 0 ); + if ( nPosY > 0 ) + DoVSplit( aSplit.Y() + aWinStart.Y() ); + else + DoVSplit( 0 ); + RepeatResize(); +} + +void ScTabView::SplitAtPixel( const Point& rPixel, BOOL bHor, BOOL bVer ) // fuer API +{ + // Pixel ist auf die ganze View bezogen, nicht auf das erste GridWin + + if (bHor) + { + if ( rPixel.X() > 0 ) + DoHSplit( rPixel.X() ); + else + DoHSplit( 0 ); + } + if (bVer) + { + if ( rPixel.Y() > 0 ) + DoVSplit( rPixel.Y() ); + else + DoVSplit( 0 ); + } + RepeatResize(); +} + +void ScTabView::InvalidateSplit() +{ + SfxBindings& rBindings = aViewData.GetBindings(); + rBindings.Invalidate( SID_WINDOW_SPLIT ); + rBindings.Invalidate( SID_WINDOW_FIX ); + + pHSplitter->SetFixed( aViewData.GetHSplitMode() == SC_SPLIT_FIX ); + pVSplitter->SetFixed( aViewData.GetVSplitMode() == SC_SPLIT_FIX ); +} + +void ScTabView::SetNewVisArea() +{ + // #63854# fuer die Controls muss bei VisAreaChanged der Draw-MapMode eingestellt sein + // (auch wenn ansonsten der Edit-MapMode gesetzt ist) + MapMode aOldMode[4]; + MapMode aDrawMode[4]; + USHORT i; + for (i=0; i<4; i++) + if (pGridWin[i]) + { + aOldMode[i] = pGridWin[i]->GetMapMode(); + aDrawMode[i] = pGridWin[i]->GetDrawMapMode(); + if (aDrawMode[i] != aOldMode[i]) + pGridWin[i]->SetMapMode(aDrawMode[i]); + } + + Window* pActive = pGridWin[aViewData.GetActivePart()]; + if (pActive) + aViewData.GetViewShell()->VisAreaChanged( + pActive->PixelToLogic(Rectangle(Point(),pActive->GetOutputSizePixel())) ); + if (pDrawView) + pDrawView->VisAreaChanged(); // kein Window uebergeben -> alle Fenster + + UpdateAllOverlays(); // #i79909# with drawing MapMode set + + for (i=0; i<4; i++) + if (pGridWin[i] && aDrawMode[i] != aOldMode[i]) + { + pGridWin[i]->flushOverlayManager(); // #i79909# flush overlays before switching to edit MapMode + pGridWin[i]->SetMapMode(aOldMode[i]); + } + + SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame(); + if (pViewFrame) + { + SfxFrame& rFrame = pViewFrame->GetFrame(); + com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = rFrame.GetController(); + if (xController.is()) + { + ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); + if (pImp) + pImp->VisAreaChanged(); + } + } + if (aViewData.GetViewShell()->HasAccessibilityObjects()) + aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_VISAREACHANGED)); +} + +sal_Bool ScTabView::HasPageFieldDataAtCursor() const +{ + ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()]; + SCCOL nCol = aViewData.GetCurX(); + SCROW nRow = aViewData.GetCurY(); + if (pWin) + return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE; + + return sal_False; +} + +void ScTabView::StartDataSelect() +{ + ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()]; + SCCOL nCol = aViewData.GetCurX(); + SCROW nRow = aViewData.GetCurY(); + + if (!pWin) + return; + + switch (pWin->GetDPFieldOrientation(nCol, nRow)) + { + case sheet::DataPilotFieldOrientation_PAGE: + // #i36598# If the cursor is on a page field's data cell, + // no meaningful input is possible anyway, so this function + // can be used to select a page field entry. + pWin->LaunchPageFieldMenu( nCol, nRow ); + break; + case sheet::DataPilotFieldOrientation_COLUMN: + case sheet::DataPilotFieldOrientation_ROW: + pWin->LaunchDPFieldMenu( nCol, nRow ); + break; + default: + pWin->DoAutoFilterMenue( nCol, nRow, TRUE ); + } +} + +void ScTabView::EnableRefInput(BOOL bFlag) +{ + aHScrollLeft.EnableInput(bFlag); + aHScrollRight.EnableInput(bFlag); + aVScrollBottom.EnableInput(bFlag); + aVScrollTop.EnableInput(bFlag); + aScrollBarBox.EnableInput(bFlag); + + // ab hier dynamisch angelegte + + if(pTabControl!=NULL) pTabControl->EnableInput(bFlag,TRUE); + + if(pGridWin[SC_SPLIT_BOTTOMLEFT]!=NULL) + pGridWin[SC_SPLIT_BOTTOMLEFT]->EnableInput(bFlag,FALSE); + if(pGridWin[SC_SPLIT_BOTTOMRIGHT]!=NULL) + pGridWin[SC_SPLIT_BOTTOMRIGHT]->EnableInput(bFlag,FALSE); + if(pGridWin[SC_SPLIT_TOPLEFT]!=NULL) + pGridWin[SC_SPLIT_TOPLEFT]->EnableInput(bFlag,FALSE); + if(pGridWin[SC_SPLIT_TOPRIGHT]!=NULL) + pGridWin[SC_SPLIT_TOPRIGHT]->EnableInput(bFlag,FALSE); + if(pColBar[SC_SPLIT_RIGHT]!=NULL) + pColBar[SC_SPLIT_RIGHT]->EnableInput(bFlag,FALSE); + if(pRowBar[SC_SPLIT_TOP]!=NULL) + pRowBar[SC_SPLIT_TOP]->EnableInput(bFlag,FALSE); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |