| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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 sal_uInt16 nScFillModeMouseModifier; // global.cxx |
| |
| using namespace com::sun::star; |
| |
| // STATIC DATA ----------------------------------------------------------- |
| |
| static Point aSwitchPos; //! Member |
| static sal_Bool bDidSwitch = sal_False; |
| |
| // ----------------------------------------------------------------------- |
| |
| // |
| // View (Gridwin / Tastatur) |
| // |
| |
| ScViewFunctionSet::ScViewFunctionSet( ScViewData* pNewViewData ) : |
| pViewData( pNewViewData ), |
| pEngine( NULL ), |
| bAnchor( sal_False ), |
| bStarted( sal_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(); |
| sal_Bool bRefMode = pScMod->IsFormulaMode(); |
| if (!bRefMode) |
| { |
| pViewData->GetView()->FakeButtonUp( GetWhich() ); // ButtonUp wird verschluckt |
| |
| ScMarkData& rMark = pViewData->GetMarkData(); |
| // rMark.SetMarking(sal_False); // es fehlt ein ButtonUp |
| rMark.MarkToSimple(); |
| if ( rMark.IsMarked() && !rMark.IsMultiMarked() ) |
| { |
| ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); |
| // bApi = sal_True -> no error mesages |
| sal_Bool bCopied = pViewData->GetView()->CopyToClip( pClipDoc, sal_False, sal_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; |
| |
| sal_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 ) |
| { |
| sal_Bool bRefMode = SC_MOD()->IsFormulaMode(); |
| ScTabView* pView = pViewData->GetView(); |
| SCTAB nTab = pViewData->GetTabNo(); |
| |
| if (bRefMode) |
| { |
| pView->DoneRefMode( sal_False ); |
| aAnchorPos.Set( nPosX, nPosY, nTab ); |
| pView->InitRefMode( aAnchorPos.Col(), aAnchorPos.Row(), aAnchorPos.Tab(), |
| SC_REFTYPE_REF ); |
| bStarted = sal_True; |
| } |
| else if (pViewData->IsAnyFillMode()) |
| { |
| aAnchorPos.Set( nPosX, nPosY, nTab ); |
| bStarted = sal_True; |
| } |
| else |
| { |
| // nicht weg und gleich wieder hin |
| if ( bStarted && pView->IsMarking( nPosX, nPosY, nTab ) ) |
| { |
| // nix |
| } |
| else |
| { |
| pView->DoneBlockMode( sal_True ); |
| aAnchorPos.Set( nPosX, nPosY, nTab ); |
| ScMarkData& rMark = pViewData->GetMarkData(); |
| if ( rMark.IsMarked() || rMark.IsMultiMarked() ) |
| { |
| pView->InitBlockMode( aAnchorPos.Col(), aAnchorPos.Row(), |
| aAnchorPos.Tab(), sal_True ); |
| bStarted = sal_True; |
| } |
| else |
| bStarted = sal_False; |
| } |
| } |
| bAnchor = sal_True; |
| } |
| |
| void __EXPORT ScViewFunctionSet::DestroyAnchor() |
| { |
| sal_Bool bRefMode = SC_MOD()->IsFormulaMode(); |
| if (bRefMode) |
| pViewData->GetView()->DoneRefMode( sal_True ); |
| else |
| pViewData->GetView()->DoneBlockMode( sal_True ); |
| |
| bAnchor = sal_False; |
| } |
| |
| void ScViewFunctionSet::SetAnchorFlag( sal_Bool bSet ) |
| { |
| bAnchor = bSet; |
| } |
| |
| sal_Bool __EXPORT ScViewFunctionSet::SetCursorAtPoint( const Point& rPointPixel, sal_Bool /* bDontSelectAtCursor */ ) |
| { |
| if ( bDidSwitch ) |
| { |
| if ( rPointPixel == aSwitchPos ) |
| return sal_False; // nicht auf falschem Fenster scrollen |
| else |
| bDidSwitch = sal_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(); |
| sal_Bool bRightScroll = ( aEffPos.X() >= aWinSize.Width() ); |
| sal_Bool bBottomScroll = ( aEffPos.Y() >= aWinSize.Height() ); |
| sal_Bool bNegScroll = ( aEffPos.X() < 0 || aEffPos.Y() < 0 ); |
| sal_Bool bScroll = bRightScroll || bBottomScroll || bNegScroll; |
| |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( aEffPos.X(), aEffPos.Y(), GetWhich(), |
| nPosX, nPosY, sal_True, sal_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 ) |
| { |
| sal_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 = sal_False, bDidSwitch = sal_True; |
| else if ( eWhich == SC_SPLIT_BOTTOMLEFT ) |
| pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bScroll = sal_False, bDidSwitch = sal_True; |
| } |
| |
| if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX ) |
| if ( aEffPos.Y() >= aWinSize.Height() ) |
| { |
| if ( eWhich == SC_SPLIT_TOPLEFT ) |
| pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT ), bScroll = sal_False, bDidSwitch = sal_True; |
| else if ( eWhich == SC_SPLIT_TOPRIGHT ) |
| pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bScroll = sal_False, bDidSwitch = sal_True; |
| } |
| } |
| |
| pViewData->ResetOldCursor(); |
| return SetCursorAtCell( nPosX, nPosY, bScroll ); |
| } |
| |
| sal_Bool ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, sal_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 sal_False; |
| |
| bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED); |
| if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) ) |
| // Don't select this cell! |
| return sal_False; |
| } |
| |
| ScModule* pScMod = SC_MOD(); |
| ScTabViewShell* pViewShell = pViewData->GetViewShell(); |
| bool bRefMode = ( pViewShell ? pViewShell->IsRefInputMode() : false ); |
| |
| sal_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( sal_True ); |
| pView->InitRefMode( nPosX, nPosY, pViewData->GetTabNo(), SC_REFTYPE_REF ); |
| } |
| |
| pView->UpdateRef( nPosX, nPosY, pViewData->GetTabNo() ); |
| pView->SelectionChanged(); |
| } |
| } |
| 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; |
| sal_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 |
| } |
| |
| sal_Bool bNegX = ( nPosX < (SCsCOL) nStartX ); |
| sal_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 = sal_False; |
| } |
| else |
| { |
| nPosX = nEndX; |
| bNegX = sal_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()) |
| { |
| sal_uInt8 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 |
| { |
| sal_Bool bHideCur = bAnchor && ( (SCCOL)nPosX != pViewData->GetCurX() || |
| (SCROW)nPosY != pViewData->GetCurY() ); |
| if (bHideCur) |
| pView->HideAllCursors(); // sonst zweimal: Block und SetCursor |
| |
| if (bAnchor) |
| { |
| if (!bStarted) |
| { |
| sal_Bool bMove = ( nPosX != (SCsCOL) aAnchorPos.Col() || |
| nPosY != (SCsROW) aAnchorPos.Row() ); |
| if ( bMove || ( pEngine && pEngine->GetMouseEvent().IsShift() ) ) |
| { |
| pView->InitBlockMode( aAnchorPos.Col(), aAnchorPos.Row(), |
| aAnchorPos.Tab(), sal_True ); |
| bStarted = sal_True; |
| } |
| } |
| if (bStarted) |
| pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab, sal_False, sal_False, sal_True ); |
| } |
| else |
| { |
| ScMarkData& rMark = pViewData->GetMarkData(); |
| if (rMark.IsMarked() || rMark.IsMultiMarked()) |
| { |
| pView->DoneBlockMode(sal_True); |
| pView->InitBlockMode( nPosX, nPosY, nTab, sal_True ); |
| pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab ); |
| |
| aAnchorPos.Set( nPosX, nPosY, nTab ); |
| bStarted = sal_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, sal_True ); |
| pView->MarkCursor( (SCCOL) nOldX, (SCROW) nOldY, nTab ); |
| |
| if ( nOldX != nPosX || nOldY != nPosY ) |
| { |
| pView->DoneBlockMode( sal_True ); |
| pView->InitBlockMode( nPosX, nPosY, nTab, sal_True ); |
| pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab ); |
| aAnchorPos.Set( nPosX, nPosY, nTab ); |
| } |
| |
| bStarted = sal_True; |
| } |
| } |
| |
| pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY ); |
| pViewData->SetRefStart( nPosX, nPosY, nTab ); |
| if (bHideCur) |
| pView->ShowAllCursors(); |
| } |
| |
| if (bHide) |
| pView->ShowAllCursors(); |
| |
| return sal_True; |
| } |
| |
| sal_Bool __EXPORT ScViewFunctionSet::IsSelectionAtPoint( const Point& rPointPixel ) |
| { |
| sal_Bool bRefMode = SC_MOD()->IsFormulaMode(); |
| if (bRefMode) |
| return sal_False; |
| |
| if (pViewData->IsAnyFillMode()) |
| return sal_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 sal_False; |
| } |
| |
| void __EXPORT ScViewFunctionSet::DeselectAtPoint( const Point& /* rPointPixel */ ) |
| { |
| // gibt's nicht |
| } |
| |
| void __EXPORT ScViewFunctionSet::DeselectAll() |
| { |
| if (pViewData->IsAnyFillMode()) |
| return; |
| |
| sal_Bool bRefMode = SC_MOD()->IsFormulaMode(); |
| if (bRefMode) |
| { |
| pViewData->GetView()->DoneRefMode( sal_False ); |
| } |
| else |
| { |
| pViewData->GetView()->DoneBlockMode( sal_False ); |
| pViewData->GetViewShell()->UpdateInputHandler(); |
| } |
| |
| bAnchor = sal_False; |
| } |
| |
| //------------------------------------------------------------------------ |
| |
| ScViewSelectionEngine::ScViewSelectionEngine( Window* pWindow, ScTabView* pView, |
| ScSplitPos eSplitPos ) : |
| SelectionEngine( pWindow, pView->GetFunctionSet() ), |
| eWhich( eSplitPos ) |
| { |
| // Parameter einstellen |
| SetSelectionMode( MULTIPLE_SELECTION ); |
| EnableDrag( sal_True ); |
| } |
| |
| |
| //------------------------------------------------------------------------ |
| |
| // |
| // Spalten- / Zeilenheader |
| // |
| |
| ScHeaderFunctionSet::ScHeaderFunctionSet( ScViewData* pNewViewData ) : |
| pViewData( pNewViewData ), |
| bColumn( sal_False ), |
| eWhich( SC_SPLIT_TOPLEFT ), |
| bAnchor( sal_False ), |
| nCursorPos( 0 ) |
| { |
| DBG_ASSERT(pViewData, "ViewData==0 bei FunctionSet"); |
| } |
| |
| void ScHeaderFunctionSet::SetColumn( sal_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( sal_True ); |
| if (bColumn) |
| { |
| pView->InitBlockMode( static_cast<SCCOL>(nCursorPos), 0, pViewData->GetTabNo(), sal_True, sal_True, sal_False ); |
| pView->MarkCursor( static_cast<SCCOL>(nCursorPos), MAXROW, pViewData->GetTabNo() ); |
| } |
| else |
| { |
| pView->InitBlockMode( 0, nCursorPos, pViewData->GetTabNo(), sal_True, sal_False, sal_True ); |
| pView->MarkCursor( MAXCOL, nCursorPos, pViewData->GetTabNo() ); |
| } |
| bAnchor = sal_True; |
| } |
| |
| void __EXPORT ScHeaderFunctionSet::DestroyAnchor() |
| { |
| pViewData->GetView()->DoneBlockMode( sal_True ); |
| bAnchor = sal_False; |
| } |
| |
| sal_Bool __EXPORT ScHeaderFunctionSet::SetCursorAtPoint( const Point& rPointPixel, sal_Bool /* bDontSelectAtCursor */ ) |
| { |
| if ( bDidSwitch ) |
| { |
| // die naechste gueltige Position muss vom anderen Fenster kommen |
| if ( rPointPixel == aSwitchPos ) |
| return sal_False; // nicht auf falschem Fenster scrollen |
| else |
| bDidSwitch = sal_False; |
| } |
| |
| // Scrolling |
| |
| Size aWinSize = pViewData->GetActiveWin()->GetOutputSizePixel(); |
| sal_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? |
| |
| sal_Bool bSwitched = sal_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 = sal_True; |
| else if ( eWhich == SC_SPLIT_BOTTOMLEFT ) |
| pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bSwitched = sal_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 = sal_True; |
| else if ( eWhich == SC_SPLIT_TOPRIGHT ) |
| pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bSwitched = sal_True; |
| } |
| } |
| } |
| if (bSwitched) |
| { |
| aSwitchPos = rPointPixel; |
| bDidSwitch = sal_True; |
| return sal_False; // nicht mit falschen Positionen rechnen |
| } |
| |
| // |
| |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), pViewData->GetActivePart(), |
| nPosX, nPosY, sal_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(); |
| sal_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( sal_True ); |
| pViewData->GetMarkData().MarkToMulti(); //! wer verstellt das ??? |
| pView->InitBlockMode( nPosX, nPosY, pViewData->GetTabNo(), sal_True, bColumn, !bColumn ); |
| |
| bAnchor = sal_True; |
| } |
| |
| pView->MarkCursor( nPosX, nPosY, pViewData->GetTabNo(), bColumn, !bColumn ); |
| |
| // SelectionChanged innerhalb von HideCursor wegen UpdateAutoFillMark |
| pView->SelectionChanged(); |
| |
| if (bHide) |
| pView->ShowAllCursors(); |
| |
| return sal_True; |
| } |
| |
| sal_Bool __EXPORT ScHeaderFunctionSet::IsSelectionAtPoint( const Point& rPointPixel ) |
| { |
| SCsCOL nPosX; |
| SCsROW nPosY; |
| pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), pViewData->GetActivePart(), |
| nPosX, nPosY, sal_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( sal_False ); |
| bAnchor = sal_False; |
| } |
| |
| //------------------------------------------------------------------------ |
| |
| ScHeaderSelectionEngine::ScHeaderSelectionEngine( Window* pWindow, ScHeaderFunctionSet* pFuncSet ) : |
| SelectionEngine( pWindow, pFuncSet ) |
| { |
| // Parameter einstellen |
| SetSelectionMode( MULTIPLE_SELECTION ); |
| EnableDrag( sal_False ); |
| } |
| |
| |
| |
| |
| |