From ecb4694c7fa1ae44a5ddd93df2dd0136d95512db Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sun, 13 Dec 2015 19:31:52 +0100 Subject: [PATCH] refs #535, updated viewbase and formatters * Fixed wrong masking * changed signal for model * update selected models * directly set object in model --- src/blackgui/models/columnformatters.cpp | 3 +- src/blackgui/models/listmodelbase.cpp | 33 ++++++++++- src/blackgui/models/listmodelbase.h | 11 ++++ src/blackgui/views/viewbase.cpp | 74 +++++++++++++++++++++++- src/blackgui/views/viewbase.h | 6 ++ 5 files changed, 119 insertions(+), 8 deletions(-) diff --git a/src/blackgui/models/columnformatters.cpp b/src/blackgui/models/columnformatters.cpp index c2323b30b..02bb9b1d7 100644 --- a/src/blackgui/models/columnformatters.cpp +++ b/src/blackgui/models/columnformatters.cpp @@ -22,10 +22,9 @@ namespace BlackGui { namespace Models { - Qt::ItemFlags CDefaultFormatter::flags(Qt::ItemFlags flags, bool editable) const { - return editable ? (flags | Qt::ItemIsEditable) : (flags ^ Qt::ItemIsEditable); + return editable ? (flags | Qt::ItemIsEditable) : (flags & ~Qt::ItemIsEditable); } CVariant CDefaultFormatter::displayRole(const CVariant &dataCVariant) const diff --git a/src/blackgui/models/listmodelbase.cpp b/src/blackgui/models/listmodelbase.cpp index b80777e96..ef9070b2c 100644 --- a/src/blackgui/models/listmodelbase.cpp +++ b/src/blackgui/models/listmodelbase.cpp @@ -13,6 +13,7 @@ #include "listmodelbase.h" #include "allmodelcontainers.h" #include "blackgui/guiutility.h" +#include "blackmisc/verify.h" #include "blackmisc/variant.h" #include "blackmisc/json.h" #include "blackmisc/blackmiscfreefunctions.h" @@ -108,13 +109,13 @@ namespace BlackGui Qt::ItemFlags f = QStandardItemModel::flags(index); if (!index.isValid()) { return f; } bool editable = this->m_columns.isEditable(index); - f = editable ? (f | Qt::ItemIsEditable) : (f ^ Qt::ItemIsEditable); + f = editable ? (f | Qt::ItemIsEditable) : (f & ~Qt::ItemIsEditable); // flags from formatter const CDefaultFormatter *formatter = this->m_columns.getFormatter(index); if (formatter) { f = formatter->flags(f, editable); } - // drag and rop + // drag and drop f = f | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; return f; @@ -137,7 +138,7 @@ namespace BlackGui QStringList CListModelBaseNonTemplate::mimeTypes() const { - static const QStringList mimes( { "application/swift.container.json" }); + static const QStringList mimes({ "application/swift.container.json" }); return mimes; } @@ -151,6 +152,21 @@ namespace BlackGui return m_modelDestroyed; } + void CListModelBaseNonTemplate::sendDataChanged(int startRowIndex, int endRowIndex) + { + BLACK_VERIFY_X(startRowIndex <= endRowIndex, Q_FUNC_INFO, "check rows"); + BLACK_VERIFY_X(startRowIndex >= 0 && endRowIndex >= 0, Q_FUNC_INFO, "check rows"); + + int columns = columnCount(); + int rows = rowCount(); + if (columns < 1) { return; } + if (startRowIndex < 0) { startRowIndex = 0; } + if (endRowIndex >= rows) { endRowIndex = rows - 1; } + QModelIndex topLeft(createIndex(startRowIndex, 0)); + QModelIndex bottomRight(createIndex(endRowIndex, columns - 1)); + emit dataChanged(topLeft, bottomRight); + } + int CListModelBaseNonTemplate::ps_updateContainer(const CVariant &variant, bool sort) { return this->performUpdateContainer(variant, sort); @@ -242,6 +258,16 @@ namespace BlackGui return false; } + template + bool CListModelBase::setInContainer(const QModelIndex &index, const ObjectType &obj) + { + if (!index.isValid()) { return false; } + int row = index.row(); + if (row < 0 || row >= this->container().size()) { return false; } + m_container[row] = obj; + return true; + } + template int CListModelBase::update(const ContainerType &container, bool sort) { @@ -479,6 +505,7 @@ namespace BlackGui { int n = this->getContainerOrFilteredContainer().size(); emit this->rowCountChanged(n, this->hasFilter()); + emit this->changed(); } template diff --git a/src/blackgui/models/listmodelbase.h b/src/blackgui/models/listmodelbase.h index ef7ca1afa..a1f446445 100644 --- a/src/blackgui/models/listmodelbase.h +++ b/src/blackgui/models/listmodelbase.h @@ -96,6 +96,10 @@ namespace BlackGui //! Model about to be destroyed? bool isModelDestroyed(); + //! Send signal that data have been changed. + //! \note Meant for scenarios where the container is directly updated and a subsequent signal is required + void sendDataChanged(int startRowIndex, int endRowIndex); + signals: //! Asynchronous update finished void asyncUpdateFinished(); @@ -103,6 +107,9 @@ namespace BlackGui //! Number of elements changed void rowCountChanged(int count, bool withFilter); + //! Model has been changed + void changed(); + //! Template free information, that object changed void objectChanged(const BlackMisc::CVariant &object, const BlackMisc::CPropertyIndex &changedIndex); @@ -147,6 +154,10 @@ namespace BlackGui //! \sa CListModelBaseNonTemplate::flags virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + //! Simple set of data in container, using class is responsible for firing signals etc. + //! \sa sendDataChanged + bool setInContainer(const QModelIndex &index, const ObjectType &obj); + //! \copydoc QStandardItemModel::rowCount() virtual int rowCount(const QModelIndex &parentIndex = QModelIndex()) const override; diff --git a/src/blackgui/views/viewbase.cpp b/src/blackgui/views/viewbase.cpp index 6163b5306..25fee30a6 100644 --- a/src/blackgui/views/viewbase.cpp +++ b/src/blackgui/views/viewbase.cpp @@ -269,6 +269,41 @@ namespace BlackGui } } + QString CViewBaseNonTemplate::getDefaultFilename() const + { + // some logic to find a useful default name + QStringList pathes(QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation)); + QString name; + if (getDockWidgetInfoArea()) { name = getDockWidgetInfoArea()->windowTitle(); } + else if (!windowTitle().isEmpty()) { name = windowType(); } + else { name = this->metaObject()->className(); } + name += ".json"; + + if (!pathes.isEmpty()) + { + QString p(CFileUtils::appendFilePaths(pathes.first(), "swift/" + name)); + if (!QDir(p).exists()) + { + p = CFileUtils::appendFilePaths(pathes.first(), "swift " + name); + } + return p; + } + else + { + return name; + } + } + + void CViewBaseNonTemplate::menuRemoveItems(Menu menusToRemove) + { + this->m_menus &= (~menusToRemove); + } + + void CViewBaseNonTemplate::menuAddItems(Menu menusToAdd) + { + this->m_menus |= menusToAdd; + } + int CViewBaseNonTemplate::ps_updateContainer(const CVariant &variant, bool sort, bool resize) { return this->performUpdateContainer(variant, sort, resize); @@ -410,7 +445,10 @@ namespace BlackGui CViewBase::CViewBase(QWidget *parent, ModelClass *model) : CViewBaseNonTemplate(parent), m_model(model) { this->setSortingEnabled(true); - if (model) { this->setModel(this->m_model); } + if (model) + { + this->setModel(this->m_model); + } } template @@ -514,13 +552,42 @@ namespace BlackGui if (!this->hasSelection()) { return ContainerType(); } ContainerType c; QModelIndexList indexes = this->selectedRows(); - for (QModelIndex &i : indexes) + for (const QModelIndex &i : indexes) { c.push_back(this->at(i)); } return c; } + template + int CViewBase::updateSelected(const CVariant &variant, const CPropertyIndex &index) + { + if (!hasSelection()) { return 0; } + QModelIndexList indexes = this->selectedRows(); + int c = 0; + int lastRow = -1; + int firstRow = -1; + + for (const QModelIndex &i : indexes) + { + if (i.row() == lastRow) { continue; } + lastRow = i.row(); + if (firstRow < 0 || lastRow < firstRow) { firstRow = lastRow; } + ObjectType obj(this->at(i)); + obj.setPropertyByIndex(variant, index); + if (this->derivedModel()->setInContainer(i, obj)) + { + c++; + } + } + + if (c > 0) + { + this->derivedModel()->sendDataChanged(firstRow, lastRow); + } + return c; + } + template ObjectType CViewBase::selectedObject() const { @@ -617,12 +684,13 @@ namespace BlackGui template void CViewBase::standardInit(ModelClass *model) { - Q_ASSERT(model || this->m_model); + Q_ASSERT_X(model || this->m_model, Q_FUNC_INFO, "Missing model"); if (model) { this->m_model = model; connect(this->m_model, &ModelClass::rowCountChanged, this, &CViewBase::rowCountChanged); connect(this->m_model, &ModelClass::objectChanged, this, &CViewBase::objectChanged); + connect(this->m_model, &ModelClass::changed, this, &CViewBase::modelChanged); } this->setModel(this->m_model); // via QTableView diff --git a/src/blackgui/views/viewbase.h b/src/blackgui/views/viewbase.h index 881a6fccc..504a6b9f4 100644 --- a/src/blackgui/views/viewbase.h +++ b/src/blackgui/views/viewbase.h @@ -153,6 +153,9 @@ namespace BlackGui //! Number of elements changed void rowCountChanged(int count, bool withFilter); + // Model changed + void modelChanged(); + //! Single object was changed in model void objectChanged(const BlackMisc::CVariant &object, const BlackMisc::CPropertyIndex &changedIndex); @@ -321,6 +324,9 @@ namespace BlackGui //! Selected objects ContainerType selectedObjects() const; + //! Update selected objects + int updateSelected(const BlackMisc::CVariant &variant, const BlackMisc::CPropertyIndex &index); + //! Selected object (or default) ObjectType selectedObject() const;