ooo-build r15454 - trunk/patches/test
- From: kyoshida svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r15454 - trunk/patches/test
- Date: Wed, 4 Mar 2009 05:04:16 +0000 (UTC)
Author: kyoshida
Date: Wed Mar 4 05:04:16 2009
New Revision: 15454
URL: http://svn.gnome.org/viewvc/ooo-build?rev=15454&view=rev
Log:
More progress on multi-range copy & paste. It's 99% complete.
Modified:
trunk/patches/test/calc-multi-range-copy-paste.diff
Modified: trunk/patches/test/calc-multi-range-copy-paste.diff
==============================================================================
--- trunk/patches/test/calc-multi-range-copy-paste.diff (original)
+++ trunk/patches/test/calc-multi-range-copy-paste.diff Wed Mar 4 05:04:16 2009
@@ -1,1419 +0,0 @@
-diff --git sc/inc/clipparam.hxx sc/inc/clipparam.hxx
-new file mode 100644
-index 0000000..79d45f9
---- /dev/null
-+++ sc/inc/clipparam.hxx
-@@ -0,0 +1,70 @@
-+/*************************************************************************
-+ *
-+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+ *
-+ * Copyright 2008 by Sun Microsystems, Inc.
-+ *
-+ * OpenOffice.org - a multi-platform office productivity suite
-+ *
-+ * $RCSfile: document.hxx,v $
-+ * $Revision: 1.115.36.9 $
-+ *
-+ * 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.
-+ *
-+ ************************************************************************/
-+
-+#ifndef SC_CLIPPARAM_HXX
-+#define SC_CLIPPARAM_HXX
-+
-+#include "rangelst.hxx"
-+
-+struct ScClipParam
-+{
-+ enum Direction { Unspecified, Column, Row };
-+
-+ ScRangeList maRanges;
-+ Direction meDirection;
-+ bool mbCutMode;
-+
-+ ScClipParam();
-+ explicit ScClipParam(const ScClipParam& r);
-+
-+ bool isMultiRange() const;
-+
-+ /**
-+ * Get the column size of a pasted range. Note that when the range is
-+ * non-contiguous, we first compress all individual ranges into a single
-+ * range, and the size of that compressed range is returned.
-+ */
-+ SCCOL getPasteColSize();
-+
-+ /**
-+ * Same as the above method, but returns the row size of the compressed
-+ * range.
-+ */
-+ SCROW getPasteRowSize();
-+
-+ /**
-+ * Return a single range that encompasses all individual ranges.
-+ */
-+ ScRange getWholeRange();
-+
-+ void transpose();
-+};
-+
-+#endif
-diff --git sc/inc/document.hxx sc/inc/document.hxx
-index d8ce3a5..b7664bc 100644
---- sc/inc/document.hxx
-+++ sc/inc/document.hxx
-@@ -138,6 +138,7 @@ class ScAutoNameCache;
- class ScTemporaryChartLock;
- class ScLookupCache;
- struct ScLookupCacheMapImpl;
-+struct ScClipParam;
-
- namespace com { namespace sun { namespace star {
- namespace lang {
-@@ -289,6 +290,7 @@ private:
- ScFieldEditEngine* pCacheFieldEditEngine;
-
- ::std::auto_ptr<ScDocProtection> pDocProtection;
-+ ::std::auto_ptr<ScClipParam> mpClipParam;
-
- ::std::auto_ptr<ScExternalRefManager> pExternalRefMgr;
- String aDocName; // opt: Dokumentname
-@@ -311,7 +313,6 @@ private:
-
- sal_uInt32 nRangeOverflowType; // used in (xml) loading for overflow warnings
-
-- ScRange aClipRange;
- ScRange aEmbedRange;
- ScAddress aCurTextWidthCalcPos;
- ScAddress aOnlineSpellPos; // within whole document
-@@ -363,7 +364,6 @@ private:
- BOOL bForcedFormulaPending;
- BOOL bCalculatingFormulaTree;
- BOOL bIsClip;
-- BOOL bCutMode;
- BOOL bIsUndo;
- BOOL bIsVisible; // set from view ctor
-
-@@ -971,6 +971,9 @@ public:
- BOOL bKeepScenarioFlags = FALSE,
- BOOL bIncludeObjects = FALSE,
- BOOL bCloneNoteCaptions = TRUE);
-+ void CopyToClip(const ScClipParam& rClipParam, ScDocument* pClipDoc,
-+ const ScMarkData* pMarks = NULL, bool bKeepScenarioFlags = false,
-+ bool bIncludeObjects = false, bool bCloneNoteCaptions = true);
- void CopyTabToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
- SCTAB nTab, ScDocument* pClipDoc = NULL);
- void CopyBlockFromClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
-@@ -998,6 +1001,12 @@ public:
- BOOL bSkipAttrForEmpty = FALSE,
- const ScRangeList * pDestRanges = NULL );
-
-+ void CopyMultiRangeFromClip(const ScAddress& rDestPos, const ScMarkData& rMark,
-+ sal_uInt16 nInsFlag, ScDocument* pClipDoc,
-+ bool bResetCut = true, bool bAsLink = false,
-+ bool bIncludeFiltered = true,
-+ bool bSkipAttrForEmpty = false);
-+
- void GetClipArea(SCCOL& nClipX, SCROW& nClipY, BOOL bIncludeFiltered);
- void GetClipStart(SCCOL& nClipX, SCROW& nClipY);
-
-@@ -1007,6 +1016,9 @@ public:
-
- SC_DLLPUBLIC void TransposeClip( ScDocument* pTransClip, USHORT nFlags, BOOL bAsLink );
-
-+ ScClipParam& GetClipParam();
-+ void SetClipParam(const ScClipParam& rParam);
-+
- void MixDocument( const ScRange& rRange, USHORT nFunction, BOOL bSkipEmpty,
- ScDocument* pSrcDoc );
-
-diff --git sc/inc/table.hxx sc/inc/table.hxx
-index 74b743f..e8865ed 100644
---- sc/inc/table.hxx
-+++ sc/inc/table.hxx
-@@ -297,6 +297,8 @@ public:
- void DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nDelFlag);
- void CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScTable* pTable,
- BOOL bKeepScenarioFlags, BOOL bCloneNoteCaptions);
-+ void CopyToClip(const ScRangeList& rRanges, ScTable* pTable,
-+ bool bKeepScenarioFlags, bool bCloneNoteCaptions);
- void CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCsCOL nDx, SCsROW nDy,
- USHORT nInsFlag, BOOL bAsLink, BOOL bSkipAttrForEmpty, ScTable* pTable);
- void StartListeningInArea( SCCOL nCol1, SCROW nRow1,
-diff --git sc/source/core/data/clipparam.cxx sc/source/core/data/clipparam.cxx
-new file mode 100644
-index 0000000..77ea4ee
---- /dev/null
-+++ sc/source/core/data/clipparam.cxx
-@@ -0,0 +1,235 @@
-+/*************************************************************************
-+ *
-+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+ *
-+ * Copyright 2008 by Sun Microsystems, Inc.
-+ *
-+ * OpenOffice.org - a multi-platform office productivity suite
-+ *
-+ * $RCSfile: document.cxx,v $
-+ * $Revision: 1.90.36.8 $
-+ *
-+ * 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 "clipparam.hxx"
-+
-+ScClipParam::ScClipParam() :
-+ meDirection(Unspecified),
-+ mbCutMode(false)
-+{
-+}
-+
-+ScClipParam::ScClipParam(const ScClipParam& r) :
-+ maRanges(r.maRanges),
-+ meDirection(r.meDirection),
-+ mbCutMode(r.mbCutMode)
-+{
-+}
-+
-+bool ScClipParam::isMultiRange() const
-+{
-+ return maRanges.Count() > 1;
-+}
-+
-+static SCCOLROW lcl_getRealColSize(ScClipParam::Direction eDir, ScRangeList& rRanges)
-+{
-+ if (!rRanges.Count())
-+ return 0;
-+
-+ switch (eDir)
-+ {
-+ case ScClipParam::Column:
-+ {
-+ SCCOLROW nColSize = 0;
-+ for (ScRangePtr p = rRanges.First(); p; p = rRanges.Next())
-+ nColSize += p->aEnd.Col() - p->aStart.Col() + 1;
-+ return nColSize;
-+ }
-+ break;
-+ case ScClipParam::Row:
-+ {
-+ // We assume that all ranges have identical column size.
-+ const ScRange& rRange = *rRanges.First();
-+ return rRange.aEnd.Col() - rRange.aStart.Col() + 1;
-+ }
-+ break;
-+ case ScClipParam::Unspecified:
-+ default:
-+ ;
-+ }
-+ return 0;
-+}
-+
-+static SCCOLROW lcl_getRealRowSize(ScClipParam::Direction eDir, ScRangeList& rRanges)
-+{
-+ if (!rRanges.Count())
-+ return 0;
-+
-+ switch (eDir)
-+ {
-+ case ScClipParam::Column:
-+ {
-+ // We assume that all ranges have identical row size.
-+ const ScRange& rRange = *rRanges.First();
-+ return rRange.aEnd.Row() - rRange.aStart.Row() + 1;
-+ }
-+ break;
-+ case ScClipParam::Row:
-+ {
-+ SCCOLROW nRowSize = 0;
-+ for (ScRangePtr p = rRanges.First(); p; p = rRanges.Next())
-+ nRowSize += p->aEnd.Row() - p->aStart.Row() + 1;
-+ return nRowSize;
-+ }
-+ break;
-+ case ScClipParam::Unspecified:
-+ default:
-+ ;
-+ }
-+ return 0;
-+}
-+
-+SCCOL ScClipParam::getPasteColSize()
-+{
-+ if (!maRanges.Count())
-+ return 0;
-+
-+ switch (meDirection)
-+ {
-+ case ScClipParam::Column:
-+ {
-+ SCCOL nColSize = 0;
-+ for (ScRangePtr p = maRanges.First(); p; p = maRanges.Next())
-+ nColSize += p->aEnd.Col() - p->aStart.Col() + 1;
-+ return nColSize;
-+ }
-+ break;
-+ case ScClipParam::Row:
-+ {
-+ // We assume that all ranges have identical column size.
-+ const ScRange& rRange = *maRanges.First();
-+ return rRange.aEnd.Col() - rRange.aStart.Col() + 1;
-+ }
-+ break;
-+ case ScClipParam::Unspecified:
-+ default:
-+ ;
-+ }
-+ return 0;
-+}
-+
-+SCROW ScClipParam::getPasteRowSize()
-+{
-+ if (!maRanges.Count())
-+ return 0;
-+
-+ switch (meDirection)
-+ {
-+ case ScClipParam::Column:
-+ {
-+ // We assume that all ranges have identical row size.
-+ const ScRange& rRange = *maRanges.First();
-+ return rRange.aEnd.Row() - rRange.aStart.Row() + 1;
-+ }
-+ break;
-+ case ScClipParam::Row:
-+ {
-+ SCROW nRowSize = 0;
-+ for (ScRangePtr p = maRanges.First(); p; p = maRanges.Next())
-+ nRowSize += p->aEnd.Row() - p->aStart.Row() + 1;
-+ return nRowSize;
-+ }
-+ break;
-+ case ScClipParam::Unspecified:
-+ default:
-+ ;
-+ }
-+ return 0;
-+}
-+
-+ScRange ScClipParam::getWholeRange()
-+{
-+ ScRange aWhole;
-+ bool bFirst = true;
-+ for (ScRange* p = maRanges.First(); p; p = maRanges.Next())
-+ {
-+ if (bFirst)
-+ {
-+ aWhole = *p;
-+ bFirst = false;
-+ continue;
-+ }
-+
-+ if (aWhole.aStart.Col() > p->aStart.Col())
-+ aWhole.aStart.SetCol(p->aStart.Col());
-+
-+ if (aWhole.aStart.Row() > p->aStart.Row())
-+ aWhole.aStart.SetRow(p->aStart.Row());
-+
-+ if (aWhole.aEnd.Col() < p->aEnd.Col())
-+ aWhole.aEnd.SetCol(p->aEnd.Col());
-+
-+ if (aWhole.aEnd.Row() > p->aEnd.Row())
-+ aWhole.aEnd.SetRow(p->aEnd.Row());
-+ }
-+ return aWhole;
-+}
-+
-+void ScClipParam::transpose()
-+{
-+ switch (meDirection)
-+ {
-+ case ScClipParam::Column:
-+ meDirection = ScClipParam::Row;
-+ break;
-+ case ScClipParam::Row:
-+ meDirection = ScClipParam::Column;
-+ break;
-+ }
-+
-+ ScRangeList aNewRanges;
-+ if (maRanges.Count())
-+ {
-+ ScRange* p = maRanges.First();
-+ SCCOL nColOrigin = p->aStart.Col();
-+ SCROW nRowOrigin = p->aStart.Row();
-+ for (; p; p = maRanges.Next())
-+ {
-+ SCCOL nColDelta = p->aStart.Col() - nColOrigin;
-+ SCROW nRowDelta = p->aStart.Row() - nRowOrigin;
-+ SCCOL nCol1 = 0;
-+ SCCOL nCol2 = static_cast<SCCOL>(p->aEnd.Row() - p->aStart.Row());
-+ SCROW nRow1 = 0;
-+ SCROW nRow2 = static_cast<SCROW>(p->aEnd.Col() - p->aStart.Col());
-+ nCol1 += static_cast<SCCOL>(nRowDelta);
-+ nCol2 += static_cast<SCCOL>(nRowDelta);
-+ nRow1 += static_cast<SCROW>(nColDelta);
-+ nRow2 += static_cast<SCROW>(nColDelta);
-+ ScRange aNew(nCol1, nRow1, p->aStart.Tab(), nCol2, nRow2, p->aStart.Tab());
-+ aNewRanges.Append(aNew);
-+ }
-+ }
-+ maRanges = aNewRanges;
-+}
-diff --git sc/source/core/data/documen2.cxx sc/source/core/data/documen2.cxx
-index 9bf31a2..7dfa529 100644
---- sc/source/core/data/documen2.cxx
-+++ sc/source/core/data/documen2.cxx
-@@ -95,6 +95,7 @@
- #include "lookupcache.hxx"
- #include "externalrefmgr.hxx"
- #include "tabprotection.hxx"
-+#include "clipparam.hxx"
- #include <com/sun/star/document/XVbaEventsHelper.hpp>
-
- // pImpl because including lookupcache.hxx in document.hxx isn't wanted, and
-@@ -154,6 +155,7 @@ ScDocument::ScDocument( ScDocumentMode eMode,
- pScriptTypeData( NULL ),
- pCacheFieldEditEngine( NULL ),
- pDocProtection( NULL ),
-+ mpClipParam( NULL ),
- pExternalRefMgr( NULL ),
- pViewOptions( NULL ),
- pDocOptions( NULL ),
-@@ -182,7 +184,6 @@ ScDocument::ScDocument( ScDocumentMode eMode,
- bForcedFormulaPending( FALSE ),
- bCalculatingFormulaTree( FALSE ),
- bIsClip( eMode == SCDOCMODE_CLIP ),
-- bCutMode( FALSE ),
- bIsUndo( eMode == SCDOCMODE_UNDO ),
- bIsVisible( FALSE ),
- bIsEmbedded( FALSE ),
-diff --git sc/source/core/data/documen3.cxx sc/source/core/data/documen3.cxx
-index 071674b..f04b1b8 100644
---- sc/source/core/data/documen3.cxx
-+++ sc/source/core/data/documen3.cxx
-@@ -80,6 +80,7 @@
- #include "listenercalls.hxx"
- #include "svtools/PasswordHelper.hxx"
- #include "tabprotection.hxx"
-+#include "clipparam.hxx"
-
- #include <memory>
-
-@@ -868,7 +869,7 @@ void ScDocument::UpdateReference( UpdateRefMode eUpdateRefMode,
- {
- ScDocument* pClipDoc = SC_MOD()->GetClipDoc();
- if (pClipDoc)
-- pClipDoc->bCutMode = FALSE;
-+ pClipDoc->GetClipParam().mbCutMode = false;
- }
- }
- }
-@@ -878,7 +879,10 @@ void ScDocument::UpdateTranspose( const ScAddress& rDestPos, ScDocument* pClipDo
- {
- DBG_ASSERT(pClipDoc->bIsClip, "UpdateTranspose: kein Clip");
-
-- ScRange aSource = pClipDoc->aClipRange; // Tab wird noch angepasst
-+ ScRange aSource;
-+ ScClipParam& rClipParam = GetClipParam();
-+ if (rClipParam.maRanges.Count())
-+ aSource = *rClipParam.maRanges.First();
- ScAddress aDest = rDestPos;
-
- SCTAB nClipTab = 0;
-diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
-index 6a97fb5..2d73cb2 100644
---- sc/source/core/data/document.cxx
-+++ sc/source/core/data/document.cxx
-@@ -94,9 +94,36 @@
- #include "postit.hxx"
- #include "externalrefmgr.hxx"
- #include "tabprotection.hxx"
-+#include "clipparam.hxx"
-
- namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
-
-+
-+#include <stdio.h>
-+#include <string>
-+
-+namespace {
-+
-+class StackPrinter
-+{
-+public:
-+ explicit StackPrinter(const char* msg) :
-+ msMsg(msg)
-+ {
-+ fprintf(stdout, "%s: --begin\n", msMsg.c_str());
-+ }
-+
-+ ~StackPrinter()
-+ {
-+ fprintf(stdout, "%s: --end\n", msMsg.c_str());
-+ }
-+
-+private:
-+ ::std::string msMsg;
-+};
-+
-+}
-+
- struct ScDefaultAttr
- {
- const ScPatternAttr* pAttr;
-@@ -1258,7 +1285,7 @@ void ScDocument::AddUndoTab( SCTAB nTab1, SCTAB nTab2, BOOL bColInfo, BOOL bRowI
- void ScDocument::SetCutMode( BOOL bVal )
- {
- if (bIsClip)
-- bCutMode = bVal;
-+ GetClipParam().mbCutMode = bVal;
- else
- {
- DBG_ERROR("SetCutMode without bIsClip");
-@@ -1269,7 +1296,7 @@ void ScDocument::SetCutMode( BOOL bVal )
- BOOL ScDocument::IsCutMode()
- {
- if (bIsClip)
-- return bCutMode;
-+ return GetClipParam().mbCutMode;
- else
- {
- DBG_ERROR("IsCutMode ohne bIsClip");
-@@ -1400,9 +1427,11 @@ void ScDocument::CopyToClip(SCCOL nCol1, SCROW nRow1,
- pClipDoc = SC_MOD()->GetClipDoc();
- }
-
-+ ScClipParam& rClipParam = pClipDoc->GetClipParam();
-+ rClipParam.maRanges.RemoveAll();
-+ rClipParam.maRanges.Append(ScRange( nCol1,nRow1,0, nCol2,nRow2,0 ));
- pClipDoc->aDocName = aDocName;
-- pClipDoc->aClipRange = ScRange( nCol1,nRow1,0, nCol2,nRow2,0 );
-- pClipDoc->ResetClip( this, pMarks );
-+ pClipDoc->ResetClip( this, pMarks );
- USHORT i;
- SCTAB j;
-
-@@ -1441,10 +1470,64 @@ void ScDocument::CopyToClip(SCCOL nCol1, SCROW nRow1,
- }
- }
-
-- pClipDoc->bCutMode = bCut;
-+ pClipDoc->GetClipParam().mbCutMode = bCut;
- }
- }
-
-+void ScDocument::CopyToClip(const ScClipParam& rClipParam,
-+ ScDocument* pClipDoc, const ScMarkData* pMarks,
-+ bool bKeepScenarioFlags, bool bIncludeObjects, bool bCloneNoteCaptions)
-+{
-+ if (bIsClip)
-+ return;
-+
-+ if (!pClipDoc)
-+ {
-+ DBG_ERROR("CopyToClip: no ClipDoc");
-+ pClipDoc = SC_MOD()->GetClipDoc();
-+ }
-+
-+#if 0
-+ USHORT i;
-+ SCTAB j;
-+
-+ std::set<USHORT> aUsedNames; // indexes of named ranges that are used in the copied cells
-+ for (j = 0; j <= MAXTAB; j++)
-+ if (pTab[j] && pClipDoc->pTab[j])
-+ if ( bAllTabs || !pMarks || pMarks->GetTableSelect(j) )
-+ pTab[j]->FindRangeNamesInUse( nCol1, nRow1, nCol2, nRow2, aUsedNames );
-+
-+ pClipDoc->pRangeName->FreeAll();
-+ for (i = 0; i < pRangeName->GetCount(); i++) //! DB-Bereiche Pivot-Bereiche auch !!!
-+ {
-+ USHORT nIndex = ((ScRangeData*)((*pRangeName)[i]))->GetIndex();
-+ bool bInUse = ( aUsedNames.find(nIndex) != aUsedNames.end() );
-+ if (bInUse)
-+ {
-+ ScRangeData* pData = new ScRangeData(*((*pRangeName)[i]));
-+ if (!pClipDoc->pRangeName->Insert(pData))
-+ delete pData;
-+ else
-+ pData->SetIndex(nIndex);
-+ }
-+ }
-+#endif
-+
-+ pClipDoc->aDocName = aDocName;
-+ pClipDoc->SetClipParam(rClipParam);
-+ pClipDoc->ResetClip(this, pMarks);
-+
-+ for (SCTAB i = 0; i <= MAXTAB; ++i)
-+ {
-+ if (!pTab[i] || !pClipDoc->pTab[i])
-+ continue;
-+
-+ if (pMarks && !pMarks->GetTableSelect(i))
-+ continue;
-+
-+ pTab[i]->CopyToClip(rClipParam.maRanges, pClipDoc->pTab[i], bKeepScenarioFlags, bCloneNoteCaptions);
-+ }
-+}
-
- void ScDocument::CopyTabToClip(SCCOL nCol1, SCROW nRow1,
- SCCOL nCol2, SCROW nRow2,
-@@ -1460,14 +1543,16 @@ void ScDocument::CopyTabToClip(SCCOL nCol1, SCROW nRow1,
- pClipDoc = SC_MOD()->GetClipDoc();
- }
-
-+ ScClipParam& rClipParam = pClipDoc->GetClipParam();
- pClipDoc->aDocName = aDocName;
-- pClipDoc->aClipRange = ScRange( nCol1,nRow1,0, nCol2,nRow2,0 );
-+ rClipParam.maRanges.RemoveAll();
-+ rClipParam.maRanges.Append(ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0));
- pClipDoc->ResetClip( this, nTab );
-
- if (pTab[nTab] && pClipDoc->pTab[nTab])
- pTab[nTab]->CopyToClip(nCol1, nRow1, nCol2, nRow2, pClipDoc->pTab[nTab], FALSE, TRUE);
-
-- pClipDoc->bCutMode = FALSE;
-+ pClipDoc->GetClipParam().mbCutMode = false;
- }
- }
-
-@@ -1497,6 +1582,7 @@ void ScDocument::TransposeClip( ScDocument* pTransClip, USHORT nFlags, BOOL bAsL
-
- // Daten
-
-+ ScRange aClipRange = GetClipParam().getWholeRange();
- if ( ValidRow(aClipRange.aEnd.Row()-aClipRange.aStart.Row()) )
- {
- for (SCTAB i=0; i<=MAXTAB; i++)
-@@ -1525,10 +1611,8 @@ void ScDocument::TransposeClip( ScDocument* pTransClip, USHORT nFlags, BOOL bAsL
- }
- }
-
-- pTransClip->aClipRange = ScRange( 0, 0, aClipRange.aStart.Tab(),
-- static_cast<SCCOL>(aClipRange.aEnd.Row() - aClipRange.aStart.Row()),
-- static_cast<SCROW>(aClipRange.aEnd.Col() - aClipRange.aStart.Col()),
-- aClipRange.aEnd.Tab() );
-+ pTransClip->SetClipParam(GetClipParam());
-+ pTransClip->GetClipParam().transpose();
- }
- else
- {
-@@ -1537,9 +1621,21 @@ void ScDocument::TransposeClip( ScDocument* pTransClip, USHORT nFlags, BOOL bAsL
-
- // Dies passiert erst beim Einfuegen...
-
-- bCutMode = FALSE;
-+ GetClipParam().mbCutMode = false;
-+}
-+
-+ScClipParam& ScDocument::GetClipParam()
-+{
-+ if (!mpClipParam.get())
-+ mpClipParam.reset(new ScClipParam);
-+
-+ return *mpClipParam;
- }
-
-+void ScDocument::SetClipParam(const ScClipParam& rParam)
-+{
-+ mpClipParam.reset(new ScClipParam(rParam));
-+}
-
- BOOL ScDocument::IsClipboardSource() const
- {
-@@ -1639,7 +1735,7 @@ void ScDocument::CopyBlockFromClip( SCCOL nCol1, SCROW nRow1,
- && ppClipTab[nClipTab + nFollow + 1] )
- ++nFollow;
-
-- if ( pCBFCP->pClipDoc->bCutMode )
-+ if ( pCBFCP->pClipDoc->GetClipParam().mbCutMode )
- {
- BOOL bOldInserting = IsInsertingFromOtherDoc();
- SetInsertingFromOtherDoc( TRUE);
-@@ -1681,7 +1777,9 @@ void ScDocument::CopyNonFilteredFromClip( SCCOL nCol1, SCROW nRow1,
- pCBFCP->pClipDoc->GetRowFlagsArray( nFlagTab);
-
- SCROW nSourceRow = rClipStartRow;
-- SCROW nSourceEnd = pCBFCP->pClipDoc->aClipRange.aEnd.Row();
-+ SCROW nSourceEnd = 0;
-+ if (pCBFCP->pClipDoc->GetClipParam().maRanges.Count())
-+ nSourceEnd = pCBFCP->pClipDoc->GetClipParam().maRanges.First()->aEnd.Row();
- SCROW nDestRow = nRow1;
-
- while ( nSourceRow <= nSourceEnd && nDestRow <= nRow2 )
-@@ -1795,17 +1893,20 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
-
- SCCOL nXw = 0;
- SCROW nYw = 0;
-+ ScRange aClipRange;
-+ if (pClipDoc->GetClipParam().maRanges.Count())
-+ aClipRange = *pClipDoc->GetClipParam().maRanges.First();
- for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++) // find largest merge overlap
- if (pClipDoc->pTab[nTab]) // all sheets of the clipboard content
- {
-- SCCOL nThisEndX = pClipDoc->aClipRange.aEnd.Col();
-- SCROW nThisEndY = pClipDoc->aClipRange.aEnd.Row();
-- pClipDoc->ExtendMerge( pClipDoc->aClipRange.aStart.Col(),
-- pClipDoc->aClipRange.aStart.Row(),
-+ SCCOL nThisEndX = aClipRange.aEnd.Col();
-+ SCROW nThisEndY = aClipRange.aEnd.Row();
-+ pClipDoc->ExtendMerge( aClipRange.aStart.Col(),
-+ aClipRange.aStart.Row(),
- nThisEndX, nThisEndY, nTab );
- // only extra value from ExtendMerge
-- nThisEndX = sal::static_int_cast<SCCOL>( nThisEndX - pClipDoc->aClipRange.aEnd.Col() );
-- nThisEndY = sal::static_int_cast<SCROW>( nThisEndY - pClipDoc->aClipRange.aEnd.Row() );
-+ nThisEndX = sal::static_int_cast<SCCOL>( nThisEndX - aClipRange.aEnd.Col() );
-+ nThisEndY = sal::static_int_cast<SCROW>( nThisEndY - aClipRange.aEnd.Row() );
- if ( nThisEndX > nXw )
- nXw = nThisEndX;
- if ( nThisEndY > nYw )
-@@ -1864,10 +1965,10 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
- if (bDoDouble)
- ScColumn::bDoubleAlloc = TRUE;
-
-- SCCOL nClipStartCol = pClipDoc->aClipRange.aStart.Col();
-- SCROW nClipStartRow = pClipDoc->aClipRange.aStart.Row();
-+ SCCOL nClipStartCol = aClipRange.aStart.Col();
-+ SCROW nClipStartRow = aClipRange.aStart.Row();
- // WaE: commented because unused: SCCOL nClipEndCol = pClipDoc->aClipRange.aEnd.Col();
-- SCROW nClipEndRow = pClipDoc->aClipRange.aEnd.Row();
-+ SCROW nClipEndRow = aClipRange.aEnd.Row();
- for (ULONG nRange = 0; nRange < pDestRanges->Count(); ++nRange)
- {
- const ScRange* pRange = pDestRanges->GetObject( nRange);
-@@ -1918,7 +2019,7 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
- nC2 = Min((SCCOL)(nC1 + nXw), nCol2);
- } while (nC1 <= nCol2);
- if (nClipStartRow > nClipEndRow)
-- nClipStartRow = pClipDoc->aClipRange.aStart.Row();
-+ nClipStartRow = aClipRange.aStart.Row();
- nC1 = nCol1;
- nC2 = nC1 + nXw;
- if (nC2 > nCol2)
-@@ -1991,19 +2092,78 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
- // nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
- BroadcastFromClip( nAllCol1, nAllRow1, nAllCol2, nAllRow2, rMark, nInsFlag );
- if (bResetCut)
-- pClipDoc->bCutMode = FALSE;
-+ pClipDoc->GetClipParam().mbCutMode = false;
- SetAutoCalc( bOldAutoCalc );
- }
- }
- }
-
-+void ScDocument::CopyMultiRangeFromClip(
-+ const ScAddress& rDestPos, const ScMarkData& rMark, sal_uInt16 nInsFlag, ScDocument* pClipDoc,
-+ bool bResetCut, bool bAsLink, bool bIncludeFiltered, bool bSkipAttrForEmpty)
-+{
-+ if (bIsClip)
-+ return;
-+
-+ if (!pClipDoc->bIsClip || !pClipDoc->GetTableCount())
-+ // There is nothing in the clip doc to copy.
-+ return;
-+
-+ SCCOL nCol1 = rDestPos.Col();
-+ SCROW nRow1 = rDestPos.Row();
-+ ScClipParam& rClipParam = pClipDoc->GetClipParam();
-+
-+ ScCopyBlockFromClipParams aCBFCP;
-+ aCBFCP.pRefUndoDoc = NULL;
-+ aCBFCP.pClipDoc = pClipDoc;
-+ aCBFCP.nInsFlag = nInsFlag;
-+ aCBFCP.bAsLink = bAsLink;
-+ aCBFCP.bSkipAttrForEmpty = bSkipAttrForEmpty;
-+ aCBFCP.nTabStart = MAXTAB;
-+ aCBFCP.nTabEnd = 0;
-+
-+ SCCOL nCols = rClipParam.getPasteColSize();
-+ SCROW nRows = rClipParam.getPasteRowSize();
-+ for (SCTAB j = 0; j <= MAXTAB; ++j)
-+ {
-+ if (pTab[j] && rMark.GetTableSelect(j))
-+ {
-+ if ( j < aCBFCP.nTabStart )
-+ aCBFCP.nTabStart = j;
-+ aCBFCP.nTabEnd = j;
-+ }
-+ }
-+
-+ if (!bSkipAttrForEmpty)
-+ {
-+ sal_uInt16 nDelFlag = IDF_CONTENTS;
-+ DeleteArea(nCol1, nRow1, nCol1+nCols-1, nRow1+nRows-1, rMark, nDelFlag);
-+ }
-+
-+ for (ScRange* p = rClipParam.maRanges.First(); p; p = rClipParam.maRanges.Next())
-+ {
-+ SCsCOL nDx = static_cast<SCsCOL>(nCol1 - p->aStart.Col());
-+ SCsROW nDy = static_cast<SCsROW>(nRow1 - p->aStart.Row());
-+ SCCOL nCol2 = nCol1 + p->aEnd.Col() - p->aStart.Col();
-+ SCROW nRow2 = nRow1 + p->aEnd.Row() - p->aStart.Row();
-+
-+ CopyBlockFromClip(nCol1, nRow1, nCol2, nRow2, rMark, nDx, nDy, &aCBFCP);
-+
-+ if (rClipParam.meDirection == ScClipParam::Column)
-+ nCol1 += p->aEnd.Col() - p->aStart.Col() + 1;
-+ if (rClipParam.meDirection == ScClipParam::Row)
-+ nRow1 += p->aEnd.Row() - p->aStart.Row() + 1;
-+ }
-+}
-
- void ScDocument::SetClipArea( const ScRange& rArea, BOOL bCut )
- {
- if (bIsClip)
- {
-- aClipRange = rArea;
-- bCutMode = bCut;
-+ ScClipParam& rClipParam = GetClipParam();
-+ rClipParam.maRanges.RemoveAll();
-+ rClipParam.maRanges.Append(rArea);
-+ rClipParam.mbCutMode = bCut;
- }
- else
- {
-@@ -2014,34 +2174,54 @@ void ScDocument::SetClipArea( const ScRange& rArea, BOOL bCut )
-
- void ScDocument::GetClipArea(SCCOL& nClipX, SCROW& nClipY, BOOL bIncludeFiltered)
- {
-- if (bIsClip)
-- {
-- nClipX = aClipRange.aEnd.Col() - aClipRange.aStart.Col();
--
-- if ( bIncludeFiltered )
-- nClipY = aClipRange.aEnd.Row() - aClipRange.aStart.Row();
-- else
-- {
-- // count non-filtered rows
-- // count on first used table in clipboard
-- SCTAB nCountTab = 0;
-- while ( nCountTab < MAXTAB && !pTab[nCountTab] )
-- ++nCountTab;
--
-- SCROW nResult = GetRowFlagsArray( nCountTab).CountForCondition(
-- aClipRange.aStart.Row(), aClipRange.aEnd.Row(),
-- CR_FILTERED, 0);
--
-- if ( nResult > 0 )
-- nClipY = nResult - 1;
-- else
-- nClipY = 0; // always return at least 1 row
-- }
-- }
-- else
-- {
-+ if (!bIsClip)
-+ {
- DBG_ERROR("GetClipArea: kein Clip");
-- }
-+ return;
-+ }
-+
-+ ScRangeList& rClipRanges = GetClipParam().maRanges;
-+ if (!rClipRanges.Count())
-+ // No clip range. Bail out.
-+ return;
-+
-+ ScRangePtr p = rClipRanges.First();
-+ SCCOL nStartCol = p->aStart.Col();
-+ SCCOL nEndCol = p->aEnd.Col();
-+ SCROW nStartRow = p->aStart.Row();
-+ SCROW nEndRow = p->aEnd.Row();
-+ for (p = rClipRanges.Next(); p; p = rClipRanges.Next())
-+ {
-+ if (p->aStart.Col() < nStartCol)
-+ nStartCol = p->aStart.Col();
-+ if (p->aStart.Row() < nStartRow)
-+ nStartRow = p->aStart.Row();
-+ if (p->aEnd.Col() > nEndCol)
-+ nEndCol = p->aEnd.Col();
-+ if (p->aEnd.Row() < nEndRow)
-+ nEndRow = p->aEnd.Row();
-+ }
-+
-+ nClipX = nEndCol - nStartCol;
-+
-+ if ( bIncludeFiltered )
-+ nClipY = nEndRow - nStartRow;
-+ else
-+ {
-+ // count non-filtered rows
-+ // count on first used table in clipboard
-+ SCTAB nCountTab = 0;
-+ while ( nCountTab < MAXTAB && !pTab[nCountTab] )
-+ ++nCountTab;
-+
-+ SCROW nResult = GetRowFlagsArray( nCountTab).CountForCondition(
-+ nStartRow, nEndRow, CR_FILTERED, 0);
-+
-+ if ( nResult > 0 )
-+ nClipY = nResult - 1;
-+ else
-+ nClipY = 0; // always return at least 1 row
-+ }
- }
-
-
-@@ -2049,8 +2229,12 @@ void ScDocument::GetClipStart(SCCOL& nClipX, SCROW& nClipY)
- {
- if (bIsClip)
- {
-- nClipX = aClipRange.aStart.Col();
-- nClipY = aClipRange.aStart.Row();
-+ ScRangeList& rClipRanges = GetClipParam().maRanges;
-+ if (rClipRanges.Count())
-+ {
-+ nClipX = rClipRanges.First()->aStart.Col();
-+ nClipY = rClipRanges.First()->aStart.Row();
-+ }
- }
- else
- {
-@@ -2066,8 +2250,12 @@ BOOL ScDocument::HasClipFilteredRows()
- while ( nCountTab < MAXTAB && !pTab[nCountTab] )
- ++nCountTab;
-
-- return GetRowFlagsArray( nCountTab).HasCondition( aClipRange.aStart.Row(),
-- aClipRange.aEnd.Row(), CR_FILTERED, CR_FILTERED);
-+ ScRangeList& rClipRanges = GetClipParam().maRanges;
-+ if (!rClipRanges.Count())
-+ return false;
-+
-+ return GetRowFlagsArray( nCountTab).HasCondition( rClipRanges.First()->aStart.Row(),
-+ rClipRanges.First()->aEnd.Row(), CR_FILTERED, CR_FILTERED);
- }
-
-
-diff --git sc/source/core/data/makefile.mk sc/source/core/data/makefile.mk
-index bd0ded7..2abd0d8 100644
---- sc/source/core/data/makefile.mk
-+++ sc/source/core/data/makefile.mk
-@@ -56,6 +56,7 @@ SLOFILES = \
- $(SLO)$/bcaslot.obj \
- $(SLO)$/cell.obj \
- $(SLO)$/cell2.obj \
-+ $(SLO)$/clipparam.obj \
- $(SLO)$/column.obj \
- $(SLO)$/column2.obj \
- $(SLO)$/column3.obj \
-diff --git sc/source/core/data/table2.cxx sc/source/core/data/table2.cxx
-index 2f92042..b92cbf8 100644
---- sc/source/core/data/table2.cxx
-+++ sc/source/core/data/table2.cxx
-@@ -367,6 +367,16 @@ void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
- }
- }
-
-+void ScTable::CopyToClip(const ScRangeList& rRanges, ScTable* pTable,
-+ bool bKeepScenarioFlags, bool bCloneNoteCaptions)
-+{
-+ ScRangeList aRanges(rRanges);
-+ for (ScRangePtr p = aRanges.First(); p; p = aRanges.Next())
-+ {
-+ CopyToClip(p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(),
-+ pTable, bKeepScenarioFlags, bCloneNoteCaptions);
-+ }
-+}
-
- void ScTable::CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
- SCsCOL nDx, SCsROW nDy, USHORT nInsFlag,
-diff --git sc/source/ui/inc/viewfunc.hxx sc/source/ui/inc/viewfunc.hxx
-index 051a705..243628c 100644
---- sc/source/ui/inc/viewfunc.hxx
-+++ sc/source/ui/inc/viewfunc.hxx
-@@ -359,6 +359,10 @@ 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,
-+ InsCellCmd eMoveMode, sal_uInt16 nUndoExtraFlags );
-+
- USHORT GetOptimalColWidth( SCCOL nCol, SCTAB nTab, BOOL bFormula );
-
- void StartFormatArea();
-diff --git sc/source/ui/view/cellsh.cxx sc/source/ui/view/cellsh.cxx
-index 53e283c..a1a07ea 100644
---- sc/source/ui/view/cellsh.cxx
-+++ sc/source/ui/view/cellsh.cxx
-@@ -205,8 +205,8 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet )
- bDisable = (!bSimpleArea) || GetViewData()->SimpleRowMarked();
- break;
-
-- case SID_COPY: // Kopieren
-- bDisable = (!bSimpleArea && eMarkType != SC_MARK_SIMPLE_FILTERED);
-+ 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 sc/source/ui/view/cellsh1.cxx sc/source/ui/view/cellsh1.cxx
-index 0868d72..e14bd59 100644
---- sc/source/ui/view/cellsh1.cxx
-+++ sc/source/ui/view/cellsh1.cxx
-@@ -125,6 +125,32 @@ using namespace ::com::sun::star;
- using namespace ::com::sun::star::beans;
- using namespace ::com::sun::star::uno;
-
-+
-+#include <stdio.h>
-+#include <string>
-+
-+namespace {
-+
-+class StackPrinter
-+{
-+public:
-+ explicit StackPrinter(const char* msg) :
-+ msMsg(msg)
-+ {
-+ fprintf(stdout, "%s: --begin\n", msMsg.c_str());
-+ }
-+
-+ ~StackPrinter()
-+ {
-+ fprintf(stdout, "%s: --end\n", msMsg.c_str());
-+ }
-+
-+private:
-+ ::std::string msMsg;
-+};
-+
-+}
-+
- //------------------------------------------------------------------
- void ScCellShell::ExecuteEdit( SfxRequest& rReq )
- {
-diff --git sc/source/ui/view/editsh.cxx sc/source/ui/view/editsh.cxx
-index ac3983e..5f4ee6a 100644
---- sc/source/ui/view/editsh.cxx
-+++ sc/source/ui/view/editsh.cxx
-@@ -215,7 +215,7 @@ void ScEditShell::Execute( SfxRequest& rReq )
- }
- break;
-
-- case SID_COPY:
-+ case SID_COPY:
- pTableView->Copy();
- break;
-
-diff --git sc/source/ui/view/tabvwsh4.cxx sc/source/ui/view/tabvwsh4.cxx
-index 551ce8a..3d49c52 100644
---- sc/source/ui/view/tabvwsh4.cxx
-+++ sc/source/ui/view/tabvwsh4.cxx
-@@ -1513,7 +1513,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 sc/source/ui/view/viewfun3.cxx sc/source/ui/view/viewfun3.cxx
-index a675074..f548c0c 100644
---- sc/source/ui/view/viewfun3.cxx
-+++ sc/source/ui/view/viewfun3.cxx
-@@ -210,9 +210,38 @@
- #include "drwtrans.hxx"
- #include "docuno.hxx"
- #include "undodat.hxx" // Amelia Wang
-+#include "clipparam.hxx"
-
- using namespace com::sun::star;
-
-+
-+#include <stdio.h>
-+#include <string>
-+
-+namespace {
-+
-+class StackPrinter
-+{
-+public:
-+ explicit StackPrinter(const char* msg) :
-+ msMsg(msg)
-+ {
-+ fprintf(stdout, "%s: --begin\n", msMsg.c_str());
-+ fflush(stdout);
-+ }
-+
-+ ~StackPrinter()
-+ {
-+ fprintf(stdout, "%s: --end\n", msMsg.c_str());
-+ fflush(stdout);
-+ }
-+
-+private:
-+ ::std::string msMsg;
-+};
-+
-+}
-+
- // STATIC DATA ---------------------------------------------------------------
-
-
-@@ -310,10 +339,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(),
-@@ -380,10 +409,126 @@ 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.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))
-+ {
-+ bValidRanges = false;
-+ break;
-+ }
-+
-+ 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(), &rMark, false, false, false);
-+
-+ 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)
-- ErrorMessage(STR_NOMULTISELECT);
-+ if (!bApi)
-+ ErrorMessage(STR_NOMULTISELECT);
- }
-
- return bDone;
-@@ -755,6 +900,11 @@ BOOL ScViewFunc::PasteFromClip( USHORT nFlags, ScDocument* pClipDoc,
- return FALSE;
- }
-
-+ ScClipParam& rClipParam = pClipDoc->GetClipParam();
-+ if (rClipParam.isMultiRange())
-+ return PasteMultiRangesFromClip(nFlags, pClipDoc, nFunction, bSkipEmpty, bTranspose, bAsLink,
-+ eMoveMode, nUndoExtraFlags);
-+
- // fuer Undo etc. immer alle oder keine Inhalte sichern
- USHORT nContFlags = IDF_NONE;
- if (nFlags & IDF_CONTENTS)
-diff --git sc/source/ui/view/viewfun4.cxx sc/source/ui/view/viewfun4.cxx
-index d3bf9ec..1ff54ec 100644
---- sc/source/ui/view/viewfun4.cxx
-+++ sc/source/ui/view/viewfun4.cxx
-@@ -81,9 +81,36 @@
- #include "impex.hxx"
- #include "editutil.hxx"
- #include "editable.hxx"
-+#include "clipparam.hxx"
-
- using namespace com::sun::star;
-
-+
-+#include <stdio.h>
-+#include <string>
-+
-+namespace {
-+
-+class StackPrinter
-+{
-+public:
-+ explicit StackPrinter(const char* msg) :
-+ msMsg(msg)
-+ {
-+ fprintf(stdout, "%s: --begin\n", msMsg.c_str());
-+ }
-+
-+ ~StackPrinter()
-+ {
-+ fprintf(stdout, "%s: --end\n", msMsg.c_str());
-+ }
-+
-+private:
-+ ::std::string msMsg;
-+};
-+
-+}
-+
- // STATIC DATA -----------------------------------------------------------
-
- BOOL bPasteIsDrop = FALSE;
-@@ -188,6 +215,128 @@ void ScViewFunc::PasteRTF( SCCOL nStartCol, SCROW nStartRow,
- }
- }
-
-+namespace {
-+
-+class CursorSwitcher
-+{
-+public:
-+ CursorSwitcher(ScViewFunc* pViewFunc) :
-+ mpViewFunc(pViewFunc)
-+ {
-+ mpViewFunc->HideCursor();
-+ }
-+
-+ ~CursorSwitcher()
-+ {
-+ mpViewFunc->ShowCursor();
-+ }
-+private:
-+ ScViewFunc* mpViewFunc;
-+};
-+
-+}
-+
-+bool ScViewFunc::PasteMultiRangesFromClip(
-+ sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction,
-+ bool bSkipEmpty, bool bTranspose, bool bAsLink, InsCellCmd eMoveMode, sal_uInt16 nUndoExtraFlags)
-+{
-+ sal_uInt16 nContFlags = IDF_NONE;
-+ if (nFlags & IDF_CONTENTS)
-+ nContFlags |= IDF_CONTENTS;
-+ if (nFlags & IDF_ATTRIB)
-+ nContFlags |= IDF_ATTRIB;
-+ // evtl. Attribute ins Undo ohne sie vom Clip ins Doc zu kopieren
-+ sal_uInt16 nUndoFlags = nContFlags;
-+ if (nUndoExtraFlags & IDF_ATTRIB)
-+ nUndoFlags |= IDF_ATTRIB;
-+ // do not copy note captions into undo document
-+ nUndoFlags |= IDF_NOCAPTIONS;
-+
-+ 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();
-+
-+ // 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;
-+
-+ if (bTranspose)
-+ {
-+ if (nRowSize > 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);
-+ }
-+
-+ // 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);
-+ aMark.SetMarkArea(aMarkedRange);
-+
-+ ::std::auto_ptr<ScDocument> pUndoDoc;
-+ if (pDoc->IsUndoEnabled())
-+ {
-+ pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
-+ pUndoDoc->InitUndoSelected(pDoc, aMark, false, false);
-+ pDoc->CopyToDocument(aMarkedRange, IDF_ALL, 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);
-+ }
-+ }
-+
-+ CursorSwitcher aCursorSwitch(this);
-+ MarkRange(aMarkedRange);
-+ pDoc->CopyMultiRangeFromClip(rCurPos, aMark, nContFlags, pClipDoc,
-+ true, bAsLink, false, bSkipEmpty);
-+
-+ if (pMixDoc.get())
-+ pDoc->MixDocument(aMarkedRange, nFunction, bSkipEmpty, pMixDoc.get());
-+
-+ pDocSh->PostPaint(rCurPos.Col(), rCurPos.Row(), rCurPos.Tab(),
-+ rCurPos.Col()+nColSize-1, rCurPos.Row()+nRowSize-1, rCurPos.Tab(),
-+ PAINT_GRID);
-+
-+ if (pDoc->IsUndoEnabled())
-+ {
-+ 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, IDF_ALL, NULL, NULL, NULL, NULL, false);
-+ pDocSh->GetUndoManager()->AddUndoAction(pUndo, false);
-+ }
-+ return true;
-+}
-+
- // Thesaurus - Undo ok
- void ScViewFunc::DoThesaurus( BOOL bRecord )
- {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]