summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Heinisch <andreas.heinisch@yahoo.de>2024-06-23 14:57:34 +0200
committerAndreas Heinisch <andreas.heinisch@yahoo.de>2024-07-05 08:11:53 +0200
commit8cf0bc36a8baa1d53b0a5fb169c6a9d5d8455289 (patch)
treeee556c4484f14c4e8781c5ab950e69cba483ce90
parent96c3d78f39ac4385880ae6f92f15f7ab3564ffcf (diff)
tdf#158110 - Paste special: improve check for cells with notes
Change-Id: Ia18d8f91ee2d4493174255424ce7e3b7310c369d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169355 Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de> Tested-by: Jenkins
-rw-r--r--sc/inc/document.hxx2
-rw-r--r--sc/inc/table.hxx1
-rw-r--r--sc/qa/uitest/pasteSpecial/tdf158110.py38
-rw-r--r--sc/source/core/data/document.cxx9
-rw-r--r--sc/source/core/data/table2.cxx14
-rw-r--r--sc/source/ui/view/viewfun3.cxx9
6 files changed, 71 insertions, 2 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 2f67225bf8ec..15f1720142fb 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1359,6 +1359,8 @@ public:
// This also includes e.g. notes. Use IsEmptyData() for cell data only.
bool IsBlockEmpty( SCCOL nStartCol, SCROW nStartRow,
SCCOL nEndCol, SCROW nEndRow, SCTAB nTab ) const;
+ bool IsNotesBlockEmpty( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, SCTAB nTab ) const;
bool IsPrintEmpty( SCCOL nStartCol, SCROW nStartRow,
SCCOL nEndCol, SCROW nEndRow, SCTAB nTab,
bool bLeftIsEmpty = false,
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 8ddc5cdc3b09..7da55e4cb3ee 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -426,6 +426,7 @@ public:
// This also includes e.g. notes. Use IsEmptyData() for cell data only.
bool IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const;
+ bool IsNotesBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const;
bool SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString& rString,
const ScSetStringParam * pParam = nullptr );
diff --git a/sc/qa/uitest/pasteSpecial/tdf158110.py b/sc/qa/uitest/pasteSpecial/tdf158110.py
index 9b0dba6ed8cd..9d775226c030 100644
--- a/sc/qa/uitest/pasteSpecial/tdf158110.py
+++ b/sc/qa/uitest/pasteSpecial/tdf158110.py
@@ -12,6 +12,7 @@ from uitest.framework import UITestCase
from libreoffice.calc.document import get_cell_by_position
from libreoffice.uno.propertyvalue import mkPropertyValues
from libreoffice.calc.paste_special import reset_default_values
+from uitest.uihelper.common import get_state_as_dict
class tdf158110(UITestCase):
def test_tdf158110_paste_special_multiple_cells(self):
@@ -45,4 +46,41 @@ class tdf158110(UITestCase):
# i.e., the comment was not copied
self.assertEqual("Comment 1", get_cell_by_position(document, 0, 1, 0).Annotation.String)
+ def test_tdf158110_paste_special_overwrite_comments(self):
+ with self.ui_test.create_doc_in_start_center("calc") as document:
+ xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
+
+ # Insert a comments
+ targetCells = ["A1", "A2", "B3", "D2"]
+ for targetCell in targetCells:
+ xGridWin.executeAction("SELECT", mkPropertyValues({"CELL": targetCell}))
+ xArgs = mkPropertyValues({"Text": "Comment 1"})
+ self.xUITest.executeCommandWithParameters(".uno:InsertAnnotation", xArgs)
+
+ # Copy cell range A1:B3 to clipboard
+ xGridWin.executeAction("SELECT", mkPropertyValues({"RANGE": "A1:B3"}))
+ self.xUITest.executeCommand(".uno:Copy")
+
+ # Paste data using special options (check only comments), i.e., overwrite comment in D2
+ xGridWin.executeAction("SELECT", mkPropertyValues({"CELL": "D1"}))
+ with self.ui_test.execute_dialog_through_command(".uno:PasteSpecial") as xPasteSpecialDlg:
+ reset_default_values(self, xPasteSpecialDlg)
+ xDateTimeChkBox = xPasteSpecialDlg.getChild("datetime")
+ xDateTimeChkBox.executeAction("CLICK", tuple())
+ xTextChkBox = xPasteSpecialDlg.getChild("text")
+ xTextChkBox.executeAction("CLICK", tuple())
+ xNumbersChkBox = xPasteSpecialDlg.getChild("numbers")
+ xNumbersChkBox.executeAction("CLICK", tuple())
+ xCommentsChkBox = xPasteSpecialDlg.getChild("comments")
+ xCommentsChkBox.executeAction("CLICK", tuple())
+
+ # Without the fix in place, this test would have failed with
+ # AssertionError: 'CheckWarningDialog' != ''
+ # i.e., the warning dialog was not shown
+ xCheckWarningDlg = self.xUITest.getTopFocusWindow()
+ self.assertEqual("CheckWarningDialog", get_state_as_dict(xCheckWarningDlg)["ID"])
+ if get_state_as_dict(xCheckWarningDlg)["ID"] == "CheckWarningDialog":
+ xYesBtn = xCheckWarningDlg.getChild("yes")
+ xYesBtn.executeAction("CLICK", tuple())
+
# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 51d636c588af..78f36e0bc462 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -5308,6 +5308,15 @@ void ScDocument::GetBorderLines( SCCOL nCol, SCROW nRow, SCTAB nTab,
*ppBottom = pBottomLine;
}
+bool ScDocument::IsNotesBlockEmpty(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ SCTAB nTab) const
+{
+ if (HasTable(nTab))
+ return maTabs[nTab]->IsNotesBlockEmpty(nStartCol, nStartRow, nEndCol, nEndRow);
+ OSL_FAIL("wrong table number");
+ return false;
+}
+
bool ScDocument::IsBlockEmpty(SCCOL nStartCol, SCROW nStartRow,
SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
{
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index aa51bec2d727..4629ce8036d1 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -2396,6 +2396,20 @@ void ScTable::SetMergedCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2
ApplyFlags(nCol1+1, nRow1+1, nCol2, nRow2, ScMF::Hor | ScMF::Ver);
}
+bool ScTable::IsNotesBlockEmpty(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
+{
+ if (!(ValidCol(nCol1) && ValidCol(nCol2)))
+ {
+ OSL_FAIL("ScTable::IsBlockEmptyNotes: invalid column number");
+ return false;
+ }
+ nCol2 = ClampToAllocatedColumns(nCol2);
+ bool bEmpty = true;
+ for (SCCOL i = nCol1; i <= nCol2 && bEmpty; i++)
+ bEmpty = aCol[i].IsNotesEmptyBlock(nRow1, nRow2);
+ return bEmpty;
+}
+
bool ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
{
if (!(ValidCol(nCol1) && ValidCol(nCol2)))
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
index f9ded7171687..d3e40076187a 100644
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -852,13 +852,18 @@ bool checkDestRangeForOverwrite(InsertDeleteFlags nFlags, const ScRangeList& rDe
{
bool bIsEmpty = true;
size_t nRangeSize = rDestRanges.size();
+
for (const auto& rTab : rMark)
{
for (size_t i = 0; i < nRangeSize && bIsEmpty; ++i)
{
const ScRange& rRange = rDestRanges[i];
- if (nFlags & InsertDeleteFlags::ADDNOTES)
- bIsEmpty = !rDoc.HasNote(rRange.aStart) && !rDoc.HasNote(rRange.aEnd);
+ // tdf#158110 - check if just the ADDNOTES flag is present without any other content
+ if ((nFlags & InsertDeleteFlags::ADDNOTES) == InsertDeleteFlags::ADDNOTES
+ && (nFlags & (InsertDeleteFlags::CONTENTS & ~InsertDeleteFlags::NOTE))
+ == InsertDeleteFlags::NONE)
+ bIsEmpty = rDoc.IsNotesBlockEmpty(rRange.aStart.Col(), rRange.aStart.Row(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(), rTab);
else
bIsEmpty = rDoc.IsBlockEmpty(rRange.aStart.Col(), rRange.aStart.Row(),
rRange.aEnd.Col(), rRange.aEnd.Row(), rTab);