diff --git a/src/Mod/Spreadsheet/App/SheetPy.xml b/src/Mod/Spreadsheet/App/SheetPy.xml index d968809ea7..f9a8348812 100644 --- a/src/Mod/Spreadsheet/App/SheetPy.xml +++ b/src/Mod/Spreadsheet/App/SheetPy.xml @@ -180,5 +180,26 @@ following dependency order. + + + + +getUsedCells() + +Get a list of the names of all cells that are marked as used. These cells may +or may not have a non-empty string content. + + + + + + + +getNonEmptyCells() + +Get a list of the names of all cells with data in them. + + + diff --git a/src/Mod/Spreadsheet/App/SheetPyImp.cpp b/src/Mod/Spreadsheet/App/SheetPyImp.cpp index c330453b01..415be1afd7 100644 --- a/src/Mod/Spreadsheet/App/SheetPyImp.cpp +++ b/src/Mod/Spreadsheet/App/SheetPyImp.cpp @@ -980,6 +980,27 @@ PyObject *SheetPy::recomputeCells(PyObject *args) { }PY_CATCH; } +PyObject *SheetPy::getUsedCells(PyObject *args) +{ + auto usedCells = getSheetPtr()->getCells()->getUsedCells(); + Py::List pyCellList; + for (const auto &cell : usedCells) { + pyCellList.append(Py::String(cell.toString())); + } + return Py::new_reference_to(pyCellList); +} + +PyObject *SheetPy::getNonEmptyCells(PyObject *args) +{ + auto usedCells = getSheetPtr()->getCells()->getNonEmptyCells(); + Py::List pyCellList; + for (const auto &cell : usedCells) { + pyCellList.append(Py::String(cell.toString())); + } + return Py::new_reference_to(pyCellList); +} + + // +++ custom attributes implementer ++++++++++++++++++++++++++++++++++++++++ PyObject *SheetPy::getCustomAttributes(const char*) const diff --git a/src/Mod/Spreadsheet/TestSpreadsheet.py b/src/Mod/Spreadsheet/TestSpreadsheet.py index 353e494537..743d5c72c7 100644 --- a/src/Mod/Spreadsheet/TestSpreadsheet.py +++ b/src/Mod/Spreadsheet/TestSpreadsheet.py @@ -1345,6 +1345,40 @@ class SpreadsheetCases(unittest.TestCase): with self.assertRaises(AttributeError): self.assertEqual(ss1.B1, "fail") + def testGetUsedCells(self): + sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') + test_cells = ['B13','C14','D15'] + for i,cell in enumerate(test_cells): + sheet.set(cell,str(i)) + + used_cells = sheet.getUsedCells() + self.assertEqual(len(used_cells), len(test_cells)) + for cell in test_cells: + self.assertTrue(cell in used_cells) + + for cell in test_cells: + sheet.set(cell,"") + sheet.setAlignment(cell,"center") + non_empty_cells = sheet.getUsedCells() + self.assertEqual(len(non_empty_cells), len(test_cells)) # Alignment counts as "used" + + def testGetNonEmptyCells(self): + sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') + test_cells = ['B13','C14','D15'] + for i,cell in enumerate(test_cells): + sheet.set(cell,str(i)) + + non_empty_cells = sheet.getNonEmptyCells() + self.assertEqual(len(non_empty_cells), len(test_cells)) + for cell in test_cells: + self.assertTrue(cell in non_empty_cells) + + for cell in test_cells: + sheet.set(cell,"") + sheet.setAlignment(cell,"center") + non_empty_cells = sheet.getNonEmptyCells() + self.assertEqual(len(non_empty_cells), 0) # Alignment does not count as "non-empty" + def tearDown(self): #closing doc FreeCAD.closeDocument(self.doc.Name)