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.
This commit is contained in:
Eelke Klein 2017-02-01 18:01:02 +01:00
parent b6d986051b
commit 6370050204
36 changed files with 769 additions and 71 deletions

27
MasterController.cpp Normal file
View file

@ -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();
}

36
MasterController.h Normal file
View file

@ -0,0 +1,36 @@
#ifndef MASTERCONTROLLER_H
#define MASTERCONTROLLER_H
#include <QObject>
#include <map>
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

14
backupdialog.cpp Normal file
View file

@ -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;
}

22
backupdialog.h Normal file
View file

@ -0,0 +1,22 @@
#ifndef BACKUPDIALOG_H
#define BACKUPDIALOG_H
#include <QDialog>
namespace Ui {
class BackupDialog;
}
class BackupDialog : public QDialog
{
Q_OBJECT
public:
explicit BackupDialog(QWidget *parent = 0);
~BackupDialog();
private:
Ui::BackupDialog *ui;
};
#endif // BACKUPDIALOG_H

54
backupdialog.ui Normal file
View file

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BackupDialog</class>
<widget class="QDialog" name="BackupDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>645</width>
<height>295</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="1">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Format</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboBox"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Filename</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -200,3 +200,13 @@ const char * const * ConnectionConfig::getValues() const
return m_values.data(); 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;
}

View file

@ -56,6 +56,7 @@ public:
const char * const * getKeywords() const; const char * const * getKeywords() const;
const char * const * getValues() const; const char * const * getValues() const;
bool isSameDatabase(const ConnectionConfig &rhs) const;
private: private:
std::string m_name; std::string m_name;
std::string m_host; std::string m_host;

View file

@ -1,20 +1,22 @@
#include "connectionmanagerwindow.h" #include "connectionmanagerwindow.h"
#include "ui_connectionmanagerwindow.h" #include "ui_connectionmanagerwindow.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "MasterController.h"
#include <QDataWidgetMapper> #include <QDataWidgetMapper>
#include <QMessageBox> #include <QMessageBox>
#include <QStandardItemModel> #include <QStandardItemModel>
#include "connectionlistmodel.h" #include "connectionlistmodel.h"
ConnectionManagerWindow::ConnectionManagerWindow(QWidget *parent) ConnectionManagerWindow::ConnectionManagerWindow(MasterController *master, QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
, ui(new Ui::ConnectionManagerWindow) , ui(new Ui::ConnectionManagerWindow)
, m_listModel(new ConnectionListModel(this)) // , m_listModel(new ConnectionListModel(this))
, m_masterController(master)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->listView->setModel(m_listModel); ui->listView->setModel(m_masterController->getConnectionListModel());
setupWidgetMappings(); setupWidgetMappings();
@ -26,10 +28,10 @@ ConnectionManagerWindow::ConnectionManagerWindow(QWidget *parent)
ConnectionManagerWindow::~ConnectionManagerWindow() ConnectionManagerWindow::~ConnectionManagerWindow()
{ {
m_listModel->save(); // m_listModel->save();
delete ui; delete ui;
delete m_listModel; // delete m_listModel;
delete m_mapper; delete m_mapper;
} }
@ -37,10 +39,13 @@ void ConnectionManagerWindow::on_actionAdd_Connection_triggered()
{ {
ConnectionConfig c; ConnectionConfig c;
c.setName("new"); c.setName("new");
m_listModel->add(c); //m_listModel->add(c);
auto clm = m_masterController->getConnectionListModel();
clm->add(c);
// Select the new row // 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); ui->listView->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::Select);
} }
@ -48,7 +53,8 @@ void ConnectionManagerWindow::on_currentChanged(const QModelIndex &current,
const QModelIndex &previous) const QModelIndex &previous)
{ {
int currow = current.row(); int currow = current.row();
m_listModel->save(prevSelection); auto clm = m_masterController->getConnectionListModel();
clm->save(prevSelection);
m_mapper->setCurrentIndex(currow); m_mapper->setCurrentIndex(currow);
prevSelection = currow; prevSelection = currow;
} }
@ -57,15 +63,17 @@ void ConnectionManagerWindow::on_actionDelete_connection_triggered()
{ {
auto ci = ui->listView->selectionModel()->currentIndex(); auto ci = ui->listView->selectionModel()->currentIndex();
if (ci.isValid()) { if (ci.isValid()) {
m_listModel->removeRow(ci.row()); auto clm = m_masterController->getConnectionListModel();
clm->removeRow(ci.row());
} }
} }
void ConnectionManagerWindow::setupWidgetMappings() void ConnectionManagerWindow::setupWidgetMappings()
{ {
auto clm = m_masterController->getConnectionListModel();
m_mapper = new QDataWidgetMapper(this); m_mapper = new QDataWidgetMapper(this);
m_mapper->setModel(m_listModel); m_mapper->setModel(clm);
m_mapper->addMapping(ui->edtName, 1); m_mapper->addMapping(ui->edtName, 1);
m_mapper->addMapping(ui->edtHost, 2); m_mapper->addMapping(ui->edtHost, 2);
m_mapper->addMapping(ui->spinPort, 3); m_mapper->addMapping(ui->spinPort, 3);
@ -77,12 +85,19 @@ void ConnectionManagerWindow::setupWidgetMappings()
void ConnectionManagerWindow::on_actionConnect_triggered() 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 ci = ui->listView->selectionModel()->currentIndex();
auto cc = m_listModel->get(ci.row()); auto cc = clm->get(ci.row());
m_listModel->save(ci.row()); clm->save(ci.row());
if (cc.valid()) { if (cc.valid()) {
auto w = new MainWindow; auto w = new MainWindow(m_masterController, nullptr);
w->setAttribute( Qt::WA_DeleteOnClose ); w->setAttribute( Qt::WA_DeleteOnClose );
w->setConfig(cc.get()); w->setConfig(cc.get());
w->show(); w->show();
@ -99,3 +114,8 @@ void ConnectionManagerWindow::on_actionQuit_application_triggered()
//closeAllWindows(); //closeAllWindows();
} }
void ConnectionManagerWindow::on_actionBackup_database_triggered()
{
// BACKUP
}

View file

@ -7,8 +7,8 @@ namespace Ui {
class ConnectionManagerWindow; class ConnectionManagerWindow;
} }
class ConnectionListModel;
class ConnectionConfig; class ConnectionConfig;
class MasterController;
class QDataWidgetMapper; class QDataWidgetMapper;
class QStandardItemModel; class QStandardItemModel;
@ -17,7 +17,7 @@ class ConnectionManagerWindow : public QMainWindow
Q_OBJECT Q_OBJECT
public: public:
explicit ConnectionManagerWindow(QWidget *parent = 0); explicit ConnectionManagerWindow(MasterController *master, QWidget *parent = 0);
~ConnectionManagerWindow(); ~ConnectionManagerWindow();
private slots: private slots:
@ -29,10 +29,12 @@ private slots:
void on_actionQuit_application_triggered(); void on_actionQuit_application_triggered();
void on_actionBackup_database_triggered();
private: private:
Ui::ConnectionManagerWindow *ui; Ui::ConnectionManagerWindow *ui;
ConnectionListModel *m_listModel = nullptr;
QDataWidgetMapper *m_mapper = nullptr; QDataWidgetMapper *m_mapper = nullptr;
MasterController *m_masterController;
int prevSelection = -1; int prevSelection = -1;

View file

@ -194,7 +194,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>800</width> <width>800</width>
<height>25</height> <height>22</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuFile"> <widget class="QMenu" name="menuFile">
@ -225,6 +225,8 @@
<addaction name="actionConnect"/> <addaction name="actionConnect"/>
<addaction name="actionAdd_Connection"/> <addaction name="actionAdd_Connection"/>
<addaction name="actionDelete_connection"/> <addaction name="actionDelete_connection"/>
<addaction name="separator"/>
<addaction name="actionBackup_database"/>
</widget> </widget>
<action name="actionAdd_Connection"> <action name="actionAdd_Connection">
<property name="icon"> <property name="icon">
@ -262,6 +264,16 @@
<string>Quit application</string> <string>Quit application</string>
</property> </property>
</action> </action>
<action name="actionBackup_database">
<property name="icon">
<iconset>
<normalon>:/icons/backups.png</normalon>
</iconset>
</property>
<property name="text">
<string>Backup database</string>
</property>
</action>
</widget> </widget>
<resources> <resources>
<include location="resources.qrc"/> <include location="resources.qrc"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
icons/backups.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -1,8 +1,7 @@
//#include "mainwindow.h" #include "MasterController.h"
//#include "databasewindow.h"
#include "connectionmanagerwindow.h"
#include <QApplication> #include <QApplication>
#include <winsock2.h> #include <winsock2.h>
#include <memory>
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -24,8 +23,9 @@ int main(int argc, char *argv[])
QCoreApplication::setOrganizationDomain("eelkeklein.nl"); QCoreApplication::setOrganizationDomain("eelkeklein.nl");
QCoreApplication::setApplicationName("pglab"); QCoreApplication::setApplicationName("pglab");
ConnectionManagerWindow w; auto master_controller = std::make_unique<MasterController>();
w.show(); master_controller->init();
int result = a.exec(); int result = a.exec();

View file

@ -14,14 +14,15 @@
#include <QCloseEvent> #include <QCloseEvent>
#include <querytab.h> #include <querytab.h>
#include "util.h" #include "util.h"
#include "MasterController.h"
namespace pg = Pgsql; namespace pg = Pgsql;
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(MasterController *master, QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
, ui(new Ui::MainWindow) , ui(new Ui::MainWindow)
, m_masterController(master)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -132,7 +133,19 @@ void MainWindow::on_actionClose_triggered()
void MainWindow::on_actionAbout_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 #if false
@ -231,5 +244,11 @@ void MainWindow::on_tabWidget_tabCloseRequested(int index)
if (qt->canClose()) { if (qt->canClose()) {
ui->tabWidget->removeTab(index); ui->tabWidget->removeTab(index);
} }
} }
void MainWindow::on_actionShow_connection_manager_triggered()
{
m_masterController->showConnectionManager();
}

View file

@ -27,14 +27,14 @@ namespace Pgsql {
} }
class QueryTab; class QueryTab;
class MasterController;
class QCloseEvent; class QCloseEvent;
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit MainWindow(QWidget *parent = 0); explicit MainWindow(MasterController *master, QWidget *parent);
~MainWindow(); ~MainWindow();
void setConfig(const ConnectionConfig &config); void setConfig(const ConnectionConfig &config);
@ -51,6 +51,8 @@ private:
TSQueue m_taskQueue; TSQueue m_taskQueue;
ConnectionConfig m_config; ConnectionConfig m_config;
MasterController *m_masterController;
QueryTab *GetActiveQueryTab(); QueryTab *GetActiveQueryTab();
@ -75,6 +77,7 @@ private slots:
void on_actionNew_SQL_triggered(); void on_actionNew_SQL_triggered();
void on_tabWidget_tabCloseRequested(int index); void on_tabWidget_tabCloseRequested(int index);
void on_actionExplain_triggered(); void on_actionExplain_triggered();
void on_actionShow_connection_manager_triggered();
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View file

@ -77,8 +77,15 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionCancel"/> <addaction name="actionCancel"/>
</widget> </widget>
<widget class="QMenu" name="menuView">
<property name="title">
<string>Window</string>
</property>
<addaction name="actionShow_connection_manager"/>
</widget>
<addaction name="menuTest"/> <addaction name="menuTest"/>
<addaction name="menuQuery"/> <addaction name="menuQuery"/>
<addaction name="menuView"/>
<addaction name="menuHelp"/> <addaction name="menuHelp"/>
</widget> </widget>
<widget class="QToolBar" name="mainToolBar"> <widget class="QToolBar" name="mainToolBar">
@ -238,6 +245,11 @@
<string>F7</string> <string>F7</string>
</property> </property>
</action> </action>
<action name="actionShow_connection_manager">
<property name="text">
<string>Show connection manager</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources> <resources>

30
opendatabase.cpp Normal file
View file

@ -0,0 +1,30 @@
#include "opendatabase.h"
#include "pgsqldatabasecatalogue.h"
Expected<OpenDatabase*> OpenDatabase::createOpenDatabase(const ConnectionConfig &cfg)
{
OpenDatabase *odb = new OpenDatabase(cfg, nullptr);
if (odb->Init()) {
return odb;
}
//return Expected<ConnectionConfig>::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;
}

32
opendatabase.h Normal file
View file

@ -0,0 +1,32 @@
#ifndef OPENDATABASE_H
#define OPENDATABASE_H
#include <QObject>
#include "connectionconfig.h"
#include "expected.h"
class PgsqlDatabaseCatalogue;
class OpenDatabase : public QObject
{
Q_OBJECT
public:
static Expected<OpenDatabase*> 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

127
paramlistmodel.cpp Normal file
View file

@ -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<int>() << 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();
//}

41
paramlistmodel.h Normal file
View file

@ -0,0 +1,41 @@
#ifndef PARAMLISTMODEL_H
#define PARAMLISTMODEL_H
#include <QAbstractTableModel>
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

29
paramtypedelegate.cpp Normal file
View file

@ -0,0 +1,29 @@
#include "paramtypedelegate.h"
#include <QComboBox>
#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<StarRating>()) {
QComboBox *cmbbx = new QComboBox(parent);
cmbbx->setModel(m_typeSelectionModel);
w = cmbbx;
// } else {
// w = QStyledItemDelegate::createEditor(parent, option, index);
// }
return w;
}

25
paramtypedelegate.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef PARAMTYPEDELEGATE_H
#define PARAMTYPEDELEGATE_H
#include <QStyledItemDelegate>
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

3
pgclass.cpp Normal file
View file

@ -0,0 +1,3 @@
#include "pgclass.h"
PgClass::PgClass() = default;

26
pgclass.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef PGCLASS_H
#define PGCLASS_H
#include <QString>
#include <pgsql/libpq-fe.h>
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

View file

@ -43,7 +43,15 @@ SOURCES += main.cpp\
pgtype.cpp \ pgtype.cpp \
pgsqldatabasecatalogue.cpp \ pgsqldatabasecatalogue.cpp \
pgtypecontainer.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 \ HEADERS += mainwindow.h \
serverproperties.h \ serverproperties.h \
@ -72,7 +80,15 @@ HEADERS += mainwindow.h \
pgtype.h \ pgtype.h \
pgsqldatabasecatalogue.h \ pgsqldatabasecatalogue.h \
pgtypecontainer.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 \ FORMS += mainwindow.ui \
serverproperties.ui \ serverproperties.ui \
@ -80,7 +96,8 @@ FORMS += mainwindow.ui \
connectionmanagerwindow.ui \ connectionmanagerwindow.ui \
databaseinspectorwidget.ui \ databaseinspectorwidget.ui \
tuplesresultwidget.ui \ tuplesresultwidget.ui \
querytab.ui querytab.ui \
backupdialog.ui
RESOURCES += \ RESOURCES += \
resources.qrc resources.qrc

4
pgnamespace.cpp Normal file
View file

@ -0,0 +1,4 @@
#include "pgnamespace.h"
PgNamespace::PgNamespace() = default;

17
pgnamespace.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef PGNAMESPACE_H
#define PGNAMESPACE_H
#include <QString>
#include <pgsql/libpq-fe.h>
class PgNamespace
{
public:
PgNamespace();
QString name;
Oid owner = InvalidOid;
QString acl;
};
#endif // PGNAMESPACE_H

View file

@ -32,7 +32,6 @@ std::string PgTypeContainer::getLoadQuery()
" typreceive, typsend, typmodin, typmodout, typanalyze, typalign, typstorage, typnotnull, \n" " typreceive, typsend, typmodin, typmodout, typanalyze, typalign, typstorage, typnotnull, \n"
" typbasetype, typtypmod, typndims, typcollation, typdefaultbin, typdefault, typacl \n" " typbasetype, typtypmod, typndims, typcollation, typdefaultbin, typdefault, typacl \n"
"FROM pg_type"; "FROM pg_type";
} }
void PgTypeContainer::load(const Pgsql::Result &res) void PgTypeContainer::load(const Pgsql::Result &res)

View file

@ -13,6 +13,7 @@
#include "explaintreemodelitem.h" #include "explaintreemodelitem.h"
#include "json/json.h" #include "json/json.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "pgtypecontainer.h"
#include "util.h" #include "util.h"
QueryTab::QueryTab(MainWindow *win, QWidget *parent) : QueryTab::QueryTab(MainWindow *win, QWidget *parent) :
@ -39,6 +40,9 @@ QueryTab::QueryTab(MainWindow *win, QWidget *parent) :
ui->queryEdit->setFont(font); ui->queryEdit->setFont(font);
highlighter.reset(new SqlHighlighter(ui->queryEdit->document())); 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); connect(ui->queryEdit, &QPlainTextEdit::textChanged, this, &QueryTab::queryTextChanged);
// m_stopwatch.setOutputLabel(ui->lblElapsedTime); // m_stopwatch.setOutputLabel(ui->lblElapsedTime);
// ui->lblElapsedTime->clear(); // ui->lblElapsedTime->clear();
@ -49,6 +53,7 @@ QueryTab::~QueryTab()
{ {
m_dbConnection.closeConnection(); m_dbConnection.closeConnection();
m_dbConnection.setStateCallback(nullptr); m_dbConnection.setStateCallback(nullptr);
// delete m_pgTypes;
delete ui; delete ui;
} }
@ -279,25 +284,46 @@ void QueryTab::queryTextChanged()
void QueryTab::connectionStateChanged(ASyncDBConnection::State state) void QueryTab::connectionStateChanged(ASyncDBConnection::State state)
{ {
QString status_str; // 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) { switch (state) {
case ASyncDBConnection::State::NotConnected: case ASyncDBConnection::State::NotConnected:
status_str = tr("Geen verbinding");
break;
case ASyncDBConnection::State::Connecting: case ASyncDBConnection::State::Connecting:
status_str = tr("Verbinden"); iconname = ":/icons/16x16/document_red.png";
break; break;
case ASyncDBConnection::State::Connected: case ASyncDBConnection::State::Connected:
status_str = tr("Verbonden"); iconname = ":/icons/16x16/document_green.png";
break; break;
case ASyncDBConnection::State::QuerySend: case ASyncDBConnection::State::QuerySend:
status_str = tr("Query verstuurd");
break;
case ASyncDBConnection::State::CancelSend: case ASyncDBConnection::State::CancelSend:
status_str = tr("Query geannuleerd"); iconname = ":/icons/16x16/document_yellow.png";
break; break;
} }
addLog(status_str); tabwidget->setTabIcon(i, QIcon(iconname));
}
// statusBar()->showMessage(status_str); // statusBar()->showMessage(status_str);
// bool connected = ASyncDBConnection::State::Connected == state; // bool connected = ASyncDBConnection::State::Connected == state;
@ -409,11 +435,17 @@ std::string QueryTab::getCommand() const
return command.toUtf8().data(); return command.toUtf8().data();
} }
void QueryTab::setTabCaption(const QString &caption, const QString &tooltip) QTabWidget *QueryTab::getTabWidget()
{ {
QWidget * w = parentWidget(); QWidget * w = parentWidget();
QWidget * p = w->parentWidget(); QWidget * p = w->parentWidget();
QTabWidget *tabwidget = dynamic_cast<QTabWidget*>(p); QTabWidget *tw = dynamic_cast<QTabWidget*>(p);
return tw;
}
void QueryTab::setTabCaption(const QString &caption, const QString &tooltip)
{
QTabWidget *tabwidget = getTabWidget();
if (tabwidget) { if (tabwidget) {
int i = tabwidget->indexOf(this); int i = tabwidget->indexOf(this);
if (i >= 0) { if (i >= 0) {
@ -438,6 +470,10 @@ void QueryTab::query_ready(std::shared_ptr<Pgsql::Result> dbres, qint64 elapsedm
trw->setResult(result_model, elapsedms); trw->setResult(result_model, elapsedms);
resultList.push_back(trw); 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); // ui->lblRowCount->setText(rowcount_str);
// resultModel.reset(new QueryResultModel(nullptr , dbres)); // resultModel.reset(new QueryResultModel(nullptr , dbres));
// ui->ResultView->setModel(resultModel.get()); // ui->ResultView->setModel(resultModel.get());

View file

@ -2,6 +2,8 @@
#define QUERYTAB_H #define QUERYTAB_H
#include "asyncdbconnection.h" #include "asyncdbconnection.h"
#include "paramlistmodel.h"
#include "paramtypedelegate.h"
#include "queryresultmodel.h" #include "queryresultmodel.h"
#include "queryexplainmodel.h" #include "queryexplainmodel.h"
#include "stopwatch.h" #include "stopwatch.h"
@ -14,11 +16,13 @@ namespace Ui {
class QueryTab; class QueryTab;
} }
class QTabWidget;
class MainWindow; class MainWindow;
class SqlHighlighter; class SqlHighlighter;
class ExplainRoot; class ExplainRoot;
class QueryResultModel; class QueryResultModel;
class QueryExplainModel; class QueryExplainModel;
class PgTypeContainer;
class QueryTab : public QWidget class QueryTab : public QWidget
@ -60,6 +64,8 @@ private:
std::unique_ptr<SqlHighlighter> highlighter; std::unique_ptr<SqlHighlighter> highlighter;
ConnectionConfig m_config; ConnectionConfig m_config;
StopWatch m_stopwatch; StopWatch m_stopwatch;
ParamListModel m_paramList;
ParamTypeDelegate m_typeDelegate;
QString m_fileName; ///< use setFileName function to set QString m_fileName; ///< use setFileName function to set
bool m_queryTextChanged = false; bool m_queryTextChanged = false;
@ -83,8 +89,10 @@ private:
void explain_ready(ExplainRoot::SPtr explain); void explain_ready(ExplainRoot::SPtr explain);
void query_ready(std::shared_ptr<Pgsql::Result> dbres, qint64 elapsedms); void query_ready(std::shared_ptr<Pgsql::Result> dbres, qint64 elapsedms);
QTabWidget *getTabWidget();
void setTabCaption(const QString &caption, const QString &tooltip); void setTabCaption(const QString &caption, const QString &tooltip);
void clearResult(); void clearResult();
private slots: private slots:
void queryTextChanged(); void queryTextChanged();

View file

@ -14,27 +14,22 @@
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item> <item>
<widget class="QSplitter" name="splitter"> <widget class="QSplitter" name="splitter_2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QPlainTextEdit" name="queryEdit"/> <widget class="QPlainTextEdit" name="queryEdit"/>
<widget class="QTableView" name="paramTableView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</widget>
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>1</number>

View file

@ -13,5 +13,9 @@
<file>icons/page_white_delete.png</file> <file>icons/page_white_delete.png</file>
<file>icons/lightbulb_off.png</file> <file>icons/lightbulb_off.png</file>
<file>icons/information.png</file> <file>icons/information.png</file>
<file>icons/16x16/document_green.png</file>
<file>icons/16x16/document_red.png</file>
<file>icons/16x16/document_yellow.png</file>
<file>icons/backups.png</file>
</qresource> </qresource>
</RCC> </RCC>

View file

@ -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;
}

21
typeselectionitemmodel.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef TYPESELECTIONITEMMODEL_H
#define TYPESELECTIONITEMMODEL_H
#include <QAbstractListModel>
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