summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
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)