ooo-build r15454 - trunk/patches/test



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]