diff options
Diffstat (limited to 'sc/source/ui/view/select.cxx')
-rw-r--r-- | sc/source/ui/view/select.cxx | 891 |
1 files changed, 891 insertions, 0 deletions
diff --git a/sc/source/ui/view/select.cxx b/sc/source/ui/view/select.cxx new file mode 100644 index 000000000000..b2c9ffdc1395 --- /dev/null +++ b/sc/source/ui/view/select.cxx @@ -0,0 +1,891 @@ +/************************************************************************* + * + * 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 --------------------------------------------------------------- + +#include <tools/urlobj.hxx> +#include <vcl/sound.hxx> +#include <sfx2/docfile.hxx> + +#include "select.hxx" +#include "sc.hrc" +#include "tabvwsh.hxx" +#include "scmod.hxx" +#include "document.hxx" +//#include "dataobj.hxx" +#include "transobj.hxx" +#include "docsh.hxx" +#include "tabprotection.hxx" + +extern USHORT nScFillModeMouseModifier; // global.cxx + +using namespace com::sun::star; + +// STATIC DATA ----------------------------------------------------------- + +static Point aSwitchPos; //! Member +static BOOL bDidSwitch = FALSE; + +// ----------------------------------------------------------------------- + +// +// View (Gridwin / Tastatur) +// + +ScViewFunctionSet::ScViewFunctionSet( ScViewData* pNewViewData ) : + pViewData( pNewViewData ), + pEngine( NULL ), + bAnchor( FALSE ), + bStarted( FALSE ) +{ + DBG_ASSERT(pViewData, "ViewData==0 bei FunctionSet"); +} + +ScSplitPos ScViewFunctionSet::GetWhich() +{ + if (pEngine) + return pEngine->GetWhich(); + else + return pViewData->GetActivePart(); +} + +void ScViewFunctionSet::SetSelectionEngine( ScViewSelectionEngine* pSelEngine ) +{ + pEngine = pSelEngine; +} + +// Drag & Drop + +void __EXPORT ScViewFunctionSet::BeginDrag() +{ + SCTAB nTab = pViewData->GetTabNo(); + + SCsCOL nPosX; + SCsROW nPosY; + if (pEngine) + { + Point aMPos = pEngine->GetMousePosPixel(); + pViewData->GetPosFromPixel( aMPos.X(), aMPos.Y(), GetWhich(), nPosX, nPosY ); + } + else + { + nPosX = pViewData->GetCurX(); + nPosY = pViewData->GetCurY(); + } + + ScModule* pScMod = SC_MOD(); + BOOL bRefMode = pScMod->IsFormulaMode(); + if (!bRefMode) + { + pViewData->GetView()->FakeButtonUp( GetWhich() ); // ButtonUp wird verschluckt + + ScMarkData& rMark = pViewData->GetMarkData(); +// rMark.SetMarking(FALSE); // es fehlt ein ButtonUp + rMark.MarkToSimple(); + if ( rMark.IsMarked() && !rMark.IsMultiMarked() ) + { + ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); + // bApi = TRUE -> no error mesages + BOOL bCopied = pViewData->GetView()->CopyToClip( pClipDoc, FALSE, TRUE ); + if ( bCopied ) + { + sal_Int8 nDragActions = pViewData->GetView()->SelectionEditable() ? + ( DND_ACTION_COPYMOVE | DND_ACTION_LINK ) : + ( DND_ACTION_COPY | DND_ACTION_LINK ); + + ScDocShell* pDocSh = pViewData->GetDocShell(); + TransferableObjectDescriptor aObjDesc; + pDocSh->FillTransferableObjectDescriptor( aObjDesc ); + aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); + // maSize is set in ScTransferObj ctor + + ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc ); + uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); + + // set position of dragged cell within range + ScRange aMarkRange = pTransferObj->GetRange(); + SCCOL nStartX = aMarkRange.aStart.Col(); + SCROW nStartY = aMarkRange.aStart.Row(); + SCCOL nHandleX = (nPosX >= (SCsCOL) nStartX) ? nPosX - nStartX : 0; + SCROW nHandleY = (nPosY >= (SCsROW) nStartY) ? nPosY - nStartY : 0; + pTransferObj->SetDragHandlePos( nHandleX, nHandleY ); + pTransferObj->SetVisibleTab( nTab ); + + pTransferObj->SetDragSource( pDocSh, rMark ); + + Window* pWindow = pViewData->GetActiveWin(); + if ( pWindow->IsTracking() ) + pWindow->EndTracking( ENDTRACK_CANCEL ); // abort selecting + + SC_MOD()->SetDragObject( pTransferObj, NULL ); // for internal D&D + pTransferObj->StartDrag( pWindow, nDragActions ); + + return; // dragging started + } + else + delete pClipDoc; + } + } + + Sound::Beep(); // can't drag +} + +// Selektion + +void __EXPORT ScViewFunctionSet::CreateAnchor() +{ + if (bAnchor) return; + + BOOL bRefMode = SC_MOD()->IsFormulaMode(); + if (bRefMode) + SetAnchor( pViewData->GetRefStartX(), pViewData->GetRefStartY() ); + else + SetAnchor( pViewData->GetCurX(), pViewData->GetCurY() ); +} + +void ScViewFunctionSet::SetAnchor( SCCOL nPosX, SCROW nPosY ) +{ + BOOL bRefMode = SC_MOD()->IsFormulaMode(); + ScTabView* pView = pViewData->GetView(); + SCTAB nTab = pViewData->GetTabNo(); + + if (bRefMode) + { + pView->DoneRefMode( FALSE ); + aAnchorPos.Set( nPosX, nPosY, nTab ); + pView->InitRefMode( aAnchorPos.Col(), aAnchorPos.Row(), aAnchorPos.Tab(), + SC_REFTYPE_REF ); + bStarted = TRUE; + } + else if (pViewData->IsAnyFillMode()) + { + aAnchorPos.Set( nPosX, nPosY, nTab ); + bStarted = TRUE; + } + else + { + // nicht weg und gleich wieder hin + if ( bStarted && pView->IsMarking( nPosX, nPosY, nTab ) ) + { + // nix + } + else + { + pView->DoneBlockMode( TRUE ); + aAnchorPos.Set( nPosX, nPosY, nTab ); + ScMarkData& rMark = pViewData->GetMarkData(); + if ( rMark.IsMarked() || rMark.IsMultiMarked() ) + { + pView->InitBlockMode( aAnchorPos.Col(), aAnchorPos.Row(), + aAnchorPos.Tab(), TRUE ); + bStarted = TRUE; + } + else + bStarted = FALSE; + } + } + bAnchor = TRUE; +} + +void __EXPORT ScViewFunctionSet::DestroyAnchor() +{ + BOOL bRefMode = SC_MOD()->IsFormulaMode(); + if (bRefMode) + pViewData->GetView()->DoneRefMode( TRUE ); + else + pViewData->GetView()->DoneBlockMode( TRUE ); + + bAnchor = FALSE; +} + +void ScViewFunctionSet::SetAnchorFlag( BOOL bSet ) +{ + bAnchor = bSet; +} + +BOOL __EXPORT ScViewFunctionSet::SetCursorAtPoint( const Point& rPointPixel, BOOL /* bDontSelectAtCursor */ ) +{ + if ( bDidSwitch ) + { + if ( rPointPixel == aSwitchPos ) + return FALSE; // nicht auf falschem Fenster scrollen + else + bDidSwitch = FALSE; + } + aSwitchPos = rPointPixel; // nur wichtig, wenn bDidSwitch + + // treat position 0 as -1, so scrolling is always possible + // (with full screen and hidden headers, the top left border may be at 0) + // (moved from ScViewData::GetPosFromPixel) + + Point aEffPos = rPointPixel; + if ( aEffPos.X() == 0 ) + aEffPos.X() = -1; + if ( aEffPos.Y() == 0 ) + aEffPos.Y() = -1; + + // Scrolling + + Size aWinSize = pEngine->GetWindow()->GetOutputSizePixel(); + BOOL bRightScroll = ( aEffPos.X() >= aWinSize.Width() ); + BOOL bBottomScroll = ( aEffPos.Y() >= aWinSize.Height() ); + BOOL bNegScroll = ( aEffPos.X() < 0 || aEffPos.Y() < 0 ); + BOOL bScroll = bRightScroll || bBottomScroll || bNegScroll; + + SCsCOL nPosX; + SCsROW nPosY; + pViewData->GetPosFromPixel( aEffPos.X(), aEffPos.Y(), GetWhich(), + nPosX, nPosY, TRUE, TRUE ); // mit Repair + + // fuer AutoFill in der Mitte der Zelle umschalten + // dabei aber nicht das Scrolling nach rechts/unten verhindern + if ( pViewData->IsFillMode() || pViewData->GetFillMode() == SC_FILL_MATRIX ) + { + BOOL bLeft, bTop; + pViewData->GetMouseQuadrant( aEffPos, GetWhich(), nPosX, nPosY, bLeft, bTop ); + ScDocument* pDoc = pViewData->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + if ( bLeft && !bRightScroll ) + do --nPosX; while ( nPosX>=0 && pDoc->ColHidden( nPosX, nTab ) ); + if ( bTop && !bBottomScroll ) + { + if (--nPosY >= 0) + { + nPosY = pDoc->LastVisibleRow(0, nPosY, nTab); + if (!ValidRow(nPosY)) + nPosY = -1; + } + } + // negativ ist erlaubt + } + + // ueber Fixier-Grenze bewegt? + + ScSplitPos eWhich = GetWhich(); + if ( eWhich == pViewData->GetActivePart() ) + { + if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ) + if ( aEffPos.X() >= aWinSize.Width() ) + { + if ( eWhich == SC_SPLIT_TOPLEFT ) + pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT ), bScroll = FALSE, bDidSwitch = TRUE; + else if ( eWhich == SC_SPLIT_BOTTOMLEFT ) + pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bScroll = FALSE, bDidSwitch = TRUE; + } + + if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX ) + if ( aEffPos.Y() >= aWinSize.Height() ) + { + if ( eWhich == SC_SPLIT_TOPLEFT ) + pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT ), bScroll = FALSE, bDidSwitch = TRUE; + else if ( eWhich == SC_SPLIT_TOPRIGHT ) + pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bScroll = FALSE, bDidSwitch = TRUE; + } + } + + pViewData->ResetOldCursor(); + return SetCursorAtCell( nPosX, nPosY, bScroll ); +} + +BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScroll ) +{ + ScTabView* pView = pViewData->GetView(); + SCTAB nTab = pViewData->GetTabNo(); + ScDocument* pDoc = pViewData->GetDocument(); + + if ( pDoc->IsTabProtected(nTab) ) + { + if (nPosX < 0 || nPosY < 0) + return false; + + ScTableProtection* pProtect = pDoc->GetTabProtection(nTab); + bool bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS); + bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS); + + if ( bSkipProtected && bSkipUnprotected ) + return FALSE; + + bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED); + if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) ) + // Don't select this cell! + return FALSE; + } + + ScModule* pScMod = SC_MOD(); + ScTabViewShell* pViewShell = pViewData->GetViewShell(); + bool bRefMode = ( pViewShell ? pViewShell->IsRefInputMode() : false ); + + BOOL bHide = !bRefMode && !pViewData->IsAnyFillMode() && + ( nPosX != (SCsCOL) pViewData->GetCurX() || nPosY != (SCsROW) pViewData->GetCurY() ); + + if (bHide) + pView->HideAllCursors(); + + if (bScroll) + { + if (bRefMode) + { + ScSplitPos eWhich = GetWhich(); + pView->AlignToCursor( nPosX, nPosY, SC_FOLLOW_LINE, &eWhich ); + } + else + pView->AlignToCursor( nPosX, nPosY, SC_FOLLOW_LINE ); + } + + if (bRefMode) + { + // #90910# if no input is possible from this doc, don't move the reference cursor around + if ( !pScMod->IsModalMode(pViewData->GetSfxDocShell()) ) + { + if (!bAnchor) + { + pView->DoneRefMode( TRUE ); + pView->InitRefMode( nPosX, nPosY, pViewData->GetTabNo(), SC_REFTYPE_REF ); + } + + pView->UpdateRef( nPosX, nPosY, pViewData->GetTabNo() ); + } + } + else if (pViewData->IsFillMode() || + (pViewData->GetFillMode() == SC_FILL_MATRIX && (nScFillModeMouseModifier & KEY_MOD1) )) + { + // Wenn eine Matrix angefasst wurde, kann mit Ctrl auf AutoFill zurueckgeschaltet werden + + SCCOL nStartX, nEndX; + SCROW nStartY, nEndY; // Block + SCTAB nDummy; + pViewData->GetSimpleArea( nStartX, nStartY, nDummy, nEndX, nEndY, nDummy ); + + if (pViewData->GetRefType() != SC_REFTYPE_FILL) + { + pView->InitRefMode( nStartX, nStartY, nTab, SC_REFTYPE_FILL ); + CreateAnchor(); + } + + ScRange aDelRange; + BOOL bOldDelMark = pViewData->GetDelMark( aDelRange ); + + if ( nPosX+1 >= (SCsCOL) nStartX && nPosX <= (SCsCOL) nEndX && + nPosY+1 >= (SCsROW) nStartY && nPosY <= (SCsROW) nEndY && + ( nPosX != nEndX || nPosY != nEndY ) ) // verkleinern ? + { + // Richtung (links oder oben) + + long nSizeX = 0; + for (SCCOL i=nPosX+1; i<=nEndX; i++) + nSizeX += pDoc->GetColWidth( i, nTab ); + long nSizeY = (long) pDoc->GetRowHeight( nPosY+1, nEndY, nTab ); + + SCCOL nDelStartX = nStartX; + SCROW nDelStartY = nStartY; + if ( nSizeX > nSizeY ) + nDelStartX = nPosX + 1; + else + nDelStartY = nPosY + 1; + // 0 braucht nicht mehr getrennt abgefragt zu werden, weil nPosX/Y auch negativ wird + + if ( nDelStartX < nStartX ) + nDelStartX = nStartX; + if ( nDelStartY < nStartY ) + nDelStartY = nStartY; + + // Bereich setzen + + pViewData->SetDelMark( ScRange( nDelStartX,nDelStartY,nTab, + nEndX,nEndY,nTab ) ); + pViewData->GetView()->UpdateShrinkOverlay(); + +#if 0 + if ( bOldDelMark ) + { + ScUpdateRect aRect( aDelRange.aStart.Col(), aDelRange.aStart.Row(), + aDelRange.aEnd.Col(), aDelRange.aEnd.Row() ); + aRect.SetNew( nDelStartX,nDelStartY, nEndX,nEndY ); + SCCOL nPaintStartX; + SCROW nPaintStartY; + SCCOL nPaintEndX; + SCROW nPaintEndY; + if (aRect.GetDiff( nPaintStartX, nPaintStartY, nPaintEndX, nPaintEndY )) + pViewData->GetView()-> + PaintArea( nPaintStartX, nPaintStartY, + nPaintEndX, nPaintEndY, SC_UPDATE_MARKS ); + } + else +#endif + pViewData->GetView()-> + PaintArea( nStartX,nDelStartY, nEndX,nEndY, SC_UPDATE_MARKS ); + + nPosX = nEndX; // roten Rahmen um ganzen Bereich lassen + nPosY = nEndY; + + // Referenz wieder richtigherum, falls unten umgedreht + if ( nStartX != pViewData->GetRefStartX() || nStartY != pViewData->GetRefStartY() ) + { + pViewData->GetView()->DoneRefMode(); + pViewData->GetView()->InitRefMode( nStartX, nStartY, nTab, SC_REFTYPE_FILL ); + } + } + else + { + if ( bOldDelMark ) + { + pViewData->ResetDelMark(); + pViewData->GetView()->UpdateShrinkOverlay(); + +#if 0 + pViewData->GetView()-> + PaintArea( aDelRange.aStart.Col(), aDelRange.aStart.Row(), + aDelRange.aEnd.Col(), aDelRange.aEnd.Row(), SC_UPDATE_MARKS ); +#endif + } + + BOOL bNegX = ( nPosX < (SCsCOL) nStartX ); + BOOL bNegY = ( nPosY < (SCsROW) nStartY ); + + long nSizeX = 0; + if ( bNegX ) + { + // #94321# in SetCursorAtPoint hidden columns are skipped. + // They must be skipped here too, or the result will always be the first hidden column. + do ++nPosX; while ( nPosX<nStartX && pDoc->ColHidden(nPosX, nTab) ); + for (SCCOL i=nPosX; i<nStartX; i++) + nSizeX += pDoc->GetColWidth( i, nTab ); + } + else + for (SCCOL i=nEndX+1; i<=nPosX; i++) + nSizeX += pDoc->GetColWidth( i, nTab ); + + long nSizeY = 0; + if ( bNegY ) + { + // #94321# in SetCursorAtPoint hidden rows are skipped. + // They must be skipped here too, or the result will always be the first hidden row. + if (++nPosY < nStartY) + { + nPosY = pDoc->FirstVisibleRow(nPosY, nStartY-1, nTab); + if (!ValidRow(nPosY)) + nPosY = nStartY; + } + nSizeY += pDoc->GetRowHeight( nPosY, nStartY-1, nTab ); + } + else + nSizeY += pDoc->GetRowHeight( nEndY+1, nPosY, nTab ); + + if ( nSizeX > nSizeY ) // Fill immer nur in einer Richtung + { + nPosY = nEndY; + bNegY = FALSE; + } + else + { + nPosX = nEndX; + bNegX = FALSE; + } + + SCCOL nRefStX = bNegX ? nEndX : nStartX; + SCROW nRefStY = bNegY ? nEndY : nStartY; + if ( nRefStX != pViewData->GetRefStartX() || nRefStY != pViewData->GetRefStartY() ) + { + pViewData->GetView()->DoneRefMode(); + pViewData->GetView()->InitRefMode( nRefStX, nRefStY, nTab, SC_REFTYPE_FILL ); + } + } + + pView->UpdateRef( nPosX, nPosY, nTab ); + } + else if (pViewData->IsAnyFillMode()) + { + BYTE nMode = pViewData->GetFillMode(); + if ( nMode == SC_FILL_EMBED_LT || nMode == SC_FILL_EMBED_RB ) + { + DBG_ASSERT( pDoc->IsEmbedded(), "!pDoc->IsEmbedded()" ); + ScRange aRange; + pDoc->GetEmbedded( aRange); + ScRefType eRefMode = (nMode == SC_FILL_EMBED_LT) ? SC_REFTYPE_EMBED_LT : SC_REFTYPE_EMBED_RB; + if (pViewData->GetRefType() != eRefMode) + { + if ( nMode == SC_FILL_EMBED_LT ) + pView->InitRefMode( aRange.aEnd.Col(), aRange.aEnd.Row(), nTab, eRefMode ); + else + pView->InitRefMode( aRange.aStart.Col(), aRange.aStart.Row(), nTab, eRefMode ); + CreateAnchor(); + } + + pView->UpdateRef( nPosX, nPosY, nTab ); + } + else if ( nMode == SC_FILL_MATRIX ) + { + SCCOL nStartX, nEndX; + SCROW nStartY, nEndY; // Block + SCTAB nDummy; + pViewData->GetSimpleArea( nStartX, nStartY, nDummy, nEndX, nEndY, nDummy ); + + if (pViewData->GetRefType() != SC_REFTYPE_FILL) + { + pView->InitRefMode( nStartX, nStartY, nTab, SC_REFTYPE_FILL ); + CreateAnchor(); + } + + if ( nPosX < nStartX ) nPosX = nStartX; + if ( nPosY < nStartY ) nPosY = nStartY; + + pView->UpdateRef( nPosX, nPosY, nTab ); + } + // else neue Modi + } + else // normales Markieren + { + BOOL bHideCur = bAnchor && ( (SCCOL)nPosX != pViewData->GetCurX() || + (SCROW)nPosY != pViewData->GetCurY() ); + if (bHideCur) + pView->HideAllCursors(); // sonst zweimal: Block und SetCursor + + if (bAnchor) + { + if (!bStarted) + { + BOOL bMove = ( nPosX != (SCsCOL) aAnchorPos.Col() || + nPosY != (SCsROW) aAnchorPos.Row() ); + if ( bMove || ( pEngine && pEngine->GetMouseEvent().IsShift() ) ) + { + pView->InitBlockMode( aAnchorPos.Col(), aAnchorPos.Row(), + aAnchorPos.Tab(), TRUE ); + bStarted = TRUE; + } + } + if (bStarted) + pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab, FALSE, FALSE, TRUE ); + } + else + { + ScMarkData& rMark = pViewData->GetMarkData(); + if (rMark.IsMarked() || rMark.IsMultiMarked()) + { + pView->DoneBlockMode(TRUE); + pView->InitBlockMode( nPosX, nPosY, nTab, TRUE ); + pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab ); + + aAnchorPos.Set( nPosX, nPosY, nTab ); + bStarted = TRUE; + } + // #i3875# *Hack* When a new cell is Ctrl-clicked with no pre-selected cells, + // it highlights that new cell as well as the old cell where the cursor is + // positioned prior to the click. A selection mode via Shift-F8 should also + // follow the same behavior. + else if ( pViewData->IsSelCtrlMouseClick() ) + { + SCCOL nOldX = pViewData->GetCurX(); + SCROW nOldY = pViewData->GetCurY(); + + pView->InitBlockMode( nOldX, nOldY, nTab, TRUE ); + pView->MarkCursor( (SCCOL) nOldX, (SCROW) nOldY, nTab ); + + if ( nOldX != nPosX || nOldY != nPosY ) + { + pView->DoneBlockMode( TRUE ); + pView->InitBlockMode( nPosX, nPosY, nTab, TRUE ); + pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab ); + aAnchorPos.Set( nPosX, nPosY, nTab ); + } + + bStarted = TRUE; + } + } + + pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY ); + pViewData->SetRefStart( nPosX, nPosY, nTab ); + if (bHideCur) + pView->ShowAllCursors(); + } + + if (bHide) + pView->ShowAllCursors(); + + return TRUE; +} + +BOOL __EXPORT ScViewFunctionSet::IsSelectionAtPoint( const Point& rPointPixel ) +{ + BOOL bRefMode = SC_MOD()->IsFormulaMode(); + if (bRefMode) + return FALSE; + + if (pViewData->IsAnyFillMode()) + return FALSE; + + ScMarkData& rMark = pViewData->GetMarkData(); + if (bAnchor || !rMark.IsMultiMarked()) + { + SCsCOL nPosX; + SCsROW nPosY; + pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), GetWhich(), nPosX, nPosY ); + return pViewData->GetMarkData().IsCellMarked( (SCCOL) nPosX, (SCROW) nPosY ); + } + + return FALSE; +} + +void __EXPORT ScViewFunctionSet::DeselectAtPoint( const Point& /* rPointPixel */ ) +{ + // gibt's nicht +} + +void __EXPORT ScViewFunctionSet::DeselectAll() +{ + if (pViewData->IsAnyFillMode()) + return; + + BOOL bRefMode = SC_MOD()->IsFormulaMode(); + if (bRefMode) + { + pViewData->GetView()->DoneRefMode( FALSE ); + } + else + { + pViewData->GetView()->DoneBlockMode( FALSE ); + pViewData->GetViewShell()->UpdateInputHandler(); + } + + bAnchor = FALSE; +} + +//------------------------------------------------------------------------ + +ScViewSelectionEngine::ScViewSelectionEngine( Window* pWindow, ScTabView* pView, + ScSplitPos eSplitPos ) : + SelectionEngine( pWindow, pView->GetFunctionSet() ), + eWhich( eSplitPos ) +{ + // Parameter einstellen + SetSelectionMode( MULTIPLE_SELECTION ); + EnableDrag( TRUE ); +} + + +//------------------------------------------------------------------------ + +// +// Spalten- / Zeilenheader +// + +ScHeaderFunctionSet::ScHeaderFunctionSet( ScViewData* pNewViewData ) : + pViewData( pNewViewData ), + bColumn( FALSE ), + eWhich( SC_SPLIT_TOPLEFT ), + bAnchor( FALSE ), + nCursorPos( 0 ) +{ + DBG_ASSERT(pViewData, "ViewData==0 bei FunctionSet"); +} + +void ScHeaderFunctionSet::SetColumn( BOOL bSet ) +{ + bColumn = bSet; +} + +void ScHeaderFunctionSet::SetWhich( ScSplitPos eNew ) +{ + eWhich = eNew; +} + +void __EXPORT ScHeaderFunctionSet::BeginDrag() +{ + // gippsnich +} + +void __EXPORT ScHeaderFunctionSet::CreateAnchor() +{ + if (bAnchor) + return; + + ScTabView* pView = pViewData->GetView(); + pView->DoneBlockMode( TRUE ); + if (bColumn) + { + pView->InitBlockMode( static_cast<SCCOL>(nCursorPos), 0, pViewData->GetTabNo(), TRUE, TRUE, FALSE ); + pView->MarkCursor( static_cast<SCCOL>(nCursorPos), MAXROW, pViewData->GetTabNo() ); + } + else + { + pView->InitBlockMode( 0, nCursorPos, pViewData->GetTabNo(), TRUE, FALSE, TRUE ); + pView->MarkCursor( MAXCOL, nCursorPos, pViewData->GetTabNo() ); + } + bAnchor = TRUE; +} + +void __EXPORT ScHeaderFunctionSet::DestroyAnchor() +{ + pViewData->GetView()->DoneBlockMode( TRUE ); + bAnchor = FALSE; +} + +BOOL __EXPORT ScHeaderFunctionSet::SetCursorAtPoint( const Point& rPointPixel, BOOL /* bDontSelectAtCursor */ ) +{ + if ( bDidSwitch ) + { + // die naechste gueltige Position muss vom anderen Fenster kommen + if ( rPointPixel == aSwitchPos ) + return FALSE; // nicht auf falschem Fenster scrollen + else + bDidSwitch = FALSE; + } + + // Scrolling + + Size aWinSize = pViewData->GetActiveWin()->GetOutputSizePixel(); + BOOL bScroll; + if (bColumn) + bScroll = ( rPointPixel.X() < 0 || rPointPixel.X() >= aWinSize.Width() ); + else + bScroll = ( rPointPixel.Y() < 0 || rPointPixel.Y() >= aWinSize.Height() ); + + // ueber Fixier-Grenze bewegt? + + BOOL bSwitched = FALSE; + if ( bColumn ) + { + if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ) + { + if ( rPointPixel.X() > aWinSize.Width() ) + { + if ( eWhich == SC_SPLIT_TOPLEFT ) + pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT ), bSwitched = TRUE; + else if ( eWhich == SC_SPLIT_BOTTOMLEFT ) + pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bSwitched = TRUE; + } + } + } + else // Zeilenkoepfe + { + if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX ) + { + if ( rPointPixel.Y() > aWinSize.Height() ) + { + if ( eWhich == SC_SPLIT_TOPLEFT ) + pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT ), bSwitched = TRUE; + else if ( eWhich == SC_SPLIT_TOPRIGHT ) + pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bSwitched = TRUE; + } + } + } + if (bSwitched) + { + aSwitchPos = rPointPixel; + bDidSwitch = TRUE; + return FALSE; // nicht mit falschen Positionen rechnen + } + + // + + SCsCOL nPosX; + SCsROW nPosY; + pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), pViewData->GetActivePart(), + nPosX, nPosY, FALSE ); + if (bColumn) + { + nCursorPos = static_cast<SCCOLROW>(nPosX); + nPosY = pViewData->GetPosY(WhichV(pViewData->GetActivePart())); + } + else + { + nCursorPos = static_cast<SCCOLROW>(nPosY); + nPosX = pViewData->GetPosX(WhichH(pViewData->GetActivePart())); + } + + ScTabView* pView = pViewData->GetView(); + BOOL bHide = pViewData->GetCurX() != nPosX || + pViewData->GetCurY() != nPosY; + if (bHide) + pView->HideAllCursors(); + + if (bScroll) + pView->AlignToCursor( nPosX, nPosY, SC_FOLLOW_LINE ); + pView->SetCursor( nPosX, nPosY ); + + if ( !bAnchor || !pView->IsBlockMode() ) + { + pView->DoneBlockMode( TRUE ); + pViewData->GetMarkData().MarkToMulti(); //! wer verstellt das ??? + pView->InitBlockMode( nPosX, nPosY, pViewData->GetTabNo(), TRUE, bColumn, !bColumn ); + + bAnchor = TRUE; + } + + pView->MarkCursor( nPosX, nPosY, pViewData->GetTabNo(), bColumn, !bColumn ); + + // SelectionChanged innerhalb von HideCursor wegen UpdateAutoFillMark + pView->SelectionChanged(); + + if (bHide) + pView->ShowAllCursors(); + + return TRUE; +} + +BOOL __EXPORT ScHeaderFunctionSet::IsSelectionAtPoint( const Point& rPointPixel ) +{ + SCsCOL nPosX; + SCsROW nPosY; + pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), pViewData->GetActivePart(), + nPosX, nPosY, FALSE ); + + ScMarkData& rMark = pViewData->GetMarkData(); + if (bColumn) + return rMark.IsColumnMarked( nPosX ); + else + return rMark.IsRowMarked( nPosY ); +} + +void __EXPORT ScHeaderFunctionSet::DeselectAtPoint( const Point& /* rPointPixel */ ) +{ +} + +void __EXPORT ScHeaderFunctionSet::DeselectAll() +{ + pViewData->GetView()->DoneBlockMode( FALSE ); + bAnchor = FALSE; +} + +//------------------------------------------------------------------------ + +ScHeaderSelectionEngine::ScHeaderSelectionEngine( Window* pWindow, ScHeaderFunctionSet* pFuncSet ) : + SelectionEngine( pWindow, pFuncSet ) +{ + // Parameter einstellen + SetSelectionMode( MULTIPLE_SELECTION ); + EnableDrag( FALSE ); +} + + + + + |