sc: recreate a pasted table only when formulas are pasted

CopyFromClip() recreates a named table the copy fully covered so the
structured-reference tokens in the pasted formulas can resolve
against it. It ran that step for any content paste, so a values-only
paste also registered the table, with its autofilter and style, even
though it carries no formula that would reference the table.

Gate the table recreation on the formula content flag, so a
values-only paste leaves the destination without a table.

Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: I8bf7b30ef4fc415229d05f57955ac9d6cf65910e
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5097
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Balázs Varga <balazs.varga@collabora.com>
(cherry picked from commit c0ec48adf51d34a50469b78df4136aaaa1dce074)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207946
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
Tomaž Vajngerl
2026-07-10 23:04:26 +02:00
committed by Xisco Fauli
parent 4c787b42eb
commit dd2decfe19
2 changed files with 46 additions and 3 deletions
+42
View File
@@ -10261,6 +10261,48 @@ CPPUNIT_TEST_FIXTURE(TestCopyPaste, testCopyToClipMultiSheetForeignTable)
m_pDoc->DeleteTab(0);
}
CPPUNIT_TEST_FIXTURE(TestCopyPaste, testCopyFromClipValuesOnlyNoTable)
{
// Pasting only values of a copied table must not recreate the table in the
// destination. The table is recreated so structured-reference formulas can
// resolve against it. A values-only paste carries no such formula, so it
// should leave the destination without a table.
m_pDoc->InsertTab(0, u"Src"_ustr);
auto pTable = std::make_unique<ScDBData>(u"MyTable"_ustr, 0, 0, 0, 2, 2, true, true);
CPPUNIT_ASSERT(m_pDoc->GetDBCollection()->getNamedDBs().insert(std::move(pTable)));
m_pDoc->SetString(0, 0, 0, u"Name"_ustr);
m_pDoc->SetValue(2, 2, 0, 42.0);
// Copy the whole table A1:C3.
ScRange aClipRange(0, 0, 0, 2, 2, 0);
ScClipParam aClipParam(aClipRange, false);
ScMarkData aMark(m_pDoc->GetSheetLimits());
aMark.SelectOneTable(0);
aMark.SetMarkArea(aClipRange);
ScDocument aClipDoc(SCDOCMODE_CLIP);
m_pDoc->CopyToClip(aClipParam, &aClipDoc, &aMark, false, false);
// Fresh destination document that has no MyTable of its own.
ScDocShellRef xDestDocSh = new ScDocShell;
xDestDocSh->DoLoad(new SfxMedium(u"file:///valuesonly.fake"_ustr, StreamMode::STD_READWRITE));
ScDocument& rDestDoc = xDestDocSh->GetDocument();
rDestDoc.InsertTab(0, u"Dest"_ustr);
// Paste values only, no formulas.
ScRange aDestRange(0, 0, 0, 2, 2, 0);
ScMarkData aDestMark(rDestDoc.GetSheetLimits());
aDestMark.SelectOneTable(0);
rDestDoc.CopyFromClip(aDestRange, aDestMark, InsertDeleteFlags::VALUE, nullptr, &aClipDoc);
ScDBCollection* pDestDBs = rDestDoc.GetDBCollection();
CPPUNIT_ASSERT_MESSAGE("a values-only paste must not recreate the table",
!pDestDBs || pDestDBs->getNamedDBs().empty());
xDestDocSh->DoClose();
m_pDoc->DeleteTab(0);
}
CPPUNIT_TEST_FIXTURE(TestCopyPaste, testCopyPasteFormulasExternalDoc)
{
SfxMedium* pMedium = new SfxMedium(u"file:///source.fake"_ustr, StreamMode::STD_READWRITE);
+4 -3
View File
@@ -3131,9 +3131,10 @@ void ScDocument::CopyFromClip(
// Recreate named tables the copy fully covered at the paste location, so the
// structured-reference tokens resolved further down bind to a table placed
// at the paste position. Must run before the cells, and their formulas, are
// copied in.
if (nInsFlag & InsertDeleteFlags::CONTENTS)
// at the paste position. Only a formula paste carries such tokens, so a
// values-only paste needs no table. Must run before the cells, and their
// formulas, are copied in.
if (nInsFlag & InsertDeleteFlags::FORMULA)
CopyDBsFromClip(rDestRange, aClipRange, pClipDoc);
bInsertingFromOtherDoc = true; // No Broadcast/Listener created at Insert