From dac9ac46f2a4b77a8307eebcca5a9d36353480b5 Mon Sep 17 00:00:00 2001 From: Bent Witthold Date: Sun, 15 Feb 2026 16:36:13 +0100 Subject: [PATCH] Added a ModelSummary class to make the overview over the model content accessible via QProperty system & a SummaryWidget to show this information. Only property rowCount as a proof of concept. Other properties will follow. --- UIs/BeetRoundWidgets/CMakeLists.txt | 1 + UIs/BeetRoundWidgets/mainwindow.cpp | 7 ++++ UIs/BeetRoundWidgets/mainwindow.h | 4 +++ .../widgets/summarywidget.cpp | 30 +++++++++++++++++ UIs/BeetRoundWidgets/widgets/summarywidget.h | 21 ++++++++++++ libs/BeetRoundCore/CMakeLists.txt | 1 + libs/BeetRoundCore/genericcore.cpp | 7 ++-- libs/BeetRoundCore/genericcore.h | 20 ++++++++---- libs/BeetRoundCore/model/modelsummary.cpp | 22 +++++++++++++ libs/BeetRoundCore/model/modelsummary.h | 32 +++++++++++++++++++ libs/BeetRoundCore/model/tablemodel.cpp | 15 ++++++++- libs/BeetRoundCore/model/tablemodel.h | 7 ++++ 12 files changed, 157 insertions(+), 10 deletions(-) create mode 100644 UIs/BeetRoundWidgets/widgets/summarywidget.cpp create mode 100644 UIs/BeetRoundWidgets/widgets/summarywidget.h create mode 100644 libs/BeetRoundCore/model/modelsummary.cpp create mode 100644 libs/BeetRoundCore/model/modelsummary.h diff --git a/UIs/BeetRoundWidgets/CMakeLists.txt b/UIs/BeetRoundWidgets/CMakeLists.txt index 1e558a0..49eaae5 100644 --- a/UIs/BeetRoundWidgets/CMakeLists.txt +++ b/UIs/BeetRoundWidgets/CMakeLists.txt @@ -37,6 +37,7 @@ if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) widgets/comboboxdelegate.h widgets/comboboxdelegate.cpp widgets/spinboxdelegate.h widgets/spinboxdelegate.cpp widgets/biddingroundcontrol.h widgets/biddingroundcontrol.cpp + widgets/summarywidget.h widgets/summarywidget.cpp ) # Define target properties for Android with Qt 6 as: # set_property(TARGET ${TARGET_APP} APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR diff --git a/UIs/BeetRoundWidgets/mainwindow.cpp b/UIs/BeetRoundWidgets/mainwindow.cpp index 1fb23d4..a042a03 100644 --- a/UIs/BeetRoundWidgets/mainwindow.cpp +++ b/UIs/BeetRoundWidgets/mainwindow.cpp @@ -16,10 +16,12 @@ #include "genericcore.h" #include "model/generalsortfiltermodel.h" #include "model/metadata.h" +#include "model/modelsummary.h" #include "model/tablemodel.h" #include "widgets/biddingroundcontrol.h" #include "widgets/comboboxdelegate.h" #include "widgets/spinboxdelegate.h" +#include "widgets/summarywidget.h" static int intColumnWidth = 30; @@ -349,6 +351,8 @@ void MainWindow::setupModelViews() { ui->tableView->setModel((QAbstractItemModel*)m_proxyModel.get()); ui->tableView->setSortingEnabled(true); ui->tableView->setColumnWidth(0, intColumnWidth); + + m_modelSummary = m_core->getModelSummary(); } void MainWindow::createActions() { @@ -554,5 +558,8 @@ void MainWindow::setupEventTab() { connect(m_core.get(), &GenericCore::currentBiddingRoundChanged, m_biddingRoundControl.get(), &BiddingRoundControl::onCurrentBiddingRoundChanged); + SummaryWidget* summaryWidget = new SummaryWidget(m_modelSummary, this); + containerLayout->addWidget(summaryWidget); + ui->tabWidget->insertTab(0, containerWidget, "Event (&1)"); } diff --git a/UIs/BeetRoundWidgets/mainwindow.h b/UIs/BeetRoundWidgets/mainwindow.h index 75f610d..2d081a7 100644 --- a/UIs/BeetRoundWidgets/mainwindow.h +++ b/UIs/BeetRoundWidgets/mainwindow.h @@ -17,6 +17,7 @@ QT_END_NAMESPACE class GenericCore; class TableModel; class GeneralSortFilterModel; +class ModelSummary; class NewItemDialog; class EditItemDialog; class BiddingRoundControl; @@ -73,9 +74,12 @@ class MainWindow : public QMainWindow { unique_ptr m_core; shared_ptr m_proxyModel; + shared_ptr m_modelSummary; + QUndoStack* m_modelUndoStack; unique_ptr m_modelUndoView; unique_ptr m_biddingRoundControl; + /// File actions unique_ptr m_newFileAct; unique_ptr m_openAct; diff --git a/UIs/BeetRoundWidgets/widgets/summarywidget.cpp b/UIs/BeetRoundWidgets/widgets/summarywidget.cpp new file mode 100644 index 0000000..bfe9904 --- /dev/null +++ b/UIs/BeetRoundWidgets/widgets/summarywidget.cpp @@ -0,0 +1,30 @@ +#include "summarywidget.h" + +#include +#include +#include + +#include + +SummaryWidget::SummaryWidget(std::shared_ptr modelSummary, QWidget* parent) + : QWidget{parent} + , m_modelSummary(modelSummary) { + QVBoxLayout* mainLayout = new QVBoxLayout(this); + + QProperty nRows(-1); + + QHBoxLayout* footerLayout = new QHBoxLayout(); + QLabel* rowCountLabel = new QLabel("Row count:"); + m_rowCoundValueLabel = new QLabel(QString::number(nRows)); + + QObject::connect(m_modelSummary.get(), &ModelSummary::rowCountChanged, [&]() { + m_rowCoundValueLabel->setText(QString::number(m_modelSummary->rowCount())); + }); + m_modelSummary->bindableRowCount().setBinding([&]() { return nRows.value(); }); + + footerLayout->addWidget(rowCountLabel); + footerLayout->addWidget(m_rowCoundValueLabel); + mainLayout->addLayout(footerLayout); + + setLayout(mainLayout); +} diff --git a/UIs/BeetRoundWidgets/widgets/summarywidget.h b/UIs/BeetRoundWidgets/widgets/summarywidget.h new file mode 100644 index 0000000..7d851d6 --- /dev/null +++ b/UIs/BeetRoundWidgets/widgets/summarywidget.h @@ -0,0 +1,21 @@ +#ifndef SUMMARYWIDGET_H +#define SUMMARYWIDGET_H + +#include + +class ModelSummary; +class QLabel; + +class SummaryWidget : public QWidget { + Q_OBJECT + + public: + explicit SummaryWidget(std::shared_ptr modelSummary, QWidget* parent = nullptr); + + private: + std::shared_ptr m_modelSummary; + + QLabel* m_rowCoundValueLabel; +}; + +#endif // SUMMARYWIDGET_H diff --git a/libs/BeetRoundCore/CMakeLists.txt b/libs/BeetRoundCore/CMakeLists.txt index fcda6a6..f852dd9 100644 --- a/libs/BeetRoundCore/CMakeLists.txt +++ b/libs/BeetRoundCore/CMakeLists.txt @@ -32,6 +32,7 @@ add_library(${TARGET_APP} STATIC model/tablemodel.h model/tablemodel.cpp model/modelitem.h model/modelitem.cpp model/generalsortfiltermodel.h model/generalsortfiltermodel.cpp + model/modelsummary.h model/modelsummary.cpp model/commands/insertrowscommand.h model/commands/insertrowscommand.cpp model/commands/removerowscommand.h model/commands/removerowscommand.cpp model/commands/edititemcommand.h model/commands/edititemcommand.cpp diff --git a/libs/BeetRoundCore/genericcore.cpp b/libs/BeetRoundCore/genericcore.cpp index 3942fc0..d4ba3d6 100644 --- a/libs/BeetRoundCore/genericcore.cpp +++ b/libs/BeetRoundCore/genericcore.cpp @@ -17,11 +17,10 @@ #include "data/settingshandler.h" #include "model/generalsortfiltermodel.h" #include "model/metadata.h" +#include "model/modelsummary.h" #include "model/tablemodel.h" #include "network/servercommunicator.h" -using namespace std; - GenericCore::GenericCore() { qDebug() << "Creating core..."; @@ -97,6 +96,8 @@ std::shared_ptr GenericCore::getSortFilterModel() const return m_sortFilterModel; } +shared_ptr GenericCore::getModelSummary() const { return m_modelSummary; } + /** * Save items to default file (in standard location). * @brief GenericCore::saveItems Saves item fo file. @@ -163,6 +164,8 @@ void GenericCore::setupModels() { m_mainModel = make_shared(m_modelUndoStack, this); m_sortFilterModel = make_shared(m_mainModel); + m_modelSummary = make_shared(m_mainModel, this); + /// QAbstractItemModelTester #ifdef QT_DEBUG m_mainModelTester = make_unique( diff --git a/libs/BeetRoundCore/genericcore.h b/libs/BeetRoundCore/genericcore.h index 9df744b..8751648 100644 --- a/libs/BeetRoundCore/genericcore.h +++ b/libs/BeetRoundCore/genericcore.h @@ -14,8 +14,11 @@ class QString; class TableModel; class GeneralSortFilterModel; +class ModelSummary; class ServerCommunicator; +using namespace std; + class GenericCore : public QObject { Q_OBJECT @@ -30,8 +33,10 @@ class GenericCore : public QObject { void triggerApplicationUpdate(const bool saveChanges); QUndoStack* getModelUndoStack() const; - std::shared_ptr getModel() const; - std::shared_ptr getSortFilterModel() const; + + shared_ptr getModel() const; + shared_ptr getSortFilterModel() const; + shared_ptr getModelSummary() const; void saveItems(); void importCSVFile(const QString& filePath); @@ -60,10 +65,11 @@ class GenericCore : public QObject { private: QUndoStack* m_modelUndoStack; - std::shared_ptr m_mainModel; - std::shared_ptr m_sortFilterModel; - std::unique_ptr m_mainModelTester; - std::unique_ptr m_proxyModelTester; + shared_ptr m_mainModel; + shared_ptr m_sortFilterModel; + shared_ptr m_modelSummary; + unique_ptr m_mainModelTester; + unique_ptr m_proxyModelTester; void setupModels(); void initModelData(); @@ -71,7 +77,7 @@ class GenericCore : public QObject { QString getMaintenanceToolFilePath() const; /// Network communication - std::unique_ptr m_serverCommunicator; + unique_ptr m_serverCommunicator; void setupServerConfiguration(); void applyServerConfiguration(); }; diff --git a/libs/BeetRoundCore/model/modelsummary.cpp b/libs/BeetRoundCore/model/modelsummary.cpp new file mode 100644 index 0000000..7be6e09 --- /dev/null +++ b/libs/BeetRoundCore/model/modelsummary.cpp @@ -0,0 +1,22 @@ +#include "modelsummary.h" + +#include "tablemodel.h" + +ModelSummary::ModelSummary(std::shared_ptr model, QObject* parent) + : QObject(parent) + , m_model(model) { + Q_ASSERT(model); + connect(m_model.get(), &TableModel::rowCountChanged, this, &ModelSummary::rowCountChanged); +} + +ModelSummary::~ModelSummary() {} + +int ModelSummary::rowCount() const { + const int nRows = m_model->rowCount(); + return nRows; +} + +QBindable ModelSummary::bindableRowCount() { + m_rowCount = m_model->rowCount(); + return &m_rowCount; +} diff --git a/libs/BeetRoundCore/model/modelsummary.h b/libs/BeetRoundCore/model/modelsummary.h new file mode 100644 index 0000000..4379c7f --- /dev/null +++ b/libs/BeetRoundCore/model/modelsummary.h @@ -0,0 +1,32 @@ +#ifndef MODELSUMMARY_H +#define MODELSUMMARY_H + +#include +#include + +class TableModel; + +using namespace std; + +class ModelSummary : public QObject { + Q_OBJECT + + Q_PROPERTY(int rowCount READ rowCount NOTIFY rowCountChanged BINDABLE bindableRowCount) + + public: + ModelSummary(shared_ptr model, QObject* parent = nullptr); + ~ModelSummary(); + + int rowCount() const; + QBindable bindableRowCount(); + + signals: + void rowCountChanged(); + + private: + shared_ptr m_model; + + Q_OBJECT_BINDABLE_PROPERTY(ModelSummary, int, m_rowCount, &ModelSummary::rowCountChanged); +}; + +#endif // MODELSUMMARY_H diff --git a/libs/BeetRoundCore/model/tablemodel.cpp b/libs/BeetRoundCore/model/tablemodel.cpp index 94f5334..d4f599a 100644 --- a/libs/BeetRoundCore/model/tablemodel.cpp +++ b/libs/BeetRoundCore/model/tablemodel.cpp @@ -46,7 +46,10 @@ QByteArray TableModel::generateExampleItems() { TableModel::TableModel(QUndoStack* undoStack, QObject* parent) : QAbstractTableModel{parent} - , m_undoStack(undoStack) {} + , m_undoStack(undoStack) { + connect(this, &TableModel::rowsInserted, this, &TableModel::onRowCountChanged); + connect(this, &TableModel::rowsRemoved, this, &TableModel::onRowCountChanged); +} Qt::ItemFlags TableModel::flags(const QModelIndex& index) const { if (!index.isValid()) { @@ -279,6 +282,16 @@ void TableModel::insertItems(int startPosition, m_undoStack->push(insertCommand); } +void TableModel::onRowCountChanged(const QModelIndex& parent, int first, int last) { + Q_UNUSED(first); + Q_UNUSED(last); + + if (parent != QModelIndex()) { + return; + } + emit rowCountChanged(); +} + void TableModel::execInsertItems(const int firstRow, const QList valueList) { const int nRows = valueList.size(); qDebug() << "Inserting" << nRows << "items..."; diff --git a/libs/BeetRoundCore/model/tablemodel.h b/libs/BeetRoundCore/model/tablemodel.h index a7d2089..5a11602 100644 --- a/libs/BeetRoundCore/model/tablemodel.h +++ b/libs/BeetRoundCore/model/tablemodel.h @@ -2,6 +2,7 @@ #define TABLEMODEL_H #include +#include "metadata.h" class QUndoStack; class ModelItem; @@ -55,6 +56,12 @@ class TableModel : public QAbstractTableModel { const QList& itemValuesList, const QModelIndex& parentIndex = QModelIndex()); + signals: + void rowCountChanged(); + + private slots: + void onRowCountChanged(const QModelIndex& parent, int first, int last); + private: /// *** members *** // TODO shared_ptr -> unique_ptr