From ca35df241f4c7dcbfcb68d7ac17b1bc6b95ba4c6 Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Thu, 11 Feb 2016 07:30:33 +0100 Subject: [PATCH 1/4] Added support for binding simple data to combo boxes. (not tested) --- core/autoform.h | 29 +++++++++++++++++++++++++++++ core/combodata.cpp | 33 +++++++++++++++++++++++++++++++++ core/combodata.h | 25 +++++++++++++++++++++++++ core/context.cpp | 6 +++--- core/core.pro | 6 ++++-- 5 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 core/combodata.cpp create mode 100644 core/combodata.h diff --git a/core/autoform.h b/core/autoform.h index 0ad1603..84fa1b0 100644 --- a/core/autoform.h +++ b/core/autoform.h @@ -8,10 +8,12 @@ #include #include #include +#include #include "iform.h" #include "service.h" #include "ivalidator.h" +#include "combodata.h" template @@ -48,6 +50,10 @@ public: } } + void registerBinding(QComboBox *combo, const QList &values) { + m_bindCombos[combo] = values; + } + void registerValidator(IValidator *validator) { m_validators.append(validator); } @@ -60,6 +66,7 @@ private: QSharedPointer m_entity; QList m_bindWidgets; QList m_validators; + QHash > m_bindCombos; bool m_newRec; void bindToUi() { @@ -67,6 +74,24 @@ private: const char* prop = widget->metaObject()->userProperty().name(); widget->setProperty(prop, ((QObject*)m_entity.data())->property(widget->objectName().toStdString().c_str())); } + + foreach (QComboBox *combo, m_bindCombos.keys()) { + int idx = 0; + QVariant field = ((QObject*)m_entity.data())->property(combo->objectName().toStdString().c_str()); + + combo->clear(); + for (int i = 0; i < m_bindCombos[combo].size(); i++) { + ComboData data = m_bindCombos[combo][i]; + combo->addItem(data.label(), data.index()); + + if (field == data.index()) { + idx = i; + } + } + + combo->setCurrentIndex(idx); + } + bindOtherToUi(); } @@ -83,6 +108,10 @@ private: ((QObject*)m_entity.data())->setProperty(widget->objectName().toStdString().c_str(), widget->property(prop)); } + foreach (QComboBox *combo, m_bindCombos.keys()) { + ((QObject*)m_entity.data())->setProperty(combo->objectName().toStdString().c_str(), combo->currentData()); + } + return bindOtherToData(); } diff --git a/core/combodata.cpp b/core/combodata.cpp new file mode 100644 index 0000000..b7ffef3 --- /dev/null +++ b/core/combodata.cpp @@ -0,0 +1,33 @@ +#include "combodata.h" + +ComboData::ComboData(const QVariant &index, const QString &label) +{ + m_index = index; + m_label = label; +} + +ComboData::~ComboData() +{ + +} +QVariant ComboData::index() const +{ + return m_index; +} + +void ComboData::setIndex(const QVariant &index) +{ + m_index = index; +} +QString ComboData::label() const +{ + return m_label; +} + +void ComboData::setLabel(const QString &label) +{ + m_label = label; +} + + + diff --git a/core/combodata.h b/core/combodata.h new file mode 100644 index 0000000..37d7ff9 --- /dev/null +++ b/core/combodata.h @@ -0,0 +1,25 @@ +#ifndef COMBODATA_H +#define COMBODATA_H + +#include + +#include "core_global.h" + +class CORESHARED_EXPORT ComboData +{ +public: + ComboData(const QVariant &index, const QString &label); + ~ComboData(); + + QVariant index() const; + void setIndex(const QVariant &index); + + QString label() const; + void setLabel(const QString &label); + +private: + QVariant m_index; + QString m_label; +}; + +#endif // COMBODATA_H diff --git a/core/context.cpp b/core/context.cpp index a28b97c..f23e585 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -49,7 +49,7 @@ void Context::loadPlugins() m_plugins.append(new Users); m_plugins.append(new Roles); - QDir pluginsDir(qApp->applicationDirPath() + "/../plugins"); + QDir pluginsDir(qApp->applicationDirPath() + "/../../plugins"); foreach (QString fileName, pluginsDir.entryList(QStringList() << "*.so" << "*.dll")) { QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName)); @@ -96,10 +96,10 @@ void Context::destroy() m_dbOpened = false; } - if (m_settings != NULL && m_settings->parent() == NULL) + /*if (m_settings != NULL && m_settings->parent() == NULL) { delete m_settings; - } + }*/ foreach (IPlugin *plugin, m_plugins) { diff --git a/core/core.pro b/core/core.pro index 509247f..474644a 100644 --- a/core/core.pro +++ b/core/core.pro @@ -43,7 +43,8 @@ SOURCES += \ savefilterdialog.cpp \ filterdialog.cpp \ itablemodel.cpp \ - iservice.cpp + iservice.cpp \ + combodata.cpp HEADERS += core.h\ core_global.h \ @@ -84,7 +85,8 @@ HEADERS += core.h\ filterdialog.h \ itablemodel.h \ data/core_global.h \ - iservice.h + iservice.h \ + combodata.h unix { target.path = /usr/lib From 1b6141923fa8eba651a837a7d53fc31cddcfb2c7 Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Thu, 11 Feb 2016 12:11:32 +0100 Subject: [PATCH 2/4] Added support for bindig relations (foreign keys) to combo boxes. --- core/autoform.h | 10 ++++++++-- core/combodata.cpp | 17 +++++++++++++---- core/combodata.h | 3 +++ core/core.h | 1 + core/core.pro | 8 ++++++-- core/data/comboitem.cpp | 11 +++++++++++ core/data/comboitem.h | 21 +++++++++++++++++++++ 7 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 core/data/comboitem.cpp create mode 100644 core/data/comboitem.h diff --git a/core/autoform.h b/core/autoform.h index 84fa1b0..cc86616 100644 --- a/core/autoform.h +++ b/core/autoform.h @@ -15,7 +15,6 @@ #include "ivalidator.h" #include "combodata.h" - template class AutoForm : public IForm { @@ -84,7 +83,14 @@ private: ComboData data = m_bindCombos[combo][i]; combo->addItem(data.label(), data.index()); - if (field == data.index()) { + if (data.index().canConvert()) { + ComboItem* ci = qobject_cast(data.index().value()); + ComboItem* ciField = qobject_cast(field.value()); + if (ci->eq(ciField)) { + idx = i; + } + } + else if (field == data.index()) { idx = i; } } diff --git a/core/combodata.cpp b/core/combodata.cpp index b7ffef3..8f02b40 100644 --- a/core/combodata.cpp +++ b/core/combodata.cpp @@ -6,10 +6,21 @@ ComboData::ComboData(const QVariant &index, const QString &label) m_label = label; } -ComboData::~ComboData() +ComboData::ComboData(const QSharedPointer &index) { + m_index = QVariant::fromValue(index); + ComboItem *ci = qobject_cast(index.data()); + + if (ci != NULL) + { + m_label = ci->toString(); + } +} +ComboData::~ComboData() +{ } + QVariant ComboData::index() const { return m_index; @@ -19,6 +30,7 @@ void ComboData::setIndex(const QVariant &index) { m_index = index; } + QString ComboData::label() const { return m_label; @@ -28,6 +40,3 @@ void ComboData::setLabel(const QString &label) { m_label = label; } - - - diff --git a/core/combodata.h b/core/combodata.h index 37d7ff9..2e8bfff 100644 --- a/core/combodata.h +++ b/core/combodata.h @@ -2,13 +2,16 @@ #define COMBODATA_H #include +#include #include "core_global.h" +#include "data/comboitem.h" class CORESHARED_EXPORT ComboData { public: ComboData(const QVariant &index, const QString &label); + ComboData(const QSharedPointer &index); ~ComboData(); QVariant index() const; diff --git a/core/core.h b/core/core.h index 0bfc109..851755f 100644 --- a/core/core.h +++ b/core/core.h @@ -8,5 +8,6 @@ #include "transaction.h" #include "gridform.h" #include "permissionservice.h" +#include "combodata.h" #endif // CORE_H diff --git a/core/core.pro b/core/core.pro index 474644a..ea2edf0 100644 --- a/core/core.pro +++ b/core/core.pro @@ -44,7 +44,8 @@ SOURCES += \ filterdialog.cpp \ itablemodel.cpp \ iservice.cpp \ - combodata.cpp + combodata.cpp \ + data/comboitem.cpp HEADERS += core.h\ core_global.h \ @@ -86,7 +87,8 @@ HEADERS += core.h\ itablemodel.h \ data/core_global.h \ iservice.h \ - combodata.h + combodata.h \ + data/comboitem.h unix { target.path = /usr/lib @@ -123,3 +125,5 @@ FORMS += \ OTHER_FILES += \ users/metaData.json \ roles/metaData.json + +TRANSLATIONS = core_cz.ts diff --git a/core/data/comboitem.cpp b/core/data/comboitem.cpp new file mode 100644 index 0000000..04f2b3b --- /dev/null +++ b/core/data/comboitem.cpp @@ -0,0 +1,11 @@ +#include "comboitem.h" + +ComboItem::ComboItem(QObject *parent) + :QObject(parent) +{ +} + +ComboItem::~ComboItem() +{ +} + diff --git a/core/data/comboitem.h b/core/data/comboitem.h new file mode 100644 index 0000000..6540e65 --- /dev/null +++ b/core/data/comboitem.h @@ -0,0 +1,21 @@ +#ifndef COMBOITEM_H +#define COMBOITEM_H + +#include "core_global.h" +#include +#include +#include + +class CORESHARED_EXPORT ComboItem : public QObject +{ + Q_OBJECT + +public: + explicit ComboItem(QObject *parent = NULL); + ~ComboItem(); + + virtual bool eq(ComboItem *other) = 0; + virtual QString toString() = 0; +}; + +#endif // COMBOITEM_H From 7ea06881ef9434b6c8c0f32485f12bdc370593a2 Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Fri, 12 Feb 2016 15:58:12 +0100 Subject: [PATCH 3/4] AutoTableModel now can display data from related table. Usage example of ComboBox binding in Accommodation plugin. --- accommodation/accommodation.pro | 9 ++-- accommodation/acform.cpp | 14 ++++++ accommodation/acform.h | 4 ++ accommodation/acform.ui | 10 +++++ accommodation/data/accommodation-data.h | 8 ++++ accommodation/data/address.cpp | 58 +++++++++++++++++++++++++ accommodation/data/address.h | 55 +++++++++++++++++++++++ accommodation/data/person.cpp | 14 ++++++ accommodation/data/person.h | 7 +++ core/autoform.h | 2 + core/autotablemodel.h | 9 +++- odb.pri | 1 + 12 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 accommodation/data/accommodation-data.h create mode 100644 accommodation/data/address.cpp create mode 100644 accommodation/data/address.h diff --git a/accommodation/accommodation.pro b/accommodation/accommodation.pro index edfc4da..8634a1f 100644 --- a/accommodation/accommodation.pro +++ b/accommodation/accommodation.pro @@ -17,7 +17,8 @@ SOURCES += accommodation.cpp \ accommodationservice.cpp \ tablemodel.cpp \ acform.cpp \ - accgrid.cpp + accgrid.cpp \ + data/address.cpp HEADERS += accommodation.h\ accommodation_global.h \ @@ -25,7 +26,9 @@ HEADERS += accommodation.h\ accommodationservice.h \ tablemodel.h \ acform.h \ - accgrid.h + accgrid.h \ + data/address.h \ + data/accommodation-data.h unix { target.path = /usr/lib @@ -53,7 +56,7 @@ OTHER_FILES += \ FORMS += \ acform.ui -ODB_FILES = accommodation/data/person.h +ODB_FILES = accommodation/data/accommodation-data.h H_DIR = $$PWD/data/*.h include(../odb.pri) diff --git a/accommodation/acform.cpp b/accommodation/acform.cpp index e412f6c..1a8aaff 100644 --- a/accommodation/acform.cpp +++ b/accommodation/acform.cpp @@ -1,5 +1,8 @@ #include "acform.h" #include "ui_acform.h" +#include + +#include "accommodation-odb.hxx" AcForm::AcForm(QWidget *parent) : AutoForm(parent), @@ -15,3 +18,14 @@ AcForm::~AcForm() { delete ui; } + +void AcForm::registerCombos() +{ + QList cbData; + Service
srv; + foreach (QSharedPointer
adr, srv.all()) { + cbData.append(ComboData(adr)); + } + + registerBinding(ui->address, cbData); +} diff --git a/accommodation/acform.h b/accommodation/acform.h index 441c767..6c49933 100644 --- a/accommodation/acform.h +++ b/accommodation/acform.h @@ -20,6 +20,10 @@ public: private: Ui::AcForm *ui; + + // AutoForm interface +protected: + virtual void registerCombos(); }; #endif // ACFORM_H diff --git a/accommodation/acform.ui b/accommodation/acform.ui index 5e7aabe..f1b3c3d 100644 --- a/accommodation/acform.ui +++ b/accommodation/acform.ui @@ -46,6 +46,16 @@ PushButton + + + + 110 + 170 + 191 + 22 + + + diff --git a/accommodation/data/accommodation-data.h b/accommodation/data/accommodation-data.h new file mode 100644 index 0000000..bf6ad45 --- /dev/null +++ b/accommodation/data/accommodation-data.h @@ -0,0 +1,8 @@ +#ifndef ACCOMMODATIONDATA_H +#define ACCOMMODATIONDATA_H + +#include "address.h" +#include "person.h" + +#endif // ACCOMMODATIONDATA_H + diff --git a/accommodation/data/address.cpp b/accommodation/data/address.cpp new file mode 100644 index 0000000..ba7cb5b --- /dev/null +++ b/accommodation/data/address.cpp @@ -0,0 +1,58 @@ +#include "address.h" + +Address::Address(QObject *parent) : ComboItem(parent) +{ + +} + +Address::~Address() +{ + +} +QString Address::city() const +{ + return m_city; +} + +void Address::setCity(const QString &city) +{ + m_city = city; +} +QString Address::street() const +{ + return m_street; +} + +void Address::setStreet(const QString &street) +{ + m_street = street; +} +QString Address::houseNumber() const +{ + return m_houseNumber; +} + +void Address::setHouseNumber(const QString &houseNumber) +{ + m_houseNumber = houseNumber; +} +int Address::id() const +{ + return m_id; +} + +void Address::setId(int id) +{ + m_id = id; +} + +bool Address::eq(ComboItem *other) +{ + Address *addr = qobject_cast(other); + return addr != NULL && m_id == addr->id(); +} + +QString Address::toString() +{ + return m_street + ", " + m_houseNumber + ", " + m_city; +} diff --git a/accommodation/data/address.h b/accommodation/data/address.h new file mode 100644 index 0000000..c81bbfd --- /dev/null +++ b/accommodation/data/address.h @@ -0,0 +1,55 @@ +#ifndef ADDRESS_H +#define ADDRESS_H + +#include +#include + +#include + +#include + +#pragma db object +class Address : public ComboItem +{ + Q_OBJECT + + Q_PROPERTY(QString city READ city WRITE setCity) + Q_PROPERTY(QString street READ street WRITE setStreet) + Q_PROPERTY(QString houseNumber READ houseNumber WRITE setHouseNumber) + +public: + explicit Address(QObject *parent = 0); + ~Address(); + + QString city() const; + void setCity(const QString &city); + + QString street() const; + void setStreet(const QString &street); + + QString houseNumber() const; + void setHouseNumber(const QString &houseNumber); + + int id() const; + void setId(int id); + +private: + friend class odb::access; + +#pragma db id auto + int m_id; + QString m_city; + QString m_street; + QString m_houseNumber; + +signals: + +public slots: + + // ComboItem interface +public: + virtual bool eq(ComboItem *other); + virtual QString toString(); +}; + +#endif // ADDRESS_H diff --git a/accommodation/data/person.cpp b/accommodation/data/person.cpp index e4304b7..8457486 100644 --- a/accommodation/data/person.cpp +++ b/accommodation/data/person.cpp @@ -1,3 +1,4 @@ +#include #include "person.h" Person::Person() @@ -30,6 +31,19 @@ void Person::setLastName(const QString &value) { lastName = value; } +QSharedPointer Person::address() const +{ + return m_address; +} + +void Person::setAddress(const QSharedPointer &address) +{ + if (qobject_cast(address.data()) != NULL) + { + m_address = qSharedPointerDynamicCast(address); + } +} + diff --git a/accommodation/data/person.h b/accommodation/data/person.h index 015b2f7..46d8f86 100644 --- a/accommodation/data/person.h +++ b/accommodation/data/person.h @@ -4,6 +4,8 @@ #include #include +#include "address.h" + #include #pragma db object @@ -13,6 +15,7 @@ class Person : public QObject Q_PROPERTY(QString firstName READ getFirstName WRITE setFirstName) Q_PROPERTY(QString lastName READ getLastName WRITE setLastName) + Q_PROPERTY(QSharedPointer address READ address WRITE setAddress) public: Person(); @@ -25,12 +28,16 @@ public: QString getLastName() const; void setLastName(const QString &value); + QSharedPointer address() const; + void setAddress(const QSharedPointer &address); + private: friend class odb::access; #pragma db id auto int id; QString firstName; QString lastName; + QSharedPointer
m_address; }; diff --git a/core/autoform.h b/core/autoform.h index cc86616..f2a8b35 100644 --- a/core/autoform.h +++ b/core/autoform.h @@ -60,6 +60,7 @@ public: protected: virtual void bindOtherToUi() {} virtual bool bindOtherToData() { return true; } + virtual void registerCombos() {} private: QSharedPointer m_entity; @@ -69,6 +70,7 @@ private: bool m_newRec; void bindToUi() { + registerCombos(); foreach (QWidget *widget, m_bindWidgets) { const char* prop = widget->metaObject()->userProperty().name(); widget->setProperty(prop, ((QObject*)m_entity.data())->property(widget->objectName().toStdString().c_str())); diff --git a/core/autotablemodel.h b/core/autotablemodel.h index 307319f..196b935 100644 --- a/core/autotablemodel.h +++ b/core/autotablemodel.h @@ -10,6 +10,7 @@ #include "core_global.h" #include "exprevaluator.h" #include "itablemodel.h" +#include "data/comboitem.h" template class AutoTableModel : public ITableModel @@ -51,7 +52,13 @@ public: QSharedPointer entity = m_list.at(index.row()); QObject *rawEntity = (QObject*)entity.data(); - return rawEntity->property(rawEntity->metaObject()->property(index.column() + 1).name()); + QVariant dispData = rawEntity->property(rawEntity->metaObject()->property(index.column() + 1).name()); + if (dispData.canConvert() && qobject_cast(dispData.value())) + { + return qobject_cast(dispData.value())->toString(); + } + + return dispData; } return QVariant::Invalid; diff --git a/odb.pri b/odb.pri index 237db9a..43ad744 100644 --- a/odb.pri +++ b/odb.pri @@ -42,6 +42,7 @@ DEFINES += DATABASE_SQLITE # ODB_FLAGS += -I $$[QT_INSTALL_HEADERS] ODB_FLAGS += -I $$[QT_INSTALL_HEADERS]/QtCore +ODB_FLAGS += -I $$PWD/core ODB_FLAGS += -D __PIC__ win32 { From 1f4f318a26c6a92f9fc58b43af8ec899251d5eea Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Sat, 13 Feb 2016 21:41:05 +0100 Subject: [PATCH 4/4] Database error handling. --- accommodation/acform.h | 1 + accommodation/data/person.cpp | 6 ++-- accommodation/data/person.h | 4 +-- core/autoform.h | 51 +++++++++++++++++++++++++-- core/context.cpp | 5 +++ core/context.h | 2 ++ core/formdialog.cpp | 6 ++++ core/formdialog.h | 4 +++ core/gridform.h | 65 +++++++++++++++++++++++++---------- core/iform.cpp | 15 ++++++++ core/iform.h | 9 +++++ core/igridform.cpp | 6 ++++ core/igridform.h | 1 + core/iservice.h | 7 +++- core/service.h | 14 ++++++++ 15 files changed, 169 insertions(+), 27 deletions(-) diff --git a/accommodation/acform.h b/accommodation/acform.h index 441c767..634f3b0 100644 --- a/accommodation/acform.h +++ b/accommodation/acform.h @@ -5,6 +5,7 @@ #include #include "data/person.h" +#include "accommodation-odb.hxx" namespace Ui { class AcForm; diff --git a/accommodation/data/person.cpp b/accommodation/data/person.cpp index e4304b7..3c785a0 100644 --- a/accommodation/data/person.cpp +++ b/accommodation/data/person.cpp @@ -3,14 +3,14 @@ Person::Person() { } -int Person::getId() const +int Person::id() const { - return id; + return m_id; } void Person::setId(int value) { - id = value; + m_id = value; } QString Person::getFirstName() const { diff --git a/accommodation/data/person.h b/accommodation/data/person.h index 015b2f7..bf784fa 100644 --- a/accommodation/data/person.h +++ b/accommodation/data/person.h @@ -16,7 +16,7 @@ class Person : public QObject public: Person(); - int getId() const; + int id() const; void setId(int value); QString getFirstName() const; @@ -28,7 +28,7 @@ public: private: friend class odb::access; #pragma db id auto - int id; + int m_id; QString firstName; QString lastName; diff --git a/core/autoform.h b/core/autoform.h index 0ad1603..fd0bbf3 100644 --- a/core/autoform.h +++ b/core/autoform.h @@ -8,10 +8,13 @@ #include #include #include +#include #include "iform.h" #include "service.h" #include "ivalidator.h" +#include "iservice.h" +#include "iplugin.h" template @@ -20,6 +23,8 @@ class AutoForm : public IForm public: explicit AutoForm(QWidget *parent = 0) : IForm(parent) { m_newRec = false; + m_serviceConnected = false; + m_saved = false; } virtual ~AutoForm() { @@ -93,14 +98,54 @@ public slots: return false; } + if (!m_serviceConnected) + { + connect(service(), &IService::dbError, [this](QString msg) { + QMessageBox::critical(this, tr("Database error"), tr(msg.toStdString().c_str())); + m_saved = false; + }); + connect(service(), &IService::dataChanged, [this]() { + m_saved = true; + }); + m_serviceConnected = true; + } + if (m_newRec) { - emit recordAdded(); + service()->save(entity()); + if (m_saved) + { + emit recordAdded(); + } } else { - emit recordUpdated(); + service()->update(entity()); + if (m_saved) + { + emit recordUpdated(); + } } - return true; + return m_saved; } + +private: + Service *service() { + IPlugin *plugin = Context::instance().plugin(pluginId()); + if (plugin == NULL) { + Q_ASSERT(false); + return NULL; + } + + Service *service = plugin->service(); + if (service == NULL) { + Q_ASSERT(false); + return NULL; + } + + return service; + } + + bool m_serviceConnected; + bool m_saved; }; #endif // AUTOFORM_H diff --git a/core/context.cpp b/core/context.cpp index a28b97c..be095d2 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -130,6 +130,11 @@ void Context::setCurrentUser(const QSharedPointer ¤tUser) m_currentUser = currentUser; } +odb::session &Context::session() +{ + return m_session; +} + void Context::checkDb(const QString &path) { { diff --git a/core/context.h b/core/context.h index 17b9062..7d28143 100644 --- a/core/context.h +++ b/core/context.h @@ -37,6 +37,8 @@ public: QSharedPointer currentUser() const; void setCurrentUser(const QSharedPointer ¤tUser); + odb::session &session(); + private: Context(); QList m_plugins; diff --git a/core/formdialog.cpp b/core/formdialog.cpp index 731e506..5d36b6e 100644 --- a/core/formdialog.cpp +++ b/core/formdialog.cpp @@ -39,3 +39,9 @@ void FormDialog::accept() QDialog::accept(); } } + +void FormDialog::reject() +{ + m_form->refresh(); + QDialog::reject(); +} diff --git a/core/formdialog.h b/core/formdialog.h index 2cdf9b4..0eaa584 100644 --- a/core/formdialog.h +++ b/core/formdialog.h @@ -31,6 +31,10 @@ private slots: // QDialog interface public slots: void accept(); + + // QDialog interface +public slots: + void reject() override; }; #endif // FORMDIALOG_H diff --git a/core/gridform.h b/core/gridform.h index 953098f..cb65446 100644 --- a/core/gridform.h +++ b/core/gridform.h @@ -10,8 +10,8 @@ #include "autotablemodel.h" #include "context.h" #include "iplugin.h" - #include "igridform.h" +#include "iservice.h" template class GridForm : public IGridForm @@ -20,14 +20,15 @@ class GridForm : public IGridForm public: explicit GridForm(QWidget *parent = 0) : IGridForm(parent) -{ - m_form = NULL; - m_tableModel = NULL; - m_formHandler = new DefaultFormHandler(); + { + m_serviceConnected = false; + m_tableModel = NULL; + m_formHandler = new DefaultFormHandler(); + + m_filterUi = new FilterUi(this, new T); + filterWidget()->layout()->addWidget(m_filterUi); + } - m_filterUi = new FilterUi(this, new T); - filterWidget()->layout()->addWidget(m_filterUi); -} virtual ~GridForm() { if (m_form != NULL && m_form->parent() == NULL) @@ -43,20 +44,26 @@ public: delete m_formHandler; } - void setForm(AutoForm *form) { + void setForm(AutoForm *aForm) { Q_ASSERT(m_form == NULL); - m_form = form; + m_form = aForm; connect(m_form, &IForm::recordAdded, [this](){ - service()->save(m_form->entity()); - m_tableModel->addRow(m_form->entity()); + //service()->save(form()->entity()); + m_tableModel->addRow(form()->entity()); emit dataChanged(); }); connect(m_form, &IForm::recordUpdated, [this](){ - service()->update(m_form->entity()); + //service()->update(form()->entity()); emit dataChanged(); }); + connect(m_form, &IForm::refreshEntity, [this](){ + if (m_tableModel != NULL) { + m_tableModel->setItemToIndex(tableView()->currentIndex(), + service()->reload(m_tableModel->itemFromIndex(tableView()->currentIndex())->id())); + } + }); } void setTableModel(AutoTableModel *tableModel) { @@ -79,6 +86,8 @@ public slots: return; } + connectService(); + m_tableModel->setData(service()->all()); tableView()->setModel(m_tableModel); @@ -93,7 +102,6 @@ public slots: } private: - AutoForm *m_form; AutoTableModel *m_tableModel; IFormHandler *m_formHandler; @@ -113,6 +121,26 @@ private: return service; } + AutoForm *form() { + return (AutoForm*)m_form; + } + + void connectService() { + if (!m_serviceConnected) + { + connect(service(), &IService::dbErrorRead, [this](QString msg) { + QMessageBox::critical(this, tr("Database error"), tr(msg.toStdString().c_str())); + }); + connect(service(), &IService::dbErrorDelete, [this](QString msg) { + QMessageBox::critical(this, tr("Database error"), tr(msg.toStdString().c_str())); + }); + + m_serviceConnected = true; + } + } + + bool m_serviceConnected; + // IGridForm interface protected: void handleNewRecord() override @@ -123,8 +151,8 @@ protected: return; } - m_form->setEntity(QSharedPointer(new T())); - m_form->setNewRec(true); + form()->setEntity(QSharedPointer(new T())); + form()->setNewRec(true); m_formHandler->showForm(m_form); } @@ -136,13 +164,14 @@ protected: return; } - m_form->setEntity(m_tableModel->itemFromIndex(tableView()->currentIndex())); - m_form->setNewRec(false); + form()->setEntity(m_tableModel->itemFromIndex(tableView()->currentIndex())); + form()->setNewRec(false); m_formHandler->showForm(m_form); } void handleDeleteRecord() override { + connectService(); if (m_form == NULL || m_tableModel == NULL || tableView()->currentIndex().row() < 0) { Q_ASSERT(false); diff --git a/core/iform.cpp b/core/iform.cpp index 27d2b59..ded8846 100644 --- a/core/iform.cpp +++ b/core/iform.cpp @@ -8,3 +8,18 @@ IForm::~IForm() { } +QString IForm::pluginId() const +{ + return m_pluginId; +} + +void IForm::setPluginId(const QString &pluginId) +{ + m_pluginId = pluginId; +} + +void IForm::refresh() +{ + emit refreshEntity(); +} + diff --git a/core/iform.h b/core/iform.h index 5bee31f..7a99e96 100644 --- a/core/iform.h +++ b/core/iform.h @@ -2,6 +2,7 @@ #define IFORM_H #include +#include #include "core_global.h" @@ -13,13 +14,21 @@ public: explicit IForm(QWidget *parent = 0); virtual ~IForm(); + QString pluginId() const; + void setPluginId(const QString &pluginId); + signals: void recordAdded(); void recordUpdated(); void validationError(const QString &errMessage); + void refreshEntity(); public slots: virtual bool saveRecord() = 0; + void refresh(); + +private: + QString m_pluginId; }; #endif // IFORM_H diff --git a/core/igridform.cpp b/core/igridform.cpp index 986b03c..ef1d899 100644 --- a/core/igridform.cpp +++ b/core/igridform.cpp @@ -14,6 +14,7 @@ IGridForm::IGridForm(QWidget *parent) : ui->filterWidget->setVisible(false); m_contextMenu = new QMenu(this); m_contextMenu->addAction(ui->actionSelectColumns); + m_form = NULL; m_columnDialog = new ColumnDialog(this); connect(m_columnDialog, SIGNAL(accepted()), this, SLOT(columnsAccepted())); @@ -32,6 +33,11 @@ void IGridForm::setPluginId(const QString &pluginId) { m_filterUi->setPluginId(pluginId); } + + if (m_form != NULL) + { + m_form->setPluginId(pluginId); + } } QString IGridForm::pluginId() diff --git a/core/igridform.h b/core/igridform.h index 499dc6a..bf22dc6 100644 --- a/core/igridform.h +++ b/core/igridform.h @@ -60,6 +60,7 @@ private: protected: FilterUi *m_filterUi; + IForm *m_form; }; #endif // IGRIDFORM_H diff --git a/core/iservice.h b/core/iservice.h index eabc038..e7fde5d 100644 --- a/core/iservice.h +++ b/core/iservice.h @@ -16,8 +16,13 @@ public: signals: void dbError(QString errMsg); + void dbErrorRead(QString errMsg); + void dbErrorInsert(QString errMsg); + void dbErrorUpdate(QString errMsg); + void dbErrorDelete(QString errMsg); void dataChanged(); - void permissionDenied(); + void updateDenied(); + void readDenied(); public slots: }; diff --git a/core/service.h b/core/service.h index e6d1f48..9caa514 100644 --- a/core/service.h +++ b/core/service.h @@ -67,6 +67,7 @@ public: catch (const odb::exception &ex) { emit dbError(ex.what()); + emit dbErrorUpdate(ex.what()); return; } @@ -88,6 +89,8 @@ public: catch (const odb::exception &ex) { emit dbError(ex.what()); + emit dbErrorInsert(ex.what()); + return; } emit dataChanged(); @@ -109,11 +112,21 @@ public: catch (const odb::exception &ex) { emit dbError(ex.what()); + emit dbErrorRead(ex.what()); } return entity; } + QSharedPointer reload(int id) { + odb::database *db = Context::instance().db(); + + Q_ASSERT(db); + + Context::instance().session().cache_erase(*db, id); + return loadById(id); + } + void erase(QSharedPointer entity) { odb::database *db = Context::instance().db(); @@ -129,6 +142,7 @@ public: catch (const odb::exception &ex) { emit dbError(ex.what()); + emit dbErrorDelete(ex.what()); } }