From 6370050204b8b624932799e0997f329ce338c69d Mon Sep 17 00:00:00 2001 From: Eelke Klein Date: Wed, 1 Feb 2017 18:01:02 +0100 Subject: [PATCH] Introduced the MasterController as part of working on loading catalogue information. Need a central piece to manage the catalogue data per database to prevent loading this multiple times. MasterController is now also used to enable reopening the connection manager from a query window after the connection manager has been closed. --- MasterController.cpp | 27 +++++++ MasterController.h | 36 +++++++++ backupdialog.cpp | 14 ++++ backupdialog.h | 22 ++++++ backupdialog.ui | 54 ++++++++++++++ connectionconfig.cpp | 10 +++ connectionconfig.h | 1 + connectionmanagerwindow.cpp | 48 ++++++++---- connectionmanagerwindow.h | 8 +- connectionmanagerwindow.ui | 14 +++- icons/16x16/document_green.png | Bin 0 -> 1309 bytes icons/16x16/document_red.png | Bin 0 -> 1306 bytes icons/16x16/document_yellow.png | Bin 0 -> 1302 bytes icons/backups.png | Bin 0 -> 2377 bytes main.cpp | 10 +-- mainwindow.cpp | 25 ++++++- mainwindow.h | 7 +- mainwindow.ui | 12 +++ opendatabase.cpp | 30 ++++++++ opendatabase.h | 32 ++++++++ paramlistmodel.cpp | 127 ++++++++++++++++++++++++++++++++ paramlistmodel.h | 41 +++++++++++ paramtypedelegate.cpp | 29 ++++++++ paramtypedelegate.h | 25 +++++++ pgclass.cpp | 3 + pgclass.h | 26 +++++++ pglab.pro | 23 +++++- pgnamespace.cpp | 4 + pgnamespace.h | 17 +++++ pgtypecontainer.cpp | 1 - querytab.cpp | 80 ++++++++++++++------ querytab.h | 8 ++ querytab.ui | 29 +++----- resources.qrc | 4 + typeselectionitemmodel.cpp | 52 +++++++++++++ typeselectionitemmodel.h | 21 ++++++ 36 files changed, 769 insertions(+), 71 deletions(-) create mode 100644 MasterController.cpp create mode 100644 MasterController.h create mode 100644 backupdialog.cpp create mode 100644 backupdialog.h create mode 100644 backupdialog.ui create mode 100644 icons/16x16/document_green.png create mode 100644 icons/16x16/document_red.png create mode 100644 icons/16x16/document_yellow.png create mode 100644 icons/backups.png create mode 100644 opendatabase.cpp create mode 100644 opendatabase.h create mode 100644 paramlistmodel.cpp create mode 100644 paramlistmodel.h create mode 100644 paramtypedelegate.cpp create mode 100644 paramtypedelegate.h create mode 100644 pgclass.cpp create mode 100644 pgclass.h create mode 100644 pgnamespace.cpp create mode 100644 pgnamespace.h create mode 100644 typeselectionitemmodel.cpp create mode 100644 typeselectionitemmodel.h diff --git a/MasterController.cpp b/MasterController.cpp new file mode 100644 index 0000000..4e55203 --- /dev/null +++ b/MasterController.cpp @@ -0,0 +1,27 @@ +#include "MasterController.h" +#include "connectionmanagerwindow.h" +#include "connectionlistmodel.h" + + +MasterController::MasterController(QObject *parent) : QObject(parent) +{} + +MasterController::~MasterController() +{ + delete m_connectionManagerWindow; + delete m_connectionListModel; +} + +void MasterController::init() +{ + m_connectionListModel = new ConnectionListModel(this); + + m_connectionManagerWindow = new ConnectionManagerWindow(this, nullptr); + m_connectionManagerWindow->show(); + +} + +void MasterController::showConnectionManager() +{ + m_connectionManagerWindow->show(); +} diff --git a/MasterController.h b/MasterController.h new file mode 100644 index 0000000..3dd5fe1 --- /dev/null +++ b/MasterController.h @@ -0,0 +1,36 @@ +#ifndef MASTERCONTROLLER_H +#define MASTERCONTROLLER_H + +#include +#include + +class ConnectionConfig; +class ConnectionListModel; +class ConnectionManagerWindow; + +class MasterController : public QObject +{ + Q_OBJECT +public: + explicit MasterController(QObject *parent = 0); + ~MasterController(); + + void init(); + + ConnectionListModel *getConnectionListModel() + { + return m_connectionListModel; + } + + void showConnectionManager(); + +signals: + +public slots: + +private: + ConnectionListModel *m_connectionListModel = nullptr; + ConnectionManagerWindow *m_connectionManagerWindow = nullptr; +}; + +#endif // MASTERCONTROLLER_H diff --git a/backupdialog.cpp b/backupdialog.cpp new file mode 100644 index 0000000..76fd0a3 --- /dev/null +++ b/backupdialog.cpp @@ -0,0 +1,14 @@ +#include "backupdialog.h" +#include "ui_backupdialog.h" + +BackupDialog::BackupDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::BackupDialog) +{ + ui->setupUi(this); +} + +BackupDialog::~BackupDialog() +{ + delete ui; +} diff --git a/backupdialog.h b/backupdialog.h new file mode 100644 index 0000000..c8f85ab --- /dev/null +++ b/backupdialog.h @@ -0,0 +1,22 @@ +#ifndef BACKUPDIALOG_H +#define BACKUPDIALOG_H + +#include + +namespace Ui { +class BackupDialog; +} + +class BackupDialog : public QDialog +{ + Q_OBJECT + +public: + explicit BackupDialog(QWidget *parent = 0); + ~BackupDialog(); + +private: + Ui::BackupDialog *ui; +}; + +#endif // BACKUPDIALOG_H diff --git a/backupdialog.ui b/backupdialog.ui new file mode 100644 index 0000000..97ea498 --- /dev/null +++ b/backupdialog.ui @@ -0,0 +1,54 @@ + + + BackupDialog + + + + 0 + 0 + 645 + 295 + + + + Dialog + + + + + + + + + + + + PushButton + + + + + + + + + + Format + + + + + + + + + + Filename + + + + + + + + diff --git a/connectionconfig.cpp b/connectionconfig.cpp index 68fc714..bcd961a 100644 --- a/connectionconfig.cpp +++ b/connectionconfig.cpp @@ -200,3 +200,13 @@ const char * const * ConnectionConfig::getValues() const return m_values.data(); } + +bool ConnectionConfig::isSameDatabase(const ConnectionConfig &rhs) const +{ + return m_host == rhs.m_host + && m_hostaddr == rhs.m_hostaddr + && m_port == rhs.m_port + && m_user == rhs.m_user + && m_password == rhs.m_password + && m_dbname == rhs.m_dbname; +} diff --git a/connectionconfig.h b/connectionconfig.h index 9412ddf..2e12228 100644 --- a/connectionconfig.h +++ b/connectionconfig.h @@ -56,6 +56,7 @@ public: const char * const * getKeywords() const; const char * const * getValues() const; + bool isSameDatabase(const ConnectionConfig &rhs) const; private: std::string m_name; std::string m_host; diff --git a/connectionmanagerwindow.cpp b/connectionmanagerwindow.cpp index 0b2cb26..7ea6963 100644 --- a/connectionmanagerwindow.cpp +++ b/connectionmanagerwindow.cpp @@ -1,20 +1,22 @@ #include "connectionmanagerwindow.h" #include "ui_connectionmanagerwindow.h" #include "mainwindow.h" +#include "MasterController.h" #include #include #include #include "connectionlistmodel.h" -ConnectionManagerWindow::ConnectionManagerWindow(QWidget *parent) +ConnectionManagerWindow::ConnectionManagerWindow(MasterController *master, QWidget *parent) : QMainWindow(parent) , ui(new Ui::ConnectionManagerWindow) - , m_listModel(new ConnectionListModel(this)) +// , m_listModel(new ConnectionListModel(this)) + , m_masterController(master) { ui->setupUi(this); - ui->listView->setModel(m_listModel); + ui->listView->setModel(m_masterController->getConnectionListModel()); setupWidgetMappings(); @@ -26,10 +28,10 @@ ConnectionManagerWindow::ConnectionManagerWindow(QWidget *parent) ConnectionManagerWindow::~ConnectionManagerWindow() { - m_listModel->save(); +// m_listModel->save(); delete ui; - delete m_listModel; +// delete m_listModel; delete m_mapper; } @@ -37,10 +39,13 @@ void ConnectionManagerWindow::on_actionAdd_Connection_triggered() { ConnectionConfig c; c.setName("new"); - m_listModel->add(c); + //m_listModel->add(c); + + auto clm = m_masterController->getConnectionListModel(); + clm->add(c); // Select the new row - auto idx = m_listModel->index(m_listModel->rowCount() - 1, 0); + auto idx = clm->index(clm->rowCount() - 1, 0); ui->listView->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::Select); } @@ -48,7 +53,8 @@ void ConnectionManagerWindow::on_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { int currow = current.row(); - m_listModel->save(prevSelection); + auto clm = m_masterController->getConnectionListModel(); + clm->save(prevSelection); m_mapper->setCurrentIndex(currow); prevSelection = currow; } @@ -57,15 +63,17 @@ void ConnectionManagerWindow::on_actionDelete_connection_triggered() { auto ci = ui->listView->selectionModel()->currentIndex(); if (ci.isValid()) { - m_listModel->removeRow(ci.row()); + auto clm = m_masterController->getConnectionListModel(); + clm->removeRow(ci.row()); } } void ConnectionManagerWindow::setupWidgetMappings() { + auto clm = m_masterController->getConnectionListModel(); m_mapper = new QDataWidgetMapper(this); - m_mapper->setModel(m_listModel); + m_mapper->setModel(clm); m_mapper->addMapping(ui->edtName, 1); m_mapper->addMapping(ui->edtHost, 2); m_mapper->addMapping(ui->spinPort, 3); @@ -77,12 +85,19 @@ void ConnectionManagerWindow::setupWidgetMappings() void ConnectionManagerWindow::on_actionConnect_triggered() { - // Open a window for this connection, maybe we should first check the connection? + // maybe we should first check the connection? + + // Have we loaded the catalogue? + // If not do so now + + + auto clm = m_masterController->getConnectionListModel(); + // Open a window for this connection, auto ci = ui->listView->selectionModel()->currentIndex(); - auto cc = m_listModel->get(ci.row()); - m_listModel->save(ci.row()); + auto cc = clm->get(ci.row()); + clm->save(ci.row()); if (cc.valid()) { - auto w = new MainWindow; + auto w = new MainWindow(m_masterController, nullptr); w->setAttribute( Qt::WA_DeleteOnClose ); w->setConfig(cc.get()); w->show(); @@ -99,3 +114,8 @@ void ConnectionManagerWindow::on_actionQuit_application_triggered() //closeAllWindows(); } + +void ConnectionManagerWindow::on_actionBackup_database_triggered() +{ + // BACKUP +} diff --git a/connectionmanagerwindow.h b/connectionmanagerwindow.h index b6ed175..3794a60 100644 --- a/connectionmanagerwindow.h +++ b/connectionmanagerwindow.h @@ -7,8 +7,8 @@ namespace Ui { class ConnectionManagerWindow; } -class ConnectionListModel; class ConnectionConfig; +class MasterController; class QDataWidgetMapper; class QStandardItemModel; @@ -17,7 +17,7 @@ class ConnectionManagerWindow : public QMainWindow Q_OBJECT public: - explicit ConnectionManagerWindow(QWidget *parent = 0); + explicit ConnectionManagerWindow(MasterController *master, QWidget *parent = 0); ~ConnectionManagerWindow(); private slots: @@ -29,10 +29,12 @@ private slots: void on_actionQuit_application_triggered(); + void on_actionBackup_database_triggered(); + private: Ui::ConnectionManagerWindow *ui; - ConnectionListModel *m_listModel = nullptr; QDataWidgetMapper *m_mapper = nullptr; + MasterController *m_masterController; int prevSelection = -1; diff --git a/connectionmanagerwindow.ui b/connectionmanagerwindow.ui index 33042f3..dc4095d 100644 --- a/connectionmanagerwindow.ui +++ b/connectionmanagerwindow.ui @@ -194,7 +194,7 @@ 0 0 800 - 25 + 22 @@ -225,6 +225,8 @@ + + @@ -262,6 +264,16 @@ Quit application + + + + :/icons/backups.png + + + + Backup database + + diff --git a/icons/16x16/document_green.png b/icons/16x16/document_green.png new file mode 100644 index 0000000000000000000000000000000000000000..5624c3c35212542db16d8a0ad967c0132d68ee4b GIT binary patch literal 1309 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 UJN=J*3M#2QUHx3vIVCg!00e^6mH+?% literal 0 HcmV?d00001 diff --git a/icons/backups.png b/icons/backups.png new file mode 100644 index 0000000000000000000000000000000000000000..41b14aa356e455621dda08b342960a7aa6821cc1 GIT binary patch literal 2377 zcmaJ@X;>5I8Vw?dVR09th(n|*OZEgvBp{NoSb`9uL=nt3gcOpA$shqmW2sV5Tu_#x zhzdneq@q-%pv7WY6tHYs*{L94WeZXfu-st9-XGUH&olEa&pGEk@A6~feSJKPk*kmh z1j5+Mlfl-m!0c7ggpd@=pT%HRQn{9mKsdRmz^o!)07bxbwASfADM;m?WM#^aWzrT5r{c?T1T20wr8yvr_5Yz#=_j-jW`qCw z{hz{0PLv$Pu|Xvip%7{t7qV_Pl$_?K0QoSa;6PCLTorvoAsAAILUO>(pMoU-0TP)A zid25Uvsg4QnG)v9grFCLj@Bw*B@z+M-Q9ug=uTo%9Nnn|0+Z;<&{oQUOtL319SKwd zWsb{$gb`9u2G4Ot|8m_w%bgtssazYG0V*W>K#{uwk^&!6rb#~U#qG0tAGxB>dtrQ* zi_@CH%{KPG8a;QVou1k4r?J%@J`Fx7(@wiWJJ!}NS5G1kdiT5-t{hcMX+Yq%-P@N3 z_YuWB>~Y;1gmuww8}fSO%3a80POD&5mP8;}CM9oGX-w0aOdIScIWy|f2LWg9Pw>3I z&oO=dgG=Uj}Srr&Cyv^z`1)(9G25)X+cL}tVzTg ztMnQ=P*bcz3N&U3%%EzJA@F9+f8|8b@D1)#5r#(0w96G@#aX<*RRCXYKTCx&WywELKcK#NI?5E6+hzr$4vF zuHD7uW{15l?#7{6&%iz6;hKEC`8&%kM8GkUqv4uUN3;d0*s;Xd+3{U>!N$HNy-7Yl zyhQu%39!9%A?-XmcI*cdm7;&NK~;KQP)M{UadiGN%Cx-6y;jg+IdHfD4%rUt>T-h( zt5Ck?24@ee04%~UBn3oHjnYqhR$1gc%5LCTJEs)pov9X+#tN^HMt1}RF!K(37HfKn z=2<%2uwQlYSHWmqQWCyT6R&EF;<;oTnE9q>*;xN+hkl+%iOS^U0rSMbShuqR{Hdat z8D~rDsPSQ+?GcYqez7th;_;WUVs)K`$C`%UlUi3hEEsr__g!0e-T-Q6A8D=c+Hho-o=Po!C^S`L@5%Z_$xoAOR_3t0C}m zu(f=;bJQTyxV&m_xzM2}MBF#<_j{^W@=#-Fq}#puD%lXuCm!3rWWNLp@$fqw*19A^ z>Xh1$+J*-9F7EE-i|U;ac&F*OGf#}Wg5!3dV_cG}gL_j9vw%%R`yn%Rf}lW@wr!Ma zRGJWe9FbWcteJ{w8~47=-TV9+{ry+EV==TNv98_TAgCAl*v9e;&&a8|pbdJtW@PdS z16ViK_^QUS3w3eF!xvj>;Fjuh9ywQD+|tQkF_;?Lx0{xN89yYRz|s#)+*#aQvWSO= zb;}B^<*Q~b{{jbV!Z$byw7L%F|(5H98 zx9n~>4-H5k@EPj(>nW*~kDmWhq#QwY^zGVU`)cN0l5zt8hPuBChRjkJmaH6>-TE*{)_dpO#rczU3w zhHPx2xUNjJ)jN3NxyI@-J1oq$Gi}pATR@*oWnJc2-}1DgIPh|MMv0;ZldCh7wcZT5 z?1rkea%_`X*Nb=i@MeOilkb9Yk)8AOPN)Y20OGBv%? z@%!}A6r=WQ9zk#G2O7mzGbRfSUCc-9#>dBde~KCcH4~%41O~b_X(rJLv115zJERP` zXZeG+K=~A#xA5tD-KFthK|NZh(?|DwWvynVzEyzrVx#a$3a39aL`aet%@Lm7_ literal 0 HcmV?d00001 diff --git a/main.cpp b/main.cpp index 3b68dad..aea82ab 100644 --- a/main.cpp +++ b/main.cpp @@ -1,8 +1,7 @@ -//#include "mainwindow.h" -//#include "databasewindow.h" -#include "connectionmanagerwindow.h" +#include "MasterController.h" #include #include +#include int main(int argc, char *argv[]) { @@ -24,8 +23,9 @@ int main(int argc, char *argv[]) QCoreApplication::setOrganizationDomain("eelkeklein.nl"); QCoreApplication::setApplicationName("pglab"); - ConnectionManagerWindow w; - w.show(); + auto master_controller = std::make_unique(); + master_controller->init(); + int result = a.exec(); diff --git a/mainwindow.cpp b/mainwindow.cpp index 962a536..5470b1c 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -14,14 +14,15 @@ #include #include #include "util.h" - +#include "MasterController.h" namespace pg = Pgsql; -MainWindow::MainWindow(QWidget *parent) +MainWindow::MainWindow(MasterController *master, QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) + , m_masterController(master) { ui->setupUi(this); @@ -132,7 +133,19 @@ void MainWindow::on_actionClose_triggered() void MainWindow::on_actionAbout_triggered() { - // + QMessageBox::about(this, "pgLab 0.1", tr( + "Copyrights 2016-2017, Eelke Klein, All Rights Reserved.\n" + "\n" + "The program is provided AS IS with NO WARRANTY OF ANY KIND," + " INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS " + "FOR A PARTICULAR PURPOSE.\n" + "\n" + "This program is dynamically linked with Qt 5.7 Copyright (C) 2016 The Qt Company Ltd. https://www.qt.io/licensing/. \n" + "\n" + "Icons by fatcow http://www.fatcow.com/free-icons provided under Creative Commons " + "attribution 3.0 license\n" + )); + } #if false @@ -231,5 +244,11 @@ void MainWindow::on_tabWidget_tabCloseRequested(int index) if (qt->canClose()) { ui->tabWidget->removeTab(index); } + } + +void MainWindow::on_actionShow_connection_manager_triggered() +{ + m_masterController->showConnectionManager(); +} diff --git a/mainwindow.h b/mainwindow.h index 230ce7c..98324c1 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -27,14 +27,14 @@ namespace Pgsql { } class QueryTab; - +class MasterController; class QCloseEvent; class MainWindow : public QMainWindow { Q_OBJECT public: - explicit MainWindow(QWidget *parent = 0); + explicit MainWindow(MasterController *master, QWidget *parent); ~MainWindow(); void setConfig(const ConnectionConfig &config); @@ -51,6 +51,8 @@ private: TSQueue m_taskQueue; ConnectionConfig m_config; + MasterController *m_masterController; + QueryTab *GetActiveQueryTab(); @@ -75,6 +77,7 @@ private slots: void on_actionNew_SQL_triggered(); void on_tabWidget_tabCloseRequested(int index); void on_actionExplain_triggered(); + void on_actionShow_connection_manager_triggered(); }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 9e066de..992e559 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -77,8 +77,15 @@ + + + Window + + + + @@ -238,6 +245,11 @@ F7 + + + Show connection manager + + diff --git a/opendatabase.cpp b/opendatabase.cpp new file mode 100644 index 0000000..06934d0 --- /dev/null +++ b/opendatabase.cpp @@ -0,0 +1,30 @@ +#include "opendatabase.h" +#include "pgsqldatabasecatalogue.h" + +Expected OpenDatabase::createOpenDatabase(const ConnectionConfig &cfg) +{ + OpenDatabase *odb = new OpenDatabase(cfg, nullptr); + if (odb->Init()) { + + return odb; + } + //return Expected::fromException(std::out_of_range("Invalid row")); +} + +OpenDatabase::OpenDatabase(const ConnectionConfig& cfg, QObject *parent) + : QObject(parent) + , m_config(cfg) + , m_catalogue(new PgsqlDatabaseCatalogue) +{ +} + +OpenDatabase::~OpenDatabase() +{ + delete m_catalogue; +} + +bool OpenDatabase::Init() +{ +// m_catalogue->load(m_config); + return true; +} diff --git a/opendatabase.h b/opendatabase.h new file mode 100644 index 0000000..91fe0e5 --- /dev/null +++ b/opendatabase.h @@ -0,0 +1,32 @@ +#ifndef OPENDATABASE_H +#define OPENDATABASE_H + +#include +#include "connectionconfig.h" +#include "expected.h" + +class PgsqlDatabaseCatalogue; + +class OpenDatabase : public QObject +{ + Q_OBJECT +public: + static Expected createOpenDatabase(const ConnectionConfig &cfg); + + OpenDatabase(const OpenDatabase &) = delete; + OpenDatabase& operator=(const OpenDatabase &) = delete; + ~OpenDatabase(); + +signals: + +public slots: + +private: + ConnectionConfig m_config; + PgsqlDatabaseCatalogue *m_catalogue; + + OpenDatabase(const ConnectionConfig& cfg, QObject *parent = 0); + bool Init(); +}; + +#endif // OPENDATABASE_H diff --git a/paramlistmodel.cpp b/paramlistmodel.cpp new file mode 100644 index 0000000..4a917ed --- /dev/null +++ b/paramlistmodel.cpp @@ -0,0 +1,127 @@ +#include "paramlistmodel.h" + +ParamListModel::ParamListModel(QObject *parent) + : QAbstractTableModel(parent) +{ +} + +QVariant ParamListModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + // FIXME: Implement me! + QVariant result; + if (orientation == Qt::Horizontal) { + if (role == Qt::DisplayRole) { + if (section == 0) { +// result = tr("$n"); + result = tr("Value"); + } + else if (section == 1) { + result = tr("Type"); + } + } + } + else if (orientation == Qt::Vertical) { + if (role == Qt::DisplayRole) { + result = tr("$%1").arg(section + 1); + } + } + return result; +} + +//bool ParamListModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) +//{ +// if (value != headerData(section, orientation, role)) { +// // FIXME: Implement me! +// emit headerDataChanged(orientation, section, section); +// return true; +// } +// return false; +//} + + +int ParamListModel::rowCount(const QModelIndex &parent) const +{ + //if (parent.isValid()) + return 2; + + // FIXME: Implement me! +} + +int ParamListModel::columnCount(const QModelIndex &parent) const +{ + //if (parent.isValid()) + return 2; + + // FIXME: Implement me! +} + +QVariant ParamListModel::data(const QModelIndex &index, int role) const +{ + QVariant result; + if (index.isValid()) { + int row = index.row(); + int col = index.column(); + if (role == Qt::DisplayRole) { + switch (col) { + case 0: // value column + result = tr("val, %1").arg(row); + break; + case 1: // type column + result = tr("type, %1").arg(row); + break; + } + } + } + + // FIXME: Implement me! + return result; +} + +bool ParamListModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (data(index, role) != value) { +// // FIXME: Implement me! + + emit dataChanged(index, index, QVector() << role); + return true; + } + return false; +} + +Qt::ItemFlags ParamListModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + + return Qt::ItemIsEnabled | Qt::ItemIsEditable; // FIXME: Implement me! +} + +//bool ParamListModel::insertRows(int row, int count, const QModelIndex &parent) +//{ +// beginInsertRows(parent, row, row + count - 1); +// // FIXME: Implement me! +// endInsertRows(); +// return false; +//} + +//bool ParamListModel::insertColumns(int column, int count, const QModelIndex &parent) +//{ +// beginInsertColumns(parent, column, column + count - 1); +// // FIXME: Implement me! +// endInsertColumns(); +//} + +//bool ParamListModel::removeRows(int row, int count, const QModelIndex &parent) +//{ +// beginRemoveRows(parent, row, row + count - 1); +// // FIXME: Implement me! +// endRemoveRows(); +// return false; +//} + +//bool ParamListModel::removeColumns(int column, int count, const QModelIndex &parent) +//{ +// beginRemoveColumns(parent, column, column + count - 1); +// // FIXME: Implement me! +// endRemoveColumns(); +//} diff --git a/paramlistmodel.h b/paramlistmodel.h new file mode 100644 index 0000000..e36e5d2 --- /dev/null +++ b/paramlistmodel.h @@ -0,0 +1,41 @@ +#ifndef PARAMLISTMODEL_H +#define PARAMLISTMODEL_H + +#include + +class ParamListModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit ParamListModel(QObject *parent = 0); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + +// bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override; + + // Basic functionality: + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + // Editable: + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole) override; + + Qt::ItemFlags flags(const QModelIndex& index) const override; + + // Add data: + // bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + //bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override; + + // Remove data: + // bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + //bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override; + +private: +}; + +#endif // PARAMLISTMODEL_H diff --git a/paramtypedelegate.cpp b/paramtypedelegate.cpp new file mode 100644 index 0000000..0ec7d83 --- /dev/null +++ b/paramtypedelegate.cpp @@ -0,0 +1,29 @@ +#include "paramtypedelegate.h" + +#include +#include "TypeSelectionItemModel.h" + +ParamTypeDelegate::ParamTypeDelegate() + : m_typeSelectionModel(new TypeSelectionItemModel) +{} + +ParamTypeDelegate::~ParamTypeDelegate() +{ + delete m_typeSelectionModel; +} + +QWidget *ParamTypeDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const + +{ + QWidget *w = nullptr; +// if (index.data().canConvert()) { + QComboBox *cmbbx = new QComboBox(parent); + cmbbx->setModel(m_typeSelectionModel); + w = cmbbx; +// } else { +// w = QStyledItemDelegate::createEditor(parent, option, index); +// } + return w; +} diff --git a/paramtypedelegate.h b/paramtypedelegate.h new file mode 100644 index 0000000..85e655c --- /dev/null +++ b/paramtypedelegate.h @@ -0,0 +1,25 @@ +#ifndef PARAMTYPEDELEGATE_H +#define PARAMTYPEDELEGATE_H + +#include + +class TypeSelectionItemModel; + +/** Item delegate for supplying a combobox for selected the parameter type in + * the parameter list. + */ +class ParamTypeDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + ParamTypeDelegate(); + ~ParamTypeDelegate(); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + +private: + TypeSelectionItemModel* m_typeSelectionModel = nullptr; +}; + +#endif // PARAMTYPEDELEGATE_H diff --git a/pgclass.cpp b/pgclass.cpp new file mode 100644 index 0000000..3d066ad --- /dev/null +++ b/pgclass.cpp @@ -0,0 +1,3 @@ +#include "pgclass.h" + +PgClass::PgClass() = default; diff --git a/pgclass.h b/pgclass.h new file mode 100644 index 0000000..acdec0d --- /dev/null +++ b/pgclass.h @@ -0,0 +1,26 @@ +#ifndef PGCLASS_H +#define PGCLASS_H + +#include +#include + +class PgClass { +public: + PgClass(); + + Oid oid = InvalidOid; + QString relname; + Oid relnamespace = InvalidOid; + Oid reltype = InvalidOid; + Oid reloftype = InvalidOid; + Oid relowner = InvalidOid; + Oid relam = InvalidOid; + Oid relfilename = InvalidOid; + Oid reltablespace = InvalidOid; + int relpages_est = 0; + float reltuples_est = 0; + int relallvisible = 0; + +}; + +#endif // PGCLASS_H diff --git a/pglab.pro b/pglab.pro index 88a3345..44074e3 100644 --- a/pglab.pro +++ b/pglab.pro @@ -43,7 +43,15 @@ SOURCES += main.cpp\ pgtype.cpp \ pgsqldatabasecatalogue.cpp \ pgtypecontainer.cpp \ - tuplesresultwidget.cpp + tuplesresultwidget.cpp \ + pgnamespace.cpp \ + pgclass.cpp \ + backupdialog.cpp \ + paramlistmodel.cpp \ + paramtypedelegate.cpp \ + typeselectionitemmodel.cpp \ + opendatabase.cpp \ + MasterController.cpp HEADERS += mainwindow.h \ serverproperties.h \ @@ -72,7 +80,15 @@ HEADERS += mainwindow.h \ pgtype.h \ pgsqldatabasecatalogue.h \ pgtypecontainer.h \ - tuplesresultwidget.h + tuplesresultwidget.h \ + pgnamespace.h \ + pgclass.h \ + backupdialog.h \ + paramlistmodel.h \ + paramtypedelegate.h \ + typeselectionitemmodel.h \ + opendatabase.h \ + MasterController.h FORMS += mainwindow.ui \ serverproperties.ui \ @@ -80,7 +96,8 @@ FORMS += mainwindow.ui \ connectionmanagerwindow.ui \ databaseinspectorwidget.ui \ tuplesresultwidget.ui \ - querytab.ui + querytab.ui \ + backupdialog.ui RESOURCES += \ resources.qrc diff --git a/pgnamespace.cpp b/pgnamespace.cpp new file mode 100644 index 0000000..a1d6590 --- /dev/null +++ b/pgnamespace.cpp @@ -0,0 +1,4 @@ +#include "pgnamespace.h" + +PgNamespace::PgNamespace() = default; + diff --git a/pgnamespace.h b/pgnamespace.h new file mode 100644 index 0000000..2c33805 --- /dev/null +++ b/pgnamespace.h @@ -0,0 +1,17 @@ +#ifndef PGNAMESPACE_H +#define PGNAMESPACE_H + +#include +#include + +class PgNamespace +{ +public: + PgNamespace(); + + QString name; + Oid owner = InvalidOid; + QString acl; +}; + +#endif // PGNAMESPACE_H diff --git a/pgtypecontainer.cpp b/pgtypecontainer.cpp index a71fe4b..72d0019 100644 --- a/pgtypecontainer.cpp +++ b/pgtypecontainer.cpp @@ -32,7 +32,6 @@ std::string PgTypeContainer::getLoadQuery() " typreceive, typsend, typmodin, typmodout, typanalyze, typalign, typstorage, typnotnull, \n" " typbasetype, typtypmod, typndims, typcollation, typdefaultbin, typdefault, typacl \n" "FROM pg_type"; - } void PgTypeContainer::load(const Pgsql::Result &res) diff --git a/querytab.cpp b/querytab.cpp index e23af9d..f9c927f 100644 --- a/querytab.cpp +++ b/querytab.cpp @@ -13,6 +13,7 @@ #include "explaintreemodelitem.h" #include "json/json.h" #include "mainwindow.h" +#include "pgtypecontainer.h" #include "util.h" QueryTab::QueryTab(MainWindow *win, QWidget *parent) : @@ -39,6 +40,9 @@ QueryTab::QueryTab(MainWindow *win, QWidget *parent) : ui->queryEdit->setFont(font); highlighter.reset(new SqlHighlighter(ui->queryEdit->document())); + ui->paramTableView->setModel(&m_paramList); + ui->paramTableView->setItemDelegateForColumn(1, &m_typeDelegate); + connect(ui->queryEdit, &QPlainTextEdit::textChanged, this, &QueryTab::queryTextChanged); // m_stopwatch.setOutputLabel(ui->lblElapsedTime); // ui->lblElapsedTime->clear(); @@ -49,6 +53,7 @@ QueryTab::~QueryTab() { m_dbConnection.closeConnection(); m_dbConnection.setStateCallback(nullptr); +// delete m_pgTypes; delete ui; } @@ -279,26 +284,47 @@ void QueryTab::queryTextChanged() void QueryTab::connectionStateChanged(ASyncDBConnection::State state) { - QString status_str; - switch (state) { - case ASyncDBConnection::State::NotConnected: - status_str = tr("Geen verbinding"); - break; - case ASyncDBConnection::State::Connecting: - status_str = tr("Verbinden"); - break; - case ASyncDBConnection::State::Connected: - status_str = tr("Verbonden"); - break; - case ASyncDBConnection::State::QuerySend: - status_str = tr("Query verstuurd"); - break; - case ASyncDBConnection::State::CancelSend: - status_str = tr("Query geannuleerd"); - break; +// QString status_str; +// switch (state) { +// case ASyncDBConnection::State::NotConnected: +// status_str = tr("Geen verbinding"); +// break; +// case ASyncDBConnection::State::Connecting: +// status_str = tr("Verbinden"); +// break; +// case ASyncDBConnection::State::Connected: +// status_str = tr("Verbonden"); +// break; +// case ASyncDBConnection::State::QuerySend: +// status_str = tr("Query verstuurd"); +// break; +// case ASyncDBConnection::State::CancelSend: +// status_str = tr("Query geannuleerd"); +// break; +// } +// addLog(status_str); + + QTabWidget *tabwidget = getTabWidget(); + if (tabwidget) { + int i = tabwidget->indexOf(this); + QString iconname; + switch (state) { + case ASyncDBConnection::State::NotConnected: + case ASyncDBConnection::State::Connecting: + iconname = ":/icons/16x16/document_red.png"; + break; + case ASyncDBConnection::State::Connected: + iconname = ":/icons/16x16/document_green.png"; + break; + case ASyncDBConnection::State::QuerySend: + case ASyncDBConnection::State::CancelSend: + iconname = ":/icons/16x16/document_yellow.png"; + break; + } + tabwidget->setTabIcon(i, QIcon(iconname)); } - addLog(status_str); -// statusBar()->showMessage(status_str); + + // statusBar()->showMessage(status_str); // bool connected = ASyncDBConnection::State::Connected == state; // ui->actionExecute_SQL->setEnabled(connected); @@ -409,11 +435,17 @@ std::string QueryTab::getCommand() const return command.toUtf8().data(); } -void QueryTab::setTabCaption(const QString &caption, const QString &tooltip) +QTabWidget *QueryTab::getTabWidget() { QWidget * w = parentWidget(); QWidget * p = w->parentWidget(); - QTabWidget *tabwidget = dynamic_cast(p); + QTabWidget *tw = dynamic_cast(p); + return tw; +} + +void QueryTab::setTabCaption(const QString &caption, const QString &tooltip) +{ + QTabWidget *tabwidget = getTabWidget(); if (tabwidget) { int i = tabwidget->indexOf(this); if (i >= 0) { @@ -437,7 +469,11 @@ void QueryTab::query_ready(std::shared_ptr dbres, qint64 elapsedm TuplesResultWidget *trw = new TuplesResultWidget; trw->setResult(result_model, elapsedms); resultList.push_back(trw); - ui->tabWidget->addTab(trw, "Data"); + ui->tabWidget->addTab(trw, "Data"); + if (resultList.size() == 1) + ui->tabWidget->setCurrentWidget(trw); + + // ui->lblRowCount->setText(rowcount_str); // resultModel.reset(new QueryResultModel(nullptr , dbres)); // ui->ResultView->setModel(resultModel.get()); diff --git a/querytab.h b/querytab.h index 402d244..28aa59b 100644 --- a/querytab.h +++ b/querytab.h @@ -2,6 +2,8 @@ #define QUERYTAB_H #include "asyncdbconnection.h" +#include "paramlistmodel.h" +#include "paramtypedelegate.h" #include "queryresultmodel.h" #include "queryexplainmodel.h" #include "stopwatch.h" @@ -14,11 +16,13 @@ namespace Ui { class QueryTab; } +class QTabWidget; class MainWindow; class SqlHighlighter; class ExplainRoot; class QueryResultModel; class QueryExplainModel; +class PgTypeContainer; class QueryTab : public QWidget @@ -60,6 +64,8 @@ private: std::unique_ptr highlighter; ConnectionConfig m_config; StopWatch m_stopwatch; + ParamListModel m_paramList; + ParamTypeDelegate m_typeDelegate; QString m_fileName; ///< use setFileName function to set bool m_queryTextChanged = false; @@ -83,8 +89,10 @@ private: void explain_ready(ExplainRoot::SPtr explain); void query_ready(std::shared_ptr dbres, qint64 elapsedms); + QTabWidget *getTabWidget(); void setTabCaption(const QString &caption, const QString &tooltip); void clearResult(); + private slots: void queryTextChanged(); diff --git a/querytab.ui b/querytab.ui index 101518b..fa809bb 100644 --- a/querytab.ui +++ b/querytab.ui @@ -14,27 +14,22 @@ Form - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - + Qt::Vertical - + + + Qt::Horizontal + + + + + true + + + 1 diff --git a/resources.qrc b/resources.qrc index e1c3cf0..2c826e3 100644 --- a/resources.qrc +++ b/resources.qrc @@ -13,5 +13,9 @@ icons/page_white_delete.png icons/lightbulb_off.png icons/information.png + icons/16x16/document_green.png + icons/16x16/document_red.png + icons/16x16/document_yellow.png + icons/backups.png diff --git a/typeselectionitemmodel.cpp b/typeselectionitemmodel.cpp new file mode 100644 index 0000000..1c24ab4 --- /dev/null +++ b/typeselectionitemmodel.cpp @@ -0,0 +1,52 @@ +#include "typeselectionitemmodel.h" + +TypeSelectionItemModel::TypeSelectionItemModel(QObject *parent) + : QAbstractListModel(parent) +{ +} + +int TypeSelectionItemModel::rowCount(const QModelIndex &parent) const +{ + int result = 10; +// if (!parent.isValid()) { + +// } + return result; +} + +int TypeSelectionItemModel::columnCount(const QModelIndex &parent) const +{ + int result = 1; +// if (parent.isValid()) +// result = 1; + + + return result; +} + +QVariant TypeSelectionItemModel::data(const QModelIndex &index, int role) const +{ + QVariant result; + if (index.isValid()) { + int row = index.row(); + int column = index.column(); + if (role == Qt::DisplayRole) { + if (column == 0) { + switch (row) { + case 0: result = "integer"; break; + case 1: result = "numeric"; break; + case 2: result = "timestamp"; break; + case 3: result = "timestamptz"; break; + case 4: result = "float"; break; + case 5: result = "double"; break; + case 6: result = "date"; break; + case 7: result = "varchar"; break; + case 8: result = "varchar"; break; + case 9: result = "varchar"; break; + + } + } + } + } + return result; +} diff --git a/typeselectionitemmodel.h b/typeselectionitemmodel.h new file mode 100644 index 0000000..0c70fa2 --- /dev/null +++ b/typeselectionitemmodel.h @@ -0,0 +1,21 @@ +#ifndef TYPESELECTIONITEMMODEL_H +#define TYPESELECTIONITEMMODEL_H + +#include + +class TypeSelectionItemModel : public QAbstractListModel +{ + Q_OBJECT + +public: + explicit TypeSelectionItemModel(QObject *parent = 0); + + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: +}; + +#endif // TYPESELECTIONITEMMODEL_H