From 37dbcf7f662d98354e80937078fbdf41cabb0e69 Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Fri, 12 Nov 2021 17:31:38 -0600 Subject: [PATCH] Spreadsheet: Add programmatic selection of cells Implement modifying the current selection programmatically via the ViewProvider object in both C++ and Python. This enables unit testing of GUI tasks that require a selection, and improves scriptability of Spreadsheet. --- src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp | 10 +++++++ src/Mod/Spreadsheet/Gui/SpreadsheetView.h | 4 +++ .../Gui/ViewProviderSpreadsheetPy.xml | 7 +++++ .../Gui/ViewProviderSpreadsheetPyImp.cpp | 29 +++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp b/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp index 4103c2fd91..84d58d7c8c 100644 --- a/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp +++ b/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp @@ -419,6 +419,16 @@ QModelIndexList SheetView::selectedIndexes() const return ui->cells->selectionModel()->selectedIndexes(); } +void SpreadsheetGui::SheetView::select(App::CellAddress cell, QItemSelectionModel::SelectionFlags flags) +{ + ui->cells->selectionModel()->select(model->index(cell.row(), cell.col()), flags); +} + +void SpreadsheetGui::SheetView::select(App::CellAddress topLeft, App::CellAddress bottomRight, QItemSelectionModel::SelectionFlags flags) +{ + ui->cells->selectionModel()->select(QItemSelection(model->index(topLeft.row(), topLeft.col()), model->index(bottomRight.row(), bottomRight.col())), flags); +} + void SheetView::deleteSelection() { ui->cells->deleteSelection(); diff --git a/src/Mod/Spreadsheet/Gui/SpreadsheetView.h b/src/Mod/Spreadsheet/Gui/SpreadsheetView.h index 141cdfe59b..524bc70f5c 100644 --- a/src/Mod/Spreadsheet/Gui/SpreadsheetView.h +++ b/src/Mod/Spreadsheet/Gui/SpreadsheetView.h @@ -73,6 +73,10 @@ public: QModelIndexList selectedIndexes() const; + void select(App::CellAddress cell, QItemSelectionModel::SelectionFlags flags); + + void select(App::CellAddress topLeft, App::CellAddress bottomRight, QItemSelectionModel::SelectionFlags flags); + QModelIndex currentIndex() const; void deleteSelection(); diff --git a/src/Mod/Spreadsheet/Gui/ViewProviderSpreadsheetPy.xml b/src/Mod/Spreadsheet/Gui/ViewProviderSpreadsheetPy.xml index 51c7b591f4..0b21aeecdf 100644 --- a/src/Mod/Spreadsheet/Gui/ViewProviderSpreadsheetPy.xml +++ b/src/Mod/Spreadsheet/Gui/ViewProviderSpreadsheetPy.xml @@ -25,5 +25,12 @@ returns a list with the selected cells + + + +select(index, flags): Select the specified cell using the given QItemSelectionModel.SelectionFlag set +select(topLeft, bottomRight, flags): Select the specified range using the given QItemSelectionModel.SelectionFlag set + + diff --git a/src/Mod/Spreadsheet/Gui/ViewProviderSpreadsheetPyImp.cpp b/src/Mod/Spreadsheet/Gui/ViewProviderSpreadsheetPyImp.cpp index ae9e3d6c69..06cc7e1b39 100644 --- a/src/Mod/Spreadsheet/Gui/ViewProviderSpreadsheetPyImp.cpp +++ b/src/Mod/Spreadsheet/Gui/ViewProviderSpreadsheetPyImp.cpp @@ -44,6 +44,35 @@ PyObject* ViewProviderSpreadsheetPy::selectedCells(PyObject* /*obj*/) return out; } +PyObject* ViewProviderSpreadsheetPy::select(PyObject* _args) +{ + ViewProviderSheet* vp = this->getViewProviderSheetPtr(); + SheetView* sheetView = vp->getView(); + Spreadsheet::Sheet* sheet = sheetView->getSheet(); + + Py::Sequence args(_args); + + const char* cell; + const char* topLeft; + const char* bottomRight; + int flags = 0; + if (args.size() == 2 && PyArg_ParseTuple(_args, "si", &cell, &flags)) { + sheetView->select(App::CellAddress(cell), static_cast(flags)); + } + else if (args.size() == 3 && PyArg_ParseTuple(_args, "ssi", &topLeft, &bottomRight, &flags)) { + sheetView->select(App::CellAddress(topLeft), App::CellAddress(bottomRight), static_cast(flags)); + } + else { + if (args.size() == 2) + throw Base::TypeError("Expects the arguments to be a cell name (e.g. 'A1') and QItemSelectionModel.SelectionFlags"); + else if (args.size() == 3) + throw Base::TypeError("Expects the arguments to be a cell name (e.g. 'A1'), a second cell name (e.g. 'B5'), and QItemSelectionModel.SelectionFlags"); + else + throw Base::TypeError("Wrong arguments to select: specify either a cell, or two cells (for a range), and QItemSelectionModel.SelectionFlags"); + } + return Py_None; +} + PyObject *ViewProviderSpreadsheetPy::getCustomAttributes(const char* /*attr*/) const { return nullptr;