diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2024-03-03 02:04:24 +0600 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2024-03-03 01:05:32 +0100 |
commit | 709866a3b8e073fab4937dcf91dcd33ff1d2bc13 (patch) | |
tree | d266569645527b0a78a24a19d6c98c2a9d907e03 /sc/source | |
parent | b0d9f3c417315eb704dc9ab906e9c24f59571942 (diff) |
tdf#99969: make sure to copy the chart source ranges to clipboard
... even when they are outside of the copied cell range. Otherwise,
it is impossible to transfer the missing data when switching to
own data on paste.
The copy of the missing ranges avoids copying cell attributes, for
performance reasons, but also to avoid overwriting the attributes
of already copied cells. Otherwise, ScDrawLayer::CopyToClip would
need the bKeepScenarioFlags, or the CopyToClipContext used in the
caller ScDocument::CopyToClip, for consistent copy; or a method to
avoid overwriting already copied cells (this change simply copies
all chart ranges, withiut checking if they were copied already).
Change-Id: Id02e0c20517e7e8a17bb0a31d1b230196cda1a58
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164294
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'sc/source')
-rw-r--r-- | sc/source/core/data/clipcontext.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/column.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 14 | ||||
-rw-r--r-- | sc/source/core/data/drwlayer.cxx | 29 |
4 files changed, 45 insertions, 8 deletions
diff --git a/sc/source/core/data/clipcontext.cxx b/sc/source/core/data/clipcontext.cxx index 4e6b925070d6..fc6f136d0372 100644 --- a/sc/source/core/data/clipcontext.cxx +++ b/sc/source/core/data/clipcontext.cxx @@ -403,8 +403,8 @@ bool CopyFromClipContext::isDateCell( const ScColumn& rCol, SCROW nRow ) const } CopyToClipContext::CopyToClipContext( - ScDocument& rDoc, bool bKeepScenarioFlags) : - ClipContextBase(rDoc), mbKeepScenarioFlags(bKeepScenarioFlags) {} + ScDocument& rDoc, bool bKeepScenarioFlags, bool bCopyChartRanges) : + ClipContextBase(rDoc), mbKeepScenarioFlags(bKeepScenarioFlags), mbCopyChartRanges(bCopyChartRanges) {} CopyToClipContext::~CopyToClipContext() {} diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 22d8cec28bc3..34524e444dc3 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -879,14 +879,16 @@ public: void ScColumn::CopyToClip( sc::CopyToClipContext& rCxt, SCROW nRow1, SCROW nRow2, ScColumn& rColumn ) const { - pAttrArray->CopyArea( nRow1, nRow2, 0, *rColumn.pAttrArray, - rCxt.isKeepScenarioFlags() ? (ScMF::All & ~ScMF::Scenario) : ScMF::All ); + if (!rCxt.isCopyChartRanges()) // No need to copy attributes for chart ranges + pAttrArray->CopyArea( nRow1, nRow2, 0, *rColumn.pAttrArray, + rCxt.isKeepScenarioFlags() ? (ScMF::All & ~ScMF::Scenario) : ScMF::All ); { CopyToClipHandler aFunc(GetDoc(), *this, rColumn, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol)); sc::ParseBlock(maCells.begin(), maCells, aFunc, nRow1, nRow2); } + if (!rCxt.isCopyChartRanges()) // No need to copy attributes for chart ranges { CopyTextAttrToClipHandler aFunc(rColumn.maCellTextAttrs); sc::ParseBlock(maCellTextAttrs.begin(), maCellTextAttrs, aFunc, nRow1, nRow2); diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 7ad5a3e2ae89..c5f3f50e0f30 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -2223,6 +2223,7 @@ void ScDocument::CopyToClip(const ScClipParam& rClipParam, sc::CopyToClipContext aCxt(*pClipDoc, bKeepScenarioFlags); CopyRangeNamesToClip(pClipDoc, aClipRange, pMarks); + // 1. Copy selected cells for (SCTAB i = 0; i < nEndTab; ++i) { if (!maTabs[i] || i >= pClipDoc->GetTableCount() || !pClipDoc->maTabs[i]) @@ -2232,12 +2233,17 @@ void ScDocument::CopyToClip(const ScClipParam& rClipParam, continue; maTabs[i]->CopyToClip(aCxt, rClipParam.maRanges, pClipDoc->maTabs[i].get()); + } - if (mpDrawLayer && bIncludeObjects) + // 2. Copy drawing objects in the selection. Do in after the first "copy cells" pass, because + // the embedded objects (charts) coud reference cells from tabs not (yet) copied; doing it now + // allows to know what is already copied, to not owerwrite attributes of already copied data. + if (mpDrawLayer && bIncludeObjects) + { + for (SCTAB i = 0; i < nEndTab; ++i) { - // also copy drawing objects - tools::Rectangle aObjRect = GetMMRect( - aClipRange.aStart.Col(), aClipRange.aStart.Row(), aClipRange.aEnd.Col(), aClipRange.aEnd.Row(), i); + tools::Rectangle aObjRect = GetMMRect(aClipRange.aStart.Col(), aClipRange.aStart.Row(), + aClipRange.aEnd.Col(), aClipRange.aEnd.Row(), i); mpDrawLayer->CopyToClip(pClipDoc, i, aObjRect); } } diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index e404d6afbdc3..b9b22791969e 100644 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -88,6 +88,7 @@ #include <docpool.hxx> #include <detfunc.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> +#include <clipcontext.hxx> #include <clipparam.hxx> #include <memory> @@ -1834,6 +1835,34 @@ void ScDrawLayer::CopyToClip( ScDocument* pClipDoc, SCTAB nTab, const tools::Rec pDestPage->InsertObject(pNewObject.get()); + // Store the chart's source data to the clipboad document, even when it's out of the + // copied range. It will be ignored when pasted to the same document; when pasted to + // another document, ScDocument::mpClipParam will provide the actually copied ranges, + // and the data copied here will be used to break connection and switch to own data + // in ScDrawLayer::CopyFromClip. + if (xOldChart && !xOldChart->hasInternalDataProvider()) + { + sc::CopyToClipContext aCxt(*pClipDoc, false, true); + OUString aChartName = static_cast<SdrOle2Obj*>(pOldObject)->GetPersistName(); + std::vector<ScRangeList> aRangesVector; + pDoc->GetChartRanges(aChartName, aRangesVector, *pDoc); + for (const ScRangeList& ranges : aRangesVector) + { + for (const ScRange& r : ranges) + { + for (SCTAB i = r.aStart.Tab(); i <= r.aEnd.Tab(); ++i) + { + ScTable* pTab = pDoc->FetchTable(i); + ScTable* pClipTab = pClipDoc->FetchTable(i); + if (!pTab || !pClipTab) + continue; + pTab->CopyToClip(aCxt, r.aStart.Col(), r.aStart.Row(), r.aEnd.Col(), + r.aEnd.Row(), pClipTab); + } + } + } + } + // no undo needed in clipboard document // charts are not updated } |