summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorscito <info@scito.ch>2021-04-21 07:36:43 +0200
committerJan Holesovsky <kendy@collabora.com>2021-04-22 15:11:17 +0200
commit6491c205acb3c166d93ef6a41199d344e21d98ac (patch)
tree7f272b39ad7afdc1fc18d86613eb935a1495850b /sc
parent75213d163b53e7002404c26fcd9cd63776a53eae (diff)
tdf#107348 tdf#45958 tdf#141215 tdf#141683 fix filtered/transpose paste
Row filtering, Special Paste transposing and multi range selections had various issues. Since the same methods are used in different code paths, I made a unified fix for these issues. Moreover, Special Paste dialog allows the combination of options. There are about 50 test cases for these various combinations of filtering, selection, transposing and pasting options. The following cases are supported and checked in test combinations: * Transposing * Filtering * Multi range column and row selection * All cell types: number, string, formula, rich text, empty * Notes * Formatting patterns (e.g. cell backgrounds and borders) * Empty cell skipping * Special Paste as link * Merged cells * Formula references: * Relative and absolute references * References to rows before and after filtered row * References to filtered row * Double references (e.g. A1:A3) Notably the following cases are fixed and tested: * Transposing of filtered data (tdf#107348) * Copy/Paste of filtered multi range selections (tdf#45958) * Transposing of filtered multi range selections (tdf#107348, tdf#45958) * Notes at different position (tdf#141215 ^) * Transposed multi range selection pasted as link (tdf#141683 ^) ^ = discovered during tests Due to the unit tests, I refactored some code. Mainly, I extracted methods to improve the readability and to avoid code duplication. Change-Id: Iccccd17d3b4deee29ac5fc7c11e17244da0d4054 Change-Id: I43cf630890e0081e55fd04cf2f8e5afdb6d9bebe Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114450 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> Reviewed-by: Jan Holesovsky <kendy@collabora.com>
Diffstat (limited to 'sc')
-rwxr-xr-x[-rw-r--r--]sc/inc/clipparam.hxx10
-rwxr-xr-x[-rw-r--r--]sc/inc/document.hxx12
-rwxr-xr-x[-rw-r--r--]sc/inc/table.hxx29
-rwxr-xr-x[-rw-r--r--]sc/qa/unit/ucalc.cxx5361
-rwxr-xr-x[-rw-r--r--]sc/qa/unit/ucalc.hxx122
-rwxr-xr-x[-rw-r--r--]sc/qa/unit/uicalc/uicalc.cxx45
-rwxr-xr-x[-rw-r--r--]sc/source/core/data/clipparam.cxx50
-rwxr-xr-x[-rw-r--r--]sc/source/core/data/document.cxx124
-rwxr-xr-x[-rw-r--r--]sc/source/core/data/formulacell.cxx22
-rwxr-xr-x[-rw-r--r--]sc/source/core/data/table2.cxx258
-rwxr-xr-x[-rw-r--r--]sc/source/ui/inc/viewfunc.hxx7
-rwxr-xr-x[-rw-r--r--]sc/source/ui/view/viewfun3.cxx30
12 files changed, 5919 insertions, 151 deletions
diff --git a/sc/inc/clipparam.hxx b/sc/inc/clipparam.hxx
index 7a4513ffb502..55f37fe1d89e 100644..100755
--- a/sc/inc/clipparam.hxx
+++ b/sc/inc/clipparam.hxx
@@ -21,6 +21,7 @@
#include "rangelst.hxx"
#include "charthelper.hxx"
+#include "document.hxx"
/**
* This struct stores general clipboard parameters associated with a
@@ -52,14 +53,19 @@ struct SC_DLLPUBLIC ScClipParam
* Same as the above method, but returns the row size of the compressed
* range.
*/
- SCROW getPasteRowSize();
+ SCROW getPasteRowSize(const ScDocument& rSrcDoc, bool bIncludeFiltered);
/**
* Return a single range that encompasses all individual ranges.
*/
ScRange getWholeRange() const;
- void transpose();
+ /**
+ * Transpose the clip parameters.
+ * Filtered rows are removed from parameters.
+ */
+ void transpose(const ScDocument& rSrcDoc, bool bIncludeFiltered,
+ bool bIsMultiRangeRowFilteredTranspose);
sal_uInt32 getSourceDocID() const { return mnSourceDocID; }
void setSourceDocID( sal_uInt32 nVal ) { mnSourceDocID = nVal; }
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 96d7ec940059..f90e74e9c030 100644..100755
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1605,9 +1605,12 @@ public:
void CopyBlockFromClip( sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1,
SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
SCCOL nDx, SCROW nDy );
- void CopyNonFilteredFromClip( sc::CopyFromClipContext& rCxt, SCCOL nCol1,
- SCROW nRow1, SCCOL nCol2, SCROW nRow2,
- const ScMarkData& rMark, SCCOL nDx, SCROW & rClipStartRow );
+ /**
+ * @return the number of non-filtered rows.
+ */
+ SCROW CopyNonFilteredFromClip(sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark, SCCOL nDx,
+ SCROW& rClipStartRow, SCROW nClipEndRow);
void StartListeningFromClip( SCCOL nCol1, SCROW nRow1,
SCCOL nCol2, SCROW nRow2,
@@ -1642,7 +1645,8 @@ public:
bool IsClipboardSource() const;
- SC_DLLPUBLIC void TransposeClip( ScDocument* pTransClip, InsertDeleteFlags nFlags, bool bAsLink );
+ SC_DLLPUBLIC void TransposeClip(ScDocument* pTransClip, InsertDeleteFlags nFlags, bool bAsLink,
+ bool bIncludeFiltered);
ScClipParam& GetClipParam();
void SetClipParam(const ScClipParam& rParam);
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 211e317cb06d..416cbb5d9337 100644..100755
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -540,10 +540,15 @@ public:
void CopyConditionalFormat( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
SCCOL nDx, SCROW nDy, const ScTable* pTable);
- void TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
- ScTable* pTransClip, InsertDeleteFlags nFlags, bool bAsLink );
+ /**
+ * @param nRowDestOffset adjustment of destination row position;
+ * used for transposed multi range selection with row direction, otherwise 0
+ */
+ void TransposeClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCROW nRowDestOffset,
+ ScTable* pTransClip, InsertDeleteFlags nFlags, bool bAsLink,
+ bool bIncludeFiltered);
- // mark of this document
+ // mark of this document
void MixMarked(
sc::MixDocContext& rCxt, const ScMarkData& rMark, ScPasteFunc nFunction,
bool bSkipEmpty, const ScTable* pSrcTab );
@@ -1246,8 +1251,22 @@ private:
SCCOL FindNextVisibleCol(SCCOL nCol, bool bRight) const;
- // Clipboard transpose for notes
- void TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1, SCROW nRow2);
+ /**
+ * Transpose clipboard patterns
+ * @param nRowDestOffset adjustment of destination row position;
+ * used for transposed multi range row selections, otherwise 0
+ */
+ void TransposeColPatterns(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1,
+ SCROW nRow2, bool bIncludeFiltered,
+ const std::vector<SCROW>& rFilteredRows, SCROW nRowDestOffset);
+
+ /**
+ * Transpose clipboard notes
+ * @param nRowDestOffset adjustment of destination row position;
+ * used for transposed multi range row selections, otherwise 0
+ */
+ void TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1, SCROW nRow2,
+ bool bIncludeFiltered, SCROW nRowDestOffset);
ScColumn* FetchColumn( SCCOL nCol );
const ScColumn* FetchColumn( SCCOL nCol ) const;
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 52dedc42c070..02988bdd5ff4 100644..100755
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -20,6 +20,7 @@
#include <scdll.hxx>
#include <formulacell.hxx>
#include <simpleformulacalc.hxx>
+#include <formulaopt.hxx>
#include <stringutil.hxx>
#include <scmatrix.hxx>
#include <drwlayer.hxx>
@@ -158,6 +159,20 @@ void Test::tearDown()
BootstrapFixture::tearDown();
}
+static ScMF lcl_getMergeFlagOfCell(const ScDocument& rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab)
+{
+ const SfxPoolItem& rPoolItem = rDoc.GetPattern(nCol, nRow, nTab)->GetItem(ATTR_MERGE_FLAG);
+ const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
+ return rMergeFlag.GetValue();
+}
+
+static ScAddress lcl_getMergeSizeOfCell(const ScDocument& rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab)
+{
+ const SfxPoolItem& rPoolItem = rDoc.GetPattern(nCol, nRow, nTab)->GetItem(ATTR_MERGE);
+ const ScMergeAttr& rMerge = static_cast<const ScMergeAttr&>(rPoolItem);
+ return ScAddress(rMerge.GetColMerge(), rMerge.GetRowMerge(), nTab);
+}
+
void Test::testCollator()
{
CollatorWrapper* p = ScGlobal::GetCollator();
@@ -2050,10 +2065,10 @@ void Test::testCellCopy()
ScAddress aDest(0,1,0);
OUString aStr("please copy me");
m_pDoc->SetString(aSrc, "please copy me");
- CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aSrc), aStr);
+ CPPUNIT_ASSERT_EQUAL(aStr, m_pDoc->GetString(aSrc));
// copy to self - why not ?
m_pDoc->CopyCellToDocument(aSrc,aDest,*m_pDoc);
- CPPUNIT_ASSERT_EQUAL(m_pDoc->GetString(aDest), aStr);
+ CPPUNIT_ASSERT_EQUAL(aStr, m_pDoc->GetString(aDest));
}
void Test::testSheetCopy()
@@ -3649,7 +3664,6 @@ void Test::testCopyPasteAsLink()
void Test::testCopyPasteTranspose()
{
m_pDoc->InsertTab(0, "Sheet1");
- m_pDoc->InsertTab(1, "Sheet2");
// We need a drawing layer in order to create caption objects.
m_pDoc->InitDrawLayer(&getDocShell());
@@ -3677,7 +3691,7 @@ void Test::testCopyPasteTranspose()
copyToClip(m_pDoc, aSrcRange, &aNewClipDoc);
ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
- aNewClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::ALL, false);
+ aNewClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::ALL, false, false);
ScRange aDestRange(3,1,1,3,3,1);//target: Sheet2.D2:D4
ScMarkData aMark(m_pDoc->GetSheetLimits());
@@ -3689,9 +3703,9 @@ void Test::testCopyPasteTranspose()
OUString aString = m_pDoc->GetString(3, 3, 1);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell Sheet2.D4 should contain: test", OUString("test"), aString);
double fValue = m_pDoc->GetValue(ScAddress(3,1,1));
- ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell should return 1", fValue, 1);
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell should return 1", 1, fValue);
fValue = m_pDoc->GetValue(ScAddress(3,2,1));
- ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula should return 2", fValue, 2);
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula should return 2", 2, fValue);
m_pDoc->GetFormula(3, 2, 1, aString);
CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula should point on Sheet2.D2", OUString("=D2+1"), aString);
@@ -3700,15 +3714,5344 @@ void Test::testCopyPasteTranspose()
CPPUNIT_ASSERT_MESSAGE("There should be a note on Sheet2.D3", m_pDoc->HasNote(ScAddress(3, 2, 1)));
CPPUNIT_ASSERT_MESSAGE("There should be a note on Sheet2.D4", m_pDoc->HasNote(ScAddress(3, 3, 1)));
CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on Sheet2.D2",
- m_pDoc->GetNote(ScAddress(3, 1, 1))->GetText(), m_pDoc->GetNote(ScAddress(0, 0, 0))->GetText());
+ m_pDoc->GetNote(ScAddress(0, 0, 0))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, 1))->GetText());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on Sheet2.D3",
- m_pDoc->GetNote(ScAddress(3, 2, 1))->GetText(), m_pDoc->GetNote(ScAddress(1, 0, 0))->GetText());
+ m_pDoc->GetNote(ScAddress(1, 0, 0))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, 1))->GetText());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on Sheet2.D4",
- m_pDoc->GetNote(ScAddress(3, 3, 1))->GetText(), m_pDoc->GetNote(ScAddress(2, 0, 0))->GetText());
+ m_pDoc->GetNote(ScAddress(2, 0, 0))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 3, 1))->GetText());
m_pDoc->DeleteTab(1);
m_pDoc->DeleteTab(0);
+}
+
+void Test::testCopyPasteSpecialMergedCellsTranspose()
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // Turn on auto calc.
+
+ m_pDoc->InsertTab(srcSheet, "Sheet1");
+ m_pDoc->InsertTab(destSheet, "Sheet2");
+
+ m_pDoc->SetValue(0, 0, srcSheet, 1); // A1
+ m_pDoc->SetValue(0, 1, srcSheet, 2); // A2
+ m_pDoc->SetValue(0, 2, srcSheet, 3); // A3
+ m_pDoc->SetValue(0, 3, srcSheet, 4); // A4
+
+ m_pDoc->DoMerge(srcSheet, 0, 1, 1, 1, false); // Merge A2 and B2
+ m_pDoc->DoMerge(srcSheet, 0, 2, 1, 2, false); // Merge A3 and B3
+
+ // Test precondition
+ CPPUNIT_ASSERT_EQUAL(ScAddress(0, 0, srcSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 0, 0, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScMF::NONE, lcl_getMergeFlagOfCell(*m_pDoc, 1, 0, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(2, 1, srcSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 0, 1, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(0, 0, srcSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 1, 1, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScMF::Hor, lcl_getMergeFlagOfCell(*m_pDoc, 1, 1, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(2, 1, srcSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 0, 2, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(0, 0, srcSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 1, 2, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScMF::Hor, lcl_getMergeFlagOfCell(*m_pDoc, 1, 2, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(0, 0, srcSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 0, 3, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScMF::NONE, lcl_getMergeFlagOfCell(*m_pDoc, 1, 3, srcSheet));
+
+ ScRange aSrcRange(0, 0, srcSheet, 1, 3, srcSheet); // Copy A1:B4 to clip.
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ copyToClip(m_pDoc, aSrcRange, &aClipDoc);
+
+ // transpose
+ ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ aClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::ALL, true, false);
+
+ ScRange aDestRange(1, 1, destSheet, 4, 2, destSheet); // Paste to B2:E3 on Sheet2.
+ ScMarkData aMark(m_pDoc->GetSheetLimits());
+ aMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::ALL, nullptr, pTransClip.get(), true,
+ false);
+ pTransClip.reset();
+
+ // Check transpose of merged cells
+ CPPUNIT_ASSERT_EQUAL(ScAddress(0, 0, destSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 1, 1, destSheet));
+ CPPUNIT_ASSERT_EQUAL(ScMF::NONE, lcl_getMergeFlagOfCell(*m_pDoc, 1, 2, destSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(1, 2, destSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 2, 1, destSheet));
+ CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(2, 1, destSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(1, 2, destSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 3, 1, destSheet));
+ CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(3, 1, destSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(0, 0, destSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 4, 1, destSheet));
+ CPPUNIT_ASSERT_EQUAL(ScMF::NONE, lcl_getMergeFlagOfCell(*m_pDoc, 4, 2, destSheet));
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+void Test::testCopyPasteSpecialMergedCellsFilteredTranspose()
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // Turn on auto calc.
+
+ m_pDoc->InsertTab(srcSheet, "Sheet1");
+ m_pDoc->InsertTab(destSheet, "Sheet2");
+
+ m_pDoc->SetValue(0, 0, srcSheet, 1); // A1
+ m_pDoc->SetValue(0, 1, srcSheet, 2); // A2
+ m_pDoc->SetValue(0, 2, srcSheet, 3); // A3
+ m_pDoc->SetValue(0, 3, srcSheet, 4); // A4
+
+ m_pDoc->DoMerge(srcSheet, 0, 1, 1, 1, false); // Merge A2 and B2
+ m_pDoc->DoMerge(srcSheet, 0, 2, 1, 2, false); // Merge A3 and B3
+
+ // Filter row 1
+ ScDBData* pDBData = new ScDBData("TRANSPOSE_TEST_DATA", srcSheet, 0, 0, 0, 3);
+ m_pDoc->SetAnonymousDBData(0, std::unique_ptr<ScDBData>(pDBData));
+
+ pDBData->SetAutoFilter(true);
+ ScRange aRange;
+ pDBData->GetArea(aRange);
+ m_pDoc->ApplyFlagsTab(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(),
+ aRange.aStart.Row(), aRange.aStart.Tab(), ScMF::Auto);
+
+ //create the query param
+ ScQueryParam aParam;
+ pDBData->GetQueryParam(aParam);
+ ScQueryEntry& rEntry = aParam.GetEntry(0);
+ rEntry.bDoQuery = true;
+ rEntry.nField = 0;
+ rEntry.eOp = SC_NOT_EQUAL;
+ rEntry.GetQueryItem().mfVal = 2; // value of row A2 -> filtering row 1
+ // add queryParam to database range.
+ pDBData->SetQueryParam(aParam);
+
+ // perform the query.
+ m_pDoc->Query(srcSheet, aParam, true);
+
+ // Test precondition
+ CPPUNIT_ASSERT_EQUAL(ScAddress(0, 0, srcSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 0, 0, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScMF::NONE, lcl_getMergeFlagOfCell(*m_pDoc, 1, 0, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(2, 1, srcSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 0, 1, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(0, 0, srcSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 1, 1, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScMF::Hor, lcl_getMergeFlagOfCell(*m_pDoc, 1, 1, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(2, 1, srcSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 0, 2, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(0, 0, srcSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 1, 2, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScMF::Hor, lcl_getMergeFlagOfCell(*m_pDoc, 1, 2, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(0, 0, srcSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 0, 3, srcSheet));
+ CPPUNIT_ASSERT_EQUAL(ScMF::NONE, lcl_getMergeFlagOfCell(*m_pDoc, 1, 3, srcSheet));
+
+ ScRange aSrcRange(0, 0, srcSheet, 1, 3, srcSheet); // Copy A1:B4 to clip.
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ copyToClip(m_pDoc, aSrcRange, &aClipDoc);
+
+ // transpose
+ ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ aClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::ALL, true, false);
+
+ ScRange aDestRange(1, 1, destSheet, 3, 2, destSheet); // Paste to B2:D3 on Sheet2.
+ ScMarkData aMark(m_pDoc->GetSheetLimits());
+ aMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::ALL, nullptr, pTransClip.get(), true,
+ false);
+ pTransClip.reset();
+
+ // Check transpose of merged cells
+ CPPUNIT_ASSERT_EQUAL(ScAddress(0, 0, destSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 1, 1, destSheet));
+ CPPUNIT_ASSERT_EQUAL(ScMF::NONE, lcl_getMergeFlagOfCell(*m_pDoc, 1, 2, destSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(1, 2, destSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 2, 1, destSheet));
+ CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(2, 1, destSheet));
+ CPPUNIT_ASSERT_EQUAL(ScAddress(0, 0, destSheet),
+ lcl_getMergeSizeOfCell(*m_pDoc, 3, 1, destSheet));
+ CPPUNIT_ASSERT_EQUAL(ScMF::NONE, lcl_getMergeFlagOfCell(*m_pDoc, 3, 2, destSheet));
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+// InsertDeleteFlags::CONTENTS
+void Test::testCopyPasteSpecialAsLinkTranspose()
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // Turn on auto calc.
+
+ m_pDoc->InsertTab(srcSheet, "Sheet1");
+ m_pDoc->InsertTab(destSheet, "Sheet2");
+
+ m_pDoc->SetValue(0, 0, srcSheet, 1); // A1
+ m_pDoc->SetValue(0, 1, srcSheet, 2); // A2
+ m_pDoc->SetValue(0, 3, srcSheet, 4); // A4
+
+ ScRange aSrcRange(0, 0, srcSheet, 0, 3, srcSheet); // Copy A1:A4 to clip.
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ copyToClip(m_pDoc, aSrcRange, &aClipDoc);
+
+ // transpose
+ ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ aClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::CONTENTS, true, false);
+
+ ScRange aDestRange(1, 1, destSheet, 4, 1, destSheet); // Paste to B2:E2 on Sheet2.
+ ScMarkData aMark(m_pDoc->GetSheetLimits());
+ aMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::CONTENTS, nullptr, pTransClip.get(),
+ true, false);
+ pTransClip.reset();
+
+ OUString aString;
+ // Check pasted content to make sure they reference the correct cells.
+ ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(1, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell B2.", pFC);
+ m_pDoc->GetFormula(1, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B2", OUString("=$Sheet1.$A$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(1.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(2, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell C2", OUString("=$Sheet1.$A$2"), aString);
+ CPPUNIT_ASSERT_EQUAL(2.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(3, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be no formula cell D2.", !pFC);
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(4, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(4, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell E2", OUString("=$Sheet1.$A$4"), aString);
+ CPPUNIT_ASSERT_EQUAL(4.0, pFC->GetValue());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+// InsertDeleteFlags::CONTENTS
+void Test::testCopyPasteSpecialAsLinkFilteredTranspose()
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // Turn on auto calc.
+
+ m_pDoc->InsertTab(srcSheet, "Sheet1");
+ m_pDoc->InsertTab(destSheet, "Sheet2");
+
+ m_pDoc->SetValue(0, 0, srcSheet, 1); // A1
+ m_pDoc->SetValue(0, 1, srcSheet, 2); // A2
+ m_pDoc->SetValue(0, 3, srcSheet, 4); // A4
+
+ // Filter row 1
+ ScDBData* pDBData = new ScDBData("TRANSPOSE_TEST_DATA", srcSheet, 0, 0, 0, 3);
+ m_pDoc->SetAnonymousDBData(0, std::unique_ptr<ScDBData>(pDBData));
+
+ pDBData->SetAutoFilter(true);
+ ScRange aRange;
+ pDBData->GetArea(aRange);
+ m_pDoc->ApplyFlagsTab(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(),
+ aRange.aStart.Row(), aRange.aStart.Tab(), ScMF::Auto);
+
+ //create the query param
+ ScQueryParam aParam;
+ pDBData->GetQueryParam(aParam);
+ ScQueryEntry& rEntry = aParam.GetEntry(0);
+ rEntry.bDoQuery = true;
+ rEntry.nField = 0;
+ rEntry.eOp = SC_NOT_EQUAL;
+ rEntry.GetQueryItem().mfVal = 2; // value of row A2 -> filtering row 1
+ // add queryParam to database range.
+ pDBData->SetQueryParam(aParam);
+
+ // perform the query.
+ m_pDoc->Query(srcSheet, aParam, true);
+
+ // Check precondition for test: row 1 is hidden/filtered
+ SCROW nRow1, nRow2;
+ SCROW nFilteredRow1, nFilteredRow2;
+ bool bHidden = m_pDoc->RowHidden(SCROW(1), srcSheet, &nRow1, &nRow2);
+ CPPUNIT_ASSERT_MESSAGE("row 1 should be hidden", bHidden);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("row 1 should be hidden", SCROW(1), nRow1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("row 1 should be hidden", SCROW(1), nRow2);
+ bool bFiltered = m_pDoc->RowFiltered(SCROW(1), srcSheet, &nFilteredRow1, &nFilteredRow2);
+ CPPUNIT_ASSERT_MESSAGE("row 1 should be filtered", bFiltered);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("row 1 should be filtered", SCROW(1), nFilteredRow1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("row 1 should be filtered", SCROW(1), nFilteredRow2);
+
+ // Copy A1:A4 to clip.
+ ScRange aSrcRange(0, 0, srcSheet, 0, 3, srcSheet);
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ copyToClip(m_pDoc, aSrcRange, &aClipDoc);
+
+ // transpose
+ ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ aClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::CONTENTS, true, false);
+
+ ScRange aDestRange(1, 1, destSheet, 3, 1, destSheet); // Paste to B2:D2 on Sheet2.
+ ScMarkData aMark(m_pDoc->GetSheetLimits());
+ aMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::CONTENTS, nullptr, pTransClip.get(),
+ true, false, false);
+ pTransClip.reset();
+
+ OUString aString;
+ // Check pasted content to make sure they reference the correct cells.
+ ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(1, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell B2.", pFC);
+ m_pDoc->GetFormula(1, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B2", OUString("=$Sheet1.$A$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(1.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be no formula cell C2.", !pFC);
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(3, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(3, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell D2", OUString("=$Sheet1.$A$4"), aString);
+ CPPUNIT_ASSERT_EQUAL(4.0, pFC->GetValue());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+// tdf#141683
+// InsertDeleteFlags::CONTENTS
+void Test::testCopyPasteSpecialMultiRangeRowAsLinkTranspose()
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // Turn on auto calc.
+
+ m_pDoc->InsertTab(srcSheet, "Sheet1");
+ m_pDoc->InsertTab(destSheet, "Sheet2");
+
+ m_pDoc->SetValue(0, 0, srcSheet, 1); // A1
+ m_pDoc->SetValue(1, 0, srcSheet, 2); // B1
+ m_pDoc->SetValue(3, 0, srcSheet, 4); // D1
+
+ m_pDoc->SetValue(0, 2, srcSheet, 11); // A3
+ m_pDoc->SetValue(1, 2, srcSheet, 12); // B3
+ m_pDoc->SetValue(3, 2, srcSheet, 14); // D3
+
+ ScMarkData aSrcMark(m_pDoc->GetSheetLimits());
+ aSrcMark.SelectOneTable(0);
+ ScClipParam aClipParam;
+ aClipParam.meDirection = ScClipParam::Row;
+ aClipParam.maRanges.push_back(ScRange(0, 0, srcSheet, 3, 0, srcSheet)); // A1:D1
+ aClipParam.maRanges.push_back(ScRange(0, 2, srcSheet, 3, 2, srcSheet)); // A3:D3
+
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ m_pDoc->CopyToClip(aClipParam, &aClipDoc, &aSrcMark, false, false);
+
+ // transpose
+ ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ aClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::CONTENTS, true, false);
+
+ ScRange aDestRange(1, 1, destSheet, 2, 4, destSheet); // Paste to B2:C5 on Sheet2.
+ ScMarkData aMark(m_pDoc->GetSheetLimits());
+ aMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyMultiRangeFromClip(ScAddress(1, 1, destSheet), aMark, InsertDeleteFlags::CONTENTS,
+ pTransClip.get(), true, false /* false fixes tdf#141683 */,
+ false, false);
+ pTransClip.reset();
+
+ OUString aString;
+ // Check pasted content to make sure they reference the correct cells.
+ ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(1, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell B2.", pFC);
+ m_pDoc->GetFormula(1, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B2", OUString("=$Sheet1.$A$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(1.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(1, 2, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell B3.", pFC);
+ m_pDoc->GetFormula(1, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B3", OUString("=$Sheet1.$B$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(2.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(1, 3, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be no formula cell B4.", !pFC);
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(1, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(1, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B5", OUString("=$Sheet1.$D$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(4.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell C2.", pFC);
+ m_pDoc->GetFormula(2, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell C2", OUString("=$Sheet1.$A$3"), aString);
+ CPPUNIT_ASSERT_EQUAL(11.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 2, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell C3.", pFC);
+ m_pDoc->GetFormula(2, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell C3", OUString("=$Sheet1.$B$3"), aString);
+ CPPUNIT_ASSERT_EQUAL(12.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 3, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be no formula cell C4.", !pFC);
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(2, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell C5", OUString("=$Sheet1.$D$3"), aString);
+ CPPUNIT_ASSERT_EQUAL(14.0, pFC->GetValue());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+// tdf#141683
+// InsertDeleteFlags::CONTENTS
+void Test::testCopyPasteSpecialMultiRangeRowAsLinkFilteredTranspose()
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // Turn on auto calc.
+
+ m_pDoc->InsertTab(srcSheet, "Sheet1");
+ m_pDoc->InsertTab(destSheet, "Sheet2");
+
+ m_pDoc->SetValue(0, 0, srcSheet, 1); // A1
+ m_pDoc->SetValue(1, 0, srcSheet, 2); // B1
+ m_pDoc->SetValue(3, 0, srcSheet, 4); // D1
+
+ m_pDoc->SetValue(0, 1, srcSheet, -1); // A2, filtered and selected
+ m_pDoc->SetValue(1, 1, srcSheet, -2); // B2, filtered and selected
+ m_pDoc->SetValue(3, 1, srcSheet, -4); // D2, filtered and selected
+
+ m_pDoc->SetValue(0, 2, srcSheet, 11); // A3
+ m_pDoc->SetValue(1, 2, srcSheet, 12); // B3
+ m_pDoc->SetValue(3, 2, srcSheet, 14); // D3
+
+ m_pDoc->SetValue(0, 3, srcSheet, -11); // A4, filtered and not selected
+ m_pDoc->SetValue(1, 3, srcSheet, -12); // B4, filtered and not selected
+ m_pDoc->SetValue(3, 3, srcSheet, -14); // D4, filtered and not selected
+
+ m_pDoc->SetValue(0, 5, srcSheet, 111); // A6
+ m_pDoc->SetValue(1, 5, srcSheet, 112); // B6
+ m_pDoc->SetValue(3, 5, srcSheet, 114); // D6
+
+ // Filter row 1
+ ScDBData* pDBData = new ScDBData("TRANSPOSE_TEST_DATA", srcSheet, 0, 0, 3, 3);
+ m_pDoc->SetAnonymousDBData(0, std::unique_ptr<ScDBData>(pDBData));
+
+ pDBData->SetAutoFilter(true);
+ ScRange aRange;
+ pDBData->GetArea(aRange);
+ m_pDoc->ApplyFlagsTab(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(),
+ aRange.aStart.Row(), aRange.aStart.Tab(), ScMF::Auto);
+
+ //create the query param
+ ScQueryParam aParam;
+ pDBData->GetQueryParam(aParam);
+ ScQueryEntry& rEntry = aParam.GetEntry(0);
+ rEntry.bDoQuery = true;
+ rEntry.nField = 0;
+ rEntry.eOp = SC_GREATER_EQUAL;
+ rEntry.GetQueryItem().mfVal = 0; // filtering neative values -> filtering row 1 and 2
+ // add queryParam to database range.
+ pDBData->SetQueryParam(aParam);
+
+ // perform the query.
+ m_pDoc->Query(srcSheet, aParam, true);
+
+ ScMarkData aSrcMark(m_pDoc->GetSheetLimits());
+ aSrcMark.SelectOneTable(0);
+ ScClipParam aClipParam;
+ aClipParam.meDirection = ScClipParam::Row;
+ aClipParam.maRanges.push_back(ScRange(0, 0, srcSheet, 3, 2, srcSheet)); // A1:C3
+ aClipParam.maRanges.push_back(ScRange(0, 5, srcSheet, 3, 5, srcSheet)); // A6:C6
+
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ m_pDoc->CopyToClip(aClipParam, &aClipDoc, &aSrcMark, false, false);
+
+ printRange(m_pDoc, aClipParam.getWholeRange(), "Src range");
+ // transpose
+ ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ aClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::CONTENTS, true, false);
+
+ printRange(&aClipDoc, ScRange(0, 0, 0, 4, 5, 0), "Base doc (&aNewClipDoc)");
+ printRange(pTransClip.get(), ScRange(0, 0, 0, 3, 3, 0),
+ "Transposed filtered clipdoc (pTransClip.get())");
+ ScRange aDestRange(1, 1, destSheet, 3, 4, destSheet); // Paste to B2:D5 on Sheet2.
+ ScMarkData aMark(m_pDoc->GetSheetLimits());
+ aMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyMultiRangeFromClip(ScAddress(1, 1, destSheet), aMark, InsertDeleteFlags::CONTENTS,
+ pTransClip.get(), true, false /* false fixes tdf#141683 */,
+ false, false);
+ pTransClip.reset();
+ printRange(m_pDoc, aDestRange, "Transposed dest sheet");
+
+ OUString aString;
+ // Check pasted content to make sure they reference the correct cells.
+ ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(1, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell B2.", pFC);
+ m_pDoc->GetFormula(1, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B2", OUString("=$Sheet1.$A$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(1.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(1, 2, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell B3.", pFC);
+ m_pDoc->GetFormula(1, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B3", OUString("=$Sheet1.$B$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(2.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(1, 3, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be no formula cell B4.", !pFC);
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(1, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(1, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B5", OUString("=$Sheet1.$D$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(4.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell C2.", pFC);
+ m_pDoc->GetFormula(2, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell C2", OUString("=$Sheet1.$A$3"), aString);
+ CPPUNIT_ASSERT_EQUAL(11.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 2, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell C3.", pFC);
+ m_pDoc->GetFormula(2, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell C3", OUString("=$Sheet1.$B$3"), aString);
+ CPPUNIT_ASSERT_EQUAL(12.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 3, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be no formula cell C4.", !pFC);
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(2, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell C5", OUString("=$Sheet1.$D$3"), aString);
+ CPPUNIT_ASSERT_EQUAL(14.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(3, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell D2.", pFC);
+ m_pDoc->GetFormula(3, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell D2", OUString("=$Sheet1.$A$6"), aString);
+ CPPUNIT_ASSERT_EQUAL(111.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(3, 2, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell D3.", pFC);
+ m_pDoc->GetFormula(3, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell D3", OUString("=$Sheet1.$B$6"), aString);
+ CPPUNIT_ASSERT_EQUAL(112.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(3, 3, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be no formula cell D4.", !pFC);
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(3, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(3, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell D5", OUString("=$Sheet1.$D$6"), aString);
+ CPPUNIT_ASSERT_EQUAL(114.0, pFC->GetValue());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+// tdf#141683
+// InsertDeleteFlags::CONTENTS
+void Test::testCopyPasteSpecialMultiRangeColAsLinkTranspose()
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // Turn on auto calc.
+
+ m_pDoc->InsertTab(srcSheet, "Sheet1");
+ m_pDoc->InsertTab(destSheet, "Sheet2");
+
+ m_pDoc->SetValue(0, 0, srcSheet, 1); // A1
+ m_pDoc->SetValue(0, 1, srcSheet, 2); // A2
+ m_pDoc->SetValue(0, 3, srcSheet, 4); // A4
+
+ m_pDoc->SetValue(2, 0, srcSheet, 11); // C1
+ m_pDoc->SetValue(2, 1, srcSheet, 12); // C2
+ m_pDoc->SetValue(2, 3, srcSheet, 14); // C4
+
+ ScMarkData aSrcMark(m_pDoc->GetSheetLimits());
+ aSrcMark.SelectOneTable(0);
+ ScClipParam aClipParam;
+ aClipParam.meDirection = ScClipParam::Column;
+ aClipParam.maRanges.push_back(ScRange(0, 0, srcSheet, 0, 3, srcSheet)); // A1:A4
+ aClipParam.maRanges.push_back(ScRange(2, 0, srcSheet, 2, 3, srcSheet)); // C1:C4
+
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ m_pDoc->CopyToClip(aClipParam, &aClipDoc, &aSrcMark, false, false);
+
+ // transpose
+ ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ aClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::CONTENTS, true, false);
+
+ ScRange aDestRange(1, 1, destSheet, 4, 2, destSheet); // Paste to B2:E3 on Sheet2.
+ ScMarkData aMark(m_pDoc->GetSheetLimits());
+ aMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyMultiRangeFromClip(ScAddress(1, 1, destSheet), aMark, InsertDeleteFlags::CONTENTS,
+ pTransClip.get(), true, false /* false fixes tdf#141683 */,
+ false, false);
+ pTransClip.reset();
+
+ OUString aString;
+ // Check pasted content to make sure they reference the correct cells.
+ ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(1, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell B2.", pFC);
+ m_pDoc->GetFormula(1, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B2", OUString("=$Sheet1.$A$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(1.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell C2.", pFC);
+ m_pDoc->GetFormula(2, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell C2", OUString("=$Sheet1.$A$2"), aString);
+ CPPUNIT_ASSERT_EQUAL(2.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(3, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be no formula cell D2.", !pFC);
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(4, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(4, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell E2", OUString("=$Sheet1.$A$4"), aString);
+ CPPUNIT_ASSERT_EQUAL(4.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(1, 2, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell B3.", pFC);
+ m_pDoc->GetFormula(1, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B3", OUString("=$Sheet1.$C$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(11.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 2, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell C3.", pFC);
+ m_pDoc->GetFormula(2, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell C3", OUString("=$Sheet1.$C$2"), aString);
+ CPPUNIT_ASSERT_EQUAL(12.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(3, 2, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be no formula cell D3.", !pFC);
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(4, 2, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(4, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell E3", OUString("=$Sheet1.$C$4"), aString);
+ CPPUNIT_ASSERT_EQUAL(14.0, pFC->GetValue());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+// tdf#141683
+// InsertDeleteFlags::CONTENTS
+void Test::testCopyPasteSpecialMultiRangeColAsLinkFilteredTranspose()
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // Turn on auto calc.
+
+ m_pDoc->InsertTab(srcSheet, "Sheet1");
+ m_pDoc->InsertTab(destSheet, "Sheet2");
+
+ m_pDoc->SetValue(0, 0, srcSheet, 1); // A1
+ m_pDoc->SetValue(0, 1, srcSheet, 2); // A2
+ m_pDoc->SetValue(0, 3, srcSheet, 4); // A4
+
+ m_pDoc->SetValue(2, 0, srcSheet, 11); // C1
+ m_pDoc->SetValue(2, 1, srcSheet, 12); // C2
+ m_pDoc->SetValue(2, 3, srcSheet, 14); // C4
+
+ // Filter row 1
+ ScDBData* pDBData = new ScDBData("TRANSPOSE_TEST_DATA", srcSheet, 0, 0, 0, 3);
+ m_pDoc->SetAnonymousDBData(0, std::unique_ptr<ScDBData>(pDBData));
+
+ pDBData->SetAutoFilter(true);
+ ScRange aRange;
+ pDBData->GetArea(aRange);
+ m_pDoc->ApplyFlagsTab(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(),
+ aRange.aStart.Row(), aRange.aStart.Tab(), ScMF::Auto);
+
+ //create the query param
+ ScQueryParam aParam;
+ pDBData->GetQueryParam(aParam);
+ ScQueryEntry& rEntry = aParam.GetEntry(0);
+ rEntry.bDoQuery = true;
+ rEntry.nField = 0;
+ rEntry.eOp = SC_NOT_EQUAL;
+ rEntry.GetQueryItem().mfVal = 2; // value of row A2 -> filtering row 1
+ // add queryParam to database range.
+ pDBData->SetQueryParam(aParam);
+
+ // perform the query.
+ m_pDoc->Query(srcSheet, aParam, true);
+
+ ScMarkData aSrcMark(m_pDoc->GetSheetLimits());
+ aSrcMark.SelectOneTable(0);
+ ScClipParam aClipParam;
+ aClipParam.meDirection = ScClipParam::Column;
+ aClipParam.maRanges.push_back(ScRange(0, 0, srcSheet, 0, 3, srcSheet)); // A1:A4
+ aClipParam.maRanges.push_back(ScRange(2, 0, srcSheet, 2, 3, srcSheet)); // C1:C4
+
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ m_pDoc->CopyToClip(aClipParam, &aClipDoc, &aSrcMark, false, false);
+
+ // transpose
+ ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ aClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::CONTENTS, true, false);
+
+ ScRange aDestRange(1, 1, destSheet, 4, 2, destSheet); // Paste to B2:E3 on Sheet2.
+ ScMarkData aMark(m_pDoc->GetSheetLimits());
+ aMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyMultiRangeFromClip(ScAddress(1, 1, destSheet), aMark, InsertDeleteFlags::CONTENTS,
+ pTransClip.get(), true, false /* false fixes tdf#141683 */,
+ false, false);
+ pTransClip.reset();
+
+ OUString aString;
+ // Check pasted content to make sure they reference the correct cells.
+ ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(1, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell B2.", pFC);
+ m_pDoc->GetFormula(1, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B2", OUString("=$Sheet1.$A$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(1.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be no formula cell C2.", !pFC);
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(3, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(3, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell D2", OUString("=$Sheet1.$A$4"), aString);
+ CPPUNIT_ASSERT_EQUAL(4.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(1, 2, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell B3.", pFC);
+ m_pDoc->GetFormula(1, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B3", OUString("=$Sheet1.$C$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(11.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 2, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be no formula cell C3.", !pFC);
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(3, 2, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(3, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell D3", OUString("=$Sheet1.$C$4"), aString);
+ CPPUNIT_ASSERT_EQUAL(14.0, pFC->GetValue());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+// InsertDeleteFlags::ALL
+void Test::testCopyPasteSpecialAllAsLinkTranspose()
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // Turn on auto calc.
+
+ m_pDoc->InsertTab(srcSheet, "Sheet1");
+ m_pDoc->InsertTab(destSheet, "Sheet2");
+
+ m_pDoc->SetValue(0, 0, srcSheet, 1); // A1
+ m_pDoc->SetValue(0, 1, srcSheet, 2); // A2
+ m_pDoc->SetValue(0, 3, srcSheet, 4); // A4
+
+ ScRange aSrcRange(0, 0, srcSheet, 0, 3, srcSheet); // Copy A1:A4 to clip.
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ copyToClip(m_pDoc, aSrcRange, &aClipDoc);
+
+ // transpose
+ ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ aClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::ALL, true, false);
+
+ ScRange aDestRange(1, 1, destSheet, 4, 1, destSheet); // Paste to B2:E2 on Sheet2.
+ ScMarkData aMark(m_pDoc->GetSheetLimits());
+ aMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::ALL, nullptr, pTransClip.get(), true,
+ false);
+ pTransClip.reset();
+
+ OUString aString;
+ // Check pasted content to make sure they reference the correct cells.
+ ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(1, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell B2.", pFC);
+ m_pDoc->GetFormula(1, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B2", OUString("=$Sheet1.$A$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(1.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(2, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell C2", OUString("=$Sheet1.$A$2"), aString);
+ CPPUNIT_ASSERT_EQUAL(2.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(3, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(3, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell D2", OUString("=$Sheet1.$A$3"), aString);
+ CPPUNIT_ASSERT_EQUAL(0.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(4, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(4, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell E2", OUString("=$Sheet1.$A$4"), aString);
+ CPPUNIT_ASSERT_EQUAL(4.0, pFC->GetValue());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+// InsertDeleteFlags::ALL
+void Test::testCopyPasteSpecialAllAsLinkFilteredTranspose()
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // Turn on auto calc.
+
+ m_pDoc->InsertTab(srcSheet, "Sheet1");
+ m_pDoc->InsertTab(destSheet, "Sheet2");
+
+ m_pDoc->SetValue(0, 0, srcSheet, 1); // A1
+ m_pDoc->SetValue(0, 1, srcSheet, 2); // A2
+ m_pDoc->SetValue(0, 3, srcSheet, 4); // A4
+
+ // Filter row 1
+ ScDBData* pDBData = new ScDBData("TRANSPOSE_TEST_DATA", srcSheet, 0, 0, 0, 3);
+ m_pDoc->SetAnonymousDBData(0, std::unique_ptr<ScDBData>(pDBData));
+
+ pDBData->SetAutoFilter(true);
+ ScRange aRange;
+ pDBData->GetArea(aRange);
+ m_pDoc->ApplyFlagsTab(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(),
+ aRange.aStart.Row(), aRange.aStart.Tab(), ScMF::Auto);
+ //create the query param
+ ScQueryParam aParam;
+ pDBData->GetQueryParam(aParam);
+ ScQueryEntry& rEntry = aParam.GetEntry(0);
+ rEntry.bDoQuery = true;
+ rEntry.nField = 0;
+ rEntry.eOp = SC_NOT_EQUAL;
+ rEntry.GetQueryItem().mfVal = 2; // value of row A2 -> filtering row 1
+ // add queryParam to database range.
+ pDBData->SetQueryParam(aParam);
+
+ // perform the query.
+ m_pDoc->Query(srcSheet, aParam, true);
+
+ // Check precondition for test: row 1 is hidden/filtered
+ SCROW nRow1, nRow2;
+ SCROW nFilteredRow1, nFilteredRow2;
+ bool bHidden = m_pDoc->RowHidden(SCROW(1), srcSheet, &nRow1, &nRow2);
+ CPPUNIT_ASSERT_MESSAGE("row 1 should be hidden", bHidden);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("row 1 should be hidden", SCROW(1), nRow1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("row 1 should be hidden", SCROW(1), nRow2);
+ bool bFiltered = m_pDoc->RowFiltered(SCROW(1), srcSheet, &nFilteredRow1, &nFilteredRow2);
+ CPPUNIT_ASSERT_MESSAGE("row 1 should be filtered", bFiltered);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("row 1 should be filtered", SCROW(1), nFilteredRow1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("row 1 should be filtered", SCROW(1), nFilteredRow2);
+
+ // Copy A1:A4 to clip.
+ ScRange aSrcRange(0, 0, srcSheet, 0, 3, srcSheet);
+ ScDocument aClipDoc(SCDOCMODE_CLIP);
+ copyToClip(m_pDoc, aSrcRange, &aClipDoc);
+
+ // transpose
+ ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ aClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::ALL, true, false);
+
+ ScRange aDestRange(1, 1, destSheet, 3, 1, destSheet); // Paste to B2:D2 on Sheet2.
+ ScMarkData aMark(m_pDoc->GetSheetLimits());
+ aMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::ALL, nullptr, pTransClip.get(), true,
+ false, false);
+ pTransClip.reset();
+
+ OUString aString;
+ // Check pasted content to make sure they reference the correct cells.
+ ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(1, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell B2.", pFC);
+ m_pDoc->GetFormula(1, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell B2", OUString("=$Sheet1.$A$1"), aString);
+ CPPUNIT_ASSERT_EQUAL(1.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(2, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(2, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell C2", OUString("=$Sheet1.$A$3"), aString);
+ CPPUNIT_ASSERT_EQUAL(0.0, pFC->GetValue());
+
+ pFC = m_pDoc->GetFormulaCell(ScAddress(3, 1, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
+ m_pDoc->GetFormula(3, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell D2", OUString("=$Sheet1.$A$4"), aString);
+ CPPUNIT_ASSERT_EQUAL(4.0, pFC->GetValue());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+// This method is used to create the different copy/paste special test cases.
+// Principle: Creation of test cases is parameterized, whereas checking uses a minimum of logic
+void Test::executeCopyPasteSpecial(bool bApplyFilter, bool bIncludedFiltered, bool bAsLink,
+ bool bTranspose, bool bMultiRangeSelection, bool bSkipEmpty,
+ ScClipParam::Direction eDirection = ScClipParam::Column,
+ bool bCalcAll = false,
+ InsertDeleteFlags aFlags
+ = InsertDeleteFlags::CONTENTS | InsertDeleteFlags::ATTRIB)
+{
+ // Reset settings needed for SUMIF() if run with other tests
+ ScFormulaOptions aOptions;
+ aOptions.SetFormulaSepArg(";");
+ getDocShell().SetFormulaOptions(aOptions);
+
+ const SCTAB srcSheet = 0;
+ m_pDoc->InsertTab(srcSheet, "SrcSheet");
+
+ // We need a drawing layer in order to create caption objects.
+ m_pDoc->InitDrawLayer(&getDocShell());
+ ScFieldEditEngine& rEditEngine = m_pDoc->GetEditEngine();
+
+ /*
+ | A | B | C | D | E | F |
+
+ 1r | 1 B*| =A1+10 *| a | R1 *| =A1+A3+60 | =SUMIF(A1:A4;"<4") |
+ 2r | 2 B*| =A2+20 b | b *| R2 *| | *| <- filtered row
+ 3r | 3 B*| =D3+30 b*| c *| 5 *| B*| |
+ 4 | 4 | =A2+40 b*| d *| R4 *| =A1+A3+70 *| =B$1+$A$3+80 *|
+ (5r | 6 | q | r bB*| s bB| t | u |) optional, for row range
+ (6 | -1 | -2 | -3 | -4 | -5 | -6 |) optional, for row range
+ (7r | -11 | -12 | -13 | -14 | -15 | -16 |) optional, for row range
+ (8 | -21 | -22 | -23 | -24 | -25 | -26 |) optional, for row range
+
+ \______________/ \________________________________________/
+ col range 1 col range 2
+
+ * means note attached
+ B means background
+ b means border
+ r means row selected for row range in multi range selection
+
+ The following test scenarios can be created:
+
+ * Filtered row
+ * Transpose
+ * All cell types: numbers, strings, formulas, rich text, empty cell
+ * Notes at different position
+ * Formula references to rows before and after filtered row
+ * Double reference (e.g. A1:A3)
+ * Relative and absolute references
+ * absolute references are not changed by transposing
+ * Formatting patterns (e.g. cell backgrounds and borders)
+ * Multi range selection with direction column and row
+
+ */
+ SCCOL nSrcCols = 6;
+ SCROW nSrcRows = 4;
+ // Add additional row for MultiRange test cases
+ if (bMultiRangeSelection)
+ {
+ nSrcRows = eDirection == ScClipParam::Row ? nSrcRows + 2 : nSrcRows;
+ nSrcCols = eDirection == ScClipParam::Column ? nSrcCols + 1 : nSrcCols;
+ }
+
+ // col A
+ m_pDoc->SetValue(0, 0, srcSheet, 1);
+ m_pDoc->SetValue(0, 1, srcSheet, 2);
+ m_pDoc->SetValue(0, 2, srcSheet, 3);
+ m_pDoc->SetValue(0, 3, srcSheet, 4);
+ // col B
+ m_pDoc->SetString(1, 0, srcSheet, "=A1+10");
+ m_pDoc->SetString(1, 1, srcSheet, "=A2+20");
+ m_pDoc->SetString(1, 2, srcSheet, "=D3+30");
+ m_pDoc->SetString(1, 3, srcSheet, "=A2+40");
+ // col C
+ m_pDoc->SetString(2, 0, srcSheet, "a");
+ m_pDoc->SetString(2, 1, srcSheet, "b");
+ m_pDoc->SetString(2, 2, srcSheet, "c");
+ m_pDoc->SetString(2, 3, srcSheet, "d");
+ // col D
+ rEditEngine.SetTextCurrentDefaults("R1");
+ m_pDoc->SetEditText(ScAddress(3, 0, srcSheet), rEditEngine.CreateTextObject());
+ rEditEngine.SetTextCurrentDefaults("R2");
+ m_pDoc->SetEditText(ScAddress(3, 1, srcSheet), rEditEngine.CreateTextObject());
+ m_pDoc->SetValue(3, 2, srcSheet, 5);
+ rEditEngine.SetTextCurrentDefaults("R4");
+ m_pDoc->SetEditText(ScAddress(3, 3, srcSheet), rEditEngine.CreateTextObject());
+ // col E
+ m_pDoc->SetValue(4, 0, srcSheet, 9);
+ m_pDoc->SetString(4, 0, srcSheet, "=A1+A3+60");
+ m_pDoc->SetEmptyCell(ScAddress(4, 1, srcSheet));
+ m_pDoc->SetEmptyCell(ScAddress(4, 2, srcSheet));
+ m_pDoc->SetString(4, 3, srcSheet, "=A1+A3+70");
+ // col F
+ m_pDoc->SetValue(5, 0, srcSheet, 9);
+ m_pDoc->SetString(5, 0, srcSheet, "=SUMIF(A1:A4;\"<4\")");
+ m_pDoc->SetEmptyCell(ScAddress(5, 1, srcSheet));
+ m_pDoc->SetEmptyCell(ScAddress(5, 2, srcSheet));
+ m_pDoc->SetString(5, 3, srcSheet, "=B$1+$A$3+80");
+
+ const SfxPoolItem* pItem = nullptr;
+
+ // row 4, additional row for MultiRange test case, otherwise not selected
+ m_pDoc->SetValue(0, 4, srcSheet, 6);
+ m_pDoc->SetString(1, 4, srcSheet, "q");
+ m_pDoc->SetString(2, 4, srcSheet, "r");
+ m_pDoc->SetString(3, 4, srcSheet, "s");
+ m_pDoc->SetString(4, 4, srcSheet, "t");
+ m_pDoc->SetString(5, 4, srcSheet, "u");
+
+ // row 5, not selected
+ m_pDoc->SetValue(0, 5, srcSheet, -1);
+ m_pDoc->SetValue(1, 5, srcSheet, -2);
+ m_pDoc->SetValue(2, 5, srcSheet, -3);
+ m_pDoc->SetValue(3, 5, srcSheet, -4);
+ m_pDoc->SetValue(4, 5, srcSheet, -5);
+ m_pDoc->SetValue(5, 5, srcSheet, -6);
+
+ // row 6, additional row for MultiRange test case, otherwise not selected
+ m_pDoc->SetValue(0, 6, srcSheet, -11);
+ m_pDoc->SetValue(1, 6, srcSheet, -12);
+ m_pDoc->SetValue(2, 6, srcSheet, -13);
+ m_pDoc->SetValue(3, 6, srcSheet, -14);
+ m_pDoc->SetValue(4, 6, srcSheet, -15);
+ m_pDoc->SetValue(5, 6, srcSheet, -16);
+
+ // row 7, additional row for MultiRange test case, otherwise not selected
+ m_pDoc->SetValue(0, 7, srcSheet, -21);
+ m_pDoc->SetValue(1, 7, srcSheet, -22);
+ m_pDoc->SetValue(2, 7, srcSheet, -23);
+ m_pDoc->SetValue(3, 7, srcSheet, -24);
+ m_pDoc->SetValue(4, 7, srcSheet, -25);
+ m_pDoc->SetValue(5, 7, srcSheet, -26);
+
+ // Col G, not selected
+ m_pDoc->SetValue(6, 0, srcSheet, 111);
+ m_pDoc->SetValue(6, 1, srcSheet, 112);
+ m_pDoc->SetValue(6, 2, srcSheet, 113);
+ m_pDoc->SetValue(6, 3, srcSheet, 114);
+ m_pDoc->SetValue(6, 4, srcSheet, 115);
+ m_pDoc->SetValue(6, 5, srcSheet, 116);
+
+ // Col H, additional col for MultiRange test case, otherwise not selected
+ m_pDoc->SetValue(7, 0, srcSheet, 121);
+ m_pDoc->SetValue(7, 1, srcSheet, 122);
+ m_pDoc->SetValue(7, 2, srcSheet, 123);
+ m_pDoc->SetValue(7, 3, srcSheet, 124);
+ m_pDoc->SetValue(7, 4, srcSheet, 125);
+ m_pDoc->SetValue(7, 5, srcSheet, 126);
+
+ // Col J, not selected
+ m_pDoc->SetValue(8, 0, srcSheet, 131);
+ m_pDoc->SetValue(8, 1, srcSheet, 132);
+ m_pDoc->SetValue(8, 2, srcSheet, 133);
+ m_pDoc->SetValue(8, 3, srcSheet, 134);
+ m_pDoc->SetValue(8, 4, srcSheet, 135);
+ m_pDoc->SetValue(8, 5, srcSheet, 136);
+
+ // add patterns
+ ScPatternAttr aCellBlueColor(m_pDoc->GetPool());
+ aCellBlueColor.GetItemSet().Put(SvxBrushItem(COL_BLUE, ATTR_BACKGROUND));
+ m_pDoc->ApplyPatternAreaTab(0, 0, 0, 2, srcSheet, aCellBlueColor);
+
+ // Check pattern precondition
+ m_pDoc->GetPattern(ScAddress(0, 0, srcSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("SrcSheet.A1 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(0, 1, srcSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("SrcSheet.A2 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(0, 3, srcSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("SrcSheet.A4 has no pattern", !pItem);
+
+ // row 2 on empty cell
+ ScPatternAttr aCellGreenColor(m_pDoc->GetPool());
+ aCellGreenColor.GetItemSet().Put(SvxBrushItem(COL_GREEN, ATTR_BACKGROUND));
+ m_pDoc->ApplyPatternAreaTab(4, 2, 4, 2, srcSheet, aCellGreenColor);
+
+ // row 4 for multi range row selection
+ ScPatternAttr aCellRedColor(m_pDoc->GetPool());
+ aCellRedColor.GetItemSet().Put(SvxBrushItem(COL_RED, ATTR_BACKGROUND));
+ m_pDoc->ApplyPatternAreaTab(2, 4, 3, 4, srcSheet, aCellRedColor);
+
+ // add borders
+ ::editeng::SvxBorderLine aLine(nullptr, 50, SvxBorderLineStyle::SOLID);
+ SvxBoxItem aBorderItem(ATTR_BORDER);
+ aBorderItem.SetLine(&aLine, SvxBoxItemLine::LEFT);
+ aBorderItem.SetLine(&aLine, SvxBoxItemLine::RIGHT);
+ m_pDoc->ApplyAttr(1, 1, srcSheet, aBorderItem);
+ m_pDoc->ApplyAttr(1, 2, srcSheet, aBorderItem);
+ m_pDoc->ApplyAttr(1, 3, srcSheet, aBorderItem);
+ // Check border precondition
+ pItem = m_pDoc->GetAttr(ScAddress(1, 0, srcSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("SrcSheet.B1 has a border", pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ pItem = m_pDoc->GetAttr(ScAddress(1, 1, srcSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("SrcSheet.B2 has a border", pItem);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ // Check border precondition 2
+ m_pDoc->GetPattern(ScAddress(1, 1, srcSheet))->GetItemSet().HasItem(ATTR_BORDER, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("SrcSheet.B2 has a border", pItem);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ // row 4 for multi range row selection
+ ::editeng::SvxBorderLine aDoubleLine(nullptr, 50, SvxBorderLineStyle::DOUBLE);
+ SvxBoxItem aDoubleBorderItem(ATTR_BORDER);
+ aDoubleBorderItem.SetLine(&aDoubleLine, SvxBoxItemLine::TOP);
+ aDoubleBorderItem.SetLine(&aDoubleLine, SvxBoxItemLine::BOTTOM);
+ m_pDoc->ApplyAttr(2, 4, srcSheet, aDoubleBorderItem);
+ m_pDoc->ApplyAttr(3, 4, srcSheet, aDoubleBorderItem);
+
+ // add notes to A1:F4
+
+ // add notes row 0
+ ScAddress aAdrA1(0, 0, srcSheet);
+ ScPostIt* pNoteA1 = m_pDoc->GetOrCreateNote(aAdrA1);
+ pNoteA1->SetText(aAdrA1, "Hello world in A1");
+ ScAddress aAdrB1(1, 0, srcSheet);
+ ScPostIt* pNoteB1 = m_pDoc->GetOrCreateNote(aAdrB1);
+ pNoteB1->SetText(aAdrB1, "Hello world in B1");
+ // No note on C1
+ ScAddress aAdrD1(3, 0, srcSheet);
+ ScPostIt* pNoteD1 = m_pDoc->GetOrCreateNote(aAdrD1);
+ pNoteD1->SetText(aAdrD1, "Hello world in D1");
+ // No note on E1
+ // No note on F1
+
+ // add notes row 1
+ ScAddress aAdrA2(0, 1, srcSheet);
+ ScPostIt* pNoteA2 = m_pDoc->GetOrCreateNote(aAdrA2);
+ pNoteA2->SetText(aAdrA2, "Hello world in A2");
+ // No note on B2
+ ScAddress aAdrC2(2, 1, srcSheet);
+ ScPostIt* pNoteC2 = m_pDoc->GetOrCreateNote(aAdrC2);
+ pNoteC2->SetText(aAdrC2, "Hello world in C2");
+ ScAddress aAdrD2(3, 1, srcSheet);
+ ScPostIt* pNoteD2 = m_pDoc->GetOrCreateNote(aAdrD2);
+ pNoteD2->SetText(aAdrD2, "Hello world in D2");
+ ScAddress aAdrE2(4, 2, srcSheet);
+ ScPostIt* pNoteE2 = m_pDoc->GetOrCreateNote(aAdrE2);
+ pNoteE2->SetText(aAdrE2, "Hello world in E2");
+ ScAddress aAdrF2(5, 1, srcSheet);
+ ScPostIt* pNoteF2 = m_pDoc->GetOrCreateNote(aAdrF2);
+ pNoteF2->SetText(aAdrF2, "Hello world in F2");
+
+ // add notes row 2
+ ScAddress aAdrA3(0, 2, srcSheet);
+ ScPostIt* pNoteA3 = m_pDoc->GetOrCreateNote(aAdrA3);
+ pNoteA3->SetText(aAdrA3, "Hello world in A3");
+ ScAddress aAdrB3(1, 2, srcSheet);
+ ScPostIt* pNoteB3 = m_pDoc->GetOrCreateNote(aAdrB3);
+ pNoteB3->SetText(aAdrB3, "Hello world in B3");
+ ScAddress aAdrC3(2, 2, srcSheet);
+ ScPostIt* pNoteC3 = m_pDoc->GetOrCreateNote(aAdrC3);
+ pNoteC3->SetText(aAdrC3, "Hello world in C3");
+ ScAddress aAdrD3(3, 2, srcSheet);
+ ScPostIt* pNoteD3 = m_pDoc->GetOrCreateNote(aAdrD3);
+ pNoteD3->SetText(aAdrD3, "Hello world in D3");
+ // No note on E3
+ // No note on F3
+
+ // add notes row 3
+ // No note on A4
+ ScAddress aAdrB4(1, 3, srcSheet);
+ ScPostIt* pNoteB4 = m_pDoc->GetOrCreateNote(aAdrB4);
+ pNoteB4->SetText(aAdrB4, "Hello world in B4");
+ ScAddress aAdrC4(2, 3, srcSheet);
+ ScPostIt* pNoteC4 = m_pDoc->GetOrCreateNote(aAdrC4);
+ pNoteC4->SetText(aAdrC4, "Hello world in C4");
+ ScAddress aAdrD4(3, 3, srcSheet);
+ ScPostIt* pNoteD4 = m_pDoc->GetOrCreateNote(aAdrD4);
+ pNoteD4->SetText(aAdrD4, "Hello world in D4");
+ ScAddress aAdrE4(4, 3, srcSheet);
+ ScPostIt* pNoteE4 = m_pDoc->GetOrCreateNote(aAdrE4);
+ pNoteE4->SetText(aAdrE4, "Hello world in E4");
+ ScAddress aAdrF4(5, 3, srcSheet);
+ ScPostIt* pNoteF4 = m_pDoc->GetOrCreateNote(aAdrF4);
+ pNoteF4->SetText(aAdrF4, "Hello world in F4");
+
+ // row 4 for multi range row selection
+ ScAddress aAdrC5(2, 4, srcSheet);
+ ScPostIt* pNoteC5 = m_pDoc->GetOrCreateNote(aAdrC5);
+ pNoteC5->SetText(aAdrC5, "Hello world in C5");
+
+ // Filter out row 1
+ if (bApplyFilter)
+ {
+ ScDBData* pDBData
+ = new ScDBData("TRANSPOSE_TEST_DATA", srcSheet, 0, 0, nSrcCols - 1, nSrcRows - 1);
+ m_pDoc->SetAnonymousDBData(srcSheet, std::unique_ptr<ScDBData>(pDBData));
+
+ pDBData->SetAutoFilter(true);
+ ScRange aRange;
+ pDBData->GetArea(aRange);
+ m_pDoc->ApplyFlagsTab(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(),
+ aRange.aStart.Row(), aRange.aStart.Tab(), ScMF::Auto);
+
+ //create the query param
+ ScQueryParam aParam;
+ pDBData->GetQueryParam(aParam);
+ ScQueryEntry& rEntry = aParam.GetEntry(0);
+ rEntry.bDoQuery = true;
+ rEntry.nField = 0;
+ rEntry.eOp = SC_NOT_EQUAL;
+ rEntry.GetQueryItem().mfVal = 2; // value of row A2 -> filtering row 1
+ // add queryParam to database range.
+ pDBData->SetQueryParam(aParam);
+
+ // perform the query.
+ m_pDoc->Query(srcSheet, aParam, true);
+
+ // Check precondition for test: row 1 is hidden/filtered
+ SCROW nRow1, nRow2;
+ SCROW nFilteredRow1, nFilteredRow2;
+ bool bHidden = m_pDoc->RowHidden(SCROW(1), srcSheet, &nRow1, &nRow2);
+ CPPUNIT_ASSERT_MESSAGE("row 1 should be hidden", bHidden);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("row 1 should be hidden", SCROW(1), nRow1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("row 1 should be hidden", SCROW(1), nRow2);
+ bool bFiltered = m_pDoc->RowFiltered(SCROW(1), srcSheet, &nFilteredRow1, &nFilteredRow2);
+ CPPUNIT_ASSERT_MESSAGE("row 1 should be filtered", bFiltered);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("row 1 should be filtered", SCROW(1), nFilteredRow1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("row 1 should be filtered", SCROW(1), nFilteredRow2);
+ }
+
+ // create destination sheet
+ const SCTAB destSheet = 1;
+ m_pDoc->InsertTab(destSheet, "DestSheet");
+ // set cells to 1000 to check empty cell behaviour and to detect destination range problems
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 10; ++j)
+ m_pDoc->SetValue(i, j, destSheet, 1000);
+
+ // transpose clipboard, paste on DestSheet
+ ScDocument aNewClipDoc(SCDOCMODE_CLIP);
+ ScMarkData aDestMark(m_pDoc->GetSheetLimits());
+ if (!bMultiRangeSelection)
+ {
+ ScRange aSrcRange(0, 0, srcSheet, nSrcCols - 1, nSrcRows - 1, srcSheet);
+ copyToClip(m_pDoc, aSrcRange, &aNewClipDoc);
+
+ // ScDocument::TransposeClip() and ScDocument::CopyFromClip() calls
+ // analog to ScViewFunc::PasteFromClip()
+ if (bTranspose)
+ {
+ ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ aNewClipDoc.TransposeClip(pTransClip.get(), aFlags, bAsLink, bIncludedFiltered);
+ ScRange aDestRange(3, 1, destSheet, 3 + nSrcRows - 1, 1 + nSrcCols - 1,
+ destSheet); //target: D2:F6
+ aDestMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyFromClip(aDestRange, aDestMark, aFlags, nullptr, pTransClip.get(), true,
+ bAsLink, bIncludedFiltered, bSkipEmpty);
+ pTransClip.reset();
+ }
+ else
+ {
+ ScRange aDestRange(3, 1, destSheet, 3 + nSrcCols - 1, 1 + nSrcRows - 1,
+ destSheet); //target: D2:I5
+ aDestMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyFromClip(aDestRange, aDestMark, aFlags, nullptr, &aNewClipDoc, true,
+ bAsLink, bIncludedFiltered, bSkipEmpty);
+ }
+ }
+ else
+ {
+ ScMarkData aSrcMark(m_pDoc->GetSheetLimits());
+ aSrcMark.SelectOneTable(0);
+ ScClipParam aClipParam;
+ aClipParam.meDirection = eDirection;
+ if (eDirection == ScClipParam::Column)
+ {
+ aClipParam.maRanges.push_back(ScRange(0, 0, srcSheet, 1, 3, srcSheet)); // A1:B4
+ aClipParam.maRanges.push_back(ScRange(3, 0, srcSheet, 5, 3, srcSheet)); // D1:F4
+ aClipParam.maRanges.push_back(ScRange(7, 0, srcSheet, 7, 3, srcSheet)); // H1:H4
+ }
+ else if (eDirection == ScClipParam::Row)
+ {
+ aClipParam.maRanges.push_back(ScRange(0, 0, srcSheet, 5, 2, srcSheet)); // A1:F3
+ aClipParam.maRanges.push_back(ScRange(0, 4, srcSheet, 5, 4, srcSheet)); // A5:F5
+ aClipParam.maRanges.push_back(ScRange(0, 6, srcSheet, 5, 6, srcSheet)); // A7:F7
+ }
+ CPPUNIT_ASSERT(aClipParam.isMultiRange());
+ m_pDoc->CopyToClip(aClipParam, &aNewClipDoc, &aSrcMark, false, false);
+
+ // ScDocument::TransposeClip() and ScDocument::CopyMultiRangeFromClip() calls
+ // analog to ScViewFunc::PasteFromClipToMultiRanges()
+ if (bTranspose)
+ {
+ printRange(m_pDoc, aClipParam.getWholeRange(), "Src range");
+ ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ aNewClipDoc.TransposeClip(pTransClip.get(), aFlags, bAsLink, bIncludedFiltered);
+ ScRange aDestRange(3, 1, destSheet, 3 + nSrcRows - 1, 1 + nSrcCols - 1 - 1,
+ destSheet); //target col: D2:G6, target row: D2:H6
+ aDestMark.SetMarkArea(aDestRange);
+ printRange(&aNewClipDoc, ScRange(0, 0, 0, nSrcCols, nSrcRows, 0),
+ "Base doc (&aNewClipDoc)");
+ printRange(pTransClip.get(), ScRange(0, 0, 0, nSrcCols, nSrcRows, 0),
+ "Transposed filtered clipdoc (pTransClip.get())");
+ m_pDoc->CopyMultiRangeFromClip(ScAddress(3, 1, destSheet), aDestMark, aFlags,
+ pTransClip.get(), true, bAsLink && !bTranspose,
+ bIncludedFiltered, bSkipEmpty);
+ pTransClip.reset();
+ printRange(m_pDoc, aDestRange, "Transposed dest sheet");
+ }
+ else
+ {
+ ScRange aDestRange(3, 1, destSheet, 3 + nSrcCols - 1 - 1, 1 + nSrcRows - 1,
+ destSheet); //target col: D2:I5, target row: D2:I6
+ aDestMark.SetMarkArea(aDestRange);
+ m_pDoc->CopyMultiRangeFromClip(ScAddress(3, 1, destSheet), aDestMark, aFlags,
+ &aNewClipDoc, true, bAsLink && !bTranspose,
+ bIncludedFiltered, bSkipEmpty);
+ }
+ }
+ if (bCalcAll)
+ m_pDoc->CalcAll();
+}
+
+void Test::testCopyPasteSpecial()
+{
+ executeCopyPasteSpecial(false, false, false, false, false, false);
+ checkCopyPasteSpecial(false);
+}
+
+void Test::testCopyPasteSpecialFiltered()
+{
+ executeCopyPasteSpecial(true, false, false, false, false, false);
+ checkCopyPasteSpecialFiltered(false);
+}
+
+void Test::testCopyPasteSpecialIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(false, true, false, false, false, false);
+ checkCopyPasteSpecial(false);
+}
+
+void Test::testCopyPasteSpecialFilteredIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, true, false, false, false, false);
+ checkCopyPasteSpecial(false);
+}
+
+// similar to Test::testCopyPasteTranspose(), but this test is more complex
+void Test::testCopyPasteSpecialTranspose()
+{
+ executeCopyPasteSpecial(false, false, false, true, false, false);
+ checkCopyPasteSpecialTranspose(false);
+}
+
+// tdf#107348
+void Test::testCopyPasteSpecialFilteredTranspose()
+{
+ executeCopyPasteSpecial(true, false, false, true, false, false);
+ checkCopyPasteSpecialFilteredTranspose(false);
+}
+
+// tdf#107348
+void Test::testCopyPasteSpecialTransposeIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, true, false, true, false, false);
+ checkCopyPasteSpecialTranspose(false);
+}
+
+void Test::testCopyPasteSpecialMultiRangeCol()
+{
+ executeCopyPasteSpecial(false, false, false, false, true, false, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeCol(false);
+}
+
+void Test::testCopyPasteSpecialMultiRangeColIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(false, true, false, false, true, false, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeCol(false);
+}
+
+// tdf#45958
+void Test::testCopyPasteSpecialMultiRangeColFiltered()
+{
+ executeCopyPasteSpecial(true, false, false, false, true, false, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeColFiltered(false);
+}
+
+// tdf#45958
+void Test::testCopyPasteSpecialMultiRangeColFilteredIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, true, false, false, true, false, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeCol(false);
+}
+
+void Test::testCopyPasteSpecialMultiRangeColTranspose()
+{
+ executeCopyPasteSpecial(false, false, false, true, true, false, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeColTranspose(false);
+}
+
+// tdf#45958, tdf#107348
+void Test::testCopyPasteSpecialMultiRangeColFilteredTranspose()
+{
+ executeCopyPasteSpecial(true, false, false, true, true, false, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeColFilteredTranspose(false);
+}
+
+// tdf#45958, tdf#107348
+void Test::testCopyPasteSpecialMultiRangeColFilteredIncludeFilteredTranspose()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, true, false, true, true, false, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeColTranspose(false);
+}
+
+void Test::testCopyPasteSpecialMultiRangeRow()
+{
+ executeCopyPasteSpecial(false, false, false, false, true, false, ScClipParam::Row);
+ checkCopyPasteSpecialMultiRangeRow(false);
+}
+
+void Test::testCopyPasteSpecialMultiRangeRowIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(false, true, false, false, true, false, ScClipParam::Row);
+ checkCopyPasteSpecialMultiRangeRow(false);
+}
+
+// tdf#45958
+void Test::testCopyPasteSpecialMultiRangeRowFiltered()
+{
+ executeCopyPasteSpecial(true, false, false, false, true, false, ScClipParam::Row);
+ checkCopyPasteSpecialMultiRangeRowFiltered(false);
+}
+
+// tdf#45958
+void Test::testCopyPasteSpecialMultiRangeRowFilteredIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, true, false, false, true, false, ScClipParam::Row);
+ checkCopyPasteSpecialMultiRangeRow(false);
+}
+
+void Test::testCopyPasteSpecialMultiRangeRowTranspose()
+{
+ executeCopyPasteSpecial(false, false, false, true, true, false, ScClipParam::Row, true);
+ checkCopyPasteSpecialMultiRangeRowTranspose(false);
+}
+
+// tdf#45958, tdf#107348
+void Test::testCopyPasteSpecialMultiRangeRowFilteredTranspose()
+{
+ executeCopyPasteSpecial(true, false, false, true, true, false, ScClipParam::Row, true);
+ checkCopyPasteSpecialMultiRangeRowFilteredTranspose(false);
+}
+
+// tdf#45958, tdf#107348
+void Test::testCopyPasteSpecialMultiRangeRowFilteredIncludeFilteredTranspose()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, true, false, true, true, false, ScClipParam::Row, true);
+ checkCopyPasteSpecialMultiRangeRowTranspose(false);
+}
+
+void Test::testCopyPasteSpecialSkipEmpty()
+{
+ executeCopyPasteSpecial(false, false, false, false, false, true);
+ checkCopyPasteSpecial(true);
+}
+
+void Test::testCopyPasteSpecialSkipEmptyFiltered()
+{
+ executeCopyPasteSpecial(true, false, false, false, false, true);
+ checkCopyPasteSpecialFiltered(true);
+}
+
+void Test::testCopyPasteSpecialSkipEmptyIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(false, true, false, false, false, true);
+ checkCopyPasteSpecial(true);
+}
+
+void Test::testCopyPasteSpecialSkipEmptyFilteredIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, true, false, false, false, true);
+ checkCopyPasteSpecial(true);
+}
+
+// similar to Test::testCopyPasteTranspose(), but this test is more complex
+void Test::testCopyPasteSpecialSkipEmptyTranspose()
+{
+ executeCopyPasteSpecial(false, false, false, true, false, true);
+ checkCopyPasteSpecialTranspose(true);
+}
+
+// tdf#107348
+void Test::testCopyPasteSpecialSkipEmptyFilteredTranspose()
+{
+ executeCopyPasteSpecial(true, false, false, true, false, true);
+ checkCopyPasteSpecialFilteredTranspose(true);
+}
+
+// tdf#107348
+void Test::testCopyPasteSpecialSkipEmptyTransposeIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, true, false, true, false, true);
+ checkCopyPasteSpecialTranspose(true);
+}
+
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeCol()
+{
+ executeCopyPasteSpecial(false, false, false, false, true, true, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeCol(true);
+}
+
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeColIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(false, true, false, false, true, true, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeCol(true);
+}
+
+// tdf#45958
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeColFiltered()
+{
+ executeCopyPasteSpecial(true, false, false, false, true, true, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeColFiltered(true);
+}
+
+// tdf#45958
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeColFilteredIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, true, false, false, true, true, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeCol(true);
+}
+
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeColTranspose()
+{
+ executeCopyPasteSpecial(false, false, false, true, true, true, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeColTranspose(true);
+}
+
+// tdf#45958, tdf#107348
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeColFilteredTranspose()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, false, false, true, true, true, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeColFilteredTranspose(true);
+}
+
+// tdf#45958, tdf#107348
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeColFilteredIncludeFilteredTranspose()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, true, false, true, true, true, ScClipParam::Column);
+ checkCopyPasteSpecialMultiRangeColTranspose(true);
+}
+
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeRow()
+{
+ executeCopyPasteSpecial(false, false, false, false, true, true, ScClipParam::Row);
+ checkCopyPasteSpecialMultiRangeRow(true);
+}
+
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeRowIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(false, true, false, false, true, true, ScClipParam::Row);
+ checkCopyPasteSpecialMultiRangeRow(true);
+}
+
+// tdf#45958
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeRowFiltered()
+{
+ executeCopyPasteSpecial(true, false, false, false, true, true, ScClipParam::Row);
+ checkCopyPasteSpecialMultiRangeRowFiltered(true);
+}
+
+// tdf#45958
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeRowFilteredIncludeFiltered()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, true, false, false, true, true, ScClipParam::Row);
+ checkCopyPasteSpecialMultiRangeRow(true);
+}
+
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeRowTranspose()
+{
+ executeCopyPasteSpecial(false, false, false, true, true, true, ScClipParam::Row, true);
+ checkCopyPasteSpecialMultiRangeRowTranspose(true);
+}
+
+// tdf#45958, tdf#107348
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeRowFilteredTranspose()
+{
+ executeCopyPasteSpecial(true, false, false, true, true, true, ScClipParam::Row, true);
+ checkCopyPasteSpecialMultiRangeRowFilteredTranspose(true);
+}
+
+// tdf#45958, tdf#107348
+void Test::testCopyPasteSpecialSkipEmptyMultiRangeRowFilteredIncludeFilteredTranspose()
+{
+ // For bIncludeFiltered=true, the non-filtered outcome is expected
+ executeCopyPasteSpecial(true, true, false, true, true, true, ScClipParam::Row, true);
+ checkCopyPasteSpecialMultiRangeRowTranspose(true);
+}
+
+// Base check, nothing filtered, nothing transposed
+void Test::checkCopyPasteSpecial(bool bSkipEmpty)
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ /*
+ | D | E | F | G | H | I |
+
+ 2 | 1 B*| =D2+10 *| a | R1 *| =D2+D4+60 | =SUMIF(D2:D5;"<4") |
+ 3 | 2 B*| =D3+20 b | b *| R2 *| | *|
+ 4 | 3 B*| =G4+30 b*| c *| 5 *| B*| |
+ 5 | 4 | =D3+40 b*| d *| R4 *| =D2+D4+70 *| =E$1+$A$3+80 *|
+
+ * means note attached
+ B means background
+ b means border
+ */
+
+ OUString aString;
+ double fValue;
+ const EditTextObject* pEditObj;
+ // col 2
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ // col 3, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(3, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(2, m_pDoc->GetValue(3, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(3, m_pDoc->GetValue(3, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(3, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 5, destSheet));
+ // col 4, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(11, m_pDoc->GetValue(4, 1, destSheet));
+ m_pDoc->GetFormula(4, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+10"), aString);
+ m_pDoc->GetFormula(4, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D3+20"), aString);
+ ASSERT_DOUBLES_EQUAL(22, m_pDoc->GetValue(4, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(35, m_pDoc->GetValue(4, 3, destSheet));
+ m_pDoc->GetFormula(4, 3, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=G4+30"), aString);
+ ASSERT_DOUBLES_EQUAL(42, m_pDoc->GetValue(4, 4, destSheet));
+ m_pDoc->GetFormula(4, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D3+40"), aString);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 5, destSheet));
+ // col 5, strings
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 0, destSheet));
+ aString = m_pDoc->GetString(5, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ aString = m_pDoc->GetString(5, 1, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("a"), aString);
+ aString = m_pDoc->GetString(5, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("b"), aString);
+ aString = m_pDoc->GetString(5, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("c"), aString);
+ aString = m_pDoc->GetString(5, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("d"), aString);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 5, destSheet));
+ aString = m_pDoc->GetString(5, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 6, rich text
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 0, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 0, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 1, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R1"), pEditObj->GetText(0));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 2, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R2"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(5, m_pDoc->GetValue(6, 3, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 4, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R4"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 5, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 5, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ // col 7, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 0, destSheet));
+ aString = m_pDoc->GetString(7, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(7, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+D4+60"), aString);
+ ASSERT_DOUBLES_EQUAL(64, m_pDoc->GetValue(7, 1, destSheet));
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(7, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ aString = m_pDoc->GetString(7, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ {
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 3, destSheet));
+ }
+ fValue = m_pDoc->GetValue(7, 4, destSheet);
+ m_pDoc->GetFormula(7, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+D4+70"), aString);
+ ASSERT_DOUBLES_EQUAL(74, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 5, destSheet));
+ aString = m_pDoc->GetString(7, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 8, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 0, destSheet));
+ aString = m_pDoc->GetString(8, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(8, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=SUMIF(D2:D5;\"<4\")"), aString);
+ ASSERT_DOUBLES_EQUAL(6, m_pDoc->GetValue(8, 1, destSheet));
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(8, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ aString = m_pDoc->GetString(8, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ {
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 3, destSheet));
+ }
+ fValue = m_pDoc->GetValue(8, 4, destSheet);
+ m_pDoc->GetFormula(8, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=E$1+$A$3+80"), aString);
+ ASSERT_DOUBLES_EQUAL(2080, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 5, destSheet));
+ aString = m_pDoc->GetString(8, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 9, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 5, destSheet));
+
+ // check patterns
+ const SfxPoolItem* pItem = nullptr;
+ m_pDoc->GetPattern(ScAddress(3, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 2, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(3, 5, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(7, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(bSkipEmpty, pItem == nullptr);
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+
+ // check border, left and right borders were transformed to top and bottom borders
+ pItem = m_pDoc->GetAttr(ScAddress(4, 1, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 3, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 4, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 5, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ // check notes after transposed copy/paste
+ // check presence of notes
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 2, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(8, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 3, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(7, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(7, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(8, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 5, destSheet)));
+
+ // check values of notes
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(2, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(2, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 3, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(7, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(7, 4, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(5, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(8, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(5, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(8, 4, destSheet))->GetText());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+void Test::checkCopyPasteSpecialFiltered(bool bSkipEmpty)
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ /*
+ | D | E | F | G | H | I |
+
+ 2 | 1 B*| =D2+10 *| a | R1 *| =D2+D4+60 | =SUMIF(D2:D5;"<4") |
+ 3 | 3 B*| =G3+30 b*| c *| 5 *| B*| |
+ 4 | 4 | =D2+40 b*| d *| R4 *| =D1+D3+70 *| =E$1+$A$3+80 *|
+ 5 | 1 B*| =D5+10 *| a | R1 *| =D5+D7+60 | =SUMIF(D5:D8;"<4") | <- repeated row
+
+ * means note attached
+ B means background
+ b means border
+ */
+
+ OUString aString;
+ double fValue;
+ const EditTextObject* pEditObj;
+
+ // col 2
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ // col 3, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(3, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(3, m_pDoc->GetValue(3, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(3, 3, destSheet));
+ fValue = m_pDoc->GetValue(3, 4, destSheet); // repeated row 1
+ ASSERT_DOUBLES_EQUAL(1, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 5, destSheet));
+ // col 4, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 0, destSheet));
+ m_pDoc->GetFormula(4, 0, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ ASSERT_DOUBLES_EQUAL(11, m_pDoc->GetValue(4, 1, destSheet));
+ m_pDoc->GetFormula(4, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+10"), aString);
+ fValue = m_pDoc->GetValue(4, 2, destSheet);
+ m_pDoc->GetFormula(4, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=G3+30"), aString);
+ ASSERT_DOUBLES_EQUAL(35, fValue);
+ fValue = m_pDoc->GetValue(4, 3, destSheet);
+ m_pDoc->GetFormula(4, 3, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+40"), aString);
+ ASSERT_DOUBLES_EQUAL(41, fValue);
+ fValue = m_pDoc->GetValue(4, 4, destSheet); // repeated row 1
+ ASSERT_DOUBLES_EQUAL(11, fValue);
+ m_pDoc->GetFormula(4, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D5+10"), aString);
+ ASSERT_DOUBLES_EQUAL(11, m_pDoc->GetValue(4, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 5, destSheet));
+ // col 5, strings
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 0, destSheet));
+ aString = m_pDoc->GetString(5, 1, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("a"), aString);
+ aString = m_pDoc->GetString(5, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("c"), aString);
+ aString = m_pDoc->GetString(5, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("d"), aString);
+ aString = m_pDoc->GetString(5, 4, destSheet); // repeated row 1
+ CPPUNIT_ASSERT_EQUAL(OUString("a"), aString);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 5, destSheet));
+ m_pDoc->GetFormula(4, 5, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ // col 6, rich text
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 0, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 0, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 1, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R1"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(5, m_pDoc->GetValue(6, 2, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 3, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R4"), pEditObj->GetText(0));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 4, destSheet)); // repeated row 1
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R1"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 5, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 5, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ // col 7, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 0, destSheet));
+ aString = m_pDoc->GetString(7, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(7, 1, destSheet, aString);
+ fValue = m_pDoc->GetValue(7, 1, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+D4+60"), aString);
+ ASSERT_DOUBLES_EQUAL(65, fValue); // formula is not adjusted due to filter row
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(7, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 2, destSheet));
+ fValue = m_pDoc->GetValue(7, 3, destSheet);
+ m_pDoc->GetFormula(7, 3, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D1+D3+70"), aString);
+ ASSERT_DOUBLES_EQUAL(1073, fValue);
+ m_pDoc->GetFormula(7, 4, destSheet, aString); // repeated row 1
+ fValue = m_pDoc->GetValue(7, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D5+D7+60"), aString);
+ ASSERT_DOUBLES_EQUAL(1061, fValue); // formula is not adjusted due to filter row
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 5, destSheet));
+ aString = m_pDoc->GetString(7, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 8, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 0, destSheet));
+ aString = m_pDoc->GetString(8, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(8, 1, destSheet, aString);
+ fValue = m_pDoc->GetValue(8, 1, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("=SUMIF(D2:D5;\"<4\")"), aString);
+ ASSERT_DOUBLES_EQUAL(5, fValue);
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(8, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 2, destSheet));
+ fValue = m_pDoc->GetValue(8, 3, destSheet);
+ m_pDoc->GetFormula(8, 3, destSheet, aString);
+ ASSERT_DOUBLES_EQUAL(2080, fValue);
+ CPPUNIT_ASSERT_EQUAL(OUString("=E$1+$A$3+80"), aString);
+ m_pDoc->GetFormula(8, 4, destSheet, aString); // repeated row 1
+ fValue = m_pDoc->GetValue(8, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("=SUMIF(D5:D8;\"<4\")"), aString);
+ ASSERT_DOUBLES_EQUAL(1, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 5, destSheet));
+ aString = m_pDoc->GetString(8, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 9, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 5, destSheet));
+
+ // check patterns
+ const SfxPoolItem* pItem = nullptr;
+ m_pDoc->GetPattern(ScAddress(3, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 2, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(3, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 5, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(7, 2, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(bSkipEmpty, pItem == nullptr);
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+
+ // check border, left and right borders were transformed to top and bottom borders
+ pItem = m_pDoc->GetAttr(ScAddress(4, 1, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 3, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 4, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ // check notes after transposed copy/paste
+ // check presence of notes
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 2, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(7, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(7, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(8, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 5, destSheet)));
+
+ // check values of notes
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(2, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 2, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(7, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(7, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(5, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(8, 3, destSheet))->GetText());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+void Test::checkCopyPasteSpecialTranspose(bool bSkipEmpty)
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ /*
+ | D | E | F | G |
+
+ 2 | 1 B*| 2 B*| 3 B*| 4 |
+ 3 | =D2+10 *| =E2+20 b | =F5+30 b*| =E2+40 b*|
+ 4 | a | b *| c *| d *|
+ 5 | R1 *| R2 *| 5 *| R4 *|
+ 6 | =D2+F2+60 | | B*| =D2+F2+70 *|
+ 7 | =SUMIF(D2:G2;"<4") | *| | =C$1+$A$1+80 *|
+
+ * means note attached
+ B means background
+ b means border
+ */
+
+ //check cell content after transposed copy/paste of filtered data
+ // Note: column F is a repetition of srcSheet.Column A
+ // Col C and G are checked to be empty
+ OUString aString;
+ double fValue;
+ const EditTextObject* pEditObj;
+ // row 0
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 0, destSheet));
+ // row 1, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 1, destSheet));
+ fValue = m_pDoc->GetValue(3, 1, destSheet); // D2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell D2", 1, fValue);
+ fValue = m_pDoc->GetValue(4, 1, destSheet); // E2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell E2", 2, fValue);
+ fValue = m_pDoc->GetValue(5, 1, destSheet); // F2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell F2", 3, fValue);
+ fValue = m_pDoc->GetValue(6, 1, destSheet); // G2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell G2", 4, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 1, destSheet));
+ // row 2, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 2, destSheet));
+ aString = m_pDoc->GetString(2, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 2, destSheet, aString); // D3
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula D3 should point on D2", OUString("=D2+10"),
+ aString);
+ fValue = m_pDoc->GetValue(3, 2, destSheet); // D3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula D3", 11, fValue);
+ m_pDoc->GetFormula(4, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula E3 should point on E2", OUString("=E2+20"),
+ aString);
+ fValue = m_pDoc->GetValue(4, 2, destSheet); // E3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula E3", 22, fValue);
+ m_pDoc->GetFormula(5, 2, destSheet, aString); // F3
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula F3 should point on F2", OUString("=F5+30"),
+ aString);
+ fValue = m_pDoc->GetValue(5, 2, destSheet); // F3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula F3", 35, fValue);
+ m_pDoc->GetFormula(6, 2, destSheet, aString); // G3
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula G3 should point on E2", OUString("=E2+40"),
+ aString);
+ fValue = m_pDoc->GetValue(6, 2, destSheet); // G3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula G3", 42, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 2, destSheet));
+ aString = m_pDoc->GetString(7, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 3, strings
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 3, destSheet));
+ aString = m_pDoc->GetString(2, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ aString = m_pDoc->GetString(3, 3, destSheet); // D4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell D4 should contain: a", OUString("a"), aString);
+ aString = m_pDoc->GetString(4, 3, destSheet); // E4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E4 should contain: b", OUString("b"), aString);
+ aString = m_pDoc->GetString(5, 3, destSheet); // F4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell F4 should contain: c", OUString("c"), aString);
+ aString = m_pDoc->GetString(6, 3, destSheet); // G4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell G4 should contain: d", OUString("d"), aString);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 3, destSheet));
+ aString = m_pDoc->GetString(7, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 4, rich text
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 4, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(2, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be no edit cell in C5.", pEditObj == nullptr);
+ pEditObj = m_pDoc->GetEditText(ScAddress(3, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be an edit cell in D5.", pEditObj);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Edit cell value wrong in D5 ", OUString("R1"),
+ pEditObj->GetText(0));
+ pEditObj = m_pDoc->GetEditText(ScAddress(4, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be an edit cell in E5.", pEditObj);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Edit cell value wrong E5.", OUString("R2"), pEditObj->GetText(0));
+ fValue = m_pDoc->GetValue(5, 4, destSheet); // F5
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell F5", 5, fValue);
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be an edit cell in G5.", pEditObj);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Edit cell value wrong G5.", OUString("R4"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 4, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(7, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be no edit cell in H5.", pEditObj == nullptr);
+ // row 5, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ aString = m_pDoc->GetString(2, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 5, destSheet, aString); // D6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula D6", OUString("=D2+F2+60"), aString);
+ fValue = m_pDoc->GetValue(3, 5, destSheet); // D6
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula D6", 64, fValue);
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(4, 5, destSheet); // E6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ aString = m_pDoc->GetString(5, 5, destSheet); // F6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ }
+ else
+ {
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 5, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 5, destSheet));
+ }
+ fValue = m_pDoc->GetValue(6, 5, destSheet); // G6
+ m_pDoc->GetFormula(6, 5, destSheet, aString); // G6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula G6", OUString("=D2+F2+70"), aString);
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula G6", 74, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 5, destSheet));
+ aString = m_pDoc->GetString(7, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 6, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 6, destSheet));
+ aString = m_pDoc->GetString(2, 6, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 6, destSheet, aString); // D7
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula D7", OUString("=SUMIF(D2:G2;\"<4\")"),
+ aString);
+ fValue = m_pDoc->GetValue(3, 6, destSheet); // D7
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula D7", 6, fValue);
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(4, 6, destSheet); // E6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ aString = m_pDoc->GetString(5, 6, destSheet); // F6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ }
+ else
+ {
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 6, destSheet));
+ }
+ fValue = m_pDoc->GetValue(6, 6, destSheet); // G7
+ m_pDoc->GetFormula(6, 6, destSheet, aString); // G7
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula G7", OUString("=C$1+$A$3+80"), aString);
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula G7", 2080, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 6, destSheet));
+ aString = m_pDoc->GetString(7, 6, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 7
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 7, destSheet));
+
+ // check patterns
+ const SfxPoolItem* pItem = nullptr;
+ m_pDoc->GetPattern(ScAddress(3, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("D2 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("D2 has blue background", COL_BLUE,
+ static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(4, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("E2 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("E2 has blue background", COL_BLUE,
+ static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(5, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("F2 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("F2 has a pattern", COL_BLUE,
+ static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(6, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("G2 has no pattern", !pItem);
+ m_pDoc->GetPattern(ScAddress(7, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("H2 has no pattern", !pItem);
+ m_pDoc->GetPattern(ScAddress(5, 5, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(bSkipEmpty, pItem == nullptr);
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+
+ // check border, left and right borders were transformed to top and bottom borders
+ pItem = m_pDoc->GetAttr(ScAddress(3, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("D3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("D3 has no top border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("D3 has no bottom border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("D3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("D3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ m_pDoc->GetPattern(ScAddress(4, 2, destSheet))->GetItemSet().HasItem(ATTR_BORDER, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("E3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("E3 has top border", static_cast<const SvxBoxItem*>(pItem)->GetTop());
+
+ pItem = m_pDoc->GetAttr(ScAddress(4, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("E3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("E3 has top border", static_cast<const SvxBoxItem*>(pItem)->GetTop());
+
+ CPPUNIT_ASSERT_MESSAGE("E3 has bottom border",
+ static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("E3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("E3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(5, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("F3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("F3 has top border", static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("F3 has bottom border",
+ static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("F3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("F3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(6, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("G3 has top border", static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("G3 has bottom border",
+ static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("G3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("G3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(7, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("H3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("H3 has no top border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("H3 has no bottom border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("H3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("H3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ // check notes after transposed copy/paste
+ // check presence of notes
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C1",
+ !m_pDoc->HasNote(ScAddress(2, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D1",
+ !m_pDoc->HasNote(ScAddress(3, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E1",
+ !m_pDoc->HasNote(ScAddress(4, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on F1",
+ !m_pDoc->HasNote(ScAddress(5, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G1",
+ !m_pDoc->HasNote(ScAddress(6, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H1",
+ !m_pDoc->HasNote(ScAddress(7, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C2",
+ !m_pDoc->HasNote(ScAddress(2, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on D2",
+ m_pDoc->HasNote(ScAddress(3, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E2",
+ m_pDoc->HasNote(ScAddress(4, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F2",
+ m_pDoc->HasNote(ScAddress(5, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G2",
+ !m_pDoc->HasNote(ScAddress(6, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H2",
+ !m_pDoc->HasNote(ScAddress(7, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C3",
+ !m_pDoc->HasNote(ScAddress(2, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on D3",
+ m_pDoc->HasNote(ScAddress(3, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E3",
+ !m_pDoc->HasNote(ScAddress(4, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F3",
+ m_pDoc->HasNote(ScAddress(5, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on G3",
+ m_pDoc->HasNote(ScAddress(6, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H3",
+ !m_pDoc->HasNote(ScAddress(7, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C4",
+ !m_pDoc->HasNote(ScAddress(2, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D4",
+ !m_pDoc->HasNote(ScAddress(3, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E4",
+ m_pDoc->HasNote(ScAddress(4, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F4",
+ m_pDoc->HasNote(ScAddress(5, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on G4",
+ m_pDoc->HasNote(ScAddress(6, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H4",
+ !m_pDoc->HasNote(ScAddress(7, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C5",
+ !m_pDoc->HasNote(ScAddress(2, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on D5",
+ m_pDoc->HasNote(ScAddress(3, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E5",
+ m_pDoc->HasNote(ScAddress(4, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F5",
+ m_pDoc->HasNote(ScAddress(5, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on G5",
+ m_pDoc->HasNote(ScAddress(6, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H5",
+ !m_pDoc->HasNote(ScAddress(7, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C6",
+ !m_pDoc->HasNote(ScAddress(2, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D6",
+ !m_pDoc->HasNote(ScAddress(3, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E6",
+ !m_pDoc->HasNote(ScAddress(4, 5, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(5, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on G6",
+ m_pDoc->HasNote(ScAddress(6, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H6",
+ !m_pDoc->HasNote(ScAddress(7, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C7",
+ !m_pDoc->HasNote(ScAddress(2, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D7",
+ !m_pDoc->HasNote(ScAddress(3, 6, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(4, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on F7",
+ !m_pDoc->HasNote(ScAddress(5, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note a G7",
+ m_pDoc->HasNote(ScAddress(6, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H7",
+ !m_pDoc->HasNote(ScAddress(7, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C8",
+ !m_pDoc->HasNote(ScAddress(2, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D8",
+ !m_pDoc->HasNote(ScAddress(3, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E8",
+ !m_pDoc->HasNote(ScAddress(4, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on F8",
+ !m_pDoc->HasNote(ScAddress(5, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G8",
+ !m_pDoc->HasNote(ScAddress(6, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H8",
+ !m_pDoc->HasNote(ScAddress(7, 7, destSheet)));
+
+ // check values of notes
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on D2",
+ m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on E2",
+ m_pDoc->GetNote(ScAddress(0, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on F2",
+ m_pDoc->GetNote(ScAddress(0, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 1, destSheet))->GetText());
+ // G2 has no note
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on D3",
+ m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, destSheet))->GetText());
+ // E3 has no note
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on F3",
+ m_pDoc->GetNote(ScAddress(1, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 2, destSheet))->GetText());
+ // D4 has no note
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on E4",
+ m_pDoc->GetNote(ScAddress(2, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on F4",
+ m_pDoc->GetNote(ScAddress(2, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on D5",
+ m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 4, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on E5",
+ m_pDoc->GetNote(ScAddress(3, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 4, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on F5",
+ m_pDoc->GetNote(ScAddress(3, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 4, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 5, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on G6",
+ m_pDoc->GetNote(ScAddress(4, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 5, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on E7",
+ m_pDoc->GetNote(ScAddress(5, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 6, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on G7",
+ m_pDoc->GetNote(ScAddress(5, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 6, destSheet))->GetText());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+void Test::checkCopyPasteSpecialFilteredTranspose(bool bSkipEmpty)
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ /*
+ ┌--- filtered src row 2 ┌--- repeated row
+ v v
+
+ | D | E | F | G |
+
+ 2 | 1 B*| 3 B*| 4 | 1 B*|
+ 3 | =D2+10 *| =E5+30 b*| =D2+40 b*| =G2+10 *|
+ 4 | a | c *| d *| a |
+ 5 | R1 *| 5 *| R4 *| R1 *|
+ 6 | =D2+F2+60 | B*| =C2+E2+70 *| =G2+I2+60 |
+ 7 | =SUMIF(D2:G2;"<4") | | =B$1+$A$1+80 *| =SUMIF(G2:J2;"<4") |
+
+ * means note attached
+ */
+
+ //check cell content after transposed copy/paste of filtered data
+ // Note: column F is a repetition of srcSheet.Column A
+ // Col C and G are checked to be empty
+ OUString aString;
+ double fValue;
+ const EditTextObject* pEditObj;
+ // row 0
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 0, destSheet));
+ // row 1, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 1, destSheet));
+ aString = m_pDoc->GetString(2, 1, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ fValue = m_pDoc->GetValue(3, 1, destSheet); // D2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell D2", 1, fValue);
+ fValue = m_pDoc->GetValue(4, 1, destSheet); // E2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell E2", 3, fValue);
+ fValue = m_pDoc->GetValue(5, 1, destSheet); // F2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell F2", 4, fValue);
+ fValue = m_pDoc->GetValue(6, 1, destSheet); // G2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell G2 (repetition of D2)", 1, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 1, destSheet));
+ aString = m_pDoc->GetString(7, 1, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 2, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 2, destSheet));
+ aString = m_pDoc->GetString(2, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ fValue = m_pDoc->GetValue(3, 2, destSheet); // D3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula D3", 11, fValue);
+ m_pDoc->GetFormula(3, 2, destSheet, aString); // D3
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula D3 should point on D2", OUString("=D2+10"),
+ aString);
+ m_pDoc->GetFormula(4, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula E3 should point on E2", OUString("=E5+30"),
+ aString);
+ fValue = m_pDoc->GetValue(4, 2, destSheet); // E3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula E3", 35, fValue);
+ m_pDoc->GetFormula(5, 2, destSheet, aString); // F3
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula F3 should point on F2", OUString("=D2+40"),
+ aString);
+ fValue = m_pDoc->GetValue(5, 2, destSheet); // F3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula F3", 41, fValue);
+ fValue = m_pDoc->GetValue(6, 2, destSheet); // G3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula F3", 11, fValue);
+ m_pDoc->GetFormula(6, 2, destSheet, aString); // G3
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula G3 should point on G2 (repetition of D3)",
+ OUString("=G2+10"), aString);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 2, destSheet));
+ aString = m_pDoc->GetString(7, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 3, strings
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 3, destSheet));
+ aString = m_pDoc->GetString(2, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ aString = m_pDoc->GetString(3, 3, destSheet); // D4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell D4 should contain: a", OUString("a"), aString);
+ aString = m_pDoc->GetString(4, 3, destSheet); // E4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E4 should contain: c", OUString("c"), aString);
+ aString = m_pDoc->GetString(5, 3, destSheet); // F4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell F4 should contain: d", OUString("d"), aString);
+ aString = m_pDoc->GetString(6, 3, destSheet); // G4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell G4 should contain: a (repetition of D4)", OUString("a"),
+ aString);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 3, destSheet));
+ aString = m_pDoc->GetString(7, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 4, rich text
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 4, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(2, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be no edit cell in C5.", pEditObj == nullptr);
+ pEditObj = m_pDoc->GetEditText(ScAddress(3, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be an edit cell in D5.", pEditObj);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Edit cell value wrong in D5 ", OUString("R1"),
+ pEditObj->GetText(0));
+ fValue = m_pDoc->GetValue(4, 4, destSheet); // E5
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell E5", 5, fValue);
+ pEditObj = m_pDoc->GetEditText(ScAddress(5, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be an edit cell in F5.", pEditObj);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Edit cell value wrong F5.", OUString("R4"), pEditObj->GetText(0));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be an edit cell in G5. (repetition of D5)", pEditObj);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Edit cell value wrong G5. (repetition of D5)", OUString("R1"),
+ pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 4, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(7, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be no edit cell in H5.", pEditObj == nullptr);
+ // row 5, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ aString = m_pDoc->GetString(2, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 5, destSheet, aString); // D6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula D6", OUString("=D2+F2+60"), aString);
+ fValue = m_pDoc->GetValue(
+ ScAddress(3, 5, destSheet)); // D6, formulas over filtered rows are not adjusted
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula D6", 65,
+ fValue); // formulas over filtered rows are not adjusted
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(4, 5, destSheet); // E6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ }
+ else
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 5, destSheet));
+ m_pDoc->GetFormula(5, 5, destSheet, aString); // F6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula F6", OUString("=C2+E2+70"), aString);
+ fValue = m_pDoc->GetValue(
+ ScAddress(5, 5, destSheet)); // F6, formulas over filtered rows are not adjusted
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula F6", 1073, fValue);
+ m_pDoc->GetFormula(6, 5, destSheet, aString); // G6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula G6 (repetition of D6)", OUString("=G2+I2+60"),
+ aString);
+ fValue = m_pDoc->GetValue(6, 5, destSheet); // G6
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula G6 (repetition of D6)", 1061, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 5, destSheet));
+ aString = m_pDoc->GetString(7, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 6, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 6, destSheet));
+ aString = m_pDoc->GetString(2, 6, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 6, destSheet, aString); // D7
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula D7", OUString("=SUMIF(D2:G2;\"<4\")"),
+ aString);
+ fValue = m_pDoc->GetValue(3, 6, destSheet); // D7
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula D7", 5, fValue);
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(4, 6, destSheet); // E7
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ }
+ else
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 6, destSheet));
+ m_pDoc->GetFormula(5, 6, destSheet, aString); // F7
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula F7", OUString("=B$1+$A$3+80"), aString);
+ fValue = m_pDoc->GetValue(5, 6, destSheet); // F7
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula F6", 2080, fValue);
+ m_pDoc->GetFormula(6, 6, destSheet, aString); // G7
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula G7 (repetition of D7)",
+ OUString("=SUMIF(G2:J2;\"<4\")"), aString);
+ fValue = m_pDoc->GetValue(6, 5, destSheet); // G7
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula G7 (repetition of D7)", 1061, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 6, destSheet));
+ aString = m_pDoc->GetString(7, 6, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+
+ // row
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 7, destSheet));
+
+ // check patterns
+
+ const SfxPoolItem* pItem = nullptr;
+ m_pDoc->GetPattern(ScAddress(3, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("D2 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("D2 has blue background", COL_BLUE,
+ static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(4, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("E2 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(5, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("F2 has no pattern", !pItem);
+ m_pDoc->GetPattern(ScAddress(6, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("G2 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("G2 has a pattern", COL_BLUE,
+ static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(7, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("H2 has no pattern", !pItem);
+ m_pDoc->GetPattern(ScAddress(4, 5, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(bSkipEmpty, pItem == nullptr);
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+
+ // check border, left and right borders were transformed to top and bottom borders
+ pItem = m_pDoc->GetAttr(ScAddress(3, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("D3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("D3 has no top border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("D3 has no bottom border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("D3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("D3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("E3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("E3 has top border", static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("E3 has bottom border",
+ static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("E3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("E3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(5, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("F3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("F3 has top border", static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("F3 has bottom border",
+ static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("F3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("F3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(6, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("G3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("G3 has no top border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("G3 has no bottom border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("G3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("G3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(7, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("H3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("H3 has no top border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("H3 has no bottom border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("H3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("H3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ // check notes after transposed copy/paste
+ // check presence of notes
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C1",
+ !m_pDoc->HasNote(ScAddress(2, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D1",
+ !m_pDoc->HasNote(ScAddress(3, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E1",
+ !m_pDoc->HasNote(ScAddress(4, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on F1",
+ !m_pDoc->HasNote(ScAddress(5, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G1",
+ !m_pDoc->HasNote(ScAddress(6, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H1",
+ !m_pDoc->HasNote(ScAddress(7, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C2",
+ !m_pDoc->HasNote(ScAddress(2, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on D2",
+ m_pDoc->HasNote(ScAddress(3, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E2",
+ m_pDoc->HasNote(ScAddress(4, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on F2",
+ !m_pDoc->HasNote(ScAddress(5, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on G2",
+ m_pDoc->HasNote(ScAddress(6, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H2",
+ !m_pDoc->HasNote(ScAddress(7, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C3",
+ !m_pDoc->HasNote(ScAddress(2, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on D3",
+ m_pDoc->HasNote(ScAddress(3, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E3",
+ m_pDoc->HasNote(ScAddress(4, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F3",
+ m_pDoc->HasNote(ScAddress(5, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on G3",
+ m_pDoc->HasNote(ScAddress(6, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H3",
+ !m_pDoc->HasNote(ScAddress(7, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C4",
+ !m_pDoc->HasNote(ScAddress(2, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D4",
+ !m_pDoc->HasNote(ScAddress(3, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E4",
+ m_pDoc->HasNote(ScAddress(4, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F4",
+ m_pDoc->HasNote(ScAddress(5, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G4",
+ !m_pDoc->HasNote(ScAddress(6, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H4",
+ !m_pDoc->HasNote(ScAddress(7, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C5",
+ !m_pDoc->HasNote(ScAddress(2, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on D5",
+ m_pDoc->HasNote(ScAddress(3, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E5",
+ m_pDoc->HasNote(ScAddress(4, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F5",
+ m_pDoc->HasNote(ScAddress(5, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on G5",
+ m_pDoc->HasNote(ScAddress(6, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H5",
+ !m_pDoc->HasNote(ScAddress(7, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C6",
+ !m_pDoc->HasNote(ScAddress(2, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D6",
+ !m_pDoc->HasNote(ScAddress(3, 5, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(4, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F6",
+ m_pDoc->HasNote(ScAddress(5, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G6",
+ !m_pDoc->HasNote(ScAddress(6, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H6",
+ !m_pDoc->HasNote(ScAddress(7, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C7",
+ !m_pDoc->HasNote(ScAddress(2, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D7",
+ !m_pDoc->HasNote(ScAddress(3, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E7",
+ !m_pDoc->HasNote(ScAddress(4, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note a F7",
+ m_pDoc->HasNote(ScAddress(5, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G7",
+ !m_pDoc->HasNote(ScAddress(6, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H7",
+ !m_pDoc->HasNote(ScAddress(7, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C8",
+ !m_pDoc->HasNote(ScAddress(2, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D8",
+ !m_pDoc->HasNote(ScAddress(3, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E8",
+ !m_pDoc->HasNote(ScAddress(4, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on F8",
+ !m_pDoc->HasNote(ScAddress(5, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G8",
+ !m_pDoc->HasNote(ScAddress(6, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H8",
+ !m_pDoc->HasNote(ScAddress(7, 7, destSheet)));
+
+ // check values of notes
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on D2",
+ m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on E2",
+ m_pDoc->GetNote(ScAddress(0, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 1, destSheet))->GetText());
+ // F2 has no note
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on G2",
+ m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on D3",
+ m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on E3",
+ m_pDoc->GetNote(ScAddress(1, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on F3",
+ m_pDoc->GetNote(ScAddress(1, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on G3",
+ m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 2, destSheet))->GetText());
+ // D4 has no note
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on E4",
+ m_pDoc->GetNote(ScAddress(2, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on F4",
+ m_pDoc->GetNote(ScAddress(2, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 3, destSheet))->GetText());
+ // G4 has no note
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on D5",
+ m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 4, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on E5",
+ m_pDoc->GetNote(ScAddress(3, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 4, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on F5",
+ m_pDoc->GetNote(ScAddress(3, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 4, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on G5",
+ m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 4, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 5, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on F6",
+ m_pDoc->GetNote(ScAddress(4, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 5, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on F7",
+ m_pDoc->GetNote(ScAddress(5, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 6, destSheet))->GetText());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+void Test::checkCopyPasteSpecialMultiRangeCol(bool bSkipEmpty)
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ /*
+ ┌--- not selected src col C
+ v
+
+ | D | E | F | G | H | I |
+
+ 2 | 1 B*| =D2+10 *| R1 *| =C2+C4+60 | =SUMIF(C2:C5;"<4") | 121 |
+ 3 | 2 B*| =D3+20 b | R2 *| | *| 122 | <- filtered row
+ 4 | 3 B*| =G4+30 b*| 5 *| B*| | 123 |
+ 5 | 4 | =D3+40 b*| R4 *| =C2+C4+70 *| =D$1+$A$1+80 *| 124 |
+
+ * means note attached
+ B means background
+ b means border
+ */
+
+ OUString aString;
+ double fValue;
+ const EditTextObject* pEditObj;
+ // col 2
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ // col 3, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(3, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(2, m_pDoc->GetValue(3, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(3, m_pDoc->GetValue(3, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(3, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 5, destSheet));
+ // col 4, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 0, destSheet));
+ aString = m_pDoc->GetString(4, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ ASSERT_DOUBLES_EQUAL(11, m_pDoc->GetValue(4, 1, destSheet));
+ m_pDoc->GetFormula(4, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+10"), aString);
+ m_pDoc->GetFormula(4, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D3+20"), aString);
+ ASSERT_DOUBLES_EQUAL(22, m_pDoc->GetValue(4, 2, destSheet));
+ fValue = m_pDoc->GetValue(4, 3, destSheet);
+ m_pDoc->GetFormula(4, 3, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=G4+30"),
+ aString); // references over selection gaps are not adjusted
+ ASSERT_DOUBLES_EQUAL(bSkipEmpty ? 1030 : 30, fValue); // It was 35
+ fValue = m_pDoc->GetValue(4, 4, destSheet);
+ m_pDoc->GetFormula(4, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D3+40"), aString);
+ ASSERT_DOUBLES_EQUAL(42, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 5, destSheet));
+ aString = m_pDoc->GetString(4, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 5, strings are not selected
+ // col 5, rich text
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 0, destSheet));
+ aString = m_pDoc->GetString(4, 5, destSheet);
+ pEditObj = m_pDoc->GetEditText(ScAddress(5, 0, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ pEditObj = m_pDoc->GetEditText(ScAddress(5, 1, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R1"), pEditObj->GetText(0));
+ pEditObj = m_pDoc->GetEditText(ScAddress(5, 2, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R2"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(5, m_pDoc->GetValue(5, 3, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(5, 4, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R4"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 5, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(5, 5, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ // col 6, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 0, destSheet));
+ aString = m_pDoc->GetString(6, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(6, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=C2+C4+60"), aString);
+ ASSERT_DOUBLES_EQUAL(2060, m_pDoc->GetValue(6, 1, destSheet)); // It was 64
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(6, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ aString = m_pDoc->GetString(6, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ {
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 3, destSheet));
+ }
+ fValue = m_pDoc->GetValue(6, 4, destSheet);
+ m_pDoc->GetFormula(6, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=C2+C4+70"), aString);
+ ASSERT_DOUBLES_EQUAL(2070, fValue); // It was 74
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 5, destSheet));
+ aString = m_pDoc->GetString(6, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 7, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 0, destSheet));
+ aString = m_pDoc->GetString(7, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(7, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("=SUMIF(C2:C5;\"<4\")"),
+ aString); // CPPUNIT_ASSERT_EQUAL(OUString("=SUMIF(D2:D5;\"<4\")"), aString);
+ ASSERT_DOUBLES_EQUAL(0, m_pDoc->GetValue(7, 1, destSheet)); // It was 6
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(7, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ aString = m_pDoc->GetString(7, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ {
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 3, destSheet));
+ }
+ fValue = m_pDoc->GetValue(7, 4, destSheet);
+ m_pDoc->GetFormula(7, 4, destSheet, aString);
+ ASSERT_DOUBLES_EQUAL(2080, fValue);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D$1+$A$3+80"), aString);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 5, destSheet));
+ aString = m_pDoc->GetString(7, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 8, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(121, m_pDoc->GetValue(8, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(122, m_pDoc->GetValue(8, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(123, m_pDoc->GetValue(8, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(124, m_pDoc->GetValue(8, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 5, destSheet));
+ // col 9, col repetition is not supported for multi range copy/paste
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 5, destSheet));
+
+ // check patterns
+ const SfxPoolItem* pItem = nullptr;
+ m_pDoc->GetPattern(ScAddress(3, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 2, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(3, 5, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(6, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(bSkipEmpty, pItem == nullptr);
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+
+ // check border, left and right borders were transformed to top and bottom borders
+ pItem = m_pDoc->GetAttr(ScAddress(4, 1, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 3, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 4, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 5, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ // check notes after transposed copy/paste
+ // check presence of notes
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 2, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(7, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 3, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(6, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(7, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 5, destSheet)));
+
+ // check values of notes
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 3, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 4, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(5, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(7, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(5, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(7, 4, destSheet))->GetText());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+void Test::checkCopyPasteSpecialMultiRangeColFiltered(bool bSkipEmpty)
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ /*
+ ┌--- not selected src col C
+ v
+
+ | D | E | F | G | H | I |
+
+ 2 | 1 B*| =D2+10 *| R1 *| =C2+C4+60 | =SUMIF(C2:C5;"<4") | 121 |
+ 3 | 3 B*| =G4+30 b*| 5 *| B*| | 123 |
+ 4 | 4 | =D2+40 b*| R4 *| =C1+C3+70 *| =D$1+$A$1+80 *| 124 |
+
+ * means note attached
+ B means background
+ b means border
+ */
+
+ OUString aString;
+ double fValue;
+ const EditTextObject* pEditObj;
+ // col 2
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ // col 3, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(3, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(3, m_pDoc->GetValue(3, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(3, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 4, destSheet));
+ // col 4, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 0, destSheet));
+ m_pDoc->GetFormula(4, 0, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ ASSERT_DOUBLES_EQUAL(11, m_pDoc->GetValue(4, 1, destSheet));
+ m_pDoc->GetFormula(4, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+10"), aString);
+ fValue = m_pDoc->GetValue(4, 2, destSheet);
+ m_pDoc->GetFormula(4, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=G3+30"),
+ aString); // references over selection gaps are not adjusted
+ ASSERT_DOUBLES_EQUAL(bSkipEmpty ? 1030 : 30, fValue); // It was 35
+ fValue = m_pDoc->GetValue(4, 3, destSheet);
+ m_pDoc->GetFormula(4, 3, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+40"), aString);
+ ASSERT_DOUBLES_EQUAL(41, fValue); // was originally 42, not adjusted by filtering
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 4, destSheet));
+ m_pDoc->GetFormula(4, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ // col 5, strings are not selected
+ // col 5, rich text
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 0, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(5, 0, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ pEditObj = m_pDoc->GetEditText(ScAddress(5, 1, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R1"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(5, m_pDoc->GetValue(5, 2, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(5, 3, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R4"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 4, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(5, 4, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ // col 6, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 0, destSheet));
+ m_pDoc->GetFormula(6, 0, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ m_pDoc->GetFormula(6, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=C2+C4+60"), aString);
+ ASSERT_DOUBLES_EQUAL(2060, m_pDoc->GetValue(6, 1, destSheet)); // It was 64
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(6, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 2, destSheet));
+ fValue = m_pDoc->GetValue(6, 3, destSheet);
+ m_pDoc->GetFormula(6, 3, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=C1+C3+70"), aString);
+ ASSERT_DOUBLES_EQUAL(2070, fValue); // It was 74
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 4, destSheet));
+ m_pDoc->GetFormula(6, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ // col 7, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 0, destSheet));
+ m_pDoc->GetFormula(7, 0, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ m_pDoc->GetFormula(7, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=SUMIF(C2:C5;\"<4\")"), aString);
+ ASSERT_DOUBLES_EQUAL(0, m_pDoc->GetValue(7, 1, destSheet)); // It was 6
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(7, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 2, destSheet));
+ fValue = m_pDoc->GetValue(7, 3, destSheet);
+ m_pDoc->GetFormula(7, 3, destSheet, aString);
+ ASSERT_DOUBLES_EQUAL(2080, fValue);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D$1+$A$3+80"), aString);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 4, destSheet));
+ m_pDoc->GetFormula(7, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ // col 8, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(121, m_pDoc->GetValue(8, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(123, m_pDoc->GetValue(8, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(124, m_pDoc->GetValue(8, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 4, destSheet));
+ // col 9, col repetition is not supported for multi range copy/paste
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 5, destSheet));
+
+ // check patterns
+ const SfxPoolItem* pItem = nullptr;
+ m_pDoc->GetPattern(ScAddress(3, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 2, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(3, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(6, 2, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(bSkipEmpty, pItem == nullptr);
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+
+ // check border, left and right borders were transformed to top and bottom borders
+ pItem = m_pDoc->GetAttr(ScAddress(4, 1, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 3, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 4, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ // check notes after transposed copy/paste
+ // check presence of notes
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 2, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(6, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(7, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 4, destSheet)));
+
+ // check values of notes
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 2, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(5, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(7, 3, destSheet))->GetText());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+void Test::checkCopyPasteSpecialMultiRangeColTranspose(bool bSkipEmpty)
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ /*
+ | D | E | F | G |
+
+ 2 | 1 B*| 2 B*| 3 B*| 4 |
+ 3 | =D2+10 *| =E2+20 b | =F5+30 b*| =E2+40 b*|
+ 4 | R1 *| R2 *| 5 *| R4 *|
+ 5 | =D1+F1+60 | | B*| =D1+F1+70 *|
+ 6 | =SUMIF(D1:G1;"<4") | *| | =C$1+$A$1+80 *|
+ 7 | 121 | 122 | 123 | 124 |
+
+ * means note attached
+ B means background
+ b means border
+ */
+
+ // check cell content after transposed copy/paste of filtered data
+ // Col C and G are checked to be empty
+ OUString aString;
+ double fValue;
+ const EditTextObject* pEditObj;
+ // row 0
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 0, destSheet));
+ // row 1, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(3, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(2, m_pDoc->GetValue(4, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(3, m_pDoc->GetValue(5, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(6, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 1, destSheet));
+ // row 2, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 2, destSheet));
+ aString = m_pDoc->GetString(2, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ ASSERT_DOUBLES_EQUAL(11, m_pDoc->GetValue(3, 2, destSheet));
+ m_pDoc->GetFormula(3, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+10"), aString);
+ m_pDoc->GetFormula(4, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=E2+20"), aString);
+ ASSERT_DOUBLES_EQUAL(22, m_pDoc->GetValue(4, 2, destSheet));
+ fValue = m_pDoc->GetValue(5, 2, destSheet);
+ m_pDoc->GetFormula(5, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=F5+30"), aString);
+ ASSERT_DOUBLES_EQUAL(bSkipEmpty ? 1030 : 30, fValue); // It was 35
+ fValue = m_pDoc->GetValue(6, 2, destSheet);
+ m_pDoc->GetFormula(6, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=E2+40"), aString);
+ ASSERT_DOUBLES_EQUAL(42, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 2, destSheet));
+ aString = m_pDoc->GetString(7, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 3, strings was not selected in multi range selection
+ // row 3, rich text
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 3, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(2, 3, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ pEditObj = m_pDoc->GetEditText(ScAddress(3, 3, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R1"), pEditObj->GetText(0));
+ pEditObj = m_pDoc->GetEditText(ScAddress(4, 3, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R2"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(5, m_pDoc->GetValue(5, 3, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 3, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R4"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 3, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(7, 3, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ // row 4, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 4, destSheet));
+ aString = m_pDoc->GetString(2, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D1+F1+60"), aString);
+ ASSERT_DOUBLES_EQUAL(2060, m_pDoc->GetValue(3, 4, destSheet)); // It was 64
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(4, 4, destSheet); // E5
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E5", EMPTY_OUSTRING, aString);
+ aString = m_pDoc->GetString(5, 4, destSheet); // F5
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E5", EMPTY_OUSTRING, aString);
+ }
+ else
+ {
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 4, destSheet));
+ }
+ fValue = m_pDoc->GetValue(6, 4, destSheet);
+ m_pDoc->GetFormula(6, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D1+F1+70"), aString);
+ ASSERT_DOUBLES_EQUAL(2070, fValue); // It was 74
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 4, destSheet));
+ aString = m_pDoc->GetString(7, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 5, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ aString = m_pDoc->GetString(2, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 5, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=SUMIF(D1:G1;\"<4\")"), aString);
+ ASSERT_DOUBLES_EQUAL(0, m_pDoc->GetValue(3, 5, destSheet)); // It was 6
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(4, 5, destSheet); // E6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ aString = m_pDoc->GetString(5, 5, destSheet); // F6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ }
+ else
+ {
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 5, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 5, destSheet));
+ }
+
+ fValue = m_pDoc->GetValue(6, 5, destSheet);
+ m_pDoc->GetFormula(6, 5, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=C$1+$A$3+80"), aString);
+ ASSERT_DOUBLES_EQUAL(2080, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 5, destSheet));
+ aString = m_pDoc->GetString(7, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 6, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(121, m_pDoc->GetValue(3, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(122, m_pDoc->GetValue(4, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(123, m_pDoc->GetValue(5, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(124, m_pDoc->GetValue(6, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 6, destSheet));
+ // row 7, not selected
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 7, destSheet));
+
+ // check patterns
+ const SfxPoolItem* pItem = nullptr;
+ m_pDoc->GetPattern(ScAddress(3, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(4, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(5, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(6, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(7, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(5, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(bSkipEmpty, pItem == nullptr);
+ // std::cout << "bSkipEmpty: " << bSkipEmpty << ", pItem == nullptr: " << (pItem == nullptr) << std::endl;
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+
+ // check border, left and right borders were transformed to top and bottom borders
+ pItem = m_pDoc->GetAttr(ScAddress(3, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ m_pDoc->GetPattern(ScAddress(4, 2, destSheet))->GetItemSet().HasItem(ATTR_BORDER, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(5, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(6, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(7, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ // check notes after transposed copy/paste
+ // check presence of notes
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 4, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(5, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 5, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(4, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 5, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 6, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 6, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 6, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 6, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 6, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 6, destSheet)));
+
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 3, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 4, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 4, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(5, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 5, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(5, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 5, destSheet))->GetText());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+void Test::checkCopyPasteSpecialMultiRangeColFilteredTranspose(bool bSkipEmpty)
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ /*
+ ┌--- filtered src row 2
+ v
+
+ | D | E | F |
+
+ 2 | 1 B*| 3 B*| 4 |
+ 3 | =D2+10 *| =E5+30 b*| =D2+40 b*|
+ <- not copied col C
+ 4 | R1 *| 5 *| R4 *|
+ 5 | =D1+F1+60 | B*| =C1+E1+70 *|
+ 6 | =SUMIF(D1:G1;"<4") | | =B$1+$A$1+80 *|
+ 7 | 121 | 123 | 124 |
+
+ * means note attached
+ B means background
+ b means border
+ */
+
+ // check cell content after transposed copy/paste of filtered data
+ // Col C and G are checked to be empty
+ OUString aString;
+ double fValue;
+ const EditTextObject* pEditObj;
+ // row 0
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 0, destSheet));
+ // row 1, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(3, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(3, m_pDoc->GetValue(4, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(5, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 1, destSheet));
+ // row 2, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ aString = m_pDoc->GetString(2, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ ASSERT_DOUBLES_EQUAL(11, m_pDoc->GetValue(3, 2, destSheet));
+ m_pDoc->GetFormula(3, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+10"), aString);
+ fValue = m_pDoc->GetValue(4, 2, destSheet);
+ m_pDoc->GetFormula(4, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=E5+30"), aString);
+ ASSERT_DOUBLES_EQUAL(bSkipEmpty ? 1030 : 30, fValue); // It was 35
+ fValue = m_pDoc->GetValue(5, 2, destSheet);
+ m_pDoc->GetFormula(5, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+40"), aString);
+ ASSERT_DOUBLES_EQUAL(41, fValue); // was originally 42, not adjusted by filtering
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 2, destSheet));
+ aString = m_pDoc->GetString(6, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 3, strings was not selected in multi range selection
+ // row 3, rich text
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 3, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(2, 3, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ pEditObj = m_pDoc->GetEditText(ScAddress(3, 3, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R1"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(5, m_pDoc->GetValue(4, 3, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(5, 3, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R4"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 3, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 3, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ // row 4, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 4, destSheet));
+ aString = m_pDoc->GetString(2, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D1+F1+60"),
+ aString); // formulas over filtered rows are not adjusted
+ ASSERT_DOUBLES_EQUAL(2060, m_pDoc->GetValue(3, 4, destSheet)); // It was 64
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(4, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 4, destSheet));
+ fValue = m_pDoc->GetValue(5, 4, destSheet);
+ m_pDoc->GetFormula(5, 4, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=C1+E1+70"),
+ aString); // formulas over filtered rows are not adjusted
+ ASSERT_DOUBLES_EQUAL(2070, fValue); // It was 74
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 4, destSheet));
+ aString = m_pDoc->GetString(6, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 5, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ aString = m_pDoc->GetString(2, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 5, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=SUMIF(D1:G1;\"<4\")"),
+ aString); // formulas over filtered rows are not adjusted
+ ASSERT_DOUBLES_EQUAL(0, m_pDoc->GetValue(3, 5, destSheet)); // It was 6
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(4, 5, destSheet); // E6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ }
+ else
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 5, destSheet));
+ fValue = m_pDoc->GetValue(5, 5, destSheet);
+ m_pDoc->GetFormula(5, 5, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=B$1+$A$3+80"), aString);
+ ASSERT_DOUBLES_EQUAL(2080, fValue);
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 5, destSheet));
+ aString = m_pDoc->GetString(6, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 6, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(121, m_pDoc->GetValue(3, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(123, m_pDoc->GetValue(4, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(124, m_pDoc->GetValue(5, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 6, destSheet));
+ // row 7, not copied
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 7, destSheet));
+ // row 8, not copied
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 7, destSheet));
+
+ // check patterns
+ const SfxPoolItem* pItem = nullptr;
+ m_pDoc->GetPattern(ScAddress(3, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(4, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(5, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(6, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(4, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(bSkipEmpty, pItem == nullptr);
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+
+ // check border, left and right borders were transformed to top and bottom borders
+ pItem = m_pDoc->GetAttr(ScAddress(3, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ m_pDoc->GetPattern(ScAddress(4, 2, destSheet))->GetItemSet().HasItem(ATTR_BORDER, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetTop());
+
+ pItem = m_pDoc->GetAttr(ScAddress(4, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(5, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(6, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ // check notes after transposed copy/paste
+ // check presence of notes
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 4, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(4, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 5, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 6, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 6, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 6, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 6, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 6, destSheet)));
+
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 3, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 4, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 4, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(5, 3, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 5, destSheet))->GetText());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+void Test::checkCopyPasteSpecialMultiRangeRow(bool bSkipEmpty)
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ /*
+ | D | E | F | G | H | I |
+
+ 2 | 1 B*| =D2+10 *| a | R1 *| =D2+D4+60 | =SUMIF(D2:D5;"<4") |
+ 3 | 2 B*| =D3+20 b | b *| R2 *| | *| <- filtered row
+ 4 | 3 B*| =G4+30 b*| c *| 5 *| B*| |
+ <- not selected row
+ 5 | 6 | q | r bB*| s bB| t | u |
+ 6 | -11 | -12 | -13 | -14 | -15 | -16 |
+
+ * means note attached
+ B means background
+ b means border
+ */
+
+ OUString aString;
+ const EditTextObject* pEditObj;
+ // col 2
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ // col 3, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(3, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(2, m_pDoc->GetValue(3, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(3, m_pDoc->GetValue(3, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(6, m_pDoc->GetValue(3, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(-11, m_pDoc->GetValue(3, 5, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 6, destSheet));
+ // col 4, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 0, destSheet));
+ aString = m_pDoc->GetString(4, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ ASSERT_DOUBLES_EQUAL(11, m_pDoc->GetValue(4, 1, destSheet));
+ m_pDoc->GetFormula(4, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+10"), aString);
+ m_pDoc->GetFormula(4, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D3+20"), aString);
+ ASSERT_DOUBLES_EQUAL(22, m_pDoc->GetValue(4, 2, destSheet));
+ m_pDoc->GetFormula(4, 3, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=G4+30"), aString);
+ ASSERT_DOUBLES_EQUAL(35, m_pDoc->GetValue(4, 3, destSheet));
+ aString = m_pDoc->GetString(4, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("q"), aString);
+ ASSERT_DOUBLES_EQUAL(-12, m_pDoc->GetValue(4, 5, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 6, destSheet));
+ aString = m_pDoc->GetString(4, 6, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 5, strings
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 0, destSheet));
+ aString = m_pDoc->GetString(5, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ aString = m_pDoc->GetString(5, 1, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("a"), aString);
+ aString = m_pDoc->GetString(5, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("b"), aString);
+ aString = m_pDoc->GetString(5, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("c"), aString);
+ aString = m_pDoc->GetString(5, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("r"), aString);
+ ASSERT_DOUBLES_EQUAL(-13, m_pDoc->GetValue(5, 5, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 6, destSheet));
+ aString = m_pDoc->GetString(5, 6, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 6, rich text
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 0, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 0, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 1, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R1"), pEditObj->GetText(0));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 2, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R2"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(5, m_pDoc->GetValue(6, 3, destSheet));
+ aString = m_pDoc->GetString(6, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("s"), aString);
+ ASSERT_DOUBLES_EQUAL(-14, m_pDoc->GetValue(6, 5, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 6, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 6, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ // col 7, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 0, destSheet));
+ aString = m_pDoc->GetString(7, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(7, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+D4+60"), aString);
+ ASSERT_DOUBLES_EQUAL(64, m_pDoc->GetValue(7, 1, destSheet));
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(7, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ aString = m_pDoc->GetString(7, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ {
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 3, destSheet));
+ }
+ aString = m_pDoc->GetString(7, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("t"), aString);
+ ASSERT_DOUBLES_EQUAL(-15, m_pDoc->GetValue(7, 5, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 6, destSheet));
+ aString = m_pDoc->GetString(7, 6, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 8, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 0, destSheet));
+ aString = m_pDoc->GetString(7, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(8, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=SUMIF(D2:D5;\"<4\")"), aString);
+ ASSERT_DOUBLES_EQUAL(6, m_pDoc->GetValue(8, 1, destSheet));
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(8, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ aString = m_pDoc->GetString(8, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ {
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 3, destSheet));
+ }
+ aString = m_pDoc->GetString(8, 4, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("u"), aString);
+ ASSERT_DOUBLES_EQUAL(-16, m_pDoc->GetValue(8, 5, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 6, destSheet));
+ aString = m_pDoc->GetString(8, 6, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 9
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 5, destSheet));
+
+ // check patterns
+ const SfxPoolItem* pItem = nullptr;
+ m_pDoc->GetPattern(ScAddress(3, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 2, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(3, 5, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(7, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(bSkipEmpty, pItem == nullptr);
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+
+ m_pDoc->GetPattern(ScAddress(4, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(5, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_RED, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(6, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_RED, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(7, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+
+ // check border, left and right borders were transformed to top and bottom borders
+ pItem = m_pDoc->GetAttr(ScAddress(4, 1, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 3, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 4, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 5, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ pItem = m_pDoc->GetAttr(ScAddress(3, 4, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 4, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(5, 4, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(6, 4, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(7, 4, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ // check notes after transposed copy/paste
+ // check presence of notes
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 2, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(8, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 3, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(7, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 4, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 5, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 5, destSheet)));
+
+ // check values of notes
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(2, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(2, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 3, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(7, 3, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(5, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(8, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(2, 4, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 4, destSheet))->GetText());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+void Test::checkCopyPasteSpecialMultiRangeRowFiltered(bool bSkipEmpty)
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ /*
+ | D | E | F | G | H | I |
+
+ 2 | 1 B*| =D2+10 *| a | R1 *| =D2+D4+60 | =SUMIF(D2:D5;"<4") |
+ 3 | 3 B*| =G3+30 b*| c *| 5 *| B*| |
+ <- not selected
+ 4 | 6 | q | r | s | t | u |
+ 5 | -11 | -12 |-13 | -14 | -15 | -16 |
+
+ * means note attached
+ B means background
+ b means border
+ */
+
+ OUString aString;
+ const EditTextObject* pEditObj;
+ // col 2
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ // col 3, numbers
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1, m_pDoc->GetValue(3, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(3, m_pDoc->GetValue(3, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(6, m_pDoc->GetValue(3, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(-11, m_pDoc->GetValue(3, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 5, destSheet));
+ // col 4, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 0, destSheet));
+ aString = m_pDoc->GetString(4, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ ASSERT_DOUBLES_EQUAL(11, m_pDoc->GetValue(4, 1, destSheet));
+ m_pDoc->GetFormula(4, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+10"), aString);
+ m_pDoc->GetFormula(4, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=G3+30"), aString);
+ ASSERT_DOUBLES_EQUAL(35, m_pDoc->GetValue(4, 2, destSheet));
+ aString = m_pDoc->GetString(4, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("q"), aString);
+ ASSERT_DOUBLES_EQUAL(-12, m_pDoc->GetValue(4, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 5, destSheet));
+ aString = m_pDoc->GetString(4, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 5, strings
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 0, destSheet));
+ aString = m_pDoc->GetString(5, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ aString = m_pDoc->GetString(5, 1, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("a"), aString);
+ aString = m_pDoc->GetString(5, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("c"), aString);
+ aString = m_pDoc->GetString(5, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("r"), aString);
+ ASSERT_DOUBLES_EQUAL(-13, m_pDoc->GetValue(5, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 5, destSheet));
+ aString = m_pDoc->GetString(5, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 6, rich text
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 0, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 0, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 1, destSheet));
+ CPPUNIT_ASSERT(pEditObj);
+ CPPUNIT_ASSERT_EQUAL(OUString("R1"), pEditObj->GetText(0));
+ ASSERT_DOUBLES_EQUAL(5, m_pDoc->GetValue(6, 2, destSheet));
+ aString = m_pDoc->GetString(6, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("s"), aString);
+ ASSERT_DOUBLES_EQUAL(-14, m_pDoc->GetValue(6, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 5, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(6, 5, destSheet));
+ CPPUNIT_ASSERT(pEditObj == nullptr);
+ // col 7, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 0, destSheet));
+ aString = m_pDoc->GetString(7, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(7, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=D2+D4+60"), aString);
+ ASSERT_DOUBLES_EQUAL(67, m_pDoc->GetValue(7, 1, destSheet));
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(7, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 2, destSheet));
+ aString = m_pDoc->GetString(7, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("t"), aString);
+ ASSERT_DOUBLES_EQUAL(-15, m_pDoc->GetValue(7, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 5, destSheet));
+ aString = m_pDoc->GetString(7, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 8, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 0, destSheet));
+ aString = m_pDoc->GetString(8, 0, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(8, 1, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL(OUString("=SUMIF(D2:D5;\"<4\")"), aString);
+ ASSERT_DOUBLES_EQUAL(6, m_pDoc->GetValue(8, 1, destSheet));
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(8, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(EMPTY_OUSTRING, aString);
+ }
+ else
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 2, destSheet));
+ aString = m_pDoc->GetString(8, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("u"), aString);
+ ASSERT_DOUBLES_EQUAL(-16, m_pDoc->GetValue(8, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 5, destSheet));
+ aString = m_pDoc->GetString(8, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // col 9
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 1, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(9, 5, destSheet));
+
+ // check patterns
+ const SfxPoolItem* pItem = nullptr;
+ m_pDoc->GetPattern(ScAddress(3, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 2, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(3, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(3, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(7, 2, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(bSkipEmpty, pItem == nullptr);
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+
+ m_pDoc->GetPattern(ScAddress(4, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(5, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_RED, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(6, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_RED, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(7, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+
+ // check border, left and right borders were transformed to top and bottom borders
+ pItem = m_pDoc->GetAttr(ScAddress(4, 1, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 3, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 4, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ pItem = m_pDoc->GetAttr(ScAddress(3, 3, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 3, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(5, 3, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(6, 3, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(7, 3, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ // check notes after transposed copy/paste
+ // check presence of notes
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 0, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 1, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 1, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(3, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(4, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 2, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(6, 2, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(7, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 2, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 3, destSheet)));
+ CPPUNIT_ASSERT(m_pDoc->HasNote(ScAddress(5, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 3, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(2, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(3, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(4, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(5, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(6, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(7, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(8, 4, destSheet)));
+ CPPUNIT_ASSERT(!m_pDoc->HasNote(ScAddress(9, 4, destSheet)));
+
+ // check values of notes
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(0, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(1, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(2, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(3, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 2, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(7, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(2, 4, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 3, destSheet))->GetText());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+void Test::checkCopyPasteSpecialMultiRangeRowTranspose(bool bSkipEmpty)
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ /*
+ | D | E | F | G | H |
+
+ 2 | 1 B*| 2 B*| 3 B*| 6 | -11 |
+ 3 | =D2+10 *| =E2+20 b | =F5+30 b*| q | -12 |
+ 4 | a | b *| c *| r | -13 |
+ 5 | R1 *| R2 *| 5 *| s | -14 |
+ 6 | =D2+F2+60 | | B*| t | -15 |
+ 7 | =SUMIF(D2:G2;"<4") | *| | u | -16 |
+
+ * means note attached
+ B means background
+ b means border
+ */
+
+ //check cell content after transposed copy/paste of filtered data
+ // Note: column F is a repetition of srcSheet.Column A
+ // Col C and G are checked to be empty
+ OUString aString;
+ double fValue;
+ const EditTextObject* pEditObj;
+ // row 0
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 0, destSheet));
+ // row 1, numbers
+ fValue = m_pDoc->GetValue(2, 1, destSheet); // C2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell C2", 1000, fValue);
+ fValue = m_pDoc->GetValue(3, 1, destSheet); // D2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell D2", 1, fValue);
+ fValue = m_pDoc->GetValue(4, 1, destSheet); // E2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell E2", 2, fValue);
+ fValue = m_pDoc->GetValue(5, 1, destSheet); // F2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell F2", 3, fValue);
+ fValue = m_pDoc->GetValue(6, 1, destSheet); // G2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell G2", 6, fValue);
+ ASSERT_DOUBLES_EQUAL(-11, m_pDoc->GetValue(7, 1, destSheet));
+ fValue = m_pDoc->GetValue(8, 1, destSheet); // I2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell I2", 1000, fValue);
+ // row 2, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 2, destSheet));
+ aString = m_pDoc->GetString(2, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ fValue = m_pDoc->GetValue(3, 2, destSheet); // D3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula D3", 11, fValue);
+ m_pDoc->GetFormula(3, 2, destSheet, aString); // D3
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula D3 should point on D2", OUString("=D2+10"),
+ aString);
+ m_pDoc->GetFormula(4, 2, destSheet, aString);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula E3 should point on E2", OUString("=E2+20"),
+ aString);
+ fValue = m_pDoc->GetValue(4, 2, destSheet); // E3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula E3", 22, fValue);
+ fValue = m_pDoc->GetValue(5, 2, destSheet); // F3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula F3", 35, fValue);
+ m_pDoc->GetFormula(5, 2, destSheet, aString); // F3
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula F3 should point on F2", OUString("=F5+30"),
+ aString);
+ aString = m_pDoc->GetString(6, 2, destSheet); // G3
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell G4 should contain: q", OUString("q"), aString);
+ ASSERT_DOUBLES_EQUAL(-12, m_pDoc->GetValue(7, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 2, destSheet));
+ aString = m_pDoc->GetString(8, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 3, strings
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 3, destSheet));
+ aString = m_pDoc->GetString(2, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ aString = m_pDoc->GetString(3, 3, destSheet); // D4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell D4 should contain: a", OUString("a"), aString);
+ aString = m_pDoc->GetString(4, 3, destSheet); // E4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E4 should contain: b", OUString("b"), aString);
+ aString = m_pDoc->GetString(5, 3, destSheet); // F4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell F4 should contain: c", OUString("c"), aString);
+ aString = m_pDoc->GetString(6, 3, destSheet); // G4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell G4 should contain: r", OUString("r"), aString);
+ ASSERT_DOUBLES_EQUAL(-13, m_pDoc->GetValue(7, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 3, destSheet));
+ aString = m_pDoc->GetString(8, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 4, rich text
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 4, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(2, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be no edit cell in C5.", pEditObj == nullptr);
+ pEditObj = m_pDoc->GetEditText(ScAddress(3, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be an edit cell in D5.", pEditObj);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Edit cell value wrong in D5 ", OUString("R1"),
+ pEditObj->GetText(0));
+ pEditObj = m_pDoc->GetEditText(ScAddress(4, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be an edit cell in E5.", pEditObj);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Edit cell value wrong E5.", OUString("R2"), pEditObj->GetText(0));
+ fValue = m_pDoc->GetValue(5, 4, destSheet); // F5
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell F5", 5, fValue);
+ aString = m_pDoc->GetString(6, 4, destSheet); // G5
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell G5 should contain: s", OUString("s"), aString);
+ ASSERT_DOUBLES_EQUAL(-14, m_pDoc->GetValue(7, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 4, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(8, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be no edit cell in I5.", pEditObj == nullptr);
+ // row 5, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ aString = m_pDoc->GetString(2, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 5, destSheet, aString); // D6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula D6", OUString("=D2+F2+60"), aString);
+ fValue = m_pDoc->GetValue(3, 5, destSheet); // D6
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula D6", 64, fValue);
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(4, 5, destSheet); // E6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ aString = m_pDoc->GetString(5, 5, destSheet); // F6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ }
+ else
+ {
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 5, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 5, destSheet));
+ }
+ aString = m_pDoc->GetString(6, 5, destSheet); // G6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell G6 should contain: t", OUString("t"), aString);
+ ASSERT_DOUBLES_EQUAL(-15, m_pDoc->GetValue(7, 5, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 5, destSheet));
+ aString = m_pDoc->GetString(8, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 6, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 6, destSheet));
+ aString = m_pDoc->GetString(2, 6, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 6, destSheet, aString); // D7
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula D7", OUString("=SUMIF(D2:G2;\"<4\")"),
+ aString);
+ fValue = m_pDoc->GetValue(3, 6, destSheet); // D7
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula D7", 6, fValue);
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(4, 6, destSheet); // E6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ aString = m_pDoc->GetString(5, 6, destSheet); // F6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ }
+ else
+ {
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 6, destSheet));
+ }
+ aString = m_pDoc->GetString(6, 6, destSheet); // G4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell G7 should contain: u", OUString("u"), aString);
+ ASSERT_DOUBLES_EQUAL(-16, m_pDoc->GetValue(7, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(8, 6, destSheet));
+ aString = m_pDoc->GetString(8, 6, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 7
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 7, destSheet));
+
+ // check patterns
+ const SfxPoolItem* pItem = nullptr;
+ m_pDoc->GetPattern(ScAddress(3, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("D2 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("D2 has blue background", COL_BLUE,
+ static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(4, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("E2 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("E2 has blue background", COL_BLUE,
+ static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(5, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("F2 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("F2 has a pattern", COL_BLUE,
+ static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(6, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("G2 has no pattern", !pItem);
+ m_pDoc->GetPattern(ScAddress(7, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("H2 has no pattern", !pItem);
+ m_pDoc->GetPattern(ScAddress(5, 5, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(bSkipEmpty, pItem == nullptr);
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+
+ // check border, left and right borders were transformed to top and bottom borders
+ pItem = m_pDoc->GetAttr(ScAddress(3, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("D3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("D3 has no top border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("D3 has no bottom border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("D3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("D3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ m_pDoc->GetPattern(ScAddress(4, 2, destSheet))->GetItemSet().HasItem(ATTR_BORDER, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("E3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("E3 has top border", static_cast<const SvxBoxItem*>(pItem)->GetTop());
+
+ pItem = m_pDoc->GetAttr(ScAddress(4, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("E3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("E3 has top border", static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("E3 has bottom border",
+ static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("E3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("E3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(5, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("F3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("F3 has top border", static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("F3 has bottom border",
+ static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("F3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("F3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(6, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("G3 has top border", !static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("G3 has bottom border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("G3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("G3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(7, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("H3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("H3 has no top border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("H3 has no bottom border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("H3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("H3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ // check notes after transposed copy/paste
+ // check presence of notes
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C1",
+ !m_pDoc->HasNote(ScAddress(2, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D1",
+ !m_pDoc->HasNote(ScAddress(3, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E1",
+ !m_pDoc->HasNote(ScAddress(4, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on F1",
+ !m_pDoc->HasNote(ScAddress(5, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G1",
+ !m_pDoc->HasNote(ScAddress(6, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H1",
+ !m_pDoc->HasNote(ScAddress(7, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C2",
+ !m_pDoc->HasNote(ScAddress(2, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on D2",
+ m_pDoc->HasNote(ScAddress(3, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E2",
+ m_pDoc->HasNote(ScAddress(4, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F2",
+ m_pDoc->HasNote(ScAddress(5, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G2",
+ !m_pDoc->HasNote(ScAddress(6, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H2",
+ !m_pDoc->HasNote(ScAddress(7, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C3",
+ !m_pDoc->HasNote(ScAddress(2, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on D3",
+ m_pDoc->HasNote(ScAddress(3, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E3",
+ !m_pDoc->HasNote(ScAddress(4, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F3",
+ m_pDoc->HasNote(ScAddress(5, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on G3",
+ !m_pDoc->HasNote(ScAddress(6, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H3",
+ !m_pDoc->HasNote(ScAddress(7, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C4",
+ !m_pDoc->HasNote(ScAddress(2, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D4",
+ !m_pDoc->HasNote(ScAddress(3, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E4",
+ m_pDoc->HasNote(ScAddress(4, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F4",
+ m_pDoc->HasNote(ScAddress(5, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on G4",
+ m_pDoc->HasNote(ScAddress(6, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H4",
+ !m_pDoc->HasNote(ScAddress(7, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C5",
+ !m_pDoc->HasNote(ScAddress(2, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on D5",
+ m_pDoc->HasNote(ScAddress(3, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E5",
+ m_pDoc->HasNote(ScAddress(4, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F5",
+ m_pDoc->HasNote(ScAddress(5, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on G5",
+ !m_pDoc->HasNote(ScAddress(6, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H5",
+ !m_pDoc->HasNote(ScAddress(7, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C6",
+ !m_pDoc->HasNote(ScAddress(2, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D6",
+ !m_pDoc->HasNote(ScAddress(3, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E6",
+ !m_pDoc->HasNote(ScAddress(4, 5, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(5, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on G6",
+ !m_pDoc->HasNote(ScAddress(6, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H6",
+ !m_pDoc->HasNote(ScAddress(7, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C7",
+ !m_pDoc->HasNote(ScAddress(2, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D7",
+ !m_pDoc->HasNote(ScAddress(3, 6, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(4, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on F7",
+ !m_pDoc->HasNote(ScAddress(5, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note a G7",
+ !m_pDoc->HasNote(ScAddress(6, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H7",
+ !m_pDoc->HasNote(ScAddress(7, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C8",
+ !m_pDoc->HasNote(ScAddress(2, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D8",
+ !m_pDoc->HasNote(ScAddress(3, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E8",
+ !m_pDoc->HasNote(ScAddress(4, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on F8",
+ !m_pDoc->HasNote(ScAddress(5, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G8",
+ !m_pDoc->HasNote(ScAddress(6, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on H8",
+ !m_pDoc->HasNote(ScAddress(7, 7, destSheet)));
+
+ // check values of notes
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on D2",
+ m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on E2",
+ m_pDoc->GetNote(ScAddress(0, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on F2",
+ m_pDoc->GetNote(ScAddress(0, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 1, destSheet))->GetText());
+ // G2 has no note
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on D3",
+ m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, destSheet))->GetText());
+ // E3 has no note
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on F3",
+ m_pDoc->GetNote(ScAddress(1, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 2, destSheet))->GetText());
+ // D4 has no note
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on E4",
+ m_pDoc->GetNote(ScAddress(2, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on F4",
+ m_pDoc->GetNote(ScAddress(2, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on D5",
+ m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 4, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on E5",
+ m_pDoc->GetNote(ScAddress(3, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 4, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on F5",
+ m_pDoc->GetNote(ScAddress(3, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 4, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 5, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on E7",
+ m_pDoc->GetNote(ScAddress(5, 1, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 6, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(2, 4, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(6, 3, destSheet))->GetText());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
+}
+
+void Test::checkCopyPasteSpecialMultiRangeRowFilteredTranspose(bool bSkipEmpty)
+{
+ const SCTAB srcSheet = 0;
+ const SCTAB destSheet = 1;
+
+ /*
+ | D | E | F | G |
+
+ 2 | 1 B*| 3 B*| 6 | -11 |
+ 3 | =D2+10 *| =F5+30 b*| q | -12 |
+ 4 | a | c *| r | -13 |
+ 5 | R1 *| 5 *| s | -14 |
+ 6 | =D2+F2+60 | B*| t | -15 |
+ 7 | =SUMIF(D2:G2;"<4") | | u | -16 |
+
+ * means note attached
+ B means background
+ b means border
+ */
+
+ //check cell content after transposed copy/paste of filtered data
+ // Note: column F is a repetition of srcSheet.Column A
+ // Col C and G are checked to be empty
+ OUString aString;
+ double fValue;
+ const EditTextObject* pEditObj;
+ // row 0
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 0, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 0, destSheet));
+ // row 1, numbers
+ fValue = m_pDoc->GetValue(2, 1, destSheet); // C2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell C2", 1000, fValue);
+ fValue = m_pDoc->GetValue(3, 1, destSheet); // D2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell D2", 1, fValue);
+ fValue = m_pDoc->GetValue(4, 1, destSheet); // E2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell E2", 3, fValue);
+ fValue = m_pDoc->GetValue(5, 1, destSheet); // F2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell F2", 6, fValue);
+ ASSERT_DOUBLES_EQUAL(-11, m_pDoc->GetValue(6, 1, destSheet));
+ fValue = m_pDoc->GetValue(7, 1, destSheet); // H2
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell H2", 1000, fValue);
+ // row 2, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 2, destSheet));
+ aString = m_pDoc->GetString(2, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ fValue = m_pDoc->GetValue(3, 2, destSheet); // D3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula D3", 11, fValue);
+ m_pDoc->GetFormula(3, 2, destSheet, aString); // D3
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula D3 should point on D2", OUString("=D2+10"),
+ aString);
+ fValue = m_pDoc->GetValue(4, 2, destSheet); // E3
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula E3", 35, fValue);
+ m_pDoc->GetFormula(4, 2, destSheet, aString); // E3
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula E3 should point on F2", OUString("=E5+30"),
+ aString);
+ aString = m_pDoc->GetString(5, 2, destSheet); // F3
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell F4 should contain: q", OUString("q"), aString);
+ ASSERT_DOUBLES_EQUAL(-12, m_pDoc->GetValue(6, 2, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 2, destSheet));
+ aString = m_pDoc->GetString(7, 2, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 3, strings
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 3, destSheet));
+ aString = m_pDoc->GetString(2, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ aString = m_pDoc->GetString(3, 3, destSheet); // D4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell D4 should contain: a", OUString("a"), aString);
+ aString = m_pDoc->GetString(4, 3, destSheet); // E4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E4 should contain: c", OUString("c"), aString);
+ aString = m_pDoc->GetString(5, 3, destSheet); // F4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell F4 should contain: r", OUString("r"), aString);
+ ASSERT_DOUBLES_EQUAL(-13, m_pDoc->GetValue(6, 3, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 3, destSheet));
+ aString = m_pDoc->GetString(7, 3, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 4, rich text
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 4, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(2, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be no edit cell in C5.", pEditObj == nullptr);
+ pEditObj = m_pDoc->GetEditText(ScAddress(3, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be an edit cell in D5.", pEditObj);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Edit cell value wrong in D5 ", OUString("R1"),
+ pEditObj->GetText(0));
+ fValue = m_pDoc->GetValue(4, 4, destSheet); // E5
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied cell E5", 5, fValue);
+ aString = m_pDoc->GetString(5, 4, destSheet); // F5
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell F5 should contain: s", OUString("s"), aString);
+ ASSERT_DOUBLES_EQUAL(-14, m_pDoc->GetValue(6, 4, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 4, destSheet));
+ pEditObj = m_pDoc->GetEditText(ScAddress(7, 4, destSheet));
+ CPPUNIT_ASSERT_MESSAGE("There should be no edit cell in H5.", pEditObj == nullptr);
+ // row 5, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 5, destSheet));
+ aString = m_pDoc->GetString(2, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 5, destSheet, aString); // D6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula D6", OUString("=D2+F2+60"), aString);
+ fValue = m_pDoc->GetValue(3, 5, destSheet); // D6
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula D6", 67, fValue);
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(4, 5, destSheet); // E6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ }
+ else
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 5, destSheet));
+ aString = m_pDoc->GetString(5, 5, destSheet); // F6
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell F6 should contain: t", OUString("t"), aString);
+ ASSERT_DOUBLES_EQUAL(-15, m_pDoc->GetValue(6, 5, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 5, destSheet));
+ aString = m_pDoc->GetString(7, 5, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 6, formulas
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 6, destSheet));
+ aString = m_pDoc->GetString(2, 6, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ m_pDoc->GetFormula(3, 6, destSheet, aString); // D7
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("transposed formula D7", OUString("=SUMIF(D2:G2;\"<4\")"),
+ aString);
+ fValue = m_pDoc->GetValue(3, 6, destSheet); // D7
+ ASSERT_DOUBLES_EQUAL_MESSAGE("transposed copied formula D7", -7, fValue);
+ if (!bSkipEmpty)
+ {
+ aString = m_pDoc->GetString(4, 6, destSheet); // E7
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell E6", EMPTY_OUSTRING, aString);
+ }
+ else
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 6, destSheet));
+ aString = m_pDoc->GetString(5, 6, destSheet); // F4
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell F7 should contain: u", OUString("u"), aString);
+ ASSERT_DOUBLES_EQUAL(-16, m_pDoc->GetValue(6, 6, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 6, destSheet));
+ aString = m_pDoc->GetString(7, 6, destSheet);
+ CPPUNIT_ASSERT_EQUAL(OUString("1000"), aString);
+ // row 7
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(2, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(3, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(4, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(5, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(6, 7, destSheet));
+ ASSERT_DOUBLES_EQUAL(1000, m_pDoc->GetValue(7, 7, destSheet));
+
+ // check patterns
+ const SfxPoolItem* pItem = nullptr;
+ m_pDoc->GetPattern(ScAddress(3, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("D2 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("D2 has blue background", COL_BLUE,
+ static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(4, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("E2 has a pattern", pItem);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("E2 has a pattern", COL_BLUE,
+ static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(5, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("F2 has no pattern", !pItem);
+ m_pDoc->GetPattern(ScAddress(6, 1, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("G2 has no pattern", !pItem);
+ m_pDoc->GetPattern(ScAddress(4, 5, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT_EQUAL(bSkipEmpty, pItem == nullptr);
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+
+ m_pDoc->GetPattern(ScAddress(5, 2, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(5, 3, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_RED, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(5, 4, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(COL_RED, static_cast<const SvxBrushItem*>(pItem)->GetColor());
+ m_pDoc->GetPattern(ScAddress(5, 5, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+ m_pDoc->GetPattern(ScAddress(5, 6, destSheet))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
+ CPPUNIT_ASSERT(!pItem);
+
+ // check border, left and right borders were transformed to top and bottom borders
+ pItem = m_pDoc->GetAttr(ScAddress(3, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("D3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("D3 has no top border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("D3 has no bottom border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("D3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("D3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ m_pDoc->GetPattern(ScAddress(4, 2, destSheet))->GetItemSet().HasItem(ATTR_BORDER, &pItem);
+ CPPUNIT_ASSERT_MESSAGE("E3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("E3 has top border", static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ pItem = m_pDoc->GetAttr(ScAddress(4, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("E3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("E3 has top border", static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("E3 has bottom border",
+ static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("E3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("E3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(5, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("F3 has top border", !static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("F3 has bottom border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("F3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("F3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(6, 2, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT_MESSAGE("G3 has a border", pItem);
+ CPPUNIT_ASSERT_MESSAGE("G3 has no top border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT_MESSAGE("G3 has no bottom border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT_MESSAGE("G3 has no left border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT_MESSAGE("G3 has no right border",
+ !static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(5, 3, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+ pItem = m_pDoc->GetAttr(ScAddress(5, 4, destSheet), ATTR_BORDER);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetTop());
+ CPPUNIT_ASSERT(!static_cast<const SvxBoxItem*>(pItem)->GetBottom());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetLeft());
+ CPPUNIT_ASSERT(static_cast<const SvxBoxItem*>(pItem)->GetRight());
+
+ // check notes after transposed copy/paste
+ // check presence of notes
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C1",
+ !m_pDoc->HasNote(ScAddress(2, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D1",
+ !m_pDoc->HasNote(ScAddress(3, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E1",
+ !m_pDoc->HasNote(ScAddress(4, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on F1",
+ !m_pDoc->HasNote(ScAddress(5, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G1",
+ !m_pDoc->HasNote(ScAddress(6, 0, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C2",
+ !m_pDoc->HasNote(ScAddress(2, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on D2",
+ m_pDoc->HasNote(ScAddress(3, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E2",
+ m_pDoc->HasNote(ScAddress(4, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on F2",
+ !m_pDoc->HasNote(ScAddress(5, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G2",
+ !m_pDoc->HasNote(ScAddress(6, 1, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C3",
+ !m_pDoc->HasNote(ScAddress(2, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on D3",
+ m_pDoc->HasNote(ScAddress(3, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E3",
+ m_pDoc->HasNote(ScAddress(4, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F3",
+ !m_pDoc->HasNote(ScAddress(5, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G3",
+ !m_pDoc->HasNote(ScAddress(6, 2, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C4",
+ !m_pDoc->HasNote(ScAddress(2, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D4",
+ !m_pDoc->HasNote(ScAddress(3, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E4",
+ m_pDoc->HasNote(ScAddress(4, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F4",
+ m_pDoc->HasNote(ScAddress(5, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G4",
+ !m_pDoc->HasNote(ScAddress(6, 3, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C5",
+ !m_pDoc->HasNote(ScAddress(2, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on D5",
+ m_pDoc->HasNote(ScAddress(3, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on E5",
+ m_pDoc->HasNote(ScAddress(4, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F5",
+ !m_pDoc->HasNote(ScAddress(5, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G5",
+ !m_pDoc->HasNote(ScAddress(6, 4, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C6",
+ !m_pDoc->HasNote(ScAddress(2, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D6",
+ !m_pDoc->HasNote(ScAddress(3, 5, destSheet)));
+ CPPUNIT_ASSERT_EQUAL(!bSkipEmpty, m_pDoc->HasNote(ScAddress(4, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be a note on F6",
+ !m_pDoc->HasNote(ScAddress(5, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G6",
+ !m_pDoc->HasNote(ScAddress(6, 5, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C7",
+ !m_pDoc->HasNote(ScAddress(2, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D7",
+ !m_pDoc->HasNote(ScAddress(3, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E7",
+ !m_pDoc->HasNote(ScAddress(4, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note a F7",
+ !m_pDoc->HasNote(ScAddress(5, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G7",
+ !m_pDoc->HasNote(ScAddress(6, 6, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on C8",
+ !m_pDoc->HasNote(ScAddress(2, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on D8",
+ !m_pDoc->HasNote(ScAddress(3, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on E8",
+ !m_pDoc->HasNote(ScAddress(4, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on F8",
+ !m_pDoc->HasNote(ScAddress(5, 7, destSheet)));
+ CPPUNIT_ASSERT_MESSAGE("There should be no note on G8",
+ !m_pDoc->HasNote(ScAddress(6, 7, destSheet)));
+
+ // check values of notes
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on D2",
+ m_pDoc->GetNote(ScAddress(0, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on E2",
+ m_pDoc->GetNote(ScAddress(0, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 1, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on D3",
+ m_pDoc->GetNote(ScAddress(1, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on E3",
+ m_pDoc->GetNote(ScAddress(1, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 2, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong content of cell note on E4",
+ m_pDoc->GetNote(ScAddress(2, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 3, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on D5",
+ m_pDoc->GetNote(ScAddress(3, 0, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(3, 4, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Content of cell note on E5",
+ m_pDoc->GetNote(ScAddress(3, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 4, destSheet))->GetText());
+ if (!bSkipEmpty)
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(4, 2, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(4, 5, destSheet))->GetText());
+ CPPUNIT_ASSERT_EQUAL(m_pDoc->GetNote(ScAddress(2, 4, srcSheet))->GetText(),
+ m_pDoc->GetNote(ScAddress(5, 3, destSheet))->GetText());
+
+ m_pDoc->DeleteTab(destSheet);
+ m_pDoc->DeleteTab(srcSheet);
}
void Test::testCopyPasteMultiRange()
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index a5488bb4fe25..fe9d6f09c1cd 100644..100755
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -14,6 +14,7 @@
#include <document.hxx>
#include <stringutil.hxx>
#include <memory>
+#include <clipparam.hxx>
struct TestImpl;
class ScUndoPaste;
@@ -385,6 +386,58 @@ public:
void testCopyPaste();
void testCopyPasteAsLink();
void testCopyPasteTranspose();
+ void testCopyPasteSpecialAsLinkTranspose();
+ void testCopyPasteSpecialAsLinkFilteredTranspose();
+ void testCopyPasteSpecialMultiRangeColAsLinkTranspose();
+ void testCopyPasteSpecialMultiRangeColAsLinkFilteredTranspose();
+ void testCopyPasteSpecialMultiRangeRowAsLinkTranspose();
+ void testCopyPasteSpecialMultiRangeRowAsLinkFilteredTranspose();
+ void testCopyPasteSpecialAllAsLinkTranspose();
+ void testCopyPasteSpecialAllAsLinkFilteredTranspose();
+ void testCopyPasteSpecial();
+ void testCopyPasteSpecialFiltered();
+ void testCopyPasteSpecialIncludeFiltered();
+ void testCopyPasteSpecialFilteredIncludeFiltered();
+ void testCopyPasteSpecialTranspose();
+ void testCopyPasteSpecialTransposeIncludeFiltered();
+ void testCopyPasteSpecialFilteredTranspose();
+ void testCopyPasteSpecialMergedCellsTranspose();
+ void testCopyPasteSpecialMergedCellsFilteredTranspose();
+ void testCopyPasteSpecialMultiRangeCol();
+ void testCopyPasteSpecialMultiRangeColFiltered();
+ void testCopyPasteSpecialMultiRangeColIncludeFiltered();
+ void testCopyPasteSpecialMultiRangeColFilteredIncludeFiltered();
+ void testCopyPasteSpecialMultiRangeColTranspose();
+ void testCopyPasteSpecialMultiRangeColFilteredTranspose();
+ void testCopyPasteSpecialMultiRangeColFilteredIncludeFilteredTranspose();
+ void testCopyPasteSpecialMultiRangeRow();
+ void testCopyPasteSpecialMultiRangeRowFiltered();
+ void testCopyPasteSpecialMultiRangeRowIncludeFiltered();
+ void testCopyPasteSpecialMultiRangeRowFilteredIncludeFiltered();
+ void testCopyPasteSpecialMultiRangeRowTranspose();
+ void testCopyPasteSpecialMultiRangeRowFilteredTranspose();
+ void testCopyPasteSpecialMultiRangeRowFilteredIncludeFilteredTranspose();
+ void testCopyPasteSpecialSkipEmpty();
+ void testCopyPasteSpecialSkipEmptyFiltered();
+ void testCopyPasteSpecialSkipEmptyIncludeFiltered();
+ void testCopyPasteSpecialSkipEmptyFilteredIncludeFiltered();
+ void testCopyPasteSpecialSkipEmptyTranspose();
+ void testCopyPasteSpecialSkipEmptyTransposeIncludeFiltered();
+ void testCopyPasteSpecialSkipEmptyFilteredTranspose();
+ void testCopyPasteSpecialSkipEmptyMultiRangeCol();
+ void testCopyPasteSpecialSkipEmptyMultiRangeColFiltered();
+ void testCopyPasteSpecialSkipEmptyMultiRangeColIncludeFiltered();
+ void testCopyPasteSpecialSkipEmptyMultiRangeColFilteredIncludeFiltered();
+ void testCopyPasteSpecialSkipEmptyMultiRangeColTranspose();
+ void testCopyPasteSpecialSkipEmptyMultiRangeColFilteredTranspose();
+ void testCopyPasteSpecialSkipEmptyMultiRangeColFilteredIncludeFilteredTranspose();
+ void testCopyPasteSpecialSkipEmptyMultiRangeRow();
+ void testCopyPasteSpecialSkipEmptyMultiRangeRowFiltered();
+ void testCopyPasteSpecialSkipEmptyMultiRangeRowIncludeFiltered();
+ void testCopyPasteSpecialSkipEmptyMultiRangeRowFilteredIncludeFiltered();
+ void testCopyPasteSpecialSkipEmptyMultiRangeRowTranspose();
+ void testCopyPasteSpecialSkipEmptyMultiRangeRowFilteredTranspose();
+ void testCopyPasteSpecialSkipEmptyMultiRangeRowFilteredIncludeFilteredTranspose();
void testCopyPasteMultiRange();
void testCopyPasteSkipEmpty();
void testCopyPasteSkipEmpty2();
@@ -753,6 +806,58 @@ public:
CPPUNIT_TEST(testCopyPaste);
CPPUNIT_TEST(testCopyPasteAsLink);
CPPUNIT_TEST(testCopyPasteTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialAsLinkTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialAllAsLinkTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeColAsLinkTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeColAsLinkFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeRowAsLinkTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeRowAsLinkFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialAsLinkFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialAllAsLinkFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialMergedCellsTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialMergedCellsFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecial);
+ CPPUNIT_TEST(testCopyPasteSpecialFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialFilteredIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialTransposeIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeCol);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeColFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeColIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeColFilteredIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeColTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeColFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeColFilteredIncludeFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeRow);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeRowFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeRowIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeRowFilteredIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeRowTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeRowFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialMultiRangeRowFilteredIncludeFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmpty);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyFilteredIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyTransposeIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeCol);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeColFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeColIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeColFilteredIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeColTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeColFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeColFilteredIncludeFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeRow);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeRowFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeRowIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeRowFilteredIncludeFiltered);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeRowTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeRowFilteredTranspose);
+ CPPUNIT_TEST(testCopyPasteSpecialSkipEmptyMultiRangeRowFilteredIncludeFilteredTranspose);
CPPUNIT_TEST(testCopyPasteMultiRange);
CPPUNIT_TEST(testCopyPasteSkipEmpty);
CPPUNIT_TEST(testCopyPasteSkipEmpty2);
@@ -895,6 +1000,23 @@ public:
private:
std::unique_ptr<TestImpl> m_pImpl;
ScDocument* m_pDoc;
+
+ void executeCopyPasteSpecial(bool bApplyFilter, bool bIncludedFiltered, bool bAsLink,
+ bool bTranspose, bool bMultiRangeSelection, bool bSkipEmpty,
+ ScClipParam::Direction eDirection, bool bCalcAll,
+ InsertDeleteFlags aFlags);
+ void checkCopyPasteSpecial(bool bSkipEmpty);
+ void checkCopyPasteSpecialFiltered(bool bSkipEmpty);
+ void checkCopyPasteSpecialTranspose(bool bSkipEmpty);
+ void checkCopyPasteSpecialFilteredTranspose(bool bSkipEmpty);
+ void checkCopyPasteSpecialMultiRangeCol(bool bSkipEmpty);
+ void checkCopyPasteSpecialMultiRangeColFiltered(bool bSkipEmpty);
+ void checkCopyPasteSpecialMultiRangeColTranspose(bool bSkipEmpty);
+ void checkCopyPasteSpecialMultiRangeColFilteredTranspose(bool bSkipEmpty);
+ void checkCopyPasteSpecialMultiRangeRow(bool bSkipEmpty);
+ void checkCopyPasteSpecialMultiRangeRowFiltered(bool bSkipEmpty);
+ void checkCopyPasteSpecialMultiRangeRowTranspose(bool bSkipEmpty);
+ void checkCopyPasteSpecialMultiRangeRowFilteredTranspose(bool bSkipEmpty);
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/uicalc/uicalc.cxx b/sc/qa/unit/uicalc/uicalc.cxx
index e42465402749..9ada6b120354 100644..100755
--- a/sc/qa/unit/uicalc/uicalc.cxx
+++ b/sc/qa/unit/uicalc/uicalc.cxx
@@ -464,6 +464,51 @@ CPPUNIT_TEST_FIXTURE(ScUiCalcTest, testTdf117706)
CPPUNIT_ASSERT_EQUAL(OUString(""), pDoc->GetString(ScAddress(0, 2, 0)));
}
+// Inspired from testTdf117706, test columns instad of rows
+CPPUNIT_TEST_FIXTURE(ScUiCalcTest, testMultiRangeCol)
+{
+ mxComponent = loadFromDesktop("private:factory/scalc");
+ ScModelObj* pModelObj = dynamic_cast<ScModelObj*>(mxComponent.get());
+ CPPUNIT_ASSERT(pModelObj);
+ ScDocument* pDoc = pModelObj->GetDocument();
+ CPPUNIT_ASSERT(pDoc);
+
+ insertStringToCell(*pModelObj, "A1", "A1");
+ insertStringToCell(*pModelObj, "C1", "C1");
+
+ // Use Adding Selection
+ dispatchCommand(mxComponent, ".uno:StatusSelectionModeExp", {});
+ Scheduler::ProcessEventsToIdle();
+
+ goToCell("A1");
+ dispatchCommand(mxComponent, ".uno:SelectColumn", {});
+ Scheduler::ProcessEventsToIdle();
+
+ dispatchCommand(mxComponent, ".uno:GoRight", {});
+ dispatchCommand(mxComponent, ".uno:GoRight", {});
+ lcl_AssertCurrentCursorPosition(2, 0);
+
+ dispatchCommand(mxComponent, ".uno:SelectColumn", {});
+ Scheduler::ProcessEventsToIdle();
+
+ dispatchCommand(mxComponent, ".uno:Copy", {});
+
+ mxComponent->dispose();
+
+ // Open a new document
+ mxComponent = loadFromDesktop("private:factory/scalc");
+ pModelObj = dynamic_cast<ScModelObj*>(mxComponent.get());
+ CPPUNIT_ASSERT(pModelObj);
+ pDoc = pModelObj->GetDocument();
+ CPPUNIT_ASSERT(pDoc);
+
+ dispatchCommand(mxComponent, ".uno:Paste", {});
+
+ CPPUNIT_ASSERT_EQUAL(OUString("A1"), pDoc->GetString(ScAddress(0, 0, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("C1"), pDoc->GetString(ScAddress(1, 0, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), pDoc->GetString(ScAddress(2, 0, 0)));
+}
+
CPPUNIT_TEST_FIXTURE(ScUiCalcTest, testTdf131442)
{
mxComponent = loadFromDesktop("private:factory/scalc");
diff --git a/sc/source/core/data/clipparam.cxx b/sc/source/core/data/clipparam.cxx
index b33c4998c10b..48840605364c 100644..100755
--- a/sc/source/core/data/clipparam.cxx
+++ b/sc/source/core/data/clipparam.cxx
@@ -70,7 +70,7 @@ SCCOL ScClipParam::getPasteColSize()
return 0;
}
-SCROW ScClipParam::getPasteRowSize()
+SCROW ScClipParam::getPasteRowSize(const ScDocument& rSrcDoc, bool bIncludeFiltered)
{
if (maRanges.empty())
return 0;
@@ -81,7 +81,10 @@ SCROW ScClipParam::getPasteRowSize()
{
// We assume that all ranges have identical row size.
const ScRange& rRange = maRanges.front();
- return rRange.aEnd.Row() - rRange.aStart.Row() + 1;
+ return bIncludeFiltered
+ ? rRange.aEnd.Row() - rRange.aStart.Row() + 1
+ : rSrcDoc.CountNonFilteredRows(rRange.aStart.Row(), rRange.aEnd.Row(),
+ rRange.aStart.Tab());
}
case ScClipParam::Row:
{
@@ -89,7 +92,10 @@ SCROW ScClipParam::getPasteRowSize()
for ( size_t i = 0, nListSize = maRanges.size(); i < nListSize; ++i )
{
const ScRange& rRange = maRanges[ i ];
- nRowSize += rRange.aEnd.Row() - rRange.aStart.Row() + 1;
+ nRowSize += bIncludeFiltered ? rRange.aEnd.Row() - rRange.aStart.Row() + 1
+ : rSrcDoc.CountNonFilteredRows(rRange.aStart.Row(),
+ rRange.aEnd.Row(),
+ rRange.aStart.Tab());
}
return nRowSize;
}
@@ -105,7 +111,8 @@ ScRange ScClipParam::getWholeRange() const
return maRanges.Combine();
}
-void ScClipParam::transpose()
+void ScClipParam::transpose(const ScDocument& rSrcDoc, bool bIncludeFiltered,
+ bool bIsMultiRangeRowFilteredTranspose)
{
switch (meDirection)
{
@@ -126,21 +133,48 @@ void ScClipParam::transpose()
const ScRange & rRange1 = maRanges.front();
SCCOL nColOrigin = rRange1.aStart.Col();
SCROW nRowOrigin = rRange1.aStart.Row();
-
+ SCROW nRowCount = 0;
for ( size_t i = 0, n = maRanges.size(); i < n; ++i )
{
const ScRange & rRange = maRanges[ i ];
SCCOL nColDelta = rRange.aStart.Col() - nColOrigin;
SCROW nRowDelta = rRange.aStart.Row() - nRowOrigin;
+ SCROW nNonFilteredRows = rSrcDoc.CountNonFilteredRows(
+ rRange.aStart.Row(), rRange.aEnd.Row(), rRange.aStart.Tab());
+ if (!bIsMultiRangeRowFilteredTranspose)
+ {
+ SCCOL nCol1 = 0;
+ SCCOL nCol2 = bIncludeFiltered
+ ? static_cast<SCCOL>(rRange.aEnd.Row() - rRange.aStart.Row())
+ : nNonFilteredRows - 1;
+ SCROW nRow1 = 0;
+ SCROW nRow2 = static_cast<SCROW>(rRange.aEnd.Col() - rRange.aStart.Col());
+ nCol1 += static_cast<SCCOL>(nRowDelta);
+ nCol2 += static_cast<SCCOL>(nRowDelta);
+ nRow1 += static_cast<SCROW>(nColDelta);
+ nRow2 += static_cast<SCROW>(nColDelta);
+ aNewRanges.push_back( ScRange(nCol1, nRow1, rRange.aStart.Tab(), nCol2, nRow2, rRange.aStart.Tab() ) );
+ }
+ else
+ nRowCount += nNonFilteredRows;
+ }
+
+ // Transpose of filtered multi range row selection is a special case since filtering
+ // and selection are in the same dimension (i.e. row), see ScDocument::TransposeClip()
+ if (bIsMultiRangeRowFilteredTranspose)
+ {
+ SCCOL nColDelta = rRange1.aStart.Col() - nColOrigin;
+ SCROW nRowDelta = rRange1.aStart.Row() - nRowOrigin;
SCCOL nCol1 = 0;
- SCCOL nCol2 = static_cast<SCCOL>(rRange.aEnd.Row() - rRange.aStart.Row());
+ SCCOL nCol2 = nRowCount - 1;
SCROW nRow1 = 0;
- SCROW nRow2 = static_cast<SCROW>(rRange.aEnd.Col() - rRange.aStart.Col());
+ SCROW nRow2 = static_cast<SCROW>(rRange1.aEnd.Col() - rRange1.aStart.Col());
nCol1 += static_cast<SCCOL>(nRowDelta);
nCol2 += static_cast<SCCOL>(nRowDelta);
nRow1 += static_cast<SCROW>(nColDelta);
nRow2 += static_cast<SCROW>(nColDelta);
- aNewRanges.push_back( ScRange(nCol1, nRow1, rRange.aStart.Tab(), nCol2, nRow2, rRange.aStart.Tab() ) );
+ aNewRanges.push_back(
+ ScRange(nCol1, nRow1, rRange1.aStart.Tab(), nCol2, nRow2, rRange1.aStart.Tab()));
}
}
maRanges = aNewRanges;
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index ad18c2f077bf..05036e0ee148 100644..100755
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -2317,17 +2317,18 @@ void ScDocument::CopyTabToClip(SCCOL nCol1, SCROW nRow1,
pClipDoc->GetClipParam().mbCutMode = false;
}
-void ScDocument::TransposeClip( ScDocument* pTransClip, InsertDeleteFlags nFlags, bool bAsLink )
+void ScDocument::TransposeClip(ScDocument* pTransClip, InsertDeleteFlags nFlags, bool bAsLink,
+ bool bIncludeFiltered)
{
OSL_ENSURE( bIsClip && pTransClip && pTransClip->bIsClip,
"TransposeClip with wrong Document" );
- // initialize
- // -> pTransClip has to be deleted before the original document!
+ // initialize
+ // -> pTransClip has to be deleted before the original document!
pTransClip->ResetClip(this, nullptr); // all
- // Take over range
+ // Take over range
if (pRangeName)
{
@@ -2341,18 +2342,62 @@ void ScDocument::TransposeClip( ScDocument* pTransClip, InsertDeleteFlags nFlags
}
}
- // The data
+ ScRange aCombinedClipRange = GetClipParam().getWholeRange();
- ScRange aClipRange = GetClipParam().getWholeRange();
- if ( ValidRow(aClipRange.aEnd.Row()-aClipRange.aStart.Row()) )
+ if (!ValidRow(aCombinedClipRange.aEnd.Row() - aCombinedClipRange.aStart.Row()))
{
- for (SCTAB i=0; i< static_cast<SCTAB>(maTabs.size()); i++)
+ SAL_WARN("sc", "TransposeClip: Too big");
+ return;
+ }
+
+ // Transpose of filtered multi range row selection is a special case since filtering
+ // and selection are in the same dimension (i.e. row).
+ // The filtered row status and the selection ranges are not available at the same time,
+ // handle this case specially, do not use GetClipParam().getWholeRange(),
+ // instead loop through the ranges, calculate the row offest and handle filtered rows and
+ // create in ScClipParam::transpose() an unified range.
+ bool bIsMultiRangeRowFilteredTranspose
+ = !bIncludeFiltered && GetClipParam().isMultiRange()
+ && HasFilteredRows(aCombinedClipRange.aStart.Row(), aCombinedClipRange.aEnd.Row(),
+ aCombinedClipRange.aStart.Tab())
+ && GetClipParam().meDirection == ScClipParam::Row;
+
+ ScRangeList aClipRanges;
+ if (bIsMultiRangeRowFilteredTranspose)
+ aClipRanges = GetClipParam().maRanges;
+ else
+ aClipRanges = ScRangeList(aCombinedClipRange);
+
+ // The data
+ ScRange aClipRange;
+ SCROW nRowCount = 0; // next consecutive row
+ for (size_t j = 0, n = aClipRanges.size(); j < n; ++j)
+ {
+ aClipRange = aClipRanges[j];
+
+ SCROW nRowOffset = 0;
+ if (bIsMultiRangeRowFilteredTranspose)
+ {
+ // adjust for the rows that are filtered
+ nRowOffset = nRowCount;
+
+ // calculate filtered rows of current clip range
+ SCROW nRowCountAll = aClipRange.aEnd.Row() - aClipRange.aStart.Row() + 1;
+ SCROW nRowCountNonFiltered = CountNonFilteredRows(
+ aClipRange.aStart.Row(), aClipRange.aEnd.Row(), aClipRange.aStart.Tab());
+ SCROW nRowCountInRange = bIncludeFiltered ? nRowCountAll : nRowCountNonFiltered;
+ nRowCount += nRowCountInRange; // for next iteration
+ }
+
+ for (SCTAB i = 0; i < static_cast<SCTAB>(maTabs.size()); i++)
+ {
if (maTabs[i])
{
- OSL_ENSURE( pTransClip->maTabs[i], "TransposeClip: Table not there" );
- maTabs[i]->TransposeClip( aClipRange.aStart.Col(), aClipRange.aStart.Row(),
- aClipRange.aEnd.Col(), aClipRange.aEnd.Row(),
- pTransClip->maTabs[i].get(), nFlags, bAsLink );
+ OSL_ENSURE(pTransClip->maTabs[i], "TransposeClip: Table not there");
+ maTabs[i]->TransposeClip(aClipRange.aStart.Col(), aClipRange.aStart.Row(),
+ aClipRange.aEnd.Col(), aClipRange.aEnd.Row(), nRowOffset,
+ pTransClip->maTabs[i].get(), nFlags, bAsLink,
+ bIncludeFiltered);
if ( mpDrawLayer && ( nFlags & InsertDeleteFlags::OBJECTS ) )
{
@@ -2371,15 +2416,13 @@ void ScDocument::TransposeClip( ScDocument* pTransClip, InsertDeleteFlags nFlags
pTransClip->mpDrawLayer->CopyFromClip( mpDrawLayer.get(), i, aSourceRect, ScAddress(0,0,i), aDestRect );
}
}
-
- pTransClip->SetClipParam(GetClipParam());
- pTransClip->GetClipParam().transpose();
- }
- else
- {
- SAL_WARN("sc", "TransposeClip: Too big");
+ }
}
+ pTransClip->SetClipParam(GetClipParam());
+ pTransClip->GetClipParam().transpose(*this, bIncludeFiltered,
+ bIsMultiRangeRowFilteredTranspose);
+
// This happens only when inserting...
GetClipParam().mbCutMode = false;
@@ -2711,9 +2754,9 @@ void ScDocument::CopyBlockFromClip(
}
}
-void ScDocument::CopyNonFilteredFromClip(
- sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
- const ScMarkData& rMark, SCCOL nDx, SCROW & rClipStartRow )
+SCROW ScDocument::CopyNonFilteredFromClip(sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1,
+ SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
+ SCCOL nDx, SCROW& rClipStartRow, SCROW nClipEndRow)
{
// call CopyBlockFromClip for ranges of consecutive non-filtered rows
// nCol1/nRow1 etc. is in target doc
@@ -2725,15 +2768,16 @@ void ScDocument::CopyNonFilteredFromClip(
++nFlagTab;
SCROW nSourceRow = rClipStartRow;
- SCROW nSourceEnd = 0;
- if (!rCxt.getClipDoc()->GetClipParam().maRanges.empty())
- nSourceEnd = rCxt.getClipDoc()->GetClipParam().maRanges.front().aEnd.Row();
+ SCROW nSourceEnd = nClipEndRow;
SCROW nDestRow = nRow1;
+ SCROW nFilteredRows = 0;
while ( nSourceRow <= nSourceEnd && nDestRow <= nRow2 )
{
// skip filtered rows
+ SCROW nSourceRowOriginal = nSourceRow;
nSourceRow = rCxt.getClipDoc()->FirstNonFilteredRow(nSourceRow, nSourceEnd, nFlagTab);
+ nFilteredRows += nSourceRow - nSourceRowOriginal;
if ( nSourceRow <= nSourceEnd )
{
@@ -2756,6 +2800,7 @@ void ScDocument::CopyNonFilteredFromClip(
}
}
rClipStartRow = nSourceRow;
+ return nFilteredRows;
}
namespace {
@@ -2936,8 +2981,8 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
}
else
{
- CopyNonFilteredFromClip(
- aCxt, nC1, nR1, nC2, nR2, rMark, nDx, nClipStartRow);
+ CopyNonFilteredFromClip(aCxt, nC1, nR1, nC2, nR2, rMark, nDx, nClipStartRow,
+ nClipEndRow);
}
nC1 = nC2 + 1;
nC2 = std::min(static_cast<SCCOL>(nC1 + nXw), nCol2);
@@ -3004,9 +3049,10 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
pClipDoc->GetClipParam().mbCutMode = false;
}
-void ScDocument::CopyMultiRangeFromClip(
- const ScAddress& rDestPos, const ScMarkData& rMark, InsertDeleteFlags nInsFlag, ScDocument* pClipDoc,
- bool bResetCut, bool bAsLink, bool /*bIncludeFiltered*/, bool bSkipAttrForEmpty)
+void ScDocument::CopyMultiRangeFromClip(const ScAddress& rDestPos, const ScMarkData& rMark,
+ InsertDeleteFlags nInsFlag, ScDocument* pClipDoc,
+ bool bResetCut, bool bAsLink, bool bIncludeFiltered,
+ bool bSkipAttrForEmpty)
{
if (bIsClip)
return;
@@ -3035,7 +3081,7 @@ void ScDocument::CopyMultiRangeFromClip(
{
// Do the deletion first.
SCCOL nColSize = rClipParam.getPasteColSize();
- SCROW nRowSize = rClipParam.getPasteRowSize();
+ SCROW nRowSize = rClipParam.getPasteRowSize(*pClipDoc, bIncludeFiltered);
DeleteArea(nCol1, nRow1, nCol1+nColSize-1, nRow1+nRowSize-1, rMark, InsertDeleteFlags::CONTENTS, false, &aBroadcastSpans);
}
@@ -3053,15 +3099,27 @@ void ScDocument::CopyMultiRangeFromClip(
SCROW nDy = static_cast<SCROW>(nRow1 - rRange.aStart.Row());
SCCOL nCol2 = nCol1 + rRange.aEnd.Col() - rRange.aStart.Col();
SCROW nEndRow = nRow1 + nRowCount - 1;
+ SCROW nFilteredRows = 0;
- CopyBlockFromClip(aCxt, nCol1, nRow1, nCol2, nEndRow, rMark, nDx, nDy);
+ if (bIncludeFiltered)
+ {
+ CopyBlockFromClip(aCxt, nCol1, nRow1, nCol2, nEndRow, rMark, nDx, nDy);
+ }
+ else
+ {
+ SCROW nClipStartRow = rRange.aStart.Row();
+ SCROW nClipEndRow = rRange.aEnd.Row();
+ nFilteredRows += CopyNonFilteredFromClip(aCxt, nCol1, nRow1, nCol2, nEndRow, rMark, nDx,
+ nClipStartRow, nClipEndRow);
+ nRowCount -= nFilteredRows;
+ }
switch (rClipParam.meDirection)
{
case ScClipParam::Row:
// Begin row for the next range being pasted.
nRow1 += nRowCount;
- break;
+ break;
case ScClipParam::Column:
nCol1 += rRange.aEnd.Col() - rRange.aStart.Col() + 1;
break;
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 93e9067b9016..2e4d81c362d7 100644..100755
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -73,7 +73,6 @@
#include <memory>
#include <map>
-#include <vector>
using namespace formula;
@@ -3754,6 +3753,15 @@ void ScFormulaCell::UpdateCompile( bool bForceIfNameInUse )
CompileTokenArray();
}
+static void lcl_TransposeReference(ScSingleRefData& rRef)
+{
+ // References to or over filtered rows are not adjusted
+ // analog to the normal (non-transposed) case
+ SCCOLROW nTemp = rRef.Col();
+ rRef.SetRelCol(rRef.Row());
+ rRef.SetRelRow(nTemp);
+}
+
// Reference transposition is only called in Clipboard Document
void ScFormulaCell::TransposeReference()
{
@@ -3769,18 +3777,10 @@ void ScFormulaCell::TransposeReference()
ScSingleRefData& rRef2 = (bDouble ? t->GetDoubleRef()->Ref2 : rRef1);
if ( !bDouble || (rRef2.IsColRel() && rRef2.IsRowRel()) )
{
- SCCOLROW nTemp;
-
- nTemp = rRef1.Col();
- rRef1.SetRelCol(rRef1.Row());
- rRef1.SetRelRow(nTemp);
+ lcl_TransposeReference(rRef1);
if ( bDouble )
- {
- nTemp = rRef2.Col();
- rRef2.SetRelCol(rRef2.Row());
- rRef2.SetRelRow(nTemp);
- }
+ lcl_TransposeReference(rRef2);
bFound = true;
}
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index a86c95da082d..af21428fde22 100644..100755
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -796,12 +796,19 @@ namespace {
class TransClipHandler
{
ScTable& mrClipTab;
+ const ScTable& mrSrcTab;
SCTAB mnSrcTab;
SCCOL mnSrcCol;
size_t mnTopRow;
+ size_t mnEndRow;
SCROW mnTransRow;
+ SCROW mnFilteredRows = 0;
+ SCROW mnRowDestOffset = 0;
bool mbAsLink;
bool mbWasCut;
+ bool mbIncludeFiltered;
+ InsertDeleteFlags mnFlags;
+ std::vector<SCROW>& mrFilteredRows;
ScAddress getDestPos(size_t nRow) const
{
@@ -822,62 +829,118 @@ class TransClipHandler
void setLink(size_t nRow)
{
- SCCOL nTransCol = nRow - mnTopRow;
- mrClipTab.SetFormulaCell(
- nTransCol, mnTransRow, createRefCell(nRow, getDestPos(nRow)));
+ SCCOL nTransCol = nRow - mnTopRow - mnFilteredRows + mnRowDestOffset;
+ mrClipTab.SetFormulaCell(nTransCol, mnTransRow,
+ createRefCell(nRow, getDestPos(nRow)));
}
public:
- TransClipHandler(ScTable& rClipTab, SCTAB nSrcTab, SCCOL nSrcCol, size_t nTopRow, SCROW nTransRow, bool bAsLink, bool bWasCut) :
- mrClipTab(rClipTab), mnSrcTab(nSrcTab), mnSrcCol(nSrcCol),
- mnTopRow(nTopRow), mnTransRow(nTransRow), mbAsLink(bAsLink), mbWasCut(bWasCut) {}
+ TransClipHandler(ScTable& rClipTab, const ScTable& rSrcTab, SCTAB nSrcTab, SCCOL nSrcCol,
+ size_t nTopRow, size_t nEndRow, SCROW nTransRow, SCROW nRowDestOffset,
+ bool bAsLink, bool bWasCut, const InsertDeleteFlags& nFlags,
+ const bool bIncludeFiltered, std::vector<SCROW>& rFilteredRows)
+ : mrClipTab(rClipTab)
+ , mrSrcTab(rSrcTab)
+ , mnSrcTab(nSrcTab)
+ , mnSrcCol(nSrcCol)
+ , mnTopRow(nTopRow)
+ , mnEndRow(nEndRow)
+ , mnTransRow(nTransRow)
+ , mnRowDestOffset(nRowDestOffset)
+ , mbAsLink(bAsLink)
+ , mbWasCut(bWasCut)
+ , mbIncludeFiltered(bIncludeFiltered)
+ , mnFlags(nFlags)
+ , mrFilteredRows(rFilteredRows)
+ {
+ // Create list of filtered rows.
+ if (!mbIncludeFiltered)
+ {
+ for (SCROW curRow = nTopRow; curRow <= static_cast<SCROW>(mnEndRow); ++curRow)
+ {
+ // maybe this loop could be optimized
+ bool bFiltered = mrSrcTab.RowFiltered(curRow, nullptr, nullptr);
+ if (bFiltered)
+ mrFilteredRows.push_back(curRow);
+ }
+ }
+ }
void operator() (size_t nRow, double fVal)
{
+ bool bFiltered = mrSrcTab.RowFiltered(nRow, nullptr, nullptr);
+ if (!mbIncludeFiltered && bFiltered)
+ {
+ mnFilteredRows++;
+ return;
+ }
+
if (mbAsLink)
{
setLink(nRow);
return;
}
- SCCOL nTransCol = nRow - mnTopRow;
+ SCCOL nTransCol = nRow - mnTopRow - mnFilteredRows + mnRowDestOffset;
mrClipTab.SetValue(nTransCol, mnTransRow, fVal);
}
void operator() (size_t nRow, const svl::SharedString& rStr)
{
+ bool bFiltered = mrSrcTab.RowFiltered(nRow, nullptr, nullptr);
+ if (!mbIncludeFiltered && bFiltered)
+ {
+ mnFilteredRows++;
+ return;
+ }
+
if (mbAsLink)
{
setLink(nRow);
return;
}
- SCCOL nTransCol = nRow - mnTopRow;
+ SCCOL nTransCol = nRow - mnTopRow - mnFilteredRows + mnRowDestOffset;
mrClipTab.SetRawString(nTransCol, mnTransRow, rStr);
}
void operator() (size_t nRow, const EditTextObject* p)
{
+ bool bFiltered = mrSrcTab.RowFiltered(nRow, nullptr, nullptr);
+ if (!mbIncludeFiltered && bFiltered)
+ {
+ mnFilteredRows++;
+ return;
+ }
+
if (mbAsLink)
{
setLink(nRow);
return;
}
- SCCOL nTransCol = nRow - mnTopRow;
+ SCCOL nTransCol = nRow - mnTopRow - mnFilteredRows + mnRowDestOffset;
mrClipTab.SetEditText(nTransCol, mnTransRow, ScEditUtil::Clone(*p, mrClipTab.GetDoc()));
}
void operator() (size_t nRow, const ScFormulaCell* p)
{
+ bool bFiltered = mrSrcTab.RowFiltered(nRow, nullptr, nullptr);
+ if (!mbIncludeFiltered && bFiltered)
+ {
+ mnFilteredRows++;
+ return;
+ }
+
if (mbAsLink)
{
setLink(nRow);
return;
}
- ScFormulaCell* pNew = new ScFormulaCell(
- *p, mrClipTab.GetDoc(), getDestPos(nRow), ScCloneFlags::StartListening);
+ ScFormulaCell* pNew = new ScFormulaCell(*p, mrClipTab.GetDoc(),
+ getDestPos(nRow - mnFilteredRows + mnRowDestOffset),
+ ScCloneFlags::StartListening);
// rotate reference
// for Cut, the references are later adjusted through UpdateTranspose
@@ -885,52 +948,99 @@ public:
if (!mbWasCut)
pNew->TransposeReference();
- SCCOL nTransCol = nRow - mnTopRow;
+ SCCOL nTransCol = nRow - mnTopRow - mnFilteredRows + mnRowDestOffset;
mrClipTab.SetFormulaCell(nTransCol, mnTransRow, pNew);
}
-};
+ // empty cells
+ void operator()(const int /*type*/, size_t nRow, size_t nDataSize)
+ {
+ for (size_t curRow = nRow; curRow < nRow + nDataSize; ++curRow)
+ {
+ bool bFiltered = mrSrcTab.RowFiltered(curRow, nullptr, nullptr);
+ if (!mbIncludeFiltered && bFiltered)
+ {
+ mnFilteredRows++;
+ continue;
}
-void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
- ScTable* pTransClip, InsertDeleteFlags nFlags, bool bAsLink )
+ if (mbAsLink && mnFlags == InsertDeleteFlags::ALL)
{
- bool bWasCut = rDocument.IsCutMode();
+ // with InsertDeleteFlags::ALL, also create links (formulas) for empty cells
+ setLink(nRow);
+ continue;
+ }
+ }
+ }
+};
+}
- ScDocument& rDestDoc = pTransClip->rDocument;
+void ScTable::TransposeClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ SCROW nRowDestOffset, ScTable* pTransClip, InsertDeleteFlags nFlags,
+ bool bAsLink, bool bIncludeFiltered)
+{
+ bool bWasCut = rDocument.IsCutMode();
for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
{
- SCROW nRow;
- if ( bAsLink && nFlags == InsertDeleteFlags::ALL )
- {
- // with InsertDeleteFlags::ALL, also create links (formulas) for empty cells
+ std::vector<SCROW> aFilteredRows;
- for ( nRow=nRow1; nRow<=nRow2; nRow++ )
- {
- // create simple formula, as in ScColumn::CreateRefCell
-
- ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
- ScSingleRefData aRef;
- aRef.InitAddress(ScAddress(nCol,nRow,nTab));
- aRef.SetFlag3D(true);
- ScTokenArray aArr(rDestDoc);
- aArr.AddSingleReference( aRef );
-
- pTransClip->SetFormulaCell(
- static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1),
- new ScFormulaCell(rDestDoc, aDestPos, aArr));
- }
- }
- else
+ TransClipHandler aFunc(*pTransClip, *this, nTab, nCol, nRow1, nRow2,
+ static_cast<SCROW>(nCol - nCol1), nRowDestOffset, bAsLink, bWasCut,
+ nFlags, bIncludeFiltered, aFilteredRows);
+
+ const sc::CellStoreType& rCells = aCol[nCol].maCells;
+
+ // Loop through all rows by iterator and call aFunc operators
+ sc::ParseAll(rCells.begin(), rCells, nRow1, nRow2, aFunc,
+ aFunc);
+
+ // Attributes
+ if (nFlags & InsertDeleteFlags::ATTRIB)
+ TransposeColPatterns(pTransClip, nCol1, nCol, nRow1, nRow2, bIncludeFiltered,
+ aFilteredRows, nRowDestOffset);
+
+ // Cell Notes - fdo#68381 paste cell notes on Transpose
+ if ((nFlags & InsertDeleteFlags::NOTE) && rDocument.HasColNotes(nCol, nTab))
+ TransposeColNotes(pTransClip, nCol1, nCol, nRow1, nRow2, bIncludeFiltered,
+ nRowDestOffset);
+ }
+}
+
+static void lcl_SetTransposedPatternInRows(ScTable* pTransClip, SCROW nAttrRow1, SCROW nAttrRow2,
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol,
+ const ScPatternAttr& rPatternAttr, bool bIncludeFiltered,
+ const std::vector<SCROW>& rFilteredRows,
+ SCROW nRowDestOffset)
+{
+ for (SCROW nRow = nAttrRow1; nRow <= nAttrRow2; nRow++)
+ {
+ size_t nFilteredRowAdjustment = 0;
+ if (!bIncludeFiltered)
{
- TransClipHandler aFunc(*pTransClip, nTab, nCol, nRow1, static_cast<SCROW>(nCol-nCol1), bAsLink, bWasCut);
- const sc::CellStoreType& rCells = aCol[nCol].maCells;
- sc::ParseAllNonEmpty(rCells.begin(), rCells, nRow1, nRow2, aFunc);
+ // aFilteredRows is sorted thus lower_bound() can be used.
+ // lower_bound() has a logarithmic complexity O(log(n))
+ auto itRow1 = std::lower_bound(rFilteredRows.begin(), rFilteredRows.end(), nRow1);
+ auto itRow = std::lower_bound(rFilteredRows.begin(), rFilteredRows.end(), nRow);
+ bool bRefRowIsFiltered = itRow != rFilteredRows.end() && *itRow == nRow;
+ if (bRefRowIsFiltered)
+ continue;
+
+ // How many filtered rows are between the formula cell and the reference?
+ // distance() has a constant complexity O(1) for vectors
+ nFilteredRowAdjustment = std::distance(itRow1, itRow);
}
- // Attribute
+ pTransClip->SetPattern(
+ static_cast<SCCOL>(nRow - nRow1 - nFilteredRowAdjustment + nRowDestOffset),
+ static_cast<SCROW>(nCol - nCol1), rPatternAttr);
+ }
+}
+void ScTable::TransposeColPatterns(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1,
+ SCROW nRow2, bool bIncludeFiltered,
+ const std::vector<SCROW>& rFilteredRows, SCROW nRowDestOffset)
+{
SCROW nAttrRow1 = {}; // spurious -Werror=maybe-uninitialized
SCROW nAttrRow2 = {}; // spurious -Werror=maybe-uninitialized
const ScPatternAttr* pPattern;
@@ -944,9 +1054,11 @@ void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
rSet.GetItemState( ATTR_MERGE_FLAG, false ) == SfxItemState::DEFAULT &&
rSet.GetItemState( ATTR_BORDER, false ) == SfxItemState::DEFAULT )
{
+ // Set pattern in cells from nAttrRow1 to nAttrRow2
// no borders or merge items involved - use pattern as-is
- for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
- pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), *pPattern );
+ lcl_SetTransposedPatternInRows(pTransClip, nAttrRow1, nAttrRow2, nCol1, nRow1,
+ nCol, *pPattern, bIncludeFiltered, rFilteredRows,
+ nRowDestOffset);
}
else
{
@@ -987,20 +1099,17 @@ void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
rNewSet.ClearItem( ATTR_MERGE_FLAG );
}
- for (nRow = nAttrRow1; nRow<=nAttrRow2; nRow++)
- pTransClip->SetPattern( static_cast<SCCOL>(nRow-nRow1),
- static_cast<SCROW>(nCol-nCol1), aNewPattern);
+ // Set pattern in cells from nAttrRow1 to nAttrRow2
+ lcl_SetTransposedPatternInRows(pTransClip, nAttrRow1, nAttrRow2, nCol1, nRow1,
+ nCol, aNewPattern, bIncludeFiltered,
+ rFilteredRows, nRowDestOffset);
}
}
- }
-
- // Cell Notes - fdo#68381 paste cell notes on Transpose
- if ( rDocument.HasColNotes(nCol, nTab) )
- TransposeColNotes(pTransClip, nCol1, nCol, nRow1, nRow2);
}
}
-void ScTable::TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1, SCROW nRow2)
+void ScTable::TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1,
+ SCROW nRow2, bool bIncludeFiltered, SCROW nRowDestOffset)
{
sc::CellNoteStoreType::const_iterator itBlk = aCol[nCol].maCellNotes.begin(), itBlkEnd = aCol[nCol].maCellNotes.end();
@@ -1023,6 +1132,7 @@ void ScTable::TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SC
return;
nRowPos = static_cast<size_t>(nRow2); // End row position.
+ SCCOL nFilteredRows = 0;
// Keep processing until we hit the end row position.
sc::cellnote_block::const_iterator itData, itDataEnd;
@@ -1035,6 +1145,7 @@ void ScTable::TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SC
itData = sc::cellnote_block::begin(*itBlk->data);
std::advance(itData, nOffsetInBlock);
+ // selected area is smaller than the iteration block
if (nBlockStart <= nRowPos && nRowPos < nBlockEnd)
{
// This block contains the end row. Only process partially.
@@ -1044,7 +1155,16 @@ void ScTable::TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SC
size_t curRow = nBlockStart + nOffsetInBlock;
for (; itData != itDataEnd; ++itData, ++curRow)
{
- ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
+ bool bFiltered = this->RowFiltered(curRow, nullptr, nullptr);
+ if (!bIncludeFiltered && bFiltered)
+ {
+ nFilteredRows++;
+ continue;
+ }
+
+ ScAddress aDestPos(
+ static_cast<SCCOL>(curRow - nRow1 - nFilteredRows + nRowDestOffset),
+ static_cast<SCROW>(nCol - nCol1), pTransClip->nTab);
pTransClip->rDocument.ReleaseNote(aDestPos);
ScPostIt* pNote = *itData;
if (pNote)
@@ -1061,7 +1181,16 @@ void ScTable::TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SC
size_t curRow = nBlockStart + nOffsetInBlock;
for (; itData != itDataEnd; ++itData, ++curRow)
{
- ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
+ bool bFiltered = this->RowFiltered(curRow, nullptr, nullptr);
+ if (!bIncludeFiltered && bFiltered)
+ {
+ nFilteredRows++;
+ continue;
+ }
+
+ ScAddress aDestPos(
+ static_cast<SCCOL>(curRow - nRow1 - nFilteredRows + nRowDestOffset),
+ static_cast<SCROW>(nCol - nCol1), pTransClip->nTab);
pTransClip->rDocument.ReleaseNote(aDestPos);
ScPostIt* pNote = *itData;
if (pNote)
@@ -1072,16 +1201,23 @@ void ScTable::TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SC
}
}
}
- else
+ else // remove dest notes for rows without notes
{
- size_t curRow;
- for ( curRow = nBlockStart + nOffsetInBlock; curRow <= nBlockEnd && curRow <= nRowPos; ++curRow)
+ for (size_t curRow = nBlockStart + nOffsetInBlock;
+ curRow <= nBlockEnd && curRow <= nRowPos; ++curRow)
{
- ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
+ bool bFiltered = this->RowFiltered(curRow, nullptr, nullptr);
+ if (!bIncludeFiltered && bFiltered && curRow < nBlockEnd)
+ {
+ nFilteredRows++;
+ continue;
+ }
+
+ ScAddress aDestPos(
+ static_cast<SCCOL>(curRow - nRow1 - nFilteredRows + nRowDestOffset),
+ static_cast<SCROW>(nCol - nCol1), pTransClip->nTab);
pTransClip->rDocument.ReleaseNote(aDestPos);
}
- if (curRow == nRowPos)
- break;
}
}
}
diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx
index 873312644634..ec037cc18e71 100644..100755
--- a/sc/source/ui/inc/viewfunc.hxx
+++ b/sc/source/ui/inc/viewfunc.hxx
@@ -352,9 +352,10 @@ private:
void PasteRTF( SCCOL nCol, SCROW nStartRow,
const css::uno::Reference< css::datatransfer::XTransferable >& rxTransferable );
- bool PasteMultiRangesFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc, ScPasteFunc nFunction,
- bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
- InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags );
+ bool PasteMultiRangesFromClip(InsertDeleteFlags nFlags, ScDocument* pClipDoc,
+ ScPasteFunc nFunction, bool bSkipEmpty, bool bIncludeFiltered,
+ bool bTranspose, bool bAsLink, bool bAllowDialogs,
+ InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags);
bool PasteFromClipToMultiRanges( InsertDeleteFlags nFlags, ScDocument* pClipDoc, ScPasteFunc nFunction,
bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
index db5987e8b2a8..476e92cd7443 100644..100755
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -905,9 +905,8 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
if (rClipParam.isMultiRange())
{
// Source data is multi-range.
- return PasteMultiRangesFromClip(
- nFlags, pClipDoc, nFunction, bSkipEmpty, bTranspose, bAsLink, bAllowDialogs,
- eMoveMode, nUndoFlags);
+ return PasteMultiRangesFromClip(nFlags, pClipDoc, nFunction, bSkipEmpty, false, bTranspose,
+ bAsLink, bAllowDialogs, eMoveMode, nUndoFlags);
}
ScMarkData& rMark = GetViewData().GetMarkData();
@@ -933,7 +932,6 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
SCCOL nX;
SCROW nY;
// include filtered rows until TransposeClip can skip them
- bIncludeFiltered = true;
pClipDoc->GetClipArea( nX, nY, true );
if ( nY > static_cast<sal_Int32>(pClipDoc->MaxCol()) ) // too many lines for transpose
{
@@ -950,7 +948,7 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
ScDrawLayer::SetGlobalDrawPersist( aTransShellRef.get() );
xTransClip.reset( new ScDocument( SCDOCMODE_CLIP ));
- pClipDoc->TransposeClip( xTransClip.get(), nFlags, bAsLink );
+ pClipDoc->TransposeClip(xTransClip.get(), nFlags, bAsLink, bIncludeFiltered);
pClipDoc = xTransClip.get();
ScDrawLayer::SetGlobalDrawPersist(nullptr);
@@ -1470,10 +1468,11 @@ bool ScViewFunc::PasteFromClip( InsertDeleteFlags nFlags, ScDocument* pClipDoc,
return true;
}
-bool ScViewFunc::PasteMultiRangesFromClip(
- InsertDeleteFlags nFlags, ScDocument* pClipDoc, ScPasteFunc nFunction,
- bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
- InsCellCmd eMoveMode, InsertDeleteFlags nUndoFlags)
+bool ScViewFunc::PasteMultiRangesFromClip(InsertDeleteFlags nFlags, ScDocument* pClipDoc,
+ ScPasteFunc nFunction, bool bSkipEmpty,
+ bool bIncludeFiltered, bool bTranspose, bool bAsLink,
+ bool bAllowDialogs, InsCellCmd eMoveMode,
+ InsertDeleteFlags nUndoFlags)
{
ScViewData& rViewData = GetViewData();
ScDocument& rDoc = rViewData.GetDocument();
@@ -1482,7 +1481,7 @@ bool ScViewFunc::PasteMultiRangesFromClip(
const ScAddress& rCurPos = rViewData.GetCurPos();
ScClipParam& rClipParam = pClipDoc->GetClipParam();
SCCOL nColSize = rClipParam.getPasteColSize();
- SCROW nRowSize = rClipParam.getPasteRowSize();
+ SCROW nRowSize = rClipParam.getPasteRowSize(*pClipDoc, bIncludeFiltered);
if (bTranspose)
{
@@ -1493,7 +1492,7 @@ bool ScViewFunc::PasteMultiRangesFromClip(
}
ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP));
- pClipDoc->TransposeClip(pTransClip.get(), nFlags, bAsLink);
+ pClipDoc->TransposeClip(pTransClip.get(), nFlags, bAsLink, bIncludeFiltered);
pClipDoc = pTransClip.release();
SCCOL nTempColSize = nColSize;
nColSize = static_cast<SCCOL>(nRowSize);
@@ -1580,8 +1579,9 @@ bool ScViewFunc::PasteMultiRangesFromClip(
rDoc.BeginDrawUndo();
InsertDeleteFlags nNoObjFlags = nFlags & ~InsertDeleteFlags::OBJECTS;
- rDoc.CopyMultiRangeFromClip(rCurPos, aMark, nNoObjFlags, pClipDoc,
- true, bAsLink, false, bSkipEmpty);
+ // in case of transpose, links were added in TransposeClip()
+ rDoc.CopyMultiRangeFromClip(rCurPos, aMark, nNoObjFlags, pClipDoc, true, bAsLink && !bTranspose,
+ bIncludeFiltered, bSkipEmpty);
if (pMixDoc)
rDoc.MixDocument(aMarkedRange, nFunction, bSkipEmpty, *pMixDoc);
@@ -1591,8 +1591,8 @@ bool ScViewFunc::PasteMultiRangesFromClip(
if (nFlags & InsertDeleteFlags::OBJECTS)
{
// Paste the drawing objects after the row heights have been updated.
- rDoc.CopyMultiRangeFromClip(rCurPos, aMark, InsertDeleteFlags::OBJECTS, pClipDoc,
- true, false, false, true);
+ rDoc.CopyMultiRangeFromClip(rCurPos, aMark, InsertDeleteFlags::OBJECTS, pClipDoc, true,
+ false, bIncludeFiltered, true);
}
if (bRowInfo)