summaryrefslogtreecommitdiff
path: root/sc/source/ui
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui')
-rw-r--r--sc/source/ui/docshell/arealink.cxx6
-rw-r--r--sc/source/ui/docshell/docfunc.cxx5
-rw-r--r--sc/source/ui/inc/cellsh.hxx3
-rw-r--r--sc/source/ui/inc/viewfunc.hxx5
-rw-r--r--sc/source/ui/navipi/content.cxx6
-rw-r--r--sc/source/ui/undo/undoblk.cxx6
-rw-r--r--sc/source/ui/unoobj/funcuno.cxx6
-rw-r--r--sc/source/ui/view/cellsh.cxx1
-rw-r--r--sc/source/ui/view/cellsh1.cxx84
-rw-r--r--sc/source/ui/view/tabcont.cxx4
-rw-r--r--sc/source/ui/view/tabvwsh4.cxx2
-rw-r--r--sc/source/ui/view/viewfun3.cxx382
-rw-r--r--sc/source/ui/view/viewfun5.cxx9
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 );