Initial commit
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
#ifndef MODEL_MANAGER_H
|
||||
#define MODEL_MANAGER_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlTableModel>
|
||||
#include <QString>
|
||||
|
||||
// The model manager inherits the QObject class to delete child objects
|
||||
class ModelManager : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QMap<QString, QSqlTableModel *> models_;
|
||||
QSqlDatabase database_;
|
||||
|
||||
public:
|
||||
// Get the singleton instance
|
||||
static ModelManager &instance();
|
||||
|
||||
QStringList registeredModelTableNames() const;
|
||||
|
||||
QStringList registeredModelTableNames(QString databaseTableName) const;
|
||||
|
||||
// Get a model
|
||||
QSqlTableModel *getModel(const QString &modelTableName) const;
|
||||
|
||||
// Get a model with a specific type
|
||||
template <typename T> T *getModelAs(const QString &modelTableName) const;
|
||||
|
||||
// Configure filters
|
||||
void resetFilter(const QString &modelTableName);
|
||||
|
||||
void setMultiColumnFilter(const QString &modelTableName,
|
||||
const QString &filter);
|
||||
|
||||
private:
|
||||
// Register a model
|
||||
template <typename T>
|
||||
bool registerModel(const QString &modelTableName, const QSqlDatabase &db);
|
||||
|
||||
// Initialize all models
|
||||
void initialize();
|
||||
|
||||
// Initialize a specific model
|
||||
template <typename T> void initializeIfExists(T *model);
|
||||
|
||||
// Private constructor for singleton pattern
|
||||
ModelManager();
|
||||
|
||||
// Private destructor
|
||||
~ModelManager();
|
||||
|
||||
// Disable copy constructor and assignment operator
|
||||
ModelManager(const ModelManager &) = delete;
|
||||
ModelManager &operator=(const ModelManager &) = delete;
|
||||
};
|
||||
|
||||
// NOTE: Implementation of template methods
|
||||
|
||||
template <typename T> void ModelManager::initializeIfExists(T *model) {
|
||||
if constexpr (std::is_invocable_v<decltype(&T::initialize), T *>) {
|
||||
model->initialize();
|
||||
} else {
|
||||
qDebug() << "Method initialize() is not available, skipping...";
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *ModelManager::getModelAs(const QString &modelTableName) const {
|
||||
auto *model = dynamic_cast<T *>(getModel(modelTableName));
|
||||
if (!model) {
|
||||
qFatal() << "Failed to downcast model for" << modelTableName
|
||||
<< "(typeid name):" << typeid(T).name();
|
||||
return nullptr;
|
||||
}
|
||||
qInfo() << "Successfully downcast model for" << modelTableName;
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ModelManager::registerModel(const QString &modelTableName,
|
||||
const QSqlDatabase &db) {
|
||||
static_assert(std::is_base_of_v<QSqlTableModel, T>,
|
||||
"Registered model must be derived from QSqlTableModel");
|
||||
|
||||
static_assert(
|
||||
std::is_constructible<T, QObject *, const QSqlDatabase &>::value,
|
||||
"Model class must have a constructor accepting QObject* and const "
|
||||
"QSqlDatabase&");
|
||||
|
||||
qInfo() << "Registering model:" << modelTableName;
|
||||
|
||||
if (models_.contains(modelTableName)) {
|
||||
qInfo() << "Model" << modelTableName << "is already registered";
|
||||
return true;
|
||||
}
|
||||
|
||||
T *model = new T(this, db); // Qt will delete the model
|
||||
model->setObjectName(modelTableName);
|
||||
initializeIfExists(model);
|
||||
|
||||
models_.insert(modelTableName, model);
|
||||
|
||||
qInfo() << "Model" << modelTableName
|
||||
<< "with database table name:" << model->tableName()
|
||||
<< "was registered successfully";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // MODEL_MANAGER_H
|
||||
Reference in New Issue
Block a user