diff options
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/table.hxx | 9 | ||||
-rw-r--r-- | sc/qa/unit/ucalc_copypaste.cxx | 44 | ||||
-rw-r--r-- | sc/source/core/data/clipparam.cxx | 10 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 11 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 36 |
5 files changed, 82 insertions, 28 deletions
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 8d938e6e5ce1..cbf97d7dbd36 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -541,12 +541,15 @@ public: void CopyConditionalFormat( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCCOL nDx, SCROW nDy, const ScTable* pTable); /** + * @param nCombinedStartRow start row of the combined range; + * used for transposed multi range selection with row direction; + * for other cases than multi range row selection this it equal to nRow1 * @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); + void TransposeClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCROW nCombinedStartRow, + SCROW nRowDestOffset, ScTable* pTransClip, InsertDeleteFlags nFlags, + bool bAsLink, bool bIncludeFiltered); // mark of this document void MixMarked( diff --git a/sc/qa/unit/ucalc_copypaste.cxx b/sc/qa/unit/ucalc_copypaste.cxx index 0bbd326eb128..35c1bb72f276 100644 --- a/sc/qa/unit/ucalc_copypaste.cxx +++ b/sc/qa/unit/ucalc_copypaste.cxx @@ -114,6 +114,7 @@ public: void testCopyPasteFormulas(); void testCopyPasteFormulasExternalDoc(); void testCopyPasteReferencesExternalDoc(); // tdf#106456 + void testTdf68976(); void testTdf71058(); CPPUNIT_TEST_SUITE(TestCopyPaste); @@ -189,6 +190,7 @@ public: CPPUNIT_TEST(testCopyPasteFormulasExternalDoc); CPPUNIT_TEST(testCopyPasteReferencesExternalDoc); + CPPUNIT_TEST(testTdf68976); CPPUNIT_TEST(testTdf71058); CPPUNIT_TEST_SUITE_END(); @@ -6820,6 +6822,48 @@ void TestCopyPaste::testCopyPasteReferencesExternalDoc() xExtDocSh->DoClose(); } +void TestCopyPaste::testTdf68976() +{ + const SCTAB nTab = 0; + m_pDoc->InsertTab(nTab, "Test"); + + m_pDoc->SetValue(0, 0, nTab, 1.0); // A1 + m_pDoc->SetString(0, 1, nTab, "=$A$1"); // A2 + m_pDoc->SetValue(0, 2, nTab, 1000.0); // A3 + + // Cut A3 to the clip document. + ScDocument aClipDoc(SCDOCMODE_CLIP); + ScRange aSrcRange(0, 2, nTab, 0, 2, nTab); + cutToClip(*m_xDocShell, aSrcRange, &aClipDoc, false); // A3 + + ScRange aDestRange(1, 3, nTab, 1, 3, nTab); // B4 + ScMarkData aDestMark(m_pDoc->GetSheetLimits()); + + // Transpose + ScDocument* pOrigClipDoc = &aClipDoc; + ScDocumentUniquePtr pTransClip(new ScDocument(SCDOCMODE_CLIP)); + aClipDoc.TransposeClip(pTransClip.get(), InsertDeleteFlags::ALL, false, true); + aDestMark.SetMarkArea(aDestRange); + // Paste + m_pDoc->CopyFromClip(aDestRange, aDestMark, InsertDeleteFlags::ALL, nullptr, pTransClip.get(), + true, false, true, false); + m_pDoc->UpdateTranspose(aDestRange.aStart, pOrigClipDoc, aDestMark, nullptr); + pTransClip.reset(); + + // Check results + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(0, 0, nTab)); // A1 + // Without the fix in place, this would have failed with + // - Expected: =$A$1 + // - Actual : =$B$4 + ASSERT_FORMULA_EQUAL(*m_pDoc, ScAddress(0, 1, nTab), "$A$1", "Wrong formula"); + // Without the fix in place, this would have failed with + // - Expected: 1 + // - Actual : 1000 + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(0, 1, nTab)); // A2 + CPPUNIT_ASSERT_EQUAL(0.0, m_pDoc->GetValue(0, 2, nTab)); // A3 + CPPUNIT_ASSERT_EQUAL(1000.0, m_pDoc->GetValue(1, 3, nTab)); // B4 +} + void TestCopyPaste::testTdf71058() { const SCTAB nTab = 0; diff --git a/sc/source/core/data/clipparam.cxx b/sc/source/core/data/clipparam.cxx index 48840605364c..1e8039deb4f5 100644 --- a/sc/source/core/data/clipparam.cxx +++ b/sc/source/core/data/clipparam.cxx @@ -153,7 +153,9 @@ void ScClipParam::transpose(const ScDocument& rSrcDoc, bool bIncludeFiltered, 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(nColOrigin + nCol1, nRowOrigin + nRow1, + rRange.aStart.Tab(), nColOrigin + nCol2, + nRowOrigin + nRow2, rRange.aStart.Tab())); } else nRowCount += nNonFilteredRows; @@ -163,6 +165,7 @@ void ScClipParam::transpose(const ScDocument& rSrcDoc, bool bIncludeFiltered, // and selection are in the same dimension (i.e. row), see ScDocument::TransposeClip() if (bIsMultiRangeRowFilteredTranspose) { + assert(!bIncludeFiltered && "bIsMultiRangeRowFilteredTranspose can only be true if bIncludeFiltered is false"); SCCOL nColDelta = rRange1.aStart.Col() - nColOrigin; SCROW nRowDelta = rRange1.aStart.Row() - nRowOrigin; SCCOL nCol1 = 0; @@ -173,8 +176,9 @@ void ScClipParam::transpose(const ScDocument& rSrcDoc, bool bIncludeFiltered, nCol2 += static_cast<SCCOL>(nRowDelta); nRow1 += static_cast<SCROW>(nColDelta); nRow2 += static_cast<SCROW>(nColDelta); - aNewRanges.push_back( - ScRange(nCol1, nRow1, rRange1.aStart.Tab(), nCol2, nRow2, rRange1.aStart.Tab())); + aNewRanges.push_back(ScRange(nColOrigin + nCol1, nRowOrigin + nRow1, + rRange1.aStart.Tab(), nColOrigin + nCol2, + nRowOrigin + nRow2, rRange1.aStart.Tab())); } } maRanges = aNewRanges; diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 012913d37924..cbce2c2a824b 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -2367,8 +2367,7 @@ void ScDocument::TransposeClip(ScDocument* pTransClip, InsertDeleteFlags nFlags, SCROW nRowCountNonFiltered = CountNonFilteredRows( aClipRange.aStart.Row(), aClipRange.aEnd.Row(), aClipRange.aStart.Tab()); assert(!bIncludeFiltered && "bIsMultiRangeRowFilteredTranspose can only be true if bIncludeFiltered is false"); - SCROW nRowCountInRange = nRowCountNonFiltered; - nRowCount += nRowCountInRange; // for next iteration + nRowCount += nRowCountNonFiltered; // for next iteration } for (SCTAB i = 0; i < static_cast<SCTAB>(maTabs.size()); i++) @@ -2376,10 +2375,10 @@ void ScDocument::TransposeClip(ScDocument* pTransClip, InsertDeleteFlags nFlags, 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(), nRowOffset, - pTransClip->maTabs[i].get(), nFlags, bAsLink, - bIncludeFiltered); + maTabs[i]->TransposeClip( + aClipRange.aStart.Col(), aClipRange.aStart.Row(), aClipRange.aEnd.Col(), + aClipRange.aEnd.Row(), aCombinedClipRange.aStart.Row(), nRowOffset, + pTransClip->maTabs[i].get(), nFlags, bAsLink, bIncludeFiltered); if ( mpDrawLayer && ( nFlags & InsertDeleteFlags::OBJECTS ) ) { diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 47afc5886ab1..3ae7c49c9d5f 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -798,6 +798,7 @@ class TransClipHandler ScTable& mrClipTab; const ScTable& mrSrcTab; SCTAB mnSrcTab; + SCCOL mnCol1; SCCOL mnSrcCol; size_t mnTopRow; size_t mnEndRow; @@ -811,7 +812,8 @@ class TransClipHandler ScAddress getDestPos(size_t nRow) const { - return ScAddress(static_cast<SCCOL>(nRow-mnTopRow), mnTransRow, mrClipTab.GetTab()); + return ScAddress(static_cast<SCCOL>(mnCol1 + nRow - mnTopRow), mnTransRow, + mrClipTab.GetTab()); } ScFormulaCell* createRefCell(size_t nSrcRow, const ScAddress& rDestPos) const @@ -828,23 +830,25 @@ class TransClipHandler void setLink(size_t nRow) { - SCCOL nTransCol = nRow - mnTopRow - mnFilteredRows + mnRowDestOffset; + SCCOL nTransCol = mnCol1 + nRow - mnTopRow - mnFilteredRows + mnRowDestOffset; mrClipTab.SetFormulaCell(nTransCol, mnTransRow, createRefCell(nRow, getDestPos(nRow))); } public: - 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) + TransClipHandler(ScTable& rClipTab, const ScTable& rSrcTab, SCTAB nSrcTab, SCCOL nCol1, + SCCOL nSrcCol, size_t nTopRow, size_t nEndRow, SCROW nCombinedStartRow, + SCROW nRowDestOffset, bool bAsLink, bool bWasCut, + const InsertDeleteFlags& nFlags, const bool bIncludeFiltered, + std::vector<SCROW>& rFilteredRows) : mrClipTab(rClipTab) , mrSrcTab(rSrcTab) , mnSrcTab(nSrcTab) + , mnCol1(nCol1) , mnSrcCol(nSrcCol) , mnTopRow(nTopRow) , mnEndRow(nEndRow) - , mnTransRow(nTransRow) + , mnTransRow(nSrcCol - nCol1 + nCombinedStartRow) , mnRowDestOffset(nRowDestOffset) , mbAsLink(bAsLink) , mbWasCut(bWasCut) @@ -879,7 +883,7 @@ public: return; } - SCCOL nTransCol = nRow - mnTopRow - mnFilteredRows + mnRowDestOffset; + SCCOL nTransCol = mnCol1 + nRow - mnTopRow - mnFilteredRows + mnRowDestOffset; mrClipTab.SetValue(nTransCol, mnTransRow, fVal); } @@ -898,7 +902,7 @@ public: return; } - SCCOL nTransCol = nRow - mnTopRow - mnFilteredRows + mnRowDestOffset; + SCCOL nTransCol = mnCol1 + nRow - mnTopRow - mnFilteredRows + mnRowDestOffset; mrClipTab.SetRawString(nTransCol, mnTransRow, rStr); } @@ -917,7 +921,7 @@ public: return; } - SCCOL nTransCol = nRow - mnTopRow - mnFilteredRows + mnRowDestOffset; + SCCOL nTransCol = mnCol1 + nRow - mnTopRow - mnFilteredRows + mnRowDestOffset; mrClipTab.SetEditText(nTransCol, mnTransRow, ScEditUtil::Clone(*p, mrClipTab.GetDoc())); } @@ -946,7 +950,7 @@ public: if (!mbWasCut) pNew->TransposeReference(); - SCCOL nTransCol = nRow - mnTopRow - mnFilteredRows + mnRowDestOffset; + SCCOL nTransCol = mnCol1 + nRow - mnTopRow - mnFilteredRows + mnRowDestOffset; mrClipTab.SetFormulaCell(nTransCol, mnTransRow, pNew); } @@ -974,8 +978,8 @@ public: } void ScTable::TransposeClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, - SCROW nRowDestOffset, ScTable* pTransClip, InsertDeleteFlags nFlags, - bool bAsLink, bool bIncludeFiltered) + SCROW nCombinedStartRow, SCROW nRowDestOffset, ScTable* pTransClip, + InsertDeleteFlags nFlags, bool bAsLink, bool bIncludeFiltered) { bool bWasCut = rDocument.IsCutMode(); @@ -983,9 +987,9 @@ void ScTable::TransposeClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, { std::vector<SCROW> aFilteredRows; - TransClipHandler aFunc(*pTransClip, *this, nTab, nCol, nRow1, nRow2, - static_cast<SCROW>(nCol - nCol1), nRowDestOffset, bAsLink, bWasCut, - nFlags, bIncludeFiltered, aFilteredRows); + TransClipHandler aFunc(*pTransClip, *this, nTab, nCol1, nCol, nRow1, nRow2, + nCombinedStartRow, nRowDestOffset, bAsLink, bWasCut, nFlags, + bIncludeFiltered, aFilteredRows); const sc::CellStoreType& rCells = aCol[nCol].maCells; |