From c722fe743c8b145a8585d8b5cc0ac5bf054270e3 Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Tue, 9 Feb 2016 10:04:17 +0100 Subject: [PATCH 1/4] Implemented application login. Minor UI improvement. Fixed memory leaks. --- application/appRc.qrc | 6 ++ application/application.pro | 10 ++- application/icons/login_32.png | Bin 0 -> 2242 bytes application/icons/login_64.png | Bin 0 -> 5954 bytes application/logindialog.cpp | 45 ++++++++++ application/logindialog.h | 29 +++++++ application/logindialog.ui | 146 +++++++++++++++++++++++++++++++++ application/main.cpp | 2 + application/mainwindow.cpp | 51 +++++++++++- application/mainwindow.h | 11 +++ application/mainwindow.ui | 25 +++++- core/context.cpp | 22 ++++- core/context.h | 7 ++ core/core.h | 1 + core/filterui.ui | 19 ++--- core/gridform.h | 10 +++ core/gridform.ui | 15 ++++ core/igridform.cpp | 1 + core/imetadataplugin.cpp | 5 +- core/imetadataplugin.h | 2 +- core/iplugin.h | 13 ++- core/permissionservice.cpp | 53 ++++++++++++ core/permissionservice.h | 10 +-- core/users/userform.cpp | 5 +- 24 files changed, 455 insertions(+), 33 deletions(-) create mode 100644 application/appRc.qrc create mode 100644 application/icons/login_32.png create mode 100644 application/icons/login_64.png create mode 100644 application/logindialog.cpp create mode 100644 application/logindialog.h create mode 100644 application/logindialog.ui diff --git a/application/appRc.qrc b/application/appRc.qrc new file mode 100644 index 0000000..8954102 --- /dev/null +++ b/application/appRc.qrc @@ -0,0 +1,6 @@ + + + icons/login_32.png + icons/login_64.png + + diff --git a/application/application.pro b/application/application.pro index 2205f9a..8f70e76 100644 --- a/application/application.pro +++ b/application/application.pro @@ -22,10 +22,13 @@ win32 { SOURCES += main.cpp\ mainwindow.cpp \ + logindialog.cpp -HEADERS += mainwindow.h +HEADERS += mainwindow.h \ + logindialog.h -FORMS += mainwindow.ui +FORMS += mainwindow.ui \ + logindialog.ui unix { @@ -43,3 +46,6 @@ else:unix: LIBS += -L$$OUT_PWD/../core/ -lcore INCLUDEPATH += $$PWD/../core DEPENDPATH += $$PWD/../core + +RESOURCES += \ + appRc.qrc diff --git a/application/icons/login_32.png b/application/icons/login_32.png new file mode 100644 index 0000000000000000000000000000000000000000..6cef08cc4569d44f0abf5e243c83dc29d8717bf2 GIT binary patch literal 2242 zcmV;z2tD_SP)N)3+?9!Y>acSDvW``){^-`y>7oM9Ad&dir{a_^k` z{m%cK?>pZzd{3J_d$!hWHovIX>t`7Zh6kyaMN#zfJl`P8@)4iUx4WvU%8MV-*qt7h zmX?YZi)AG_TuzQtj7B493>w2~wSwM(06+l2?(Xi5G-W-3#D)YwbQHs8 z0;H#>$4woR0#FnMkw^rAKmd)6jsH4-{(Skqefz>c8lbSS@C97_TEac|q!Xfy;^<9G!lc6E`ZFVONMiV08 z5U$_2jwTP}7Pp@rJa|wu6aX@HoI1|V&PINg3)x0LMivyonVb%Lk^=(ILBo+jLCckk zIQow|{QVp6;krYI9~lY&<@Q*We#!$5Of1MoTJ|Vdhh>7-aAXWT?LQ*`bvtTn_TY*; z_>&D=YrY%`fL7}6Q^!`59#iv&Ve-SHVYb-d%p3)sP6E#{kN{wG0AtYzE?oGgzZIFb z%F0T4C;;lHt5{h%5yMj*@b>mlG#FqqnPDObvojrnprt(`p%j@E2vax)FQiPElXtJq z?+7q%+_?D^Ub}w3tODKbt>6WLoLeaV&15DDMLk5L1w4hLI$0)wXgGL$_|yfHh6I2T z5%2d6oSR=>kYm;aIL0^_)YTJ&s)R)0sndz^WTZ}4!!asH_vAgcV&0Gd{7;3#+%)sa zDS0-5gG?c3hTdR`t00P$jC8srhA%;`7YC!IMBSL-fH=jXo zyXUH;*S@T1&4mVww21i{4Zc2(f>FSqtTR*Q^AjC}4s47h2lG;m*RaJv>fV|8#f9slWN+08&+bdRBH;{j-G`Ip=ypP{Yn8X<*k8m;o4TWe9X!hN0~QxJVEN zM;crOQ}M@lcVX(!m*QqvK@ZhJU$^(8`KJHlzxJm*f!w7)*cU%5p?F;6x1j@i%JHr^fCQ(WgH@pFguas^G0-iHhwa}2yt!o?il14ETj9hO zoau-IV5c&z+v&`9A*qBa3w{tH(QD$*dQbfczP5Ac8Mku()#5SvSw%T%IMn2Zold#a zB$5gel1SiB+5mti=p+^!a;m~X2&h=zQIsl?Z z!IB&XkK2uR_SHcsoreI0=af(_iqV3ulkXwpXM4e)eF>4adbqpj+Gc7APuCjNv4Ws9 z=|p*nYgzPoJQK1-+m+|%&c+A-ZYG7aFzQ7Z;}8<8q(l>XysXVwemp#e${~n+1s73I_GT3;4CgMogPd`sG%bOiF%PzFjeDlP+rJ2 zDR3Nl1M4P#iO$9=a8?9|TbU@UI?T6YF>XM)40A)N+?ISip=naK~6z+kLUIwml9eG@RPb>cp!0o21`g~+G;#;kRgA))A zW>Cc`(H+bykua^DN)Hu4D@ExyVnophZQcp1a{}&G_$i|Y{2Dsx?4AMs3w}x(sWl(R QcK`qY07*qoM6N<$f-HL~T>t<8 literal 0 HcmV?d00001 diff --git a/application/icons/login_64.png b/application/icons/login_64.png new file mode 100644 index 0000000000000000000000000000000000000000..1f1c17e7f7cf5dbd6e8bebc12ac0ce7ea559fc79 GIT binary patch literal 5954 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 literal 0 HcmV?d00001 diff --git a/application/logindialog.cpp b/application/logindialog.cpp new file mode 100644 index 0000000..b46ea77 --- /dev/null +++ b/application/logindialog.cpp @@ -0,0 +1,45 @@ +#include "logindialog.h" +#include "ui_logindialog.h" +#include "../core/core.h" +#include + +LoginDialog::LoginDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::LoginDialog) +{ + ui->setupUi(this); +} + +LoginDialog::~LoginDialog() +{ + delete ui; +} + +QString LoginDialog::login() const +{ + return ui->editLogin->text(); +} + +QString LoginDialog::password() const +{ + return ui->editPassword->text(); +} + +void LoginDialog::reset() +{ + ui->editLogin->setText(""); + ui->editPassword->setText(""); +} + +void LoginDialog::accept() +{ + PermissionService srv; + if (srv.checkLogin(ui->editLogin->text(), ui->editPassword->text())) + { + QDialog::accept(); + } + else + { + QMessageBox::critical(this, "Bad login", "Bad login or password"); + } +} diff --git a/application/logindialog.h b/application/logindialog.h new file mode 100644 index 0000000..c905835 --- /dev/null +++ b/application/logindialog.h @@ -0,0 +1,29 @@ +#ifndef LOGINDIALOG_H +#define LOGINDIALOG_H + +#include + +namespace Ui { +class LoginDialog; +} + +class LoginDialog : public QDialog +{ + Q_OBJECT + +public: + explicit LoginDialog(QWidget *parent = 0); + ~LoginDialog(); + QString login() const; + QString password() const; + void reset(); + +private: + Ui::LoginDialog *ui; + + // QDialog interface +public slots: + void accept() override; +}; + +#endif // LOGINDIALOG_H diff --git a/application/logindialog.ui b/application/logindialog.ui new file mode 100644 index 0000000..b4fd75e --- /dev/null +++ b/application/logindialog.ui @@ -0,0 +1,146 @@ + + + LoginDialog + + + + 0 + 0 + 408 + 220 + + + + Login + + + true + + + + 0 + + + 0 + + + 0 + + + + + background-color: rgb(255, 255, 255); + + + + + + + + + :/icons/login_64.png + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + Login + + + + + + + + + + Password + + + + + + + QLineEdit::Password + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + + + + buttonBox + accepted() + LoginDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + LoginDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/application/main.cpp b/application/main.cpp index f332ade..ac8a17e 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -1,5 +1,6 @@ #include "mainwindow.h" #include +#include #include @@ -7,6 +8,7 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; + w.move(QApplication::desktop()->screen()->rect().center() - w.rect().center()); w.show(); return a.exec(); diff --git a/application/mainwindow.cpp b/application/mainwindow.cpp index 05adcbd..2d26eb6 100644 --- a/application/mainwindow.cpp +++ b/application/mainwindow.cpp @@ -13,6 +13,22 @@ MainWindow::MainWindow(QWidget *parent) : ui(new Ui::MainWindow) { ui->setupUi(this); + m_lblUser = new QLabel(this); + ui->statusBar->addWidget(m_lblUser); + + m_loginDialog = new LoginDialog(this); + + connect(m_loginDialog, &LoginDialog::accepted, [this]{ + PermissionService service; + QSharedPointer u = service.loadUser(m_loginDialog->login()); + m_lblUser->setText(u->name()); + m_loginDialog->reset(); + Context::instance().setCurrentUser(u); + }); + + connect(m_loginDialog, &LoginDialog::rejected, [this]{ + close(); + }); Context::instance().loadPlugins(); int i = 0; @@ -27,6 +43,11 @@ MainWindow::MainWindow(QWidget *parent) : } ((QVBoxLayout*)ui->navigation->layout())->addStretch(1); + + if (Context::instance().db() != NULL) + { + ui->navigation->setEnabled(true); + } } MainWindow::~MainWindow() @@ -59,13 +80,37 @@ void MainWindow::openPlugin() void MainWindow::on_actionOpen_database_triggered() { - QFileDialog dialog(this); + /*QFileDialog dialog(this); dialog.setNameFilter(tr("Database Files (*.db)")); - dialog.setWindowTitle(tr("Open Database")); - Context::instance().openDb(dialog.getOpenFileName()); + dialog.setWindowTitle(tr("Open Database"));*/ + + QString dbFile = QFileDialog::getOpenFileName(this, "Open Database", "", "Database Files (*.db)"); + if (!dbFile.isEmpty()) + { + Context::instance().openDb(dbFile); + ui->navigation->setEnabled(true); + on_actionLogin_triggered(); + } } void MainWindow::on_tabWidget_tabCloseRequested(int index) { ui->tabWidget->removeTab(index); } + +void MainWindow::on_actionLogin_triggered() +{ + QSharedPointer u; + Context::instance().setCurrentUser(u); + m_lblUser->setText(""); + m_loginDialog->show(); +} + +void MainWindow::showEvent(QShowEvent *evt) +{ + QWidget::showEvent(evt); + if (Context::instance().db() != NULL && Context::instance().currentUser().data() == NULL) + { + m_loginDialog->show(); + } +} diff --git a/application/mainwindow.h b/application/mainwindow.h index af6786d..dd14b47 100644 --- a/application/mainwindow.h +++ b/application/mainwindow.h @@ -2,6 +2,9 @@ #define MAINWINDOW_H #include +#include + +#include "logindialog.h" #define PLUGIN_INDEX "plug_index" @@ -25,8 +28,16 @@ private slots: void on_tabWidget_tabCloseRequested(int index); + void on_actionLogin_triggered(); + private: Ui::MainWindow *ui; + LoginDialog *m_loginDialog; + QLabel *m_lblUser; + + // QWidget interface +protected: + void showEvent(QShowEvent *evt); }; #endif // MAINWINDOW_H diff --git a/application/mainwindow.ui b/application/mainwindow.ui index d408b6b..901b429 100644 --- a/application/mainwindow.ui +++ b/application/mainwindow.ui @@ -15,8 +15,17 @@ + + 0 + + + 0 + + + false + @@ -52,6 +61,8 @@ File + + @@ -63,6 +74,7 @@ false + @@ -75,8 +87,19 @@ Open database... + + + + :/icons/login_32.png:/icons/login_32.png + + + Login... + + - + + + diff --git a/core/context.cpp b/core/context.cpp index dc607a8..a28b97c 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -15,6 +15,11 @@ #include "roles/roles.h" #include "permissionservice.h" +Context::~Context() +{ + this->destroy(); +} + Context &Context::instance() { static Context ctx; @@ -91,7 +96,10 @@ void Context::destroy() m_dbOpened = false; } - delete m_settings; + if (m_settings != NULL && m_settings->parent() == NULL) + { + delete m_settings; + } foreach (IPlugin *plugin, m_plugins) { @@ -112,6 +120,16 @@ Context::Context() m_dbOpened = false; } +QSharedPointer Context::currentUser() const +{ + return m_currentUser; +} + +void Context::setCurrentUser(const QSharedPointer ¤tUser) +{ + m_currentUser = currentUser; +} + void Context::checkDb(const QString &path) { { @@ -226,4 +244,6 @@ void Context::checkPermissions() } } } + + permService.checkForAdmin(); } diff --git a/core/context.h b/core/context.h index 4ef2cfb..17b9062 100644 --- a/core/context.h +++ b/core/context.h @@ -7,10 +7,12 @@ #include #include #include +#include #include "define.h" #include "core_global.h" #include "transaction.h" +#include "data/core-data.h" #include #include @@ -20,6 +22,7 @@ class IPlugin; class CORESHARED_EXPORT Context { public: + ~Context(); static Context &instance(); QList plugins(); IPlugin *plugin(const QString &pluginId); @@ -31,6 +34,9 @@ public: void destroy(); QStringList defaultPerms(); + QSharedPointer currentUser() const; + void setCurrentUser(const QSharedPointer ¤tUser); + private: Context(); QList m_plugins; @@ -38,6 +44,7 @@ private: QSettings *m_settings; bool m_dbOpened; odb::session m_session; + QSharedPointer m_currentUser; QStringList m_solved; diff --git a/core/core.h b/core/core.h index a8f6fcd..0bfc109 100644 --- a/core/core.h +++ b/core/core.h @@ -7,5 +7,6 @@ #include "imetadataplugin.h" #include "transaction.h" #include "gridform.h" +#include "permissionservice.h" #endif // CORE_H diff --git a/core/filterui.ui b/core/filterui.ui index 5c3e4a9..c39fdcd 100644 --- a/core/filterui.ui +++ b/core/filterui.ui @@ -70,14 +70,11 @@ Apply - - 1 - Go - + :/icons/ok.svg:/icons/ok.svg @@ -119,14 +116,11 @@ Save - - 1 - Save - + :/icons/save.svg:/icons/save.svg @@ -145,14 +139,11 @@ Manage - - 1 - Manage - + :/icons/list.svg:/icons/list.svg @@ -229,6 +220,8 @@ - + + + diff --git a/core/gridform.h b/core/gridform.h index cb80568..953098f 100644 --- a/core/gridform.h +++ b/core/gridform.h @@ -30,6 +30,16 @@ public: } virtual ~GridForm() { + if (m_form != NULL && m_form->parent() == NULL) + { + delete m_form; + } + + if (m_tableModel != NULL && m_tableModel->parent() == NULL) + { + delete m_tableModel; + } + delete m_formHandler; } diff --git a/core/gridform.ui b/core/gridform.ui index adb0a8f..a201617 100644 --- a/core/gridform.ui +++ b/core/gridform.ui @@ -19,6 +19,9 @@ + + Add record + false @@ -45,6 +48,9 @@ + + Edit record + E @@ -65,6 +71,9 @@ + + Delete record + D @@ -85,6 +94,9 @@ + + Filter + F @@ -108,6 +120,9 @@ + + Print + P diff --git a/core/igridform.cpp b/core/igridform.cpp index 560a794..986b03c 100644 --- a/core/igridform.cpp +++ b/core/igridform.cpp @@ -21,6 +21,7 @@ IGridForm::IGridForm(QWidget *parent) : IGridForm::~IGridForm() { + delete ui; } void IGridForm::setPluginId(const QString &pluginId) diff --git a/core/imetadataplugin.cpp b/core/imetadataplugin.cpp index 2c92307..0f4fcfd 100644 --- a/core/imetadataplugin.cpp +++ b/core/imetadataplugin.cpp @@ -10,14 +10,11 @@ IMetaDataPlugin::IMetaDataPlugin() { m_service = NULL; + m_ui = NULL; } IMetaDataPlugin::~IMetaDataPlugin() { - if (m_service != NULL) - { - delete m_service; - } } QString IMetaDataPlugin::pluginName() diff --git a/core/imetadataplugin.h b/core/imetadataplugin.h index a9c7f2d..ece23ca 100644 --- a/core/imetadataplugin.h +++ b/core/imetadataplugin.h @@ -10,7 +10,7 @@ class CORESHARED_EXPORT IMetaDataPlugin : public IPlugin { public: IMetaDataPlugin(); - ~IMetaDataPlugin(); + virtual ~IMetaDataPlugin(); // IPlugin interface public: diff --git a/core/iplugin.h b/core/iplugin.h index fce9a2f..990fa44 100644 --- a/core/iplugin.h +++ b/core/iplugin.h @@ -19,7 +19,18 @@ public: m_service = NULL; } - virtual ~IPlugin() { } + virtual ~IPlugin() { + if (m_service != NULL) + { + delete m_service; + } + + if (m_ui != NULL && m_ui->parent() == NULL) + { + delete m_ui; + } + } + virtual QString pluginName() = 0; virtual QString pluginId() = 0; virtual QString pluginDescription() = 0; diff --git a/core/permissionservice.cpp b/core/permissionservice.cpp index f3a0b60..c222b3c 100644 --- a/core/permissionservice.cpp +++ b/core/permissionservice.cpp @@ -1,4 +1,9 @@ +#include "core-odb.hxx" #include "permissionservice.h" +#include + +typedef odb::query permQuery; +typedef odb::result permResult; PermissionService::PermissionService() { @@ -36,3 +41,51 @@ QSharedPointer PermissionService::forNameAndPlugin(const QString &na return p; } +bool PermissionService::checkLogin(const QString &login, const QString &password) +{ + + QSharedPointer user = loadUser(login); + if (user.data()) + { + return user->password() == encryptPassword(password) && user->active(); + } + + return false; +} + +QSharedPointer PermissionService::loadUser(const QString &login) +{ + odb::database *db = Context::instance().db(); + + Transaction tr; + return db->query_one("login = " + odb::query::_ref(login)); +} + +void PermissionService::checkForAdmin() +{ + odb::database *db = Context::instance().db(); + + Transaction tr; + odb::query q(odb::query::isAdmin == true); + odb::result r = db->query(q); + + if (r.empty()) + { + QSharedPointer admin(new User); + admin->setLogin("admin"); + admin->setName("Administrator"); + admin->setIsAdmin(true); + admin->setPassword(encryptPassword("admin")); + admin->setActive(true); + + db->persist(admin); + } + + tr.commit(); +} + +QString PermissionService::encryptPassword(const QString &plainPasswd) +{ + return QString(QCryptographicHash::hash(plainPasswd.toUtf8(),QCryptographicHash::Sha256).toBase64()); +} + diff --git a/core/permissionservice.h b/core/permissionservice.h index f48af7f..000660a 100644 --- a/core/permissionservice.h +++ b/core/permissionservice.h @@ -2,8 +2,7 @@ #define PERMISSIONSERVICE_H #include "service.h" -#include "permission.h" -#include "core-odb.hxx" +#include "data/core-data.h" #include "core_global.h" #include #include @@ -14,9 +13,6 @@ #include #include -typedef odb::query permQuery; -typedef odb::result permResult; - class CORESHARED_EXPORT PermissionService : public Service { public: @@ -25,6 +21,10 @@ public: QList > forPlugin(const QString &pluginId); QSharedPointer forNameAndPlugin(const QString &name, const QString &pluginId); + bool checkLogin(const QString &login, const QString &password); + QSharedPointer loadUser(const QString &login); + void checkForAdmin(); + QString encryptPassword(const QString &plainPasswd); }; #endif // PERMISSIONSERVICE_H diff --git a/core/users/userform.cpp b/core/users/userform.cpp index dd3edc8..1b8ce7d 100644 --- a/core/users/userform.cpp +++ b/core/users/userform.cpp @@ -5,9 +5,9 @@ #include #include "../data/core-data.h" #include "../service.h" +#include "../permissionservice.h" #include "../emptystringvalidator.h" #include "../samestringvalidator.h" -#include UserForm::UserForm(QWidget *parent) : AutoForm(parent), @@ -69,8 +69,9 @@ bool UserForm::bindOtherToData() this->entity()->addRole(srv.loadById(ui->tableWidget->item(i,0)->data(Qt::UserRole).toInt())); } } + PermissionService permService; if (m_passChanged){ - this->entity()->setPassword(QString(QCryptographicHash::hash(ui->password->text().toUtf8(),QCryptographicHash::Sha256).toBase64())); + this->entity()->setPassword(permService.encryptPassword(ui->password->text())); } return true; } From 69c6068c0dd46ec0c3b6898e76158f1a94a1050b Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Tue, 9 Feb 2016 10:10:22 +0100 Subject: [PATCH 2/4] Added -p switch to cp command in ODB build phase. --- odb.pri | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/odb.pri b/odb.pri index afcea2e..237db9a 100644 --- a/odb.pri +++ b/odb.pri @@ -72,7 +72,12 @@ odb.clean = $$TARGET-odb.cxx $$TARGET-odb.hxx $$TARGET-odb.ixx $$TARGET.sql QMAKE_EXTRA_COMPILERS += odb odbhc.target = odbhc -odbhc.commands = $(COPY) $$H_DIR . +unix { + odbhc.commands = $(COPY) -p $$H_DIR . +} +win32 { + odbhc.commands = $(COPY) $$H_DIR . +} QMAKE_EXTRA_TARGETS += odbhc PRE_TARGETDEPS += odbhc From bc77f671ae93f4ea396c9cdaccc7b29fbd8aab1f Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Tue, 9 Feb 2016 10:33:08 +0100 Subject: [PATCH 3/4] Fixed MSVS build. --- core/core.pro | 3 ++- core/data/core_global.h | 12 ++++++++++++ core/data/permission.h | 3 ++- core/data/role.h | 3 ++- core/data/user.h | 3 ++- 5 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 core/data/core_global.h diff --git a/core/core.pro b/core/core.pro index 0dd72c2..bdd8b7e 100644 --- a/core/core.pro +++ b/core/core.pro @@ -81,7 +81,8 @@ HEADERS += core.h\ samestringvalidator.h \ savefilterdialog.h \ filterdialog.h \ - itablemodel.h + itablemodel.h \ + data/core_global.h unix { target.path = /usr/lib diff --git a/core/data/core_global.h b/core/data/core_global.h new file mode 100644 index 0000000..b519481 --- /dev/null +++ b/core/data/core_global.h @@ -0,0 +1,12 @@ +#ifndef CORE_GLOBAL_H +#define CORE_GLOBAL_H + +#include + +#if defined(CORE_LIBRARY) +# define CORESHARED_EXPORT Q_DECL_EXPORT +#else +# define CORESHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // CORE_GLOBAL_H diff --git a/core/data/permission.h b/core/data/permission.h index c6dcfca..ba6b1c7 100644 --- a/core/data/permission.h +++ b/core/data/permission.h @@ -2,6 +2,7 @@ #define PERMISSION_H #include "core-data.h" +#include "core_global.h" #include #include @@ -12,7 +13,7 @@ #include #pragma db object -class Permission : public QObject +class CORESHARED_EXPORT Permission : public QObject { Q_OBJECT Q_PROPERTY(QString pluginId READ pluginId WRITE setPluginId) diff --git a/core/data/role.h b/core/data/role.h index 44d1a38..3119f5f 100644 --- a/core/data/role.h +++ b/core/data/role.h @@ -2,6 +2,7 @@ #define ROLE_H #include "core-data.h" +#include "core_global.h" #include #include @@ -12,7 +13,7 @@ #include #pragma db object -class Role : public QObject +class CORESHARED_EXPORT Role : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName) diff --git a/core/data/user.h b/core/data/user.h index 0bce4d5..d7e8b85 100644 --- a/core/data/user.h +++ b/core/data/user.h @@ -2,6 +2,7 @@ #define USER_H #include "core-data.h" +#include "core_global.h" #include #include @@ -12,7 +13,7 @@ #include #pragma db object -class User : public QObject +class CORESHARED_EXPORT User : public QObject { Q_OBJECT Q_PROPERTY(QString login READ login WRITE setLogin) From 3d9e18253120e62a0e8bf35e1bcef5bfc78803b3 Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Tue, 9 Feb 2016 16:05:02 +0100 Subject: [PATCH 4/4] Added IService QObject derived class for emiting Qt signals from service objects. --- core/core.pro | 6 ++-- core/iplugin.h | 2 +- core/iservice.cpp | 12 +++++++ core/iservice.h | 25 +++++++++++++++ core/service.h | 79 ++++++++++++++++++++++++++++++++++++++--------- 5 files changed, 106 insertions(+), 18 deletions(-) create mode 100644 core/iservice.cpp create mode 100644 core/iservice.h diff --git a/core/core.pro b/core/core.pro index bdd8b7e..509247f 100644 --- a/core/core.pro +++ b/core/core.pro @@ -42,7 +42,8 @@ SOURCES += \ samestringvalidator.cpp \ savefilterdialog.cpp \ filterdialog.cpp \ - itablemodel.cpp + itablemodel.cpp \ + iservice.cpp HEADERS += core.h\ core_global.h \ @@ -82,7 +83,8 @@ HEADERS += core.h\ savefilterdialog.h \ filterdialog.h \ itablemodel.h \ - data/core_global.h + data/core_global.h \ + iservice.h unix { target.path = /usr/lib diff --git a/core/iplugin.h b/core/iplugin.h index 990fa44..6a1605b 100644 --- a/core/iplugin.h +++ b/core/iplugin.h @@ -58,7 +58,7 @@ public: protected: QWidget *m_ui; - void *m_service; + IService *m_service; }; #define PluginInterface_iid "cz.itsolved.prodejna.IPlugin" diff --git a/core/iservice.cpp b/core/iservice.cpp new file mode 100644 index 0000000..281d46b --- /dev/null +++ b/core/iservice.cpp @@ -0,0 +1,12 @@ +#include "iservice.h" + +IService::IService(QObject *parent) : QObject(parent) +{ + +} + +IService::~IService() +{ + +} + diff --git a/core/iservice.h b/core/iservice.h new file mode 100644 index 0000000..eabc038 --- /dev/null +++ b/core/iservice.h @@ -0,0 +1,25 @@ +#ifndef ISERVICE_H +#define ISERVICE_H + +#include +#include + +#include "core_global.h" + +class CORESHARED_EXPORT IService : public QObject +{ + Q_OBJECT + +public: + explicit IService(QObject *parent = 0); + virtual ~IService(); + +signals: + void dbError(QString errMsg); + void dataChanged(); + void permissionDenied(); + +public slots: +}; + +#endif // ISERVICE_H diff --git a/core/service.h b/core/service.h index f56207e..e6d1f48 100644 --- a/core/service.h +++ b/core/service.h @@ -12,14 +12,15 @@ #include "core_global.h" #include "context.h" +#include "iservice.h" #include "transaction.h" template -class Service +class Service : public IService { public: - Service() { } + explicit Service(QObject *parent = NULL) :IService(parent) { } explicit Service(const QString &pluginId) { m_pluginId = pluginId; @@ -31,14 +32,23 @@ public: Q_ASSERT(db); Transaction tx; - odb::result res = db->template query(); - QList > ret; - for (typename odb::result::iterator it = res.begin(); it != res.end(); it++) { - ret.append(it.load()); + + try + { + odb::result res = db->template query(); + + for (typename odb::result::iterator it = res.begin(); it != res.end(); it++) { + ret.append(it.load()); + } + + tx.commit(); + } + catch (const odb::exception &ex) + { + emit dbError(ex.what()); } - tx.commit(); return ret; } @@ -48,8 +58,19 @@ public: Q_ASSERT(db); Transaction tx; - db->persist(entity); - tx.commit(); + + try + { + db->persist(entity); + tx.commit(); + } + catch (const odb::exception &ex) + { + emit dbError(ex.what()); + return; + } + + emit dataChanged(); } void update(QSharedPointer entity) { @@ -58,8 +79,18 @@ public: Q_ASSERT(db); Transaction tx; - db->update(entity); - tx.commit(); + + try + { + db->update(entity); + tx.commit(); + } + catch (const odb::exception &ex) + { + emit dbError(ex.what()); + } + + emit dataChanged(); } QSharedPointer loadById(int id) { @@ -68,8 +99,18 @@ public: Q_ASSERT(db); Transaction tx; - QSharedPointer entity = db->template load(id); - tx.commit(); + QSharedPointer entity; + + try + { + entity = db->template load(id); + tx.commit(); + } + catch (const odb::exception &ex) + { + emit dbError(ex.what()); + } + return entity; } @@ -79,8 +120,16 @@ public: Q_ASSERT(db); Transaction tx; - db->erase(entity); - tx.commit(); + + try + { + db->erase(entity); + tx.commit(); + } + catch (const odb::exception &ex) + { + emit dbError(ex.what()); + } } void setPluginId(const QString &pluginId) {