Skip to content

Commit

Permalink
Extended Selection & Deletion of Path Points (#179)
Browse files Browse the repository at this point in the history
* Overload `RowRemovalOperation::RemoveRows` to accept a `QModelIndexList` of all selected rows.
* Set [QAbstractItemView::ExtendedSelection](https://doc.qt.io/qt-5/qabstractitemview.html#SelectionMode-enum) on Path editor points list view so we can select to delete many points at once. This does not change the fact that there is a current index inside the selection which has the focus if an edit is requested.
* Set [QAbstractItemView::SelectRows](https://doc.qt.io/qt-5/qabstractitemview.html#SelectionBehavior-enum) on Path editors points list view so we are actually selecting the entire point, which is similar to GM/LGM and feels less awkward. There is still a current index inside the selected row which has the focus if an edit is requested in a specific column item (aka the field).
* Use the new `RowRemovalOperation` overload to bulk delete all the selected points in the path editor. I used [QItemSelectionModel::selectedRows](https://doc.qt.io/qt-5/qitemselectionmodel.html#selectedRows) so that we only delete points where every column (aka the entire row) is selected. This should always be the case since I've also changed the selection behavior to select rows instead of items.
* Remove selection after setting the current index, which already does a correct selection. As I've stated, the current index resides in the selection and belongs to the selection model.
* Add clarifying comments to the selection update slot about interaction with the above changes.
* The selected indexes passed to selection change slot may be empty and yet there is still a selection and so enabling of the delete button now needs to check the global selection model of the points table to determine if anything is selected. It should also check if there are selected rows and not just selected items.
* The selected point in the preview area is now the last, most recently selected point in the global, cumulative list selection.
* Deleting a point now keeps the same row selected, unless the last point is being deleted. This is how GM and the main Qt examples work with as well. Bounds checking is done against the row count so when the last point is deleted we do go to the previous row.
  • Loading branch information
RobertBColton authored Sep 1, 2020
1 parent b2dba24 commit 33a6d74
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 17 deletions.
32 changes: 17 additions & 15 deletions Editors/PathEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,6 @@ void PathEditor::MousePressed(Qt::MouseButton button) {
if (pt == _ui->roomView->mousePos) {
QModelIndex newSelectIndex = _pointsModel->index(i, Path::Point::kXFieldNumber);
_ui->pointsTableView->setCurrentIndex(newSelectIndex);
_ui->pointsTableView->selectionModel()->select(newSelectIndex,
QItemSelectionModel::QItemSelectionModel::ClearAndSelect);
return;
}
}
Expand All @@ -212,12 +210,17 @@ void PathEditor::MouseReleased(Qt::MouseButton button) {
}
}

void PathEditor::UpdateSelection(const QItemSelection& selected, const QItemSelection& /*deselected*/) {
int selectIndex = -1;
if (!selected.indexes().empty()) selectIndex = selected.indexes()[0].row();
_ui->roomView->selectedPointIndex = selectIndex;
void PathEditor::UpdateSelection(const QItemSelection& /*selected*/, const QItemSelection& /*deselected*/) {
auto selectedPoints = _ui->pointsTableView->selectionModel()->selectedRows();
bool hasSelectedPoint = !selectedPoints.empty();
// delete button should be enabled if the cumulative selection is not empty
// and contains at least one selected row with every column selected
_ui->deletePointButton->setEnabled(hasSelectedPoint);
// keep most recently selected point selected in the preview
if (hasSelectedPoint)
_ui->roomView->selectedPointIndex = selectedPoints.last().row();
// update preview on point selection and deselection
_ui->pathPreviewBackground->update();
_ui->deletePointButton->setDisabled((selectIndex == -1));
}

void PathEditor::on_addPointButton_pressed() {
Expand All @@ -232,17 +235,16 @@ void PathEditor::on_insertPointButton_pressed() {

void PathEditor::on_deletePointButton_pressed() {
int deleteIndex = _ui->pointsTableView->selectionModel()->currentIndex().row();
{
RepeatedMessageModel::RowRemovalOperation remover(_pointsModel);
remover.RemoveRow(deleteIndex);
}
// this operation is temporary and will self destruct immediately removing the rows
RepeatedMessageModel::RowRemovalOperation(_pointsModel)
.RemoveRows(_ui->pointsTableView->selectionModel()->selectedRows());

if (_pointsModel->rowCount() > 0) {
QModelIndex newSelectIndex =
_pointsModel->index((deleteIndex == 0) ? 0 : deleteIndex - 1, Path::Point::kXFieldNumber);
auto rowCount = _ui->pointsTableView->model()->rowCount();
QModelIndex newSelectIndex = _pointsModel->index(
(deleteIndex >= rowCount) ? rowCount - 1 : deleteIndex,
Path::Point::kXFieldNumber);
_ui->pointsTableView->setCurrentIndex(newSelectIndex);
_ui->pointsTableView->selectionModel()->select(newSelectIndex,
QItemSelectionModel::QItemSelectionModel::ClearAndSelect);
} else {
_ui->deletePointButton->setDisabled(true);
_ui->pointsTableView->selectionModel()->clearSelection();
Expand Down
4 changes: 2 additions & 2 deletions Editors/PathEditor.ui
Original file line number Diff line number Diff line change
Expand Up @@ -513,10 +513,10 @@
<item>
<widget class="QTableView" name="pointsTableView">
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
Expand Down
4 changes: 4 additions & 0 deletions Models/RepeatedModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ class RepeatedModel : public ProtoModel {
void RemoveRows(int row, int count) {
for (int i = row; i < row + count; ++i) _rows.insert(i);
}
void RemoveRows(const QModelIndexList& indexes) {
foreach (auto index, indexes)
RemoveRow(index.row());
}

~RowRemovalOperation() {
if (_rows.empty()) return;
Expand Down

0 comments on commit 33a6d74

Please sign in to comment.