diff --git a/icons/page_white_copy.png b/icons/page_white_copy.png new file mode 100644 index 0000000..4c21085 Binary files /dev/null and b/icons/page_white_copy.png differ diff --git a/mainwindow.cpp b/mainwindow.cpp index 5470b1c..457f8eb 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -15,6 +15,7 @@ #include #include "util.h" #include "MasterController.h" +#include "OpenDatabase.h" namespace pg = Pgsql; @@ -25,8 +26,9 @@ MainWindow::MainWindow(MasterController *master, QWidget *parent) , m_masterController(master) { ui->setupUi(this); - ui->tabWidget->setDocumentMode(true); + + //ui->tabWidget->setTabsClosable(true); } @@ -55,6 +57,10 @@ QueryTab *MainWindow::GetActiveQueryTab() void MainWindow::setConfig(const ConnectionConfig &config) { m_config = config; + auto res = OpenDatabase::createOpenDatabase(config); + if (res.valid()) { + m_database = res.get(); + } QString title = "pglab - "; title += m_config.name().c_str(); setWindowTitle(title); @@ -140,7 +146,8 @@ void MainWindow::on_actionAbout_triggered() " 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" + "This program is dynamically linked with Qt 5.8 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" @@ -252,3 +259,15 @@ void MainWindow::on_actionShow_connection_manager_triggered() { m_masterController->showConnectionManager(); } + +void MainWindow::on_actionCopy_triggered() +{ + // What should be copied? + + QWidget *w = QApplication::focusWidget(); + QTableView *tv = dynamic_cast(w); + if (tv) { + copySelectionToClipboard(tv); + } + //this->ui-> +} diff --git a/mainwindow.h b/mainwindow.h index 98324c1..f091695 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -29,6 +29,7 @@ namespace Pgsql { class QueryTab; class MasterController; class QCloseEvent; +class OpenDatabase; class MainWindow : public QMainWindow { @@ -43,13 +44,14 @@ public: */ void QueueTask(TSQueue::t_Callable c); - + OpenDatabase* getDatabase() { return m_database; } private: Ui::MainWindow *ui; TSQueue m_taskQueue; ConnectionConfig m_config; + OpenDatabase *m_database; MasterController *m_masterController; @@ -78,6 +80,7 @@ private slots: void on_tabWidget_tabCloseRequested(int index); void on_actionExplain_triggered(); void on_actionShow_connection_manager_triggered(); + void on_actionCopy_triggered(); }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 992e559..e0486e4 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -83,7 +83,14 @@ + + + Edit + + + + @@ -101,6 +108,8 @@ + + @@ -250,6 +259,19 @@ Show connection manager + + + + :/icons/page_white_copy.png + + + + Copy + + + Ctrl+C + + diff --git a/opendatabase.cpp b/opendatabase.cpp index c86005a..4e4c488 100644 --- a/opendatabase.cpp +++ b/opendatabase.cpp @@ -1,5 +1,7 @@ -#include "opendatabase.h" +#include "OpenDatabase.h" #include "pgsqldatabasecatalogue.h" +#include "PgsqlConn.h" +#include "typeselectionitemmodel.h" Expected OpenDatabase::createOpenDatabase(const ConnectionConfig &cfg) { @@ -26,6 +28,26 @@ OpenDatabase::~OpenDatabase() bool OpenDatabase::Init() { -// m_catalogue->load(m_config); + Pgsql::Connection conn; + auto kw = m_config.getKeywords(); + auto vals = m_config.getValues(); + if (conn.connect(kw, vals, 0)) { + m_catalogue->loadAll(conn); + } return true; } + +PgsqlDatabaseCatalogue* OpenDatabase::getCatalogue() +{ + return m_catalogue; +} + + +TypeSelectionItemModel* OpenDatabase::getTypeSelectionModel() +{ + if (m_typeSelectionModel == nullptr) { + m_typeSelectionModel = new TypeSelectionItemModel(nullptr); + m_typeSelectionModel->setTypeList(m_catalogue->getTypes()); + } + return m_typeSelectionModel; +} diff --git a/opendatabase.h b/opendatabase.h index bc8d656..6aed1e4 100644 --- a/opendatabase.h +++ b/opendatabase.h @@ -6,6 +6,7 @@ #include "expected.h" class PgsqlDatabaseCatalogue; +class TypeSelectionItemModel; /** Instances of this class represent a single database on which atleast one * window is opened. This class is used to track details about that database. @@ -20,6 +21,8 @@ public: OpenDatabase& operator=(const OpenDatabase &) = delete; ~OpenDatabase(); + PgsqlDatabaseCatalogue* getCatalogue(); + TypeSelectionItemModel* getTypeSelectionModel(); signals: public slots: @@ -28,6 +31,8 @@ private: ConnectionConfig m_config; PgsqlDatabaseCatalogue *m_catalogue; + TypeSelectionItemModel *m_typeSelectionModel = nullptr; + OpenDatabase(const ConnectionConfig& cfg, QObject *parent = 0); bool Init(); }; diff --git a/paramlistmodel.cpp b/paramlistmodel.cpp index 4a917ed..2ec9070 100644 --- a/paramlistmodel.cpp +++ b/paramlistmodel.cpp @@ -1,4 +1,4 @@ -#include "paramlistmodel.h" +#include "ParamListModel.h" ParamListModel::ParamListModel(QObject *parent) : QAbstractTableModel(parent) diff --git a/paramtypedelegate.cpp b/paramtypedelegate.cpp index 0ec7d83..f24b02e 100644 --- a/paramtypedelegate.cpp +++ b/paramtypedelegate.cpp @@ -1,15 +1,17 @@ -#include "paramtypedelegate.h" +#include "ParamTypeDelegate.h" #include #include "TypeSelectionItemModel.h" ParamTypeDelegate::ParamTypeDelegate() - : m_typeSelectionModel(new TypeSelectionItemModel) {} ParamTypeDelegate::~ParamTypeDelegate() +{} + +void ParamTypeDelegate::setTypeSelectionModel(TypeSelectionItemModel* model) { - delete m_typeSelectionModel; + m_typeSelectionModel = model; } QWidget *ParamTypeDelegate::createEditor(QWidget *parent, @@ -18,12 +20,16 @@ QWidget *ParamTypeDelegate::createEditor(QWidget *parent, { 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); -// } + + QComboBox *cmbbx = new QComboBox(parent); + cmbbx->setModel(m_typeSelectionModel); + w = cmbbx; + +// ... +// m_ComboBox->setView(m_ColumnView); +// m_ComboBox->view()->setCornerWidget(new QSizeGrip(m_ColumnView)); +// m_ComboBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +// ... + return w; } diff --git a/paramtypedelegate.h b/paramtypedelegate.h index 85e655c..c0befd0 100644 --- a/paramtypedelegate.h +++ b/paramtypedelegate.h @@ -17,7 +17,7 @@ public: QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - + void setTypeSelectionModel(TypeSelectionItemModel* model); private: TypeSelectionItemModel* m_typeSelectionModel = nullptr; }; diff --git a/pglab.pro b/pglab.pro index 26a73bc..622c741 100644 --- a/pglab.pro +++ b/pglab.pro @@ -13,7 +13,7 @@ TEMPLATE = app INCLUDEPATH += C:\prog\include DEFINES += WIN32_LEAN_AND_MEAN NOMINMAX -LIBS += c:\prog\lib\libpq.lib User32.lib ws2_32.lib +LIBS += c:\prog\lib\libpq.lib c:\prog\lib\fmt.lib User32.lib ws2_32.lib SOURCES += main.cpp\ mainwindow.cpp \ @@ -45,11 +45,11 @@ SOURCES += main.cpp\ pgnamespace.cpp \ pgclass.cpp \ backupdialog.cpp \ - paramlistmodel.cpp \ - paramtypedelegate.cpp \ typeselectionitemmodel.cpp \ - opendatabase.cpp \ - MasterController.cpp + MasterController.cpp \ + ParamTypeDelegate.cpp \ + OpenDatabase.cpp \ + ParamListModel.cpp HEADERS += mainwindow.h \ sqlparser.h \ @@ -80,11 +80,11 @@ HEADERS += mainwindow.h \ pgnamespace.h \ pgclass.h \ backupdialog.h \ - paramlistmodel.h \ - paramtypedelegate.h \ typeselectionitemmodel.h \ - opendatabase.h \ - MasterController.h + MasterController.h \ + ParamTypeDelegate.h \ + OpenDatabase.h \ + ParamListModel.h FORMS += mainwindow.ui \ databasewindow.ui \ diff --git a/pgsqldatabasecatalogue.cpp b/pgsqldatabasecatalogue.cpp index c4829ee..41fe061 100644 --- a/pgsqldatabasecatalogue.cpp +++ b/pgsqldatabasecatalogue.cpp @@ -4,7 +4,6 @@ PgsqlDatabaseCatalogue::PgsqlDatabaseCatalogue() { - } PgsqlDatabaseCatalogue::~PgsqlDatabaseCatalogue() diff --git a/pgsqldatabasecatalogue.h b/pgsqldatabasecatalogue.h index a85c1cd..892df5c 100644 --- a/pgsqldatabasecatalogue.h +++ b/pgsqldatabasecatalogue.h @@ -25,7 +25,7 @@ public: const PgTypeContainer* getTypes() const { return m_types; } private: - PgTypeContainer *m_types; + PgTypeContainer *m_types = nullptr; }; #endif // PGSQLDATABASECATALOGUE_H diff --git a/pgtypecontainer.cpp b/pgtypecontainer.cpp index 72d0019..8e2900f 100644 --- a/pgtypecontainer.cpp +++ b/pgtypecontainer.cpp @@ -24,6 +24,11 @@ const PgType& PgTypeContainer::getTypeByName(const QString &name) const return m_invalidType; } +const PgType& PgTypeContainer::getTypeByIdx(int idx) const +{ + return m_types.at(idx); +} + std::string PgTypeContainer::getLoadQuery() { return diff --git a/pgtypecontainer.h b/pgtypecontainer.h index 2a3a4de..6c65ce7 100644 --- a/pgtypecontainer.h +++ b/pgtypecontainer.h @@ -20,6 +20,7 @@ public: t_Types::const_iterator end() const { return m_types.end(); } void clear(); + int count() const { return (int)m_types.size(); } std::string getLoadQuery(); void load(const Pgsql::Result &res); @@ -29,6 +30,7 @@ public: */ const PgType& getTypeByOid(Oid oid) const; const PgType& getTypeByName(const QString &name) const; + const PgType& getTypeByIdx(int idx) const; private: PgType m_invalidType; ///< default constructed object for when a non existent type is being retrieved. t_Types m_types; // Keep sorted by Oid diff --git a/querytab.cpp b/querytab.cpp index f9c927f..234ee94 100644 --- a/querytab.cpp +++ b/querytab.cpp @@ -13,6 +13,7 @@ #include "explaintreemodelitem.h" #include "json/json.h" #include "mainwindow.h" +#include "OpenDatabase.h" #include "pgtypecontainer.h" #include "util.h" @@ -40,6 +41,9 @@ QueryTab::QueryTab(MainWindow *win, QWidget *parent) : ui->queryEdit->setFont(font); highlighter.reset(new SqlHighlighter(ui->queryEdit->document())); + OpenDatabase* open_database = m_win->getDatabase(); + m_typeDelegate.setTypeSelectionModel(open_database->getTypeSelectionModel()); + ui->paramTableView->setModel(&m_paramList); ui->paramTableView->setItemDelegateForColumn(1, &m_typeDelegate); diff --git a/querytab.h b/querytab.h index 28aa59b..273efea 100644 --- a/querytab.h +++ b/querytab.h @@ -2,8 +2,8 @@ #define QUERYTAB_H #include "asyncdbconnection.h" -#include "paramlistmodel.h" -#include "paramtypedelegate.h" +#include "ParamListModel.h" +#include "ParamTypeDelegate.h" #include "queryresultmodel.h" #include "queryexplainmodel.h" #include "stopwatch.h" diff --git a/resources.qrc b/resources.qrc index 2c826e3..8f234dd 100644 --- a/resources.qrc +++ b/resources.qrc @@ -17,5 +17,6 @@ icons/16x16/document_red.png icons/16x16/document_yellow.png icons/backups.png + icons/page_white_copy.png diff --git a/typeselectionitemmodel.cpp b/typeselectionitemmodel.cpp index 1c24ab4..b4ee893 100644 --- a/typeselectionitemmodel.cpp +++ b/typeselectionitemmodel.cpp @@ -1,4 +1,5 @@ #include "typeselectionitemmodel.h" +#include "PgTypeContainer.h" TypeSelectionItemModel::TypeSelectionItemModel(QObject *parent) : QAbstractListModel(parent) @@ -7,7 +8,7 @@ TypeSelectionItemModel::TypeSelectionItemModel(QObject *parent) int TypeSelectionItemModel::rowCount(const QModelIndex &parent) const { - int result = 10; + int result = m_types->count(); // if (!parent.isValid()) { // } @@ -32,21 +33,32 @@ QVariant TypeSelectionItemModel::data(const QModelIndex &index, int role) const 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; + const PgType &tp = m_types->getTypeByIdx(row); + result = tp.typname; - } +// 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; } + +void TypeSelectionItemModel::setTypeList(const PgTypeContainer* types) +{ + beginResetModel(); + m_types = types; + //emit dataChanged(this->createIndex(0, 0), this->createIndex(types->count(), 0), QVector() << Qt::DisplayRole); + endResetModel(); +} diff --git a/typeselectionitemmodel.h b/typeselectionitemmodel.h index 0c70fa2..5206725 100644 --- a/typeselectionitemmodel.h +++ b/typeselectionitemmodel.h @@ -3,6 +3,8 @@ #include +class PgTypeContainer; + class TypeSelectionItemModel : public QAbstractListModel { Q_OBJECT @@ -10,12 +12,14 @@ class TypeSelectionItemModel : public QAbstractListModel public: explicit TypeSelectionItemModel(QObject *parent = 0); + void setTypeList(const PgTypeContainer* types); 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: + const PgTypeContainer* m_types; }; #endif // TYPESELECTIONITEMMODEL_H