From 993a0ebbe979e32d20c479648357dacc58ba97e6 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Mon, 13 Jun 2016 23:04:44 +0200 Subject: [PATCH] View / model fixes / improvements * allow upfront checking of formatter roles * selection mode menus adjusted (data approach no longer worked with CSlot) * removed unused style sheet parts * minor View/Model tweaks/formatting --- src/blackgui/data/qss/stdwidget.qss | 13 ------ src/blackgui/models/columnformatters.cpp | 14 +++++-- src/blackgui/models/columnformatters.h | 3 ++ src/blackgui/models/listmodelbase.cpp | 47 +++++++++++++--------- src/blackgui/models/listmodelbase.h | 14 ++++--- src/blackgui/models/listmodeldbobjects.cpp | 2 +- src/blackgui/views/viewbase.cpp | 41 ++++++++++--------- src/blackgui/views/viewbase.h | 8 +++- src/blackgui/views/viewdbobjects.h | 4 +- 9 files changed, 83 insertions(+), 63 deletions(-) diff --git a/src/blackgui/data/qss/stdwidget.qss b/src/blackgui/data/qss/stdwidget.qss index 48fdd2104..87710faab 100644 --- a/src/blackgui/data/qss/stdwidget.qss +++ b/src/blackgui/data/qss/stdwidget.qss @@ -110,19 +110,6 @@ BlackGui--CDropSite { margin: 2px; } -/* -QTableView[isShowingLoadIndicator="true"] { - background-image: url(:/preloaders/icons/preloaders/FillingRing64.gif); - background-repeat: no-repeat; - background-position: center; -} -QTableView[isShowingLoadIndicator="false"] { - background-image: url(:/own/icons/own/transparent1px.png); - background-repeat: no-repeat; - background-position: center; -} -*/ - /* Validator bar */ BlackGui--Editors--CValidationIndicator { background: black; /* background is background color here */ diff --git a/src/blackgui/models/columnformatters.cpp b/src/blackgui/models/columnformatters.cpp index ec953470c..d9ff50ca8 100644 --- a/src/blackgui/models/columnformatters.cpp +++ b/src/blackgui/models/columnformatters.cpp @@ -93,17 +93,25 @@ namespace BlackGui return CVariant::fromValue(static_cast(cs)); } + bool CDefaultFormatter::supportsRole(int role) const + { + // generally supported? + if (role == Qt::TextAlignmentRole || role == Qt::UserRole) { return true; } + + // specific? + return this->m_supportedRoles.contains(role); + } + CVariant CDefaultFormatter::data(int role, const CVariant &inputData) const { - Qt::ItemDataRole roleEnum = static_cast(role); + if (!this->supportsRole(role)) { return CVariant(); } + const Qt::ItemDataRole roleEnum = static_cast(role); // always supported if (roleEnum == Qt::TextAlignmentRole) return { alignmentRole() }; // check if (role == Qt::UserRole) { return CDefaultFormatter::displayRole(inputData); } // just as data provider - if (this->m_supportedRoles.isEmpty()) { return CVariant(); } - if (!this->m_supportedRoles.contains(role)) { return CVariant(); } switch (roleEnum) { case Qt::DisplayRole: diff --git a/src/blackgui/models/columnformatters.h b/src/blackgui/models/columnformatters.h index 1de2b044e..8ca7788f0 100644 --- a/src/blackgui/models/columnformatters.h +++ b/src/blackgui/models/columnformatters.h @@ -73,6 +73,9 @@ namespace BlackGui //! Alignment available? virtual bool hasAlignment() const { return m_alignment >= 0; } + //! Is given role supported by formatter + bool supportsRole(int role) const; + //! Receives CVariant of column data, and returns CVariant wrapping string, pixmap, or other values depending on role virtual BlackMisc::CVariant data(int role, const BlackMisc::CVariant &inputData) const; diff --git a/src/blackgui/models/listmodelbase.cpp b/src/blackgui/models/listmodelbase.cpp index 6b8560d08..848436aab 100644 --- a/src/blackgui/models/listmodelbase.cpp +++ b/src/blackgui/models/listmodelbase.cpp @@ -225,6 +225,13 @@ namespace BlackGui connect(this, &CListModelBaseNonTemplate::dataChanged, this, &CListModelBaseNonTemplate::ps_onDataChanged); } + bool CListModelBaseNonTemplate::isHoveredRow(const QModelIndex &modelIndex) const + { + if (this->m_hoverRow < 0) { return false; } + if (!modelIndex.isValid()) { return false; } + return modelIndex.row() == this->m_hoverRow; + } + template CListModelBase::CListModelBase(const QString &translationContext, QObject *parent) : CListModelBaseNonTemplate(translationContext, parent) @@ -282,12 +289,26 @@ namespace BlackGui { // check / init if (!this->isValidIndex(index)) { return QVariant(); } + + // Hover effect + if (role == Qt::BackgroundRole) + { + if (this->isHoveredRow(index)) + { + return QBrush(Qt::red); + } + return CListModelBaseNonTemplate::data(index, role); + } + + // Formatter const CDefaultFormatter *formatter = this->m_columns.getFormatter(index); Q_ASSERT_X(formatter, Q_FUNC_INFO, "Missing formatter"); - if (!formatter) { return QVariant(); } - //! Formatted data - ObjectType obj = this->containerOrFilteredContainer()[index.row()]; + // Upfront checking avoids unnecessary data fetching + if (!formatter || !formatter->supportsRole(role)) { return CListModelBaseNonTemplate::data(index, role); } + + // Formatted data + const ObjectType obj = this->containerOrFilteredContainer()[index.row()]; BlackMisc::CPropertyIndex propertyIndex = this->columnToPropertyIndex(index.column()); return formatter->data(role, obj.propertyByIndex(propertyIndex)).getQVariant(); } @@ -296,26 +317,14 @@ namespace BlackGui bool CListModelBase::setData(const QModelIndex &index, const QVariant &value, int role) { Qt::ItemDataRole dataRole = static_cast(role); - if (!(dataRole == Qt::UserRole || dataRole == Qt::EditRole)) - { - return false; - } + if (!(dataRole == Qt::UserRole || dataRole == Qt::EditRole)) { return false; } // check / init - if (!this->isValidIndex(index)) - { - return false; - } - if (!this->m_columns.isEditable(index)) - { - return false; - } + if (!this->isValidIndex(index)) { return false; } + if (!this->m_columns.isEditable(index)) { return false; } const CDefaultFormatter *formatter = this->m_columns.getFormatter(index); Q_ASSERT(formatter); - if (!formatter) - { - return false; - } + if (!formatter) { return false; } ObjectType obj = this->m_container[index.row()]; ObjectType currentObject(obj); diff --git a/src/blackgui/models/listmodelbase.h b/src/blackgui/models/listmodelbase.h index 4aa1800eb..eb805af07 100644 --- a/src/blackgui/models/listmodelbase.h +++ b/src/blackgui/models/listmodelbase.h @@ -161,11 +161,15 @@ namespace BlackGui //! Helper method with template free signature virtual int performUpdateContainer(const BlackMisc::CVariant &variant, bool sort) = 0; - CColumns m_columns; //!< columns metadata - int m_sortedColumn; //!< current sort column - bool m_modelDestroyed = false; //!< model is about to be destroyed - Qt::SortOrder m_sortOrder; //!< sort order (asc/desc) - Qt::DropActions m_dropActions = Qt::IgnoreAction; //!< drop actions + //! Row to be hovered? + bool isHoveredRow(const QModelIndex &modelIndex) const; + + CColumns m_columns; //!< columns metadata + int m_hoverRow = -1; //!< hovered row number + int m_sortedColumn; //!< currently sorted column + bool m_modelDestroyed = false; //!< model is about to be destroyed + Qt::SortOrder m_sortOrder; //!< sort order (asc/desc) + Qt::DropActions m_dropActions = Qt::IgnoreAction; //!< drop actions private: BlackMisc::CDigestSignal m_dsModelsChanged { this, &CListModelBaseNonTemplate::changed, &CListModelBaseNonTemplate::ps_onChangedDigest, 500, 10 }; diff --git a/src/blackgui/models/listmodeldbobjects.cpp b/src/blackgui/models/listmodeldbobjects.cpp index 8934d0d08..0cd36b1a1 100644 --- a/src/blackgui/models/listmodeldbobjects.cpp +++ b/src/blackgui/models/listmodeldbobjects.cpp @@ -40,7 +40,7 @@ namespace BlackGui if (isHighlightIndex(index)) { return QBrush(m_highlightColor); } if (!highlightDbData()) { return CListModelBase::data(index, role); } - ObjectType obj(this->at(index)); + const ObjectType obj(this->at(index)); // highlight DB models if (obj.hasValidDbKey()) { diff --git a/src/blackgui/views/viewbase.cpp b/src/blackgui/views/viewbase.cpp index 4dbfcb273..f31a0f3c2 100644 --- a/src/blackgui/views/viewbase.cpp +++ b/src/blackgui/views/viewbase.cpp @@ -303,20 +303,17 @@ namespace BlackGui { if (sm != MultiSelection) { - QAction *a = menuActions.addAction("Switch to multi selection", CMenuAction::pathViewSelection(), nullptr, { this, &CViewBaseNonTemplate::ps_toggleSelectionMode }); - a->setData(MultiSelection); + menuActions.addAction("Switch to multi selection", CMenuAction::pathViewSelection(), nullptr, { this, &CViewBaseNonTemplate::ps_setMultiSelection }); } if (sm != ExtendedSelection) { - QAction *a = menuActions.addAction("Switch to extended selection", CMenuAction::pathViewSelection(), nullptr, { this, &CViewBaseNonTemplate::ps_toggleSelectionMode }); - a->setData(ExtendedSelection); + menuActions.addAction("Switch to extended selection", CMenuAction::pathViewSelection(), nullptr, { this, &CViewBaseNonTemplate::ps_setExtendedSelection }); } if (sm != SingleSelection) { - QAction *a = menuActions.addAction("Switch to single selection", CMenuAction::pathViewSelection(), nullptr, { this, &CViewBaseNonTemplate::ps_toggleSelectionMode }); - a->setData(SingleSelection); + menuActions.addAction("Switch to single selection", CMenuAction::pathViewSelection(), nullptr, { this, &CViewBaseNonTemplate::ps_setSingleSelection }); } } @@ -628,20 +625,28 @@ namespace BlackGui this->m_displayAutomatically = a->isChecked(); } - void CViewBaseNonTemplate::ps_toggleSelectionMode() + + void CViewBaseNonTemplate::ps_setSingleSelection() { if (this->m_originalSelectionMode == ExtendedSelection || this->m_originalSelectionMode == MultiSelection) { - QAction *action = qobject_cast(sender()); - if (action && action->data().isValid() && action->data().canConvert()) - { - SelectionMode sm = static_cast(action->data().toInt()); - this->setSelectionMode(sm); - } - else - { - this->setSelectionMode(this->m_originalSelectionMode); - } + this->setSelectionMode(SingleSelection); + } + } + + void CViewBaseNonTemplate::ps_setExtendedSelection() + { + if (this->m_originalSelectionMode == ExtendedSelection || this->m_originalSelectionMode == MultiSelection) + { + this->setSelectionMode(ExtendedSelection); + } + } + + void CViewBaseNonTemplate::ps_setMultiSelection() + { + if (this->m_originalSelectionMode == ExtendedSelection || this->m_originalSelectionMode == MultiSelection) + { + this->setSelectionMode(MultiSelection); } } @@ -962,7 +967,7 @@ namespace BlackGui // see model for implementing logic of drag this->viewport()->setAcceptDrops(allowDrop); this->setDragEnabled(allowDrag); - this->setDropIndicatorShown(allowDrop); + this->setDropIndicatorShown(allowDrag || allowDrop); this->m_model->allowDrop(allowDrop); } diff --git a/src/blackgui/views/viewbase.h b/src/blackgui/views/viewbase.h index 8af56c7c1..6b2b9207a 100644 --- a/src/blackgui/views/viewbase.h +++ b/src/blackgui/views/viewbase.h @@ -437,8 +437,12 @@ namespace BlackGui //! Toggle auto display flag void ps_toggleAutoDisplay(); - //! Toogle between single and multi selection - void ps_toggleSelectionMode(); + //! \name Change selection modes + //! @{ + void ps_setMultiSelection(); + void ps_setExtendedSelection(); + void ps_setSingleSelection(); + //! @} //! Clear the model virtual void ps_clear() { this->clear(); } diff --git a/src/blackgui/views/viewdbobjects.h b/src/blackgui/views/viewdbobjects.h index f8dcaf28f..cb2fbb0ee 100644 --- a/src/blackgui/views/viewdbobjects.h +++ b/src/blackgui/views/viewdbobjects.h @@ -104,8 +104,8 @@ namespace BlackGui private: QList m_menuActions; - QLineEdit *m_leOrder = nullptr; - QFrame *m_frame = nullptr; + QLineEdit *m_leOrder = nullptr; + QFrame *m_frame = nullptr; QIntValidator *m_validator = nullptr; }; } // namespace