فهرست منبع

Models registry was added

Denis V. Dedkov 2 سال پیش
والد
کامیت
4ed4ecd429

+ 1 - 1
CMakeLists.txt

@@ -18,7 +18,6 @@ set(PROJECT_SOURCES
         main.cpp
         qml/qml.qrc
         models/basemodel.h models/basemodel.cpp
-        models/ordersmodel.h models/ordersmodel.cpp
         models/usersmodel.h models/usersmodel.cpp
         viewmodels/usersviewmodel.h viewmodels/usersviewmodel.cpp
         viewmodels/storesviewmodel.h viewmodels/storesviewmodel.cpp
@@ -27,6 +26,7 @@ set(PROJECT_SOURCES
         viewmodels/settingsviewmodel.h viewmodels/settingsviewmodel.cpp
         services/beerservice.h services/beerservice.cpp
         services/settingsservice.h services/settingsservice.cpp
+        services/modelsregister.h services/modelsregister.cpp
         ${TS_FILES}
 )
 

+ 5 - 0
main.cpp

@@ -5,6 +5,8 @@
 #include <QTranslator>
 #include <QQmlContext>
 
+#include "models/usersmodel.h"
+
 #include "viewmodels/usersviewmodel.h"
 #include "viewmodels/productsviewmodel.h"
 #include "viewmodels/ordersviewmodel.h"
@@ -13,6 +15,7 @@
 
 #include "services/beerservice.h"
 #include "services/settingsservice.h"
+#include "services/modelsregister.h"
 
 int main(int argc, char *argv[])
 {
@@ -41,6 +44,8 @@ int main(int argc, char *argv[])
 
     engine.addImportPath("qrc:/");
 
+    ModelsRegister::registerModel(new UsersModel());
+
     engine.rootContext()->setContextProperty("beerService", BeerService::instance());
     engine.rootContext()->setContextProperty("settingsService", SettingsService::instance());
 

+ 0 - 15
models/ordersmodel.cpp

@@ -1,15 +0,0 @@
-#include "ordersmodel.h"
-
-OrdersModel::OrdersModel(QObject *parent) : BaseModel { "orders", parent }
-{
-}
-
-QVariantList OrdersModel::orders() const
-{
-    return items();
-}
-
-void OrdersModel::submitOrder(const QVariantMap &order) const
-{
-    addItem(order);
-}

+ 0 - 17
models/ordersmodel.h

@@ -1,17 +0,0 @@
-#ifndef ORDERSMODEL_H
-#define ORDERSMODEL_H
-
-#include "basemodel.h"
-
-class OrdersModel : public BaseModel
-{
-    Q_OBJECT
-
-public:
-    explicit OrdersModel(QObject *parent = nullptr);
-
-    QVariantList orders() const;
-    void submitOrder(const QVariantMap &order) const;
-};
-
-#endif // ORDERSMODEL_H

+ 16 - 10
qml/Views/SettingsView.qml

@@ -26,13 +26,23 @@ Page {
             width: parent.width
 
             text: model.title
-            subtitle: settingsService[model.name]
+            subtitle: model.subtitle || ""
+
+            function valueAccepted() {
+                model.value = editor.value
+            }
+
+            function disconnectDialog() {
+                inputDialog.accepted.disconnect(valueAccepted)
+            }
 
             onClicked: {
                 inputDialog.title = model.title
-                inputDialog.name = model.name
                 inputDialog.control = controls[model.control]
+                inputDialog.initialValue = model.value
                 inputDialog.choiceModel = model.choiceModel
+                inputDialog.accepted.connect(valueAccepted)
+                inputDialog.closed.connect(disconnectDialog)
                 inputDialog.open()
             }
         }
@@ -41,8 +51,8 @@ Page {
     Dialog {
         id: inputDialog
 
-        property string name: ""
         property var choiceModel: undefined
+        property var initialValue: undefined
         property alias control: editor.sourceComponent
 
         width: root.width * 0.8
@@ -60,10 +70,6 @@ Page {
 
             anchors.fill: parent
         }
-
-        onAccepted: {
-            settingsService[inputDialog.name] = editor.value
-        }
     }
 
     Component {
@@ -72,10 +78,10 @@ Page {
         TextField {
             id: textField
 
-            property alias value: textField.text
+            property string value: text
 
             inputMethodHints: Qt.ImhNoAutoUppercase
-            text: settingsService[inputDialog.name] || ""
+            text: inputDialog.initialValue || ""
         }
     }
 
@@ -97,7 +103,7 @@ Page {
                     property var valueId: modelData.id
                     text: modelData.name
                     width: parent.width
-                    checked: settingsService[inputDialog.name] === valueId
+                    checked: inputDialog.initialValue === valueId
                     ButtonGroup.group: group
                 }
             }

+ 23 - 0
services/modelsregister.cpp

@@ -0,0 +1,23 @@
+#include "modelsregister.h"
+
+#include "models/basemodel.h"
+
+void ModelsRegister::registerModel(BaseModel *model)
+{
+    Q_ASSERT(model != nullptr);
+
+    model->setParent(&instance()->m_parent);
+
+    instance()->m_models[model->entity()] = model;
+}
+
+BaseModel *ModelsRegister::model(const QString &name)
+{
+    Q_ASSERT(!name.isEmpty());
+
+    if (!instance()->m_models.contains(name)) {
+        registerModel(new BaseModel(name, &instance()->m_parent));
+    }
+
+    return instance()->m_models.value(name);
+}

+ 28 - 0
services/modelsregister.h

@@ -0,0 +1,28 @@
+#ifndef MODELSREGISTER_H
+#define MODELSREGISTER_H
+
+#include <QMap>
+#include <QObject>
+
+class BaseModel;
+class ModelsRegister
+{
+public:
+    static ModelsRegister *instance()
+    {
+        static ModelsRegister i;
+        return &i;
+    }
+
+    static void registerModel(BaseModel *model);
+    static BaseModel *model(const QString &name);
+
+private:
+    ModelsRegister() = default;
+    ~ModelsRegister() = default;
+
+    QObject m_parent;
+    QMap<QString, BaseModel *> m_models;
+};
+
+#endif // MODELSREGISTER_H

+ 11 - 9
viewmodels/ordersviewmodel.cpp

@@ -2,13 +2,15 @@
 
 #include <QDateTime>
 
+#include "models/basemodel.h"
+
 OrdersViewModel::OrdersViewModel(QObject *parent)
     : QAbstractListModel{parent}
 {
-    connect(&m_ordersModel, &BaseModel::dataChanged, this, &OrdersViewModel::reload);
-    connect(&m_usersModel, &BaseModel::dataChanged, this, &OrdersViewModel::reload);
-    connect(&m_productsModel, &BaseModel::dataChanged, this, &OrdersViewModel::reload);
-    connect(&m_storesModel, &BaseModel::dataChanged, this, &OrdersViewModel::reload);
+    connect(m_ordersModel, &BaseModel::dataChanged, this, &OrdersViewModel::reload);
+    connect(m_usersModel, &BaseModel::dataChanged, this, &OrdersViewModel::reload);
+    connect(m_productsModel, &BaseModel::dataChanged, this, &OrdersViewModel::reload);
+    connect(m_storesModel, &BaseModel::dataChanged, this, &OrdersViewModel::reload);
 
     reload();
 }
@@ -45,18 +47,18 @@ void OrdersViewModel::reload()
 
     m_model.clear();
 
-    for (const QVariant &vOrder : m_ordersModel.orders()) {
+    for (const QVariant &vOrder : m_ordersModel->items()) {
         QVariantMap order = vOrder.toMap();
         QDateTime orderTime = QDateTime::fromSecsSinceEpoch(order.value("ts", 0).toDouble());
         order["date"] = orderTime.date();
         order["time"] = orderTime.time();
-        order["userName"] = m_usersModel.itemProperty(order["userId"].toString(), "name").toString();
-        order["storeName"] = m_storesModel.itemProperty(order["storeId"].toString(), "name").toString();
+        order["userName"] = m_usersModel->itemProperty(order["userId"].toString(), "name").toString();
+        order["storeName"] = m_storesModel->itemProperty(order["storeId"].toString(), "name").toString();
 
         QVariantList prodModel;
         for (const QVariant &prod : order["products"].toList()) {
             QVariantMap product = prod.toMap();
-            product["product"] = m_productsModel.itemProperty(product.value("productId").toString(), "name");
+            product["product"] = m_productsModel->itemProperty(product.value("productId").toString(), "name");
             prodModel << product;
         }
         order["products"] = prodModel;
@@ -64,7 +66,7 @@ void OrdersViewModel::reload()
         m_model << order;
     }
 
-    std::sort(m_model.begin(), m_model.end(), [](const QVariant &l, const QVariant &r) {
+    std::sort(m_model.begin(), m_model.end(), [](const QVariant &l, const QVariant &r) -> bool {
         return l.toMap().value("ts").toDouble() < r.toMap().value("ts").toDouble();
     });
 

+ 5 - 6
viewmodels/ordersviewmodel.h

@@ -3,8 +3,7 @@
 
 #include <QAbstractListModel>
 
-#include "models/ordersmodel.h"
-#include "models/usersmodel.h"
+#include "services/modelsregister.h"
 
 class OrdersViewModel : public QAbstractListModel
 {
@@ -32,10 +31,10 @@ private:
 
     void reload();
 
-    OrdersModel m_ordersModel;
-    UsersModel m_usersModel;
-    BaseModel m_productsModel = BaseModel("products", this);
-    BaseModel m_storesModel = BaseModel("stores", this);
+    BaseModel *m_ordersModel = ModelsRegister::model("orders");
+    BaseModel *m_usersModel = ModelsRegister::model("users");
+    BaseModel *m_productsModel = ModelsRegister::model("products");
+    BaseModel *m_storesModel = ModelsRegister::model("stores");
 
     QVariantList m_model;
 };

+ 8 - 8
viewmodels/productsviewmodel.cpp

@@ -1,17 +1,17 @@
 #include "productsviewmodel.h"
 
+#include "models/basemodel.h"
 #include "services/settingsservice.h"
-#include "models/ordersmodel.h"
 
 ProductsViewModel::ProductsViewModel(QObject *parent)
     : QObject{parent}
 {
-    connect(&m_productsModel, &BaseModel::dataChanged, this, &ProductsViewModel::productsChanged);
+    connect(m_productsModel, &BaseModel::dataChanged, this, &ProductsViewModel::productsChanged);
 }
 
 QVariantList ProductsViewModel::products() const
 {
-    return m_productsModel.items();
+    return m_productsModel->items();
 }
 
 QVariantList ProductsViewModel::order() const
@@ -19,7 +19,7 @@ QVariantList ProductsViewModel::order() const
     QVariantList res;
 
     for (auto it = m_order.constBegin(); it != m_order.constEnd(); ++it) {
-        QVariantMap product = m_productsModel.item(it.key());
+        QVariantMap product = m_productsModel->item(it.key());
         product["count"] = it.value().toMap().value("quantity").toDouble();
         res << product;
     }
@@ -32,7 +32,7 @@ float ProductsViewModel::orderSum() const
     float res = 0.0;
 
     for (auto it = m_order.constBegin(); it != m_order.constEnd(); ++it) {
-        QVariantMap product = m_productsModel.item(it.key());
+        QVariantMap product = m_productsModel->item(it.key());
         float price = product.value("price", 0.0).toFloat();
         float quantity = it.value().toMap().value("quantity").toDouble();
         res += quantity * price;
@@ -44,7 +44,7 @@ float ProductsViewModel::orderSum() const
 void ProductsViewModel::setOrderValue(const QString &productId, float value)
 {
     if (value) {
-        float price = m_productsModel.itemProperty(productId, "price", 0.0).toFloat();
+        float price = m_productsModel->itemProperty(productId, "price", 0.0).toFloat();
         m_order[productId] = QVariantMap {
             { "productId", productId },
             { "quantity", value},
@@ -59,8 +59,8 @@ void ProductsViewModel::setOrderValue(const QString &productId, float value)
 
 void ProductsViewModel::submitOrder()
 {
-    OrdersModel model;
-    model.submitOrder(QVariantMap {
+    BaseModel *ordersModel = ModelsRegister::model("orders");
+    ordersModel->addItem({
         { "userId", settings()->selectedUserId() },
         { "storeId", settings()->selectedStoreId() },
         { "products", m_order.values() },

+ 3 - 2
viewmodels/productsviewmodel.h

@@ -2,8 +2,9 @@
 #define PRODUCTSVIEWMODEL_H
 
 #include <QObject>
+#include <QVariantMap>
 
-#include "models/basemodel.h"
+#include "services/modelsregister.h"
 
 class SettingsService;
 class ProductsViewModel : public QObject
@@ -31,7 +32,7 @@ signals:
 private:
     SettingsService *settings() const;
 
-    BaseModel m_productsModel = BaseModel("products", this);
+    BaseModel *m_productsModel = ModelsRegister::model("products");
     QVariantMap m_order;
 };
 

+ 61 - 7
viewmodels/settingsviewmodel.cpp

@@ -1,5 +1,10 @@
 #include "settingsviewmodel.h"
 
+#include "services/modelsregister.h"
+#include "services/settingsservice.h"
+
+#include "models/basemodel.h"
+
 SettingsViewModel::SettingsViewModel(QObject *parent)
     : QAbstractListModel{parent}
 {
@@ -7,10 +12,16 @@ SettingsViewModel::SettingsViewModel(QObject *parent)
             << SettingItem { tr("Selected user id"), "selectedUserId", "choice", "users" }
             << SettingItem { tr("Selected store"), "selectedStoreId", "choice", "stores" };
 
-    m_models["users"] = new BaseModel("users", this);
-    m_models["stores"] = new BaseModel("stores", this);
-}
+    QModelIndex selectedUserIdIndex = index(1);
+    QModelIndex selectedStoreIdIndex = index(2);
 
+    connect(settings(), &SettingsService::selectedUserIdChanged, this, [this, selectedUserIdIndex]() {
+        emit dataChanged(selectedUserIdIndex, selectedUserIdIndex);
+    });
+    connect(settings(), &SettingsService::selectedStoreIdChanged, this, [this, selectedStoreIdIndex]() {
+        emit dataChanged(selectedStoreIdIndex, selectedStoreIdIndex);
+    });
+}
 
 int SettingsViewModel::rowCount(const QModelIndex &) const
 {
@@ -27,7 +38,8 @@ QVariant SettingsViewModel::data(const QModelIndex &index, int role) const
 
     switch (role) {
     case Roles::Title: return item.title;
-    case Roles::PropertyName: return item.propertyName;
+    case Roles::Subtitle: return subtitle(item.propertyName, item.modelName);
+    case Roles::Value: return settings()->property(item.propertyName.toLocal8Bit());
     case Roles::ControlType: return item.controlType;
     case Roles::Model: return model(item.modelName);
     default:
@@ -41,17 +53,59 @@ QHash<int, QByteArray> SettingsViewModel::roleNames() const
 {
     return QHash<int, QByteArray> {
         { Roles::Title, "title" },
-        { Roles::PropertyName, "name" },
+        { Roles::Subtitle, "subtitle" },
+        { Roles::Value, "value" },
         { Roles::ControlType, "control" },
         { Roles::Model, "choiceModel" }
     };
 }
 
+bool SettingsViewModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+    if (!index.isValid()) {
+        return false;
+    }
+
+    if (Roles::Value != role) {
+        return false;
+    }
+
+    SettingItem item = m_items.at(index.row());
+    bool res = settings()->setProperty(item.propertyName.toLocal8Bit(), value);
+    if (res) {
+        emit dataChanged(index, index);
+    }
+
+    return res;
+}
+
+Qt::ItemFlags SettingsViewModel::flags(const QModelIndex &index) const
+{
+    return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
+}
+
+SettingsService *SettingsViewModel::settings() const
+{
+    return SettingsService::instance();
+}
+
 QVariant SettingsViewModel::model(const QString &modelName) const
 {
-    if (!m_models.contains(modelName)) {
+    BaseModel *model = modelName.isEmpty() ? nullptr : ModelsRegister::model(modelName);
+    if (!model) {
         return {};
     }
 
-    return m_models[modelName]->items();
+    return model->items();
+}
+
+QVariant SettingsViewModel::subtitle(const QString &propertyName, const QString &modelName) const
+{
+    BaseModel *model = modelName.isEmpty() ? nullptr : ModelsRegister::model(modelName);
+    QVariant propertyValue = settings()->property(propertyName.toLocal8Bit());
+    if (model) {
+        return model->itemProperty(propertyValue.toString(), "name");
+    }
+
+    return propertyValue;
 }

+ 8 - 4
viewmodels/settingsviewmodel.h

@@ -3,8 +3,7 @@
 
 #include <QAbstractListModel>
 
-#include "models/basemodel.h"
-
+class SettingsService;
 class SettingsViewModel : public QAbstractListModel
 {
     Q_OBJECT
@@ -16,10 +15,14 @@ public:
     QVariant data(const QModelIndex &index, int role) const override;
     QHash<int, QByteArray> roleNames() const override;
 
+    bool setData(const QModelIndex &index, const QVariant &value, int role) override;
+    Qt::ItemFlags flags(const QModelIndex &index) const override;
+
 private:
     enum Roles {
         Title = Qt::UserRole + 1,
-        PropertyName,
+        Subtitle,
+        Value,
         ControlType,
         Model
     };
@@ -38,10 +41,11 @@ private:
             modelName(modelName) {}
     };
 
+    SettingsService *settings() const;
     QVariant model(const QString &modelName) const;
+    QVariant subtitle(const QString &propertyName, const QString &modelName) const;
 
     QList<SettingItem> m_items;
-    QMap<QString, BaseModel *> m_models;
 };
 
 #endif // SETTINGSVIEWMODEL_H

+ 5 - 4
viewmodels/storesviewmodel.cpp

@@ -1,12 +1,13 @@
 #include "storesviewmodel.h"
 
+#include "models/basemodel.h"
 #include "services/settingsservice.h"
 
 StoresViewModel::StoresViewModel(QObject *parent)
     : QObject{parent}
 {
-    connect(&m_storesModel, &BaseModel::dataChanged, this, &StoresViewModel::storesChanged);
-    connect(&m_storesModel, &BaseModel::dataChanged, this, &StoresViewModel::selectedStoreNameChanged);
+    connect(m_storesModel, &BaseModel::dataChanged, this, &StoresViewModel::storesChanged);
+    connect(m_storesModel, &BaseModel::dataChanged, this, &StoresViewModel::selectedStoreNameChanged);
 
     connect(settings(), &SettingsService::selectedStoreIdChanged, this, &StoresViewModel::selectedStoreChanged);
     connect(settings(), &SettingsService::selectedStoreIdChanged, this, &StoresViewModel::selectedStoreNameChanged);
@@ -14,7 +15,7 @@ StoresViewModel::StoresViewModel(QObject *parent)
 
 QVariantList StoresViewModel::stores() const
 {
-    return m_storesModel.items();
+    return m_storesModel->items();
 }
 
 QString StoresViewModel::selectedStore() const
@@ -29,7 +30,7 @@ void StoresViewModel::setSelectedStore(const QString &newSelectedStore)
 
 QString StoresViewModel::selectedStoreName() const
 {
-    return m_storesModel.itemProperty(selectedStore(), "name").toString();
+    return m_storesModel->itemProperty(selectedStore(), "name").toString();
 }
 
 SettingsService *StoresViewModel::settings() const

+ 2 - 2
viewmodels/storesviewmodel.h

@@ -3,7 +3,7 @@
 
 #include <QObject>
 
-#include "models/basemodel.h"
+#include "services/modelsregister.h"
 
 class SettingsService;
 class StoresViewModel : public QObject
@@ -30,7 +30,7 @@ signals:
 private:
     SettingsService *settings() const;
 
-    BaseModel m_storesModel = BaseModel("stores", this);
+    BaseModel *m_storesModel = ModelsRegister::model("stores");
 };
 
 #endif // STORESVIEWMODEL_H

+ 5 - 4
viewmodels/usersviewmodel.cpp

@@ -1,12 +1,13 @@
 #include "usersviewmodel.h"
 
+#include "models/basemodel.h"
 #include "services/settingsservice.h"
 
 UsersViewModel::UsersViewModel(QObject *parent)
     : QObject{parent}
 {
-    connect(&m_usersModel, &BaseModel::dataChanged, this, &UsersViewModel::usersChanged);
-    connect(&m_usersModel, &BaseModel::dataChanged, this, &UsersViewModel::selectedUserNameChanged);
+    connect(m_usersModel, &BaseModel::dataChanged, this, &UsersViewModel::usersChanged);
+    connect(m_usersModel, &BaseModel::dataChanged, this, &UsersViewModel::selectedUserNameChanged);
 
     connect(settings(), &SettingsService::selectedUserIdChanged, this, &UsersViewModel::selectedUserChanged);
     connect(settings(), &SettingsService::selectedUserIdChanged, this, &UsersViewModel::selectedUserNameChanged);
@@ -14,7 +15,7 @@ UsersViewModel::UsersViewModel(QObject *parent)
 
 QVariantList UsersViewModel::users() const
 {
-    return m_usersModel.users();
+    return m_usersModel->items();
 }
 
 QString UsersViewModel::selectedUser() const
@@ -29,7 +30,7 @@ void UsersViewModel::setSelectedUser(const QString &newSelectedUser)
 
 QString UsersViewModel::selectedUserName() const
 {
-    return m_usersModel.itemProperty(selectedUser(), "name").toString();
+    return m_usersModel->itemProperty(selectedUser(), "name").toString();
 }
 
 SettingsService *UsersViewModel::settings() const

+ 2 - 2
viewmodels/usersviewmodel.h

@@ -3,7 +3,7 @@
 
 #include <QObject>
 
-#include "models/usersmodel.h"
+#include "services/modelsregister.h"
 
 class SettingsService;
 class UsersViewModel : public QObject
@@ -30,7 +30,7 @@ signals:
 private:
     SettingsService *settings() const;
 
-    UsersModel m_usersModel;
+    BaseModel *m_usersModel = ModelsRegister::model("users");
 };
 
 #endif // USERSVIEWMODEL_H