diff options
Diffstat (limited to 'sc/source/ui')
-rw-r--r-- | sc/source/ui/docshell/arealink.cxx | 6 | ||||
-rw-r--r-- | sc/source/ui/docshell/docfunc.cxx | 5 | ||||
-rw-r--r-- | sc/source/ui/inc/cellsh.hxx | 3 | ||||
-rw-r--r-- | sc/source/ui/inc/viewfunc.hxx | 5 | ||||
-rw-r--r-- | sc/source/ui/navipi/content.cxx | 6 | ||||
-rw-r--r-- | sc/source/ui/undo/undoblk.cxx | 6 | ||||
-rw-r--r-- | sc/source/ui/unoobj/funcuno.cxx | 6 | ||||
-rw-r--r-- | sc/source/ui/view/cellsh.cxx | 1 | ||||
-rw-r--r-- | sc/source/ui/view/cellsh1.cxx | 84 | ||||
-rw-r--r-- | sc/source/ui/view/tabcont.cxx | 4 | ||||
-rw-r--r-- | sc/source/ui/view/tabvwsh4.cxx | 2 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun3.cxx | 382 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun5.cxx | 9 |
13 files changed, 436 insertions, 83 deletions
diff --git a/sc/source/ui/docshell/arealink.cxx b/sc/source/ui/docshell/arealink.cxx index a290a81d9078..a9e5f7ce8218 100644 --- a/sc/source/ui/docshell/arealink.cxx +++ b/sc/source/ui/docshell/arealink.cxx @@ -63,6 +63,7 @@ #include "sc.hrc" //CHINA001 #include "scabstdlg.hxx" //CHINA001 +#include "clipparam.hxx" struct AreaLink_Impl { @@ -389,9 +390,8 @@ BOOL ScAreaLink::Refresh( const String& rNewFile, const String& rNewFilter, aSourceMark.SelectOneTable( nSrcTab ); // selektieren fuer CopyToClip aSourceMark.SetMarkArea( aTokenRange ); - pSrcDoc->CopyToClip( aTokenRange.aStart.Col(), aTokenRange.aStart.Row(), - aTokenRange.aEnd.Col(), aTokenRange.aEnd.Row(), - FALSE, &aClipDoc, FALSE, &aSourceMark ); + ScClipParam aClipParam(aTokenRange, false); + pSrcDoc->CopyToClip(aClipParam, &aClipDoc, &aSourceMark); if ( aClipDoc.HasAttrib( 0,0,nSrcTab, MAXCOL,MAXROW,nSrcTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) ) diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 424e4731a324..608c1c688ea9 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -94,6 +94,7 @@ #include "compiler.hxx" #include "scui_def.hxx" //CHINA001 #include "tabprotection.hxx" +#include "clipparam.hxx" #include <memory> @@ -2276,8 +2277,8 @@ BOOL ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos, } ScDrawLayer::SetGlobalDrawPersist(aDragShellRef); - pDoc->CopyToClip( nStartCol, nStartRow, nEndCol, nEndRow, bCut, pClipDoc, - FALSE, &aSourceMark, bScenariosAdded, TRUE ); + ScClipParam aClipParam(ScRange(nStartCol, nStartRow, 0, nEndCol, nEndRow, 0), false); + pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bScenariosAdded, true); ScDrawLayer::SetGlobalDrawPersist(NULL); diff --git a/sc/source/ui/inc/cellsh.hxx b/sc/source/ui/inc/cellsh.hxx index 8e09b7350bb1..90adbe40d2d2 100644 --- a/sc/source/ui/inc/cellsh.hxx +++ b/sc/source/ui/inc/cellsh.hxx @@ -42,6 +42,7 @@ class SvxClipboardFmtItem; class TransferableDataHelper; class TransferableClipboardListener; class AbstractScLinkedAreaDlg; +class ScTabViewShell; struct CellShell_Impl { @@ -101,6 +102,8 @@ public: void ExecutePageSel( SfxRequest& rReq ); void ExecuteMove( SfxRequest& rReq ); void GetStateCursor( SfxItemSet& rSet ); + + static void PasteFromClipboard( ScViewData* pViewData, ScTabViewShell* pTabViewShell, bool bShowDialog ); }; #endif diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index 228c4b4c1489..066aadca817a 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -348,6 +348,11 @@ private: void PasteRTF( SCCOL nCol, SCROW nStartRow, const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& rxTransferable ); + bool PasteMultiRangesFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction, + bool bSkipEmpty, bool bTranspos, bool bAsLink, bool bAllowDialogs, + InsCellCmd eMoveMode, sal_uInt16 nCondFlags, sal_uInt16 nUndoFlags ); + void PostPasteFromClip(const ScRange& rPasteRange, const ScMarkData& rMark); + USHORT GetOptimalColWidth( SCCOL nCol, SCTAB nTab, BOOL bFormula ); void StartFormatArea(); diff --git a/sc/source/ui/navipi/content.cxx b/sc/source/ui/navipi/content.cxx index a2db7e4e48f0..af3b5f0dee5e 100644 --- a/sc/source/ui/navipi/content.cxx +++ b/sc/source/ui/navipi/content.cxx @@ -71,6 +71,7 @@ #include "navicfg.hxx" #include "navsett.hxx" #include "postit.hxx" +#include "clipparam.hxx" using namespace com::sun::star; @@ -1103,9 +1104,8 @@ void lcl_DoDragCells( ScDocShell* pSrcShell, const ScRange& rRange, USHORT nFlag aMark ) ) { ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); - pSrcDoc->CopyToClip( rRange.aStart.Col(), rRange.aStart.Row(), - rRange.aEnd.Col(), rRange.aEnd.Row(), - FALSE, pClipDoc, FALSE, &aMark ); + ScClipParam aClipParam(rRange, false); + pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aMark); // pClipDoc->ExtendMerge( rRange, TRUE ); TransferableObjectDescriptor aObjDesc; diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx index e44f5e7a6478..3df8e99348c0 100644 --- a/sc/source/ui/undo/undoblk.cxx +++ b/sc/source/ui/undo/undoblk.cxx @@ -64,6 +64,7 @@ #include "transobj.hxx" #include "refundo.hxx" #include "undoolk.hxx" +#include "clipparam.hxx" #include "sc.hrc" @@ -1316,9 +1317,8 @@ void __EXPORT ScUndoDragDrop::Redo() aSourceMark.SelectTable( nTab, TRUE ); // do not clone objects and note captions into clipdoc (see above) - pDoc->CopyToClip( aSrcRange.aStart.Col(), aSrcRange.aStart.Row(), - aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row(), - bCut, pClipDoc, FALSE, &aSourceMark, bKeepScenarioFlags, FALSE, FALSE ); + ScClipParam aClipParam(aSrcRange, bCut); + pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bKeepScenarioFlags, false, false); if (bCut) { diff --git a/sc/source/ui/unoobj/funcuno.cxx b/sc/source/ui/unoobj/funcuno.cxx index 1d9f3a1d9213..a50b4003b0ac 100644 --- a/sc/source/ui/unoobj/funcuno.cxx +++ b/sc/source/ui/unoobj/funcuno.cxx @@ -57,6 +57,7 @@ #include "patattr.hxx" #include "docpool.hxx" #include "attrib.hxx" +#include "clipparam.hxx" using namespace com::sun::star; @@ -175,9 +176,8 @@ BOOL lcl_CopyData( ScDocument* pSrcDoc, const ScRange& rSrcRange, ScMarkData aSourceMark; aSourceMark.SelectOneTable( nSrcTab ); // for CopyToClip aSourceMark.SetMarkArea( rSrcRange ); - pSrcDoc->CopyToClip( rSrcRange.aStart.Col(),rSrcRange.aStart.Row(), - rSrcRange.aEnd.Col(),rSrcRange.aEnd.Row(), - FALSE, pClipDoc, FALSE, &aSourceMark ); + ScClipParam aClipParam(rSrcRange, false); + pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false); if ( pClipDoc->HasAttrib( 0,0,nSrcTab, MAXCOL,MAXROW,nSrcTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) ) diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx index 54c8ff12e189..722885363346 100644 --- a/sc/source/ui/view/cellsh.cxx +++ b/sc/source/ui/view/cellsh.cxx @@ -206,7 +206,6 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet ) break; case SID_COPY: // Kopieren - bDisable = (!bSimpleArea && eMarkType != SC_MARK_SIMPLE_FILTERED); // nur wegen Matrix nicht editierbar? Matrix nicht zerreissen //! schlaegt nicht zu, wenn geschuetzt UND Matrix, aber damit //! muss man leben.. wird in Copy-Routine abgefangen, sonst diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx index e5bb702402d8..7f632f62c2ba 100644 --- a/sc/source/ui/view/cellsh1.cxx +++ b/sc/source/ui/view/cellsh1.cxx @@ -104,6 +104,7 @@ #include "dpgroup.hxx" // for ScDPNumGroupInfo #include "spellparam.hxx" #include "postit.hxx" +#include "clipparam.hxx" #include "globstr.hrc" #include "scui_def.hxx" //CHINA001 @@ -1182,41 +1183,9 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) case SID_PASTE: { - Window* pWin = GetViewData()->GetActiveWin(); - ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin ); - ScDocument* pThisDoc = GetViewData()->GetDocument(); - ScDPObject* pDPObj = pThisDoc->GetDPAtCursor( GetViewData()->GetCurX(), - GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); - if ( pOwnClip && pDPObj ) - { - // paste from Calc into DataPilot table: sort (similar to drag & drop) - - ScDocument* pClipDoc = pOwnClip->GetDocument(); - SCTAB nSourceTab = pOwnClip->GetVisibleTab(); - - SCCOL nClipStartX; - SCROW nClipStartY; - SCCOL nClipEndX; - SCROW nClipEndY; - pClipDoc->GetClipStart( nClipStartX, nClipStartY ); - pClipDoc->GetClipArea( nClipEndX, nClipEndY, TRUE ); - nClipEndX = nClipEndX + nClipStartX; - nClipEndY = nClipEndY + nClipStartY; // GetClipArea returns the difference - - ScRange aSource( nClipStartX, nClipStartY, nSourceTab, nClipEndX, nClipEndY, nSourceTab ); - BOOL bDone = pTabViewShell->DataPilotMove( aSource, GetViewData()->GetCurPos() ); - if ( !bDone ) - pTabViewShell->ErrorMessage( STR_ERR_DATAPILOT_INPUT ); - } - else - { - // normal paste - WaitObject aWait( GetViewData()->GetDialogParent() ); - pTabViewShell->PasteFromSystem(); - } + PasteFromClipboard ( GetViewData(), pTabViewShell, true ); rReq.Done(); } - pTabViewShell->CellContentChanged(); // => PasteFromSystem() ??? break; case SID_CLIPBOARD_FORMAT_ITEMS: @@ -2226,3 +2195,52 @@ IMPL_LINK( ScCellShell, DialogClosed, AbstractScLinkedAreaDlg*, EMPTYARG ) return 0; } +void ScCellShell::PasteFromClipboard( ScViewData* pViewData, ScTabViewShell* pTabViewShell, bool bShowDialog ) +{ + Window* pWin = pViewData->GetActiveWin(); + ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin ); + ScDocument* pThisDoc = pViewData->GetDocument(); + ScDPObject* pDPObj = pThisDoc->GetDPAtCursor( pViewData->GetCurX(), + pViewData->GetCurY(), pViewData->GetTabNo() ); + if ( pOwnClip && pDPObj ) + { + // paste from Calc into DataPilot table: sort (similar to drag & drop) + + ScDocument* pClipDoc = pOwnClip->GetDocument(); + SCTAB nSourceTab = pOwnClip->GetVisibleTab(); + + SCCOL nClipStartX; + SCROW nClipStartY; + SCCOL nClipEndX; + SCROW nClipEndY; + pClipDoc->GetClipStart( nClipStartX, nClipStartY ); + pClipDoc->GetClipArea( nClipEndX, nClipEndY, TRUE ); + nClipEndX = nClipEndX + nClipStartX; + nClipEndY = nClipEndY + nClipStartY; // GetClipArea returns the difference + + ScRange aSource( nClipStartX, nClipStartY, nSourceTab, nClipEndX, nClipEndY, nSourceTab ); + BOOL bDone = pTabViewShell->DataPilotMove( aSource, pViewData->GetCurPos() ); + if ( !bDone ) + pTabViewShell->ErrorMessage( STR_ERR_DATAPILOT_INPUT ); + } + else + { + // normal paste + WaitObject aWait( pViewData->GetDialogParent() ); + if (!pOwnClip) + pTabViewShell->PasteFromSystem(); + else + { + ScDocument* pClipDoc = pOwnClip->GetDocument(); + sal_uInt16 nFlags = IDF_ALL; + if (pClipDoc->GetClipParam().isMultiRange()) + // For multi-range paste, we paste values by default. + nFlags &= ~IDF_FORMULA; + + pTabViewShell->PasteFromClip( nFlags, pClipDoc, + PASTE_NOFUNC, FALSE, FALSE, FALSE, INS_NONE, IDF_NONE, + bShowDialog ); // allow warning dialog + } + } + pTabViewShell->CellContentChanged(); // => PasteFromSystem() ??? +} diff --git a/sc/source/ui/view/tabcont.cxx b/sc/source/ui/view/tabcont.cxx index 3bfb8729cd37..db1a8952aeef 100644 --- a/sc/source/ui/view/tabcont.cxx +++ b/sc/source/ui/view/tabcont.cxx @@ -49,6 +49,7 @@ #include "sc.hrc" #include "globstr.hrc" #include "transobj.hxx" +#include "clipparam.hxx" // STATIC DATA ----------------------------------------------------------- @@ -447,7 +448,8 @@ void ScTabControl::DoDrag( const Region& /* rRegion */ ) aTabMark.SetMarkArea( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab) ); ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); - pDoc->CopyToClip( 0,0, MAXCOL,MAXROW, FALSE, pClipDoc, FALSE, &aTabMark ); + ScClipParam aClipParam(ScRange(0, 0, 0, MAXCOL, MAXROW, 0), false); + pDoc->CopyToClip(aClipParam, pClipDoc, &aTabMark, false); TransferableObjectDescriptor aObjDesc; pDocSh->FillTransferableObjectDescriptor( aObjDesc ); diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx index 29ebede481b9..e34741ba4c6b 100644 --- a/sc/source/ui/view/tabvwsh4.cxx +++ b/sc/source/ui/view/tabvwsh4.cxx @@ -1510,7 +1510,7 @@ BOOL ScTabViewShell::TabKeyInput(const KeyEvent& rKEvt) // #51889# Spezialfall: Copy/Cut bei Mehrfachselektion -> Fehlermeldung // (Slot ist disabled, SfxViewShell::KeyInput wuerde also kommentarlos verschluckt) KeyFuncType eFunc = aCode.GetFunction(); - if ( eFunc == KEYFUNC_COPY || eFunc == KEYFUNC_CUT ) + if ( eFunc == KEYFUNC_CUT ) { ScRange aDummy; ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy ); diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index 9dda9a097395..4b5d59b80284 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -212,6 +212,7 @@ #include "transobj.hxx" #include "drwtrans.hxx" #include "docuno.hxx" +#include "clipparam.hxx" using namespace com::sun::star; @@ -312,10 +313,10 @@ BOOL ScViewFunc::CopyToClip( ScDocument* pClipDoc, BOOL bCut, BOOL bApi, BOOL bI ScRange aRange; ScMarkType eMarkType = GetViewData()->GetSimpleArea( aRange ); + ScDocument* pDoc = GetViewData()->GetDocument(); + ScMarkData& rMark = GetViewData()->GetMarkData(); if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED ) { - ScDocument* pDoc = GetViewData()->GetDocument(); - ScMarkData& rMark = GetViewData()->GetMarkData(); if ( !pDoc->HasSelectedBlockMatrixFragment( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), @@ -342,9 +343,8 @@ BOOL ScViewFunc::CopyToClip( ScDocument* pClipDoc, BOOL bCut, BOOL bApi, BOOL bI ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) ); } - pDoc->CopyToClip( aRange.aStart.Col(), aRange.aStart.Row(), - aRange.aEnd.Col(), aRange.aEnd.Row(), - bCut, pClipDoc, FALSE, &rMark, FALSE, bIncludeObjects ); + ScClipParam aClipParam(aRange, bCut); + pDoc->CopyToClip(aClipParam, pClipDoc, &rMark, false, false, bIncludeObjects); if (bSysClip) { ScDrawLayer::SetGlobalDrawPersist(NULL); @@ -382,6 +382,124 @@ BOOL ScViewFunc::CopyToClip( ScDocument* pClipDoc, BOOL bCut, BOOL bApi, BOOL bI ErrorMessage(STR_MATRIXFRAGMENTERR); } } + else if (eMarkType == SC_MARK_MULTI) + { + bool bSuccess = false; + ScClipParam aClipParam; + aClipParam.mbCutMode = false; + rMark.MarkToSimple(); + rMark.FillRangeListWithMarks(&aClipParam.maRanges, false); + + do + { + if (bCut) + // We con't support cutting of multi-selections. + break; + + if (pClipDoc) + // TODO: What's this for? + break; + + ::std::auto_ptr<ScDocument> pDocClip(new ScDocument(SCDOCMODE_CLIP)); + + // Check for geometrical feasibility of the ranges. + bool bValidRanges = true; + ScRangePtr p = aClipParam.maRanges.First(); + SCCOL nPrevColDelta = 0; + SCROW nPrevRowDelta = 0; + SCCOL nPrevCol = p->aStart.Col(); + SCROW nPrevRow = p->aStart.Row(); + SCCOL nPrevColSize = p->aEnd.Col() - p->aStart.Col() + 1; + SCROW nPrevRowSize = p->aEnd.Row() - p->aStart.Row() + 1; + for (p = aClipParam.maRanges.Next(); p; p = aClipParam.maRanges.Next()) + { + if (pDoc->HasSelectedBlockMatrixFragment( + p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), rMark)) + { + if (!bApi) + ErrorMessage(STR_MATRIXFRAGMENTERR); + return false; + } + + SCCOL nColDelta = p->aStart.Col() - nPrevCol; + SCROW nRowDelta = p->aStart.Row() - nPrevRow; + + if ((nColDelta && nRowDelta) || (nPrevColDelta && nRowDelta) || (nPrevRowDelta && nColDelta)) + { + bValidRanges = false; + break; + } + + if (aClipParam.meDirection == ScClipParam::Unspecified) + { + if (nColDelta) + aClipParam.meDirection = ScClipParam::Column; + if (nRowDelta) + aClipParam.meDirection = ScClipParam::Row; + } + + SCCOL nColSize = p->aEnd.Col() - p->aStart.Col() + 1; + SCROW nRowSize = p->aEnd.Row() - p->aStart.Row() + 1; + + if (aClipParam.meDirection == ScClipParam::Column && nRowSize != nPrevRowSize) + { + // column-oriented ranges must have identical row size. + bValidRanges = false; + break; + } + if (aClipParam.meDirection == ScClipParam::Row && nColSize != nPrevColSize) + { + // likewise, row-oriented ranges must have identical + // column size. + bValidRanges = false; + break; + } + + nPrevCol = p->aStart.Col(); + nPrevRow = p->aStart.Row(); + nPrevColDelta = nColDelta; + nPrevRowDelta = nRowDelta; + nPrevColSize = nColSize; + nPrevRowSize = nRowSize; + } + if (!bValidRanges) + break; + + pDoc->CopyToClip(aClipParam, pDocClip.get(), false, &rMark, false, bIncludeObjects); + + ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); + if ( pChangeTrack ) + pChangeTrack->ResetLastCut(); // kein CutMode mehr + + { + ScDocShell* pDocSh = GetViewData()->GetDocShell(); + TransferableObjectDescriptor aObjDesc; + pDocSh->FillTransferableObjectDescriptor( aObjDesc ); + aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); + // maSize is set in ScTransferObj ctor + + ScTransferObj* pTransferObj = new ScTransferObj( pDocClip.release(), aObjDesc ); + uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); + + if ( ScGlobal::pDrawClipDocShellRef ) + { + SfxObjectShellRef aPersistRef( &(*ScGlobal::pDrawClipDocShellRef) ); + pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive + } + + pTransferObj->CopyToClipboard( GetActiveWin() ); // system clipboard + SC_MOD()->SetClipObject( pTransferObj, NULL ); // internal clipboard + } + + bSuccess = true; + } + while (false); + + if (!bSuccess && !bApi) + ErrorMessage(STR_NOMULTISELECT); + + bDone = bSuccess; + } else { if (!bApi) @@ -408,9 +526,8 @@ ScTransferObj* ScViewFunc::CopyToTransferable() BOOL bAnyOle = pDoc->HasOLEObjectsInArea( aRange, &rMark ); ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) ); - pDoc->CopyToClip( aRange.aStart.Col(), aRange.aStart.Row(), - aRange.aEnd.Col(), aRange.aEnd.Row(), - FALSE, pClipDoc, FALSE, &rMark, FALSE, TRUE ); + ScClipParam aClipParam(aRange, false); + pDoc->CopyToClip(aClipParam, pClipDoc, &rMark, false, false, true); ScDrawLayer::SetGlobalDrawPersist(NULL); pClipDoc->ExtendMerge( aRange, TRUE ); @@ -739,6 +856,52 @@ BOOL lcl_SelHasAttrib( ScDocument* pDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, // internes Paste +namespace { + +class CursorSwitcher +{ +public: + CursorSwitcher(ScViewFunc* pViewFunc) : + mpViewFunc(pViewFunc) + { + mpViewFunc->HideCursor(); + } + + ~CursorSwitcher() + { + mpViewFunc->ShowCursor(); + } +private: + ScViewFunc* mpViewFunc; +}; + +bool lcl_checkDestRangeForOverwrite(const ScRange& rDestRange, const ScDocument* pDoc, const ScMarkData& rMark, Window* pParentWnd) +{ + bool bIsEmpty = true; + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab < nTabCount && bIsEmpty; ++nTab) + { + if (!rMark.GetTableSelect(nTab)) + continue; + + bIsEmpty = pDoc->IsBlockEmpty(nTab, rDestRange.aStart.Col(), rDestRange.aStart.Row(), + rDestRange.aEnd.Col(), rDestRange.aEnd.Row()); + } + + if (!bIsEmpty) + { + ScReplaceWarnBox aBox(pParentWnd); + if (aBox.Execute() != RET_YES) + { + // changing the configuration is within the ScReplaceWarnBox + return false; + } + } + return true; +} + +} + BOOL ScViewFunc::PasteFromClip( USHORT nFlags, ScDocument* pClipDoc, USHORT nFunction, BOOL bSkipEmpty, BOOL bTranspose, BOOL bAsLink, @@ -764,6 +927,12 @@ BOOL ScViewFunc::PasteFromClip( USHORT nFlags, ScDocument* pClipDoc, // do not copy note captions into undo document nUndoFlags |= IDF_NOCAPTIONS; + ScClipParam& rClipParam = pClipDoc->GetClipParam(); + if (rClipParam.isMultiRange()) + return PasteMultiRangesFromClip( + nFlags, pClipDoc, nFunction, bSkipEmpty, bTranspose, bAsLink, bAllowDialogs, + eMoveMode, nContFlags, nUndoFlags); + BOOL bCutMode = pClipDoc->IsCutMode(); // if transposing, take from original clipdoc BOOL bIncludeFiltered = bCutMode; @@ -992,23 +1161,8 @@ BOOL ScViewFunc::PasteFromClip( USHORT nFlags, ScDocument* pClipDoc, SC_MOD()->GetInputOptions().GetReplaceCellsWarn(); if ( bAskIfNotEmpty ) { - BOOL bIsEmpty = TRUE; - SCTAB nTabCount = pDoc->GetTableCount(); - for (SCTAB nTab=0; nTab<nTabCount && bIsEmpty; nTab++) - if ( aFilteredMark.GetTableSelect(nTab) && - !pDoc->IsBlockEmpty( nTab, aUserRange.aStart.Col(), aUserRange.aStart.Row(), - aUserRange.aEnd.Col(), aUserRange.aEnd.Row() ) ) - bIsEmpty = FALSE; - - if ( !bIsEmpty ) - { - ScReplaceWarnBox aBox( GetViewData()->GetDialogParent() ); - if ( aBox.Execute() != RET_YES ) - { - // changing the configuration is within the ScReplaceWarnBox - return FALSE; - } - } + if (!lcl_checkDestRangeForOverwrite(aUserRange, pDoc, aFilteredMark, GetViewData()->GetDialogParent())) + return false; } } @@ -1302,7 +1456,179 @@ BOOL ScViewFunc::PasteFromClip( USHORT nFlags, ScDocument* pClipDoc, // AdjustBlockHeight has already been called above aModificator.SetDocumentModified(); - pDocSh->UpdateOle(GetViewData()); + PostPasteFromClip(aUserRange, rMark); + return TRUE; +} + +bool ScViewFunc::PasteMultiRangesFromClip( + sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction, + bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs, + InsCellCmd eMoveMode, sal_uInt16 /*nContFlags*/, sal_uInt16 nUndoFlags) +{ + ScViewData& rViewData = *GetViewData(); + ScDocument* pDoc = rViewData.GetDocument(); + ScDocShell* pDocSh = rViewData.GetDocShell(); + ScMarkData aMark(rViewData.GetMarkData()); + const ScAddress& rCurPos = rViewData.GetCurPos(); + ScClipParam& rClipParam = pClipDoc->GetClipParam(); + SCCOL nColSize = rClipParam.getPasteColSize(); + SCROW nRowSize = rClipParam.getPasteRowSize(); + + if (bTranspose) + { + if (static_cast<SCROW>(rCurPos.Col()) + nRowSize-1 > static_cast<SCROW>(MAXCOL)) + { + ErrorMessage(STR_PASTE_FULL); + return false; + } + + ::std::auto_ptr<ScDocument> pTransClip(new ScDocument(SCDOCMODE_CLIP)); + pClipDoc->TransposeClip(pTransClip.get(), nFlags, bAsLink); + pClipDoc = pTransClip.release(); + SCCOL nTempColSize = nColSize; + nColSize = static_cast<SCCOL>(nRowSize); + nRowSize = static_cast<SCROW>(nTempColSize); + } + + if (!ValidCol(rCurPos.Col()+nColSize-1) || !ValidRow(rCurPos.Row()+nRowSize-1)) + { + ErrorMessage(STR_PASTE_FULL); + return false; + } + + // Determine the first and last selected sheet numbers. + SCTAB nTab1 = aMark.GetFirstSelected(); + SCTAB nTab2 = nTab1; + for (SCTAB i = nTab1+1; i <= MAXTAB; ++i) + if (aMark.GetTableSelect(i)) + nTab2 = i; + + ScDocShellModificator aModificator(*pDocSh); + + // For multi-selection paste, we don't support cell duplication for larger + // destination range. In case the destination is marked, we reset it to + // the clip size. + ScRange aMarkedRange(rCurPos.Col(), rCurPos.Row(), nTab1, + rCurPos.Col()+nColSize-1, rCurPos.Row()+nRowSize-1, nTab2); + + // Extend the marked range to account for filtered rows in the destination + // area. + if (ScViewUtil::HasFiltered(aMarkedRange, pDoc)) + { + if (!ScViewUtil::FitToUnfilteredRows(aMarkedRange, pDoc, nRowSize)) + return false; + } + + bool bAskIfNotEmpty = + bAllowDialogs && (nFlags & IDF_CONTENTS) && + nFunction == PASTE_NOFUNC && SC_MOD()->GetInputOptions().GetReplaceCellsWarn(); + + if (bAskIfNotEmpty) + { + if (!lcl_checkDestRangeForOverwrite(aMarkedRange, pDoc, aMark, rViewData.GetDialogParent())) + return false; + } + + aMark.SetMarkArea(aMarkedRange); + MarkRange(aMarkedRange); + + bool bInsertCells = (eMoveMode != INS_NONE); + if (bInsertCells) + { + if (!InsertCells(eMoveMode, pDoc->IsUndoEnabled(), true)) + return false; + } + + ::std::auto_ptr<ScDocument> pUndoDoc; + if (pDoc->IsUndoEnabled()) + { + pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO)); + pUndoDoc->InitUndoSelected(pDoc, aMark, false, false); + pDoc->CopyToDocument(aMarkedRange, nUndoFlags, false, pUndoDoc.get(), &aMark, true); + } + + ::std::auto_ptr<ScDocument> pMixDoc; + if ( bSkipEmpty || nFunction ) + { + if ( nFlags & IDF_CONTENTS ) + { + pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO)); + pMixDoc->InitUndoSelected(pDoc, aMark, false, false); + pDoc->CopyToDocument(aMarkedRange, IDF_CONTENTS, false, pMixDoc.get(), &aMark, true); + } + } + + /* Make draw layer and start drawing undo. + - Needed before AdjustBlockHeight to track moved drawing objects. + - Needed before pDoc->CopyFromClip to track inserted note caption objects. + */ + if (nFlags & IDF_OBJECTS) + pDocSh->MakeDrawLayer(); + if (pDoc->IsUndoEnabled()) + pDoc->BeginDrawUndo(); + + CursorSwitcher aCursorSwitch(this); + sal_uInt16 nNoObjFlags = nFlags & ~IDF_OBJECTS; + pDoc->CopyMultiRangeFromClip(rCurPos, aMark, nNoObjFlags, pClipDoc, + true, bAsLink, false, bSkipEmpty); + + if (pMixDoc.get()) + pDoc->MixDocument(aMarkedRange, nFunction, bSkipEmpty, pMixDoc.get()); + + AdjustBlockHeight(); // update row heights before pasting objects + + if (nFlags & IDF_OBJECTS) + { + // Paste the drawing objects after the row heights have been updated. + pDoc->CopyMultiRangeFromClip(rCurPos, aMark, IDF_OBJECTS, pClipDoc, + true, false, false, true); + } + + pDocSh->PostPaint( + aMarkedRange.aStart.Col(), aMarkedRange.aStart.Row(), nTab1, + aMarkedRange.aEnd.Col(), aMarkedRange.aEnd.Row(), nTab1, PAINT_GRID); + + if (pDoc->IsUndoEnabled()) + { + SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager(); + String aUndo = ScGlobal::GetRscString( + pClipDoc->IsCutMode() ? STR_UNDO_CUT : STR_UNDO_COPY); + pUndoMgr->EnterListAction(aUndo, aUndo); + + ScUndoPasteOptions aOptions; // store options for repeat + aOptions.nFunction = nFunction; + aOptions.bSkipEmpty = bSkipEmpty; + aOptions.bTranspose = bTranspose; + aOptions.bAsLink = bAsLink; + aOptions.eMoveMode = eMoveMode; + + ScUndoPaste* pUndo = new ScUndoPaste(pDocSh, + aMarkedRange.aStart.Col(), + aMarkedRange.aStart.Row(), + aMarkedRange.aStart.Tab(), + aMarkedRange.aEnd.Col(), + aMarkedRange.aEnd.Row(), + aMarkedRange.aEnd.Tab(), + aMark, pUndoDoc.release(), NULL, nFlags|nUndoFlags, NULL, NULL, NULL, NULL, false, &aOptions); + + if (bInsertCells) + pUndoMgr->AddUndoAction(new ScUndoWrapper(pUndo), true); + else + pUndoMgr->AddUndoAction(pUndo, false); + + pUndoMgr->LeaveListAction(); + } + aModificator.SetDocumentModified(); + PostPasteFromClip(aMarkedRange, aMark); + return true; +} + +void ScViewFunc::PostPasteFromClip(const ScRange& rPasteRange, const ScMarkData& rMark) +{ + ScViewData* pViewData = GetViewData(); + ScDocShell* pDocSh = pViewData->GetDocShell(); + ScDocument* pDoc = pViewData->GetDocument(); + pDocSh->UpdateOle(pViewData); SelectionChanged(); @@ -1316,7 +1642,7 @@ BOOL ScViewFunc::PasteFromClip( USHORT nFlags, ScDocument* pClipDoc, { if ( rMark.GetTableSelect( i ) ) { - ScRange aChangeRange( aUserRange ); + ScRange aChangeRange(rPasteRange); aChangeRange.aStart.SetTab( i ); aChangeRange.aEnd.SetTab( i ); aChangeRanges.Append( aChangeRange ); @@ -1324,8 +1650,6 @@ BOOL ScViewFunc::PasteFromClip( USHORT nFlags, ScDocument* pClipDoc, } pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges ); } - - return TRUE; } diff --git a/sc/source/ui/view/viewfun5.cxx b/sc/source/ui/view/viewfun5.cxx index f8b89a85e11c..35af3ee2a2e3 100644 --- a/sc/source/ui/view/viewfun5.cxx +++ b/sc/source/ui/view/viewfun5.cxx @@ -79,6 +79,7 @@ #include "asciiopt.hxx" #include "scabstdlg.hxx" +#include "clipparam.hxx" #include <vcl/msgbox.hxx> #include <sfx2/viewfrm.hxx> #include <svx/dbaexchange.hxx> @@ -163,12 +164,12 @@ BOOL ScViewFunc::PasteDataFormat( ULONG nFormatId, if ( pSrcDoc->GetDataStart( nSrcTab, nFirstCol, nFirstRow ) ) pSrcDoc->GetCellArea( nSrcTab, nLastCol, nLastRow ); else - { + { nFirstCol = nLastCol = 0; nFirstRow = nLastRow = 0; - } - pSrcDoc->CopyToClip( nFirstCol, nFirstRow, nLastCol, nLastRow, - FALSE, pClipDoc, FALSE, &aSrcMark ); + } + ScClipParam aClipParam(ScRange(nFirstCol, nFirstRow, 0, nLastCol, nLastRow, 0), false); + pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aSrcMark); ScGlobal::SetClipDocName( xDocShRef->GetTitle( SFX_TITLE_FULLNAME ) ); SetCursor( nPosX, nPosY ); |