From 30b65d6c364bac5a7fcec6dbbe8a58586fa97e96 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sat, 23 Mar 2019 19:56:08 +0100 Subject: [PATCH] Fixed selection of view rows when changing to filtered data * return values for select functions * select function must be "public override" * reselect filtered data as well --- src/blackgui/models/listmodelbase.cpp | 15 ++++++++++++- src/blackgui/models/listmodelbase.h | 2 +- src/blackgui/views/viewbase.cpp | 2 +- src/blackgui/views/viewbase.h | 6 +++--- src/blackgui/views/viewbasenontemplate.cpp | 15 +++++++------ src/blackgui/views/viewdbobjects.cpp | 25 ++++++++++++++-------- src/blackgui/views/viewdbobjects.h | 16 +++++++++----- 7 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/blackgui/models/listmodelbase.cpp b/src/blackgui/models/listmodelbase.cpp index d6f86e2dc..d93788f2d 100644 --- a/src/blackgui/models/listmodelbase.cpp +++ b/src/blackgui/models/listmodelbase.cpp @@ -176,9 +176,10 @@ namespace BlackGui this->beginResetModel(); m_container = performSort ? sortedContainer : container; - this->updateFilteredContainer(); + this->updateFilteredContainer(); // use sorted container for filtered if applicable this->endResetModel(); + // reselect if implemented in specialized view if (!selection.isEmpty()) { m_selectionModel->selectObjects(selection); @@ -265,6 +266,12 @@ namespace BlackGui template void CListModelBase::takeFilterOwnership(std::unique_ptr > &filter) { + ContainerType selection; + if (m_selectionModel) + { + selection = m_selectionModel->selectedObjects(); + } + if (!filter) { this->removeFilter(); // clear filter @@ -283,6 +290,12 @@ namespace BlackGui // invalid filter, so clear filter this->removeFilter(); } + + // reselect if implemented in specialized views + if (!selection.isEmpty()) + { + m_selectionModel->selectObjects(selection); + } } template diff --git a/src/blackgui/models/listmodelbase.h b/src/blackgui/models/listmodelbase.h index 7721e0794..4763987db 100644 --- a/src/blackgui/models/listmodelbase.h +++ b/src/blackgui/models/listmodelbase.h @@ -138,8 +138,8 @@ namespace BlackGui int removeIf(K0 k0, V0 v0, KeysValues... keysValues) { int c = m_container.removeIf(BlackMisc::Predicates::MemberEqual(k0, v0, keysValues...)); - if (c > 0) { this->emitModelDataChanged();} this->updateFilteredContainer(); + if (c > 0) { this->emitModelDataChanged();} return c; } diff --git a/src/blackgui/views/viewbase.cpp b/src/blackgui/views/viewbase.cpp index b44decb24..fef285f1b 100644 --- a/src/blackgui/views/viewbase.cpp +++ b/src/blackgui/views/viewbase.cpp @@ -583,7 +583,7 @@ namespace BlackGui } m_model = model; - m_model->setSelectionModel(this); + m_model->setSelectionModel(this); // set myself as selection model bool c = connect(m_model, &ModelClass::modelDataChanged, this, &CViewBase::modelDataChanged); Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed"); c = connect(m_model, &ModelClass::modelDataChangedDigest, this, &CViewBase::modelDataChangedDigest); diff --git a/src/blackgui/views/viewbase.h b/src/blackgui/views/viewbase.h index e65763adb..133c46f15 100644 --- a/src/blackgui/views/viewbase.h +++ b/src/blackgui/views/viewbase.h @@ -232,7 +232,7 @@ namespace BlackGui virtual QModelIndexList unselectedRows() const; //! Select given rows - void selectRows(const QSet &rows); + int selectRows(const QSet &rows); //! Number of selected rows int selectedRowCount() const; @@ -725,7 +725,7 @@ namespace BlackGui virtual void sortByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder) override; virtual void setNoSorting() override { m_model->setNoSorting(); } virtual BlackMisc::CPropertyIndex getSortProperty() const override { return m_model->getSortProperty(); } - virtual int getSortColumn() const override { return m_model->getSortColumn(); } + virtual int getSortColumn() const override { return m_model->getSortColumn(); } virtual bool hasValidSortColumn() const override { return m_model->hasValidSortColumn(); } virtual Qt::SortOrder getSortOrder() const override { return m_model->getSortOrder(); } //! @} @@ -780,7 +780,7 @@ namespace BlackGui //! @{ virtual bool reachedResizeThreshold(int containrerSize = -1) const override; virtual void performModeBasedResizeToContent() override; - virtual int performUpdateContainer(const BlackMisc::CVariant &variant, bool sort, bool resize) override; + virtual int performUpdateContainer(const BlackMisc::CVariant &variant, bool sort, bool resize) override; virtual void updateSortIndicator() override; virtual void mouseOverCallback(const QModelIndex &index, bool mouseOver) override; virtual void drawDropIndicator(bool indicator) override; diff --git a/src/blackgui/views/viewbasenontemplate.cpp b/src/blackgui/views/viewbasenontemplate.cpp index 9e3c93a22..e12be56c6 100644 --- a/src/blackgui/views/viewbasenontemplate.cpp +++ b/src/blackgui/views/viewbasenontemplate.cpp @@ -144,10 +144,10 @@ namespace BlackGui this->setFilterWidgetImpl(filterWidget); if (filterWidget) { - bool s = connect(filterWidget, &CFilterWidget::changeFilter, this, &CViewBaseNonTemplate::filterWidgetChangedFilter); - Q_ASSERT_X(s, Q_FUNC_INFO, "filter connect"); - s = connect(this, &CViewBaseNonTemplate::modelDataChanged, filterWidget, &CFilterWidget::onRowCountChanged); - Q_ASSERT_X(s, Q_FUNC_INFO, "filter connect"); + bool s = connect(filterWidget, &CFilterWidget::changeFilter, this, &CViewBaseNonTemplate::filterWidgetChangedFilter, Qt::QueuedConnection); + Q_ASSERT_X(s, Q_FUNC_INFO, "filter connect changeFilter"); + s = connect(this, &CViewBaseNonTemplate::modelDataChanged, filterWidget, &CFilterWidget::onRowCountChanged, Qt::QueuedConnection); + Q_ASSERT_X(s, Q_FUNC_INFO, "filter connect modelDataChanged"); Q_UNUSED(s); } } @@ -490,11 +490,11 @@ namespace BlackGui return unselected; } - void CViewBaseNonTemplate::selectRows(const QSet &rows) + int CViewBaseNonTemplate::selectRows(const QSet &rows) { - if (!this->selectionModel()) { return; } + if (!this->selectionModel()) { return 0; } - // multiple times faster than multiple than this->selectRow() + // multiple times faster than multiple this->selectRow() this->clearSelection(); QItemSelection selectedItems; const int columns = this->model()->columnCount() - 1; @@ -503,6 +503,7 @@ namespace BlackGui selectedItems.select(this->model()->index(r, 0), this->model()->index(r, columns)); } this->selectionModel()->select(selectedItems, QItemSelectionModel::Select); + return selectedItems.size(); } int CViewBaseNonTemplate::selectedRowCount() const diff --git a/src/blackgui/views/viewdbobjects.cpp b/src/blackgui/views/viewdbobjects.cpp index 14115add1..88b470bec 100644 --- a/src/blackgui/views/viewdbobjects.cpp +++ b/src/blackgui/views/viewdbobjects.cpp @@ -60,16 +60,16 @@ namespace BlackGui } template - void CViewWithDbObjects::selectDbKey(const KeyType &key) + bool CViewWithDbObjects::selectDbKey(const KeyType &key) { const QSet set({key}); - this->selectDbKeys(set); + return this->selectDbKeys(set) > 0; } template - void CViewWithDbObjects::selectDbKeys(const QSet &keys) + int CViewWithDbObjects::selectDbKeys(const QSet &keys) { - if (keys.isEmpty()) { return; } + if (keys.isEmpty()) { return 0; } this->clearSelection(); int r = -1; QSet rows; @@ -82,7 +82,7 @@ namespace BlackGui rows.insert(r); } } - this->selectRows(rows); + return this->selectRows(rows); } template @@ -119,9 +119,17 @@ namespace BlackGui return c; } + template + void CViewWithDbObjects::selectObjects(const ContainerType &selectedObjects) + { + if (selectedObjects.isEmpty()) { return; } + this->selectDbKeys(selectedObjects.toDbKeySet()); + } + template void CViewWithDbObjects::customMenu(Menus::CMenuActions &menuActions) { + // extensions would go here CViewBase::customMenu(menuActions); } @@ -181,10 +189,8 @@ namespace BlackGui template void COrderableViewWithDbObjects::selectObjects(const ContainerType &selectedObjects) { - if (!selectedObjects.isEmpty()) - { - this->selectDbKeys(selectedObjects.toDbKeySet()); - } + if (selectedObjects.isEmpty()) { return; } + this->selectDbKeys(selectedObjects.toDbKeySet()); } template @@ -232,6 +238,7 @@ namespace BlackGui // see here for the reason of thess forward instantiations // https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl + template class CViewWithDbObjects; template class CViewWithDbObjects; template class CViewWithDbObjects; diff --git a/src/blackgui/views/viewdbobjects.h b/src/blackgui/views/viewdbobjects.h index 71fca07b4..3dbc26db6 100644 --- a/src/blackgui/views/viewdbobjects.h +++ b/src/blackgui/views/viewdbobjects.h @@ -52,10 +52,10 @@ namespace BlackGui ObjectType oldestObject() const; //! Select given DB key - void selectDbKey(const KeyType &key); + bool selectDbKey(const KeyType &key); //! Select given DB keys - void selectDbKeys(const QSet &keys); + int selectDbKeys(const QSet &keys); //! Get selected DB keys QSet selectedDbKeys() const; @@ -66,6 +66,9 @@ namespace BlackGui //! Update or insert data (based on DB key) int replaceOrAddObjectsByKey(const ContainerType &container); + //! Select by DB keys + virtual void selectObjects(const ContainerType &selectedObjects) override; + protected: //! Constructor explicit CViewWithDbObjects(QWidget *parent = nullptr); @@ -91,6 +94,9 @@ namespace BlackGui //! Model DB key type using KeyType = typename T::KeyType; + //! Select by DB keys + virtual void selectObjects(const ContainerType &selectedObjects) override; + protected: //! Constructor explicit COrderableViewWithDbObjects(QWidget *parent = nullptr); @@ -98,9 +104,6 @@ namespace BlackGui //! \copydoc BlackGui::Views::CViewBaseNonTemplate::customMenu virtual void customMenu(BlackGui::Menus::CMenuActions &menuActions) override; - //! Reselect by DB keys - virtual void selectObjects(const ContainerType &selectedObjects) override; - //! Move selected items void moveSelectedItems(int order); @@ -124,4 +127,7 @@ namespace BlackGui }; } // namespace } // namespace + +//! \endcond + #endif // guard