From 97137c46a6ea768a860f8955839a4670770015cb Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sat, 17 Dec 2016 19:15:54 +0100 Subject: [PATCH] refs #785, use selection interface with views * adjusted sortByPropertyIndex, selectObjects * function to select by row numbers --- src/blackgui/views/viewbase.cpp | 49 ++++++++++------------------ src/blackgui/views/viewbase.h | 27 +++++++-------- src/blackgui/views/viewdbobjects.cpp | 6 ++-- src/blackgui/views/viewdbobjects.h | 2 +- 4 files changed, 36 insertions(+), 48 deletions(-) diff --git a/src/blackgui/views/viewbase.cpp b/src/blackgui/views/viewbase.cpp index 14a101231..6b82bbe44 100644 --- a/src/blackgui/views/viewbase.cpp +++ b/src/blackgui/views/viewbase.cpp @@ -403,6 +403,19 @@ namespace BlackGui return this->selectionModel()->selectedRows(); } + void CViewBaseNonTemplate::selectRows(const QSet &rows) + { + // Multi row selection only work in MultiSelection + this->clearSelection(); + const SelectionMode m = this->selectionMode(); + this->setSelectionMode(MultiSelection); + for (int r : rows) + { + this->selectRow(r); + } + this->setSelectionMode(m); + } + int CViewBaseNonTemplate::selectedRowCount() const { if (!this->hasSelection()) { return 0;} @@ -778,9 +791,7 @@ namespace BlackGui } } - const ContainerType selected(this->selectedObjects()); const int c = this->m_model->update(container, sort); - this->reselect(selected); // resize after real update according to mode if (presizeThresholdReached) @@ -1104,27 +1115,9 @@ namespace BlackGui } template - void CViewBase::sortByPropertyIndex(const CPropertyIndex &propertyIndex, Qt::SortOrder order, bool reselect) + void CViewBase::sortByPropertyIndex(const CPropertyIndex &propertyIndex, Qt::SortOrder order) { - if (!reselect) - { - this->m_model->sortByPropertyIndex(propertyIndex, order); - } - else - { - // hack: we reselect the already selected objects - // as sorting takes place (sync/async) in the model, and the model does not know about the selection - // we do this deferred as the model sort can be asynchronously - const ContainerType selected(this->selectedObjects()); - this->m_model->sortByPropertyIndex(propertyIndex, order); - if (!selected.isEmpty()) - { - QTimer::singleShot(2000, [ = ]() - { - this->reselect(selected); - }); - } - } + this->m_model->sortByPropertyIndex(propertyIndex, order); } template @@ -1211,6 +1204,7 @@ namespace BlackGui } this->m_model = model; + this->m_model->setSelectionModel(this); bool c = connect(this->m_model, &ModelClass::modelDataChanged, this, &CViewBase::modelDataChanged); Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed"); c = connect(this->m_model, &ModelClass::objectChanged, this, &CViewBase::objectChanged); @@ -1219,8 +1213,6 @@ namespace BlackGui Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed"); c = connect(this->m_model, &ModelClass::changed, this, &CViewBase::onModelChanged); Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed"); - - Q_UNUSED(c); } @@ -1284,7 +1276,7 @@ namespace BlackGui } template - void CViewBase::reselect(const ContainerType &selectedObjects) + void CViewBase::selectObjects(const ContainerType &selectedObjects) { Q_UNUSED(selectedObjects); } @@ -1367,13 +1359,6 @@ namespace BlackGui } } - template - void CViewBase::ps_selectedObjectsLoopback(const CVariant &selectedObjects) - { - const ContainerType selectedObjs = selectedObjects.value(); - this->reselect(selectedObjs); - } - template bool CViewBase::ps_filterDialogFinished(int status) { diff --git a/src/blackgui/views/viewbase.h b/src/blackgui/views/viewbase.h index fe13c1a10..bd10cf60e 100644 --- a/src/blackgui/views/viewbase.h +++ b/src/blackgui/views/viewbase.h @@ -15,6 +15,7 @@ #include "blackgui/components/enablefordockwidgetinfoarea.h" #include "blackgui/menus/menuaction.h" #include "blackgui/models/modelfilter.h" +#include "blackgui/models/selectionmodel.h" #include "blackgui/settings/guisettings.h" #include "blackgui/blackguiexport.h" #include "blackmisc/namevariantpairlist.h" @@ -147,7 +148,7 @@ namespace BlackGui virtual void setSorting(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder) = 0; //! Sort by index - virtual void sortByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder, bool reselect = false) = 0; + virtual void sortByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder) = 0; //! Allow to drag and/or drop value objects virtual void allowDragDrop(bool allowDrag, bool allowDrop) = 0; @@ -188,6 +189,9 @@ namespace BlackGui //! Selected rows if any QModelIndexList selectedRows() const; + //! Select given rows + void selectRows(const QSet &rows); + //! Number of selected rows int selectedRowCount() const; @@ -412,9 +416,6 @@ namespace BlackGui //! Helper method with template free signature serving as callback from threaded worker int ps_updateContainer(const BlackMisc::CVariant &variant, bool sort, bool resize); - //! Helper method with template free signature to allow reselection of objects - virtual void ps_selectedObjectsLoopback(const BlackMisc::CVariant &selectedObjects) = 0; - //! Display the filter dialog void ps_displayFilterDialog(); @@ -494,7 +495,9 @@ namespace BlackGui Q_DECLARE_OPERATORS_FOR_FLAGS(BlackGui::Views::CViewBaseNonTemplate::Menu) //! Base class for views - template class CViewBase : public CViewBaseNonTemplate + template class CViewBase : + public CViewBaseNonTemplate, + public BlackGui::Models::ISelectionModel { // I cannot use Q_OBJECT here, because of error: Template classes not supported by Q_OBJECT // Cannot declare slots as SLOT because I have no Q_OBJECT macro @@ -534,8 +537,11 @@ namespace BlackGui //! \copydoc BlackGui::Models::CListModelBase::containerOrFilteredContainer const ContainerType &containerOrFilteredContainer() const; - //! Selected objects - ContainerType selectedObjects() const; + //! \name Selection model interface + //! @{ + virtual void selectObjects(const ContainerType &selectedObjects) override; + virtual ContainerType selectedObjects() const override; + //! @} //! First selected, the only one, or default ObjectType firstSelectedOrDefaultObject() const; @@ -588,7 +594,7 @@ namespace BlackGui virtual bool isDropAllowed() const override; virtual bool acceptDrop(const QMimeData *mimeData) const override; virtual void setSorting(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder) override; - virtual void sortByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder, bool reselect = false) override; + virtual void sortByPropertyIndex(const BlackMisc::CPropertyIndex &propertyIndex, Qt::SortOrder order = Qt::AscendingOrder) override; //! @} //! Column count @@ -643,10 +649,6 @@ namespace BlackGui virtual void drawDropIndicator(bool indicator) override; //! @} - //! Reselect given objects - //! \remark override this function to select models again - virtual void reselect(const ContainerType &selectedObjects); - //! Modify JSON data loaded in BlackGui::Views::CViewBaseNonTemplate::ps_loadJson virtual BlackMisc::CStatusMessage modifyLoadedJsonData(ContainerType &data) const; @@ -669,7 +671,6 @@ namespace BlackGui virtual void ps_rowSelected(const QModelIndex &index) override; virtual BlackMisc::CStatusMessage ps_loadJson() override; virtual BlackMisc::CStatusMessage ps_saveJson() const override; - virtual void ps_selectedObjectsLoopback(const BlackMisc::CVariant &selectedObjects) override; //! @} }; } // namespace diff --git a/src/blackgui/views/viewdbobjects.cpp b/src/blackgui/views/viewdbobjects.cpp index b6a212721..ee92dd631 100644 --- a/src/blackgui/views/viewdbobjects.cpp +++ b/src/blackgui/views/viewdbobjects.cpp @@ -59,15 +59,17 @@ namespace BlackGui if (keys.isEmpty()) { return; } this->clearSelection(); int r = -1; + QSet rows; for (const ObjectType &obj : CViewBase::containerOrFilteredContainer()) { r++; if (!obj.hasValidDbKey()) { continue; } if (keys.contains(obj.getDbKey())) { - this->selectRow(r); + rows.insert(r); } } + this->selectRows(rows); } template @@ -164,7 +166,7 @@ namespace BlackGui } template - void COrderableViewWithDbObjects::reselect(const ContainerType &selectedObjects) + void COrderableViewWithDbObjects::selectObjects(const ContainerType &selectedObjects) { if (!selectedObjects.isEmpty()) { diff --git a/src/blackgui/views/viewdbobjects.h b/src/blackgui/views/viewdbobjects.h index 903e8b7cb..6e3a5858a 100644 --- a/src/blackgui/views/viewdbobjects.h +++ b/src/blackgui/views/viewdbobjects.h @@ -88,7 +88,7 @@ namespace BlackGui virtual void customMenu(BlackGui::Menus::CMenuActions &menuActions) override; //! Reselect by DB keys - virtual void reselect(const ContainerType &selectedObjects) override; + virtual void selectObjects(const ContainerType &selectedObjects) override; //! Move selected items void moveSelectedItems(int order);