summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Balland <laurent.balland@mailo.fr>2023-12-07 19:38:54 +0100
committerLaurent Balland <laurent.balland@mailo.fr>2024-04-17 19:25:25 +0200
commited0165f6cbd1f3f9e47be26fe5d60c29eb946030 (patch)
treee5cd2f23b8817b45a048a1673c3d3ceeedd75fa3
parent88f6a250076eb2a825084c84193b84f3b94ce112 (diff)
tdf#129701 Skip empty cell: treat last column
This is a combination of 2 commits. tdf#129701 Skip empty cell: treat last column When pasting data as text, with "Skip empty cells" not checked, empty cells in the last column of the source do not empty cells in destination, because there is nothing anymore to paste and while loop stops. This commit adds a flag to check if the last cell of each line is empty, and treat it if "Skip empty cells" is not checked. Add UITest to Copy data with empty cells; Paste Unformatted text, without "Skip empty cells"; Check data with empty cells in last column. xChange-Id: Idec823fb1c27b803f49c6d13d6c757ef0f41e437 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160951 Tested-by: Jenkins Reviewed-by: Laurent Balland <laurent.balland@mailo.fr> (cherry picked from commit e66ffda7c7f1e78dbca082ff7549ded121dc7356) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163536 Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com> (cherry picked from commit 60e0ebe633b1dee8bb2a66b9d133f5303749d8d5) tdf#129701 Follow-up of previous change According to comments in https://gerrit.libreoffice.org/c/core/+/163536 Follow-up of previous change xChange-Id: Icd7b6798d6ef35ca9574125cd3d4c4d89044569c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166133 Tested-by: Jenkins Reviewed-by: Eike Rathke <erack@redhat.com> (cherry picked from commit 47187acee758680cda8086b6e295ef7beea3491b) Change-Id: Idec823fb1c27b803f49c6d13d6c757ef0f41e437 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164493 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Jenkins Reviewed-by: Laurent Balland <laurent.balland@mailo.fr>
-rw-r--r--sc/qa/uitest/data/tdf129701.odsbin0 -> 23138 bytes
-rw-r--r--sc/qa/uitest/pasteSpecial/tdf129701-PasteUnformated.py70
-rw-r--r--sc/source/ui/docshell/impex.cxx17
3 files changed, 85 insertions, 2 deletions
diff --git a/sc/qa/uitest/data/tdf129701.ods b/sc/qa/uitest/data/tdf129701.ods
new file mode 100644
index 000000000000..94407fcd566e
--- /dev/null
+++ b/sc/qa/uitest/data/tdf129701.ods
Binary files differ
diff --git a/sc/qa/uitest/pasteSpecial/tdf129701-PasteUnformated.py b/sc/qa/uitest/pasteSpecial/tdf129701-PasteUnformated.py
new file mode 100644
index 000000000000..596cd62f8bc1
--- /dev/null
+++ b/sc/qa/uitest/pasteSpecial/tdf129701-PasteUnformated.py
@@ -0,0 +1,70 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+from uitest.framework import UITestCase
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.uihelper.common import get_url_for_data_file
+from uitest.uihelper.common import get_state_as_dict
+from libreoffice.calc.document import get_cell_by_position
+
+class tdf129701(UITestCase):
+
+ def test_tdf129701(self):
+
+ with self.ui_test.load_file(get_url_for_data_file("tdf129701.ods")):
+ xCalcDoc = self.xUITest.getTopFocusWindow()
+ gridwin = xCalcDoc.getChild("grid_window")
+ gridwin.executeAction("SELECT", mkPropertyValues({"RANGE": "D21:F25"}))
+ self.xUITest.executeCommand(".uno:Copy")
+
+ gridwin.executeAction("SELECT", mkPropertyValues({"CELL": "J4"}))
+ with self.ui_test.execute_dialog_through_command(".uno:PasteUnformatted", close_button="ok") as xDialog:
+
+ xSkipEmtyCells = xDialog.getChild("skipemptycells")
+ xSeparatedBy = xDialog.getChild("toseparatedby")
+ xTab = xDialog.getChild("tab")
+ xMergeDelimiters = xDialog.getChild("mergedelimiters")
+
+ xSeparatedBy.executeAction("CLICK", tuple())
+ if get_state_as_dict(xTab)['Selected'] == 'false':
+ xTab.executeAction("CLICK", tuple())
+ if get_state_as_dict(xMergeDelimiters)['Selected'] == 'true':
+ xMergeDelimiters.executeAction("CLICK", tuple())
+ if get_state_as_dict(xSkipEmtyCells)['Selected'] == 'true':
+ xSkipEmtyCells.executeAction("CLICK", tuple())
+ # Check wether Skip empty cells is unselected
+ self.assertEqual('false', get_state_as_dict(xSkipEmtyCells)['Selected'])
+
+ document = self.ui_test.get_component()
+ # Without the fix in place, this test would have failed with
+ # non empty cells in column 11
+
+ self.assertEqual( "x1", get_cell_by_position(document, 0, 9, 3).getString())
+ self.assertEqual( "" , get_cell_by_position(document, 0,10, 3).getString())
+ self.assertEqual( "" , get_cell_by_position(document, 0,11, 3).getString())
+ self.assertEqual("A16", get_cell_by_position(document, 0,12, 3).getString())
+ self.assertEqual( "" , get_cell_by_position(document, 0, 9, 4).getString())
+ self.assertEqual( "x2", get_cell_by_position(document, 0,10, 4).getString())
+ self.assertEqual( "" , get_cell_by_position(document, 0,11, 4).getString())
+ self.assertEqual("A17", get_cell_by_position(document, 0,12, 4).getString())
+ self.assertEqual( "" , get_cell_by_position(document, 0, 9, 5).getString())
+ self.assertEqual( "" , get_cell_by_position(document, 0,10, 5).getString())
+ self.assertEqual( "x3", get_cell_by_position(document, 0,11, 5).getString())
+ self.assertEqual("A18", get_cell_by_position(document, 0,12, 5).getString())
+ self.assertEqual( "" , get_cell_by_position(document, 0, 9, 6).getString())
+ self.assertEqual( "x4", get_cell_by_position(document, 0,10, 6).getString())
+ self.assertEqual( "" , get_cell_by_position(document, 0,11, 6).getString())
+ self.assertEqual("A19", get_cell_by_position(document, 0,12, 6).getString())
+ self.assertEqual( "x5", get_cell_by_position(document, 0, 9, 7).getString())
+ self.assertEqual( "x6", get_cell_by_position(document, 0,10, 7).getString())
+ self.assertEqual( "x7", get_cell_by_position(document, 0,11, 7).getString())
+ self.assertEqual("A20", get_cell_by_position(document, 0,12, 7).getString())
+
+ self.ui_test.close_doc()
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx
index c405fb2c45a3..233e1a14a52c 100644
--- a/sc/source/ui/docshell/impex.cxx
+++ b/sc/source/ui/docshell/impex.cxx
@@ -1656,6 +1656,7 @@ bool ScImportExport::ExtText2Doc( SvStream& rStrm )
ScDocumentImport aDocImport(rDoc);
do
{
+ const SCCOL nLastCol = nEndCol; // tdf#129701 preserve value of nEndCol
for( ;; )
{
aLine = ReadCsvLine(rStrm, !bFixed, aSeps, cStr, cDetectSep);
@@ -1739,11 +1740,14 @@ bool ScImportExport::ExtText2Doc( SvStream& rStrm )
SCCOL nSourceCol = 0;
sal_uInt16 nInfoStart = 0;
const sal_Unicode* p = aLine.getStr();
+ // tdf#129701 if there is only one column, and user wants to treat empty cells,
+ // we need to detect *p = null
+ bool bIsLastColEmpty = !(*p) && !bSkipEmptyCells && !bDetermineRange;
// Yes, the check is nCol<=rDoc.MaxCol()+1, +1 because it is only an
// overflow if there is really data following to be put behind
// the last column, which doesn't happen if info is
// SC_COL_SKIP.
- while (*p && nCol <= rDoc.MaxCol()+1)
+ while ( (*p || bIsLastColEmpty) && nCol <= rDoc.MaxCol()+1)
{
bool bIsQuoted = false;
p = ScImportExport::ScanNextFieldFromString( p, aCell,
@@ -1775,8 +1779,17 @@ bool ScImportExport::ExtText2Doc( SvStream& rStrm )
pEnglishTransliteration.get(), pEnglishCalendar.get());
}
++nCol;
- }
+ if (bIsLastColEmpty)
+ {
+ bIsLastColEmpty = false; // toggle to stop
+ }
+ else
+ {
+ // tdf#129701 detect if there is a last empty column when we need it
+ bIsLastColEmpty = (nCol == nLastCol) && !(*p) && !bSkipEmptyCells && !bDetermineRange;
+ }
+ }
++nSourceCol;
}
}