From 3af26d915e0fff7c7559833f914164b67252d55f Mon Sep 17 00:00:00 2001 From: eelke Date: Sun, 19 Feb 2017 11:12:43 +0100 Subject: [PATCH] Can use the parameter list in the query window now. Still requires extensive testing for all possible types. --- src/ASyncDBConnection.cpp | 38 +++-- src/ASyncDBConnection.h | 6 + src/ParamListModel.cpp | 84 ++++++----- src/ParamListModel.h | 38 +++-- src/ParamTypeDelegate.cpp | 64 ++++++++ src/ParamTypeDelegate.h | 9 +- src/PgsqlConn.cpp | 10 ++ src/PgsqlConn.h | 3 + src/Pgsql_Params.cpp | 21 ++- src/Pgsql_Params.h | 11 +- src/QueryTab.cpp | 118 ++++++--------- src/QueryTab.h | 31 +++- src/QueryTab.ui | 268 +++++++++++++++++++++------------ src/typeselectionitemmodel.cpp | 2 +- 14 files changed, 461 insertions(+), 242 deletions(-) diff --git a/src/ASyncDBConnection.cpp b/src/ASyncDBConnection.cpp index dafaffc..95fa5f5 100644 --- a/src/ASyncDBConnection.cpp +++ b/src/ASyncDBConnection.cpp @@ -51,6 +51,16 @@ bool ASyncDBConnection::send(const std::string &command, on_result_callback on_r return true; } +bool ASyncDBConnection::send(const std::string &command, Pgsql::Params params, on_result_callback on_result) +{ + { + std::lock_guard lg(m_threadData.m_commandQueue.m_mutex); + m_threadData.m_commandQueue.m_queue.emplace(command, std::move(params), on_result); + m_threadData.m_commandQueue.m_newEvent.set(); + } + return true; +} + bool ASyncDBConnection::cancel() { return m_threadData.cancel(); @@ -243,21 +253,29 @@ void ASyncDBConnection::Thread::doNewCommand() { // todo: send command // get command from top of queue (but leave it in the queue, we need the callback) - std::string command; { std::lock_guard lg(m_commandQueue.m_mutex); if (! m_commandQueue.m_queue.empty()) { - command = m_commandQueue.m_queue.front().command; + const Command &command = m_commandQueue.m_queue.front(); + if (!command.command.empty()) { + bool query_send = false; + if (command.params.empty()) + query_send = m_connection.sendQuery(command.command.c_str()); + else + query_send = m_connection.sendQueryParams(command.command.c_str(), command.params); + + if (query_send) { + m_timer.start(); + doStateCallback(State::QuerySend); + } + else { + std::string error = m_connection.getErrorMessage(); + // todo: need to report the error + } + } } } - if (!command.empty() && m_connection.sendQuery(command)) { - m_timer.start(); - doStateCallback(State::QuerySend); - } - else { - std::string error = m_connection.getErrorMessage(); - // todo: need to report the error - } + } void ASyncDBConnection::Thread::waitForResult() diff --git a/src/ASyncDBConnection.h b/src/ASyncDBConnection.h index 5c8af2d..07bb1bf 100644 --- a/src/ASyncDBConnection.h +++ b/src/ASyncDBConnection.h @@ -2,6 +2,7 @@ #define ASYNCDBCONNECTION_H #include "PgsqlConn.h" +#include "Pgsql_Params.h" #include "win32event.h" #include "connectionconfig.h" #include @@ -48,6 +49,7 @@ public: If the command gives multiple results on_result will be called for each result. */ bool send(const std::string &command, on_result_callback on_result); + bool send(const std::string &command, Pgsql::Params params, on_result_callback on_result); bool cancel(); @@ -56,12 +58,16 @@ private: class Command { public: std::string command; + Pgsql::Params params; on_result_callback on_result; Command() = default; Command(const std::string &cmd, on_result_callback cb) : command(cmd), on_result(cb) {} + Command(const std::string &cmd, Pgsql::Params &&p, on_result_callback cb) + : command(cmd), params(p), on_result(cb) + {} }; /// Contains all the members accessed by the thread diff --git a/src/ParamListModel.cpp b/src/ParamListModel.cpp index 2ec9070..801e441 100644 --- a/src/ParamListModel.cpp +++ b/src/ParamListModel.cpp @@ -11,12 +11,13 @@ QVariant ParamListModel::headerData(int section, Qt::Orientation orientation, in QVariant result; if (orientation == Qt::Horizontal) { if (role == Qt::DisplayRole) { - if (section == 0) { -// result = tr("$n"); + switch (section) { + case ColValue: result = tr("Value"); - } - else if (section == 1) { + break; + case ColType: result = tr("Type"); + break; } } } @@ -39,20 +40,14 @@ QVariant ParamListModel::headerData(int section, Qt::Orientation orientation, in //} -int ParamListModel::rowCount(const QModelIndex &parent) const +int ParamListModel::rowCount(const QModelIndex &) const { - //if (parent.isValid()) - return 2; - - // FIXME: Implement me! + return m_paramList.size(); } -int ParamListModel::columnCount(const QModelIndex &parent) const +int ParamListModel::columnCount(const QModelIndex &) const { - //if (parent.isValid()) - return 2; - - // FIXME: Implement me! + return ColumnCount; } QVariant ParamListModel::data(const QModelIndex &index, int role) const @@ -62,28 +57,40 @@ QVariant ParamListModel::data(const QModelIndex &index, int role) const int row = index.row(); int col = index.column(); if (role == Qt::DisplayRole) { + const auto& record = m_paramList[row]; switch (col) { - case 0: // value column - result = tr("val, %1").arg(row); + case ColValue: // value column + result = record.value; // tr("val, %1").arg(row); break; - case 1: // type column - result = tr("type, %1").arg(row); + case ColType: // type column + result = record.type; // 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! + if (role == Qt::EditRole) { + int row = index.row(); + int col = index.column(); + auto& record = m_paramList[row]; + switch (col) { + case ColValue: + record.value = value.toString(); + break; + case ColType: + record.type = value.toString(); + break; + } - emit dataChanged(index, index, QVector() << role); - return true; + emit dataChanged(index, index, QVector() << role); + return true; + } } return false; } @@ -93,16 +100,18 @@ Qt::ItemFlags ParamListModel::flags(const QModelIndex &index) const if (!index.isValid()) return Qt::NoItemFlags; - return Qt::ItemIsEnabled | Qt::ItemIsEditable; // FIXME: Implement me! + return Qt::ItemIsEnabled | Qt::ItemIsEditable; } -//bool ParamListModel::insertRows(int row, int count, const QModelIndex &parent) -//{ -// beginInsertRows(parent, row, row + count - 1); -// // FIXME: Implement me! -// endInsertRows(); -// return false; -//} +bool ParamListModel::insertRows(int row, int count, const QModelIndex &parent) +{ + beginInsertRows(parent, row, row + count - 1); + // FIXME: Implement me! + auto iter = m_paramList.begin() + row; + m_paramList.insert(iter, count, Param()); + endInsertRows(); + return true; +} //bool ParamListModel::insertColumns(int column, int count, const QModelIndex &parent) //{ @@ -111,13 +120,14 @@ Qt::ItemFlags ParamListModel::flags(const QModelIndex &index) const // 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::removeRows(int row, int count, const QModelIndex &parent) +{ + beginRemoveRows(parent, row, row + count - 1); + auto iter = m_paramList.begin() + row; + m_paramList.erase(iter, iter + count); + endRemoveRows(); + return true; +} //bool ParamListModel::removeColumns(int column, int count, const QModelIndex &parent) //{ diff --git a/src/ParamListModel.h b/src/ParamListModel.h index e36e5d2..11acfc3 100644 --- a/src/ParamListModel.h +++ b/src/ParamListModel.h @@ -2,12 +2,29 @@ #define PARAMLISTMODEL_H #include +#include +#include "Pgsql_declare.h" -class ParamListModel : public QAbstractTableModel -{ +class ParamListModel : public QAbstractTableModel { Q_OBJECT - public: + class Param { + public: + QString value; ///< the value of the parameter (currently this is passed directly) + QString type = InvalidOid; ///< the type of the parameter + + Param() = default; + Param(const QString &v, const QString t) + : value(v), type(t) + {} + }; + + enum e_Column { + ColValue = 0, + ColType, + ColumnCount // Keep last not a column just the count + }; + explicit ParamListModel(QObject *parent = 0); // Header: @@ -26,16 +43,15 @@ public: int role = Qt::EditRole) override; Qt::ItemFlags flags(const QModelIndex& index) const override; + bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) 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; - + auto begin() const { return m_paramList.begin(); } + auto end() const { return m_paramList.end(); } private: + + using t_ParamList = std::vector; + t_ParamList m_paramList; }; #endif // PARAMLISTMODEL_H diff --git a/src/ParamTypeDelegate.cpp b/src/ParamTypeDelegate.cpp index f24b02e..595eda9 100644 --- a/src/ParamTypeDelegate.cpp +++ b/src/ParamTypeDelegate.cpp @@ -33,3 +33,67 @@ QWidget *ParamTypeDelegate::createEditor(QWidget *parent, return w; } + +void ParamTypeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ +// if (index.data().canConvert()) { +// StarRating starRating = qvariant_cast(index.data()); +// StarEditor *starEditor = qobject_cast(editor); +// starEditor->setStarRating(starRating); +// } else { +// QStyledItemDelegate::setEditorData(editor, index); +// } + if (index.column() == 1) { + QComboBox *cmbbx = dynamic_cast(editor); + if (cmbbx) { + auto data = index.data(); + if (data.canConvert()) { + QModelIndexList indexes = m_typeSelectionModel->match( + m_typeSelectionModel->index(0, 1), Qt::DisplayRole, data, 1, Qt::MatchFlags( Qt::MatchExactly )); + if (!indexes.empty()) { + cmbbx->setCurrentIndex(indexes.at(0).row()); + } + else { + cmbbx->setCurrentIndex(-1); + } + } + } + } + else { + QStyledItemDelegate::setEditorData(editor, index); + } +} + +void ParamTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const +{ +// if (index.data().canConvert()) { +// StarEditor *starEditor = qobject_cast(editor); +// model->setData(index, QVariant::fromValue(starEditor->starRating())); +// } else { +// QStyledItemDelegate::setModelData(editor, model, index); +// } + if (index.column() == 1) { + QComboBox *cmbbx = dynamic_cast(editor); + if (cmbbx) { + auto data = index.data(); + if (data.canConvert()) { + QVariant d = m_typeSelectionModel->data( + m_typeSelectionModel->index(cmbbx->currentIndex(), 0)); + model->setData(index, d); + } + } + } else { + QStyledItemDelegate::setModelData(editor, model, index); + } +} + + + +// triggered by editing finished from editor +void ParamTypeDelegate::commitAndCloseEditor() +{ +// StarEditor *editor = qobject_cast(sender()); +// emit commitData(editor); +// emit closeEditor(editor); +} diff --git a/src/ParamTypeDelegate.h b/src/ParamTypeDelegate.h index c0befd0..c6d463f 100644 --- a/src/ParamTypeDelegate.h +++ b/src/ParamTypeDelegate.h @@ -8,8 +8,7 @@ class TypeSelectionItemModel; /** Item delegate for supplying a combobox for selected the parameter type in * the parameter list. */ -class ParamTypeDelegate : public QStyledItemDelegate -{ +class ParamTypeDelegate : public QStyledItemDelegate { Q_OBJECT public: ParamTypeDelegate(); @@ -18,8 +17,14 @@ public: QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void setTypeSelectionModel(TypeSelectionItemModel* model); + void setEditorData(QWidget *editor, const QModelIndex &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const override; private: TypeSelectionItemModel* m_typeSelectionModel = nullptr; + +private slots: + void commitAndCloseEditor(); }; #endif // PARAMTYPEDELEGATE_H diff --git a/src/PgsqlConn.cpp b/src/PgsqlConn.cpp index fe764fe..78b37d5 100644 --- a/src/PgsqlConn.cpp +++ b/src/PgsqlConn.cpp @@ -1,5 +1,6 @@ #include "PgsqlConn.h" #include "Pgsql_declare.h" +#include "Pgsql_Params.h" #include @@ -158,6 +159,15 @@ bool Connection::sendQuery(const char *query) return res == 1; } +bool Connection::sendQueryParams(const char * command, const Params ¶ms) +{ + int res = PQsendQueryParams(conn, command, params.size(), params.types(), + params.values(), params.lengths(), params.formats(), + 0); // text format + + return res == 1; +} + std::shared_ptr Connection::getResult() { PGresult *r = PQgetResult(conn); diff --git a/src/PgsqlConn.h b/src/PgsqlConn.h index 7288762..80654c7 100644 --- a/src/PgsqlConn.h +++ b/src/PgsqlConn.h @@ -41,6 +41,7 @@ namespace Pgsql { class Result; + class Params; @@ -126,6 +127,8 @@ namespace Pgsql { return sendQuery(command.toUtf8().data()); } + bool sendQueryParams(const char * command, const Params ¶ms); + std::shared_ptr getResult(); bool consumeInput(); diff --git a/src/Pgsql_Params.cpp b/src/Pgsql_Params.cpp index 02dfa48..256c420 100644 --- a/src/Pgsql_Params.cpp +++ b/src/Pgsql_Params.cpp @@ -25,12 +25,26 @@ Params& Params::operator=(const Params& rhs) return *this; } -Params::Params(const Params&& rhs) +Params::Params(Params&& rhs) : m_paramTypes(std::move(rhs.m_paramTypes)) , m_paramValues(std::move(rhs.m_paramValues)) , m_paramLengths(std::move(rhs.m_paramLengths)) , m_paramFormats(std::move(rhs.m_paramFormats)) -{} +{ + //rhs.m_paramValues.clear(); // make sure origin is empty, to prevent double deletion +} + +Params& Params::operator=(Params&& rhs) +{ + if (&rhs != this) { + m_paramTypes = std::move(rhs.m_paramTypes); + m_paramValues = std::move(rhs.m_paramValues); + //rhs.m_paramValues.clear(); // make sure origin is empty, to prevent double deletion + m_paramLengths = std::move(rhs.m_paramLengths); + m_paramFormats = std::move(rhs.m_paramFormats); + } + return *this; +} Params::~Params() { @@ -49,8 +63,9 @@ void Params::add(const QString &s, Oid oid) { auto ba = s.toUtf8(); const int len = ba.size(); - char * p = new char[len]; + char * p = new char[len+1]; std::memcpy(p, ba.data(), len); + p[len] = 0; addText(p, oid); } diff --git a/src/Pgsql_Params.h b/src/Pgsql_Params.h index a3cd7d7..7e10e88 100644 --- a/src/Pgsql_Params.h +++ b/src/Pgsql_Params.h @@ -13,7 +13,8 @@ namespace Pgsql { Params(); Params(const Params& rhs); Params& operator=(const Params& rhs); - Params(const Params&& rhs); + Params(Params&& rhs); + Params& operator=(Params&& rhs); ~Params(); @@ -26,6 +27,14 @@ namespace Pgsql { void addBinary(const char *data, int length, Oid oid); void clear(); + bool empty() const { return m_paramTypes.empty(); } + int size() const { return m_paramTypes.size(); } + + const Oid* types() const { return m_paramTypes.data(); } + const char* const* values() const { return m_paramValues.data(); } + const int* lengths() const { return m_paramLengths.data(); } + const int* formats() const { return m_paramFormats.data(); } + private: using t_paramValues = std::vector; diff --git a/src/QueryTab.cpp b/src/QueryTab.cpp index 3f9453d..1a06897 100644 --- a/src/QueryTab.cpp +++ b/src/QueryTab.cpp @@ -4,6 +4,7 @@ #include "SqlSyntaxHighlighter.h" #include +#include #include #include #include @@ -19,6 +20,44 @@ #include "pgsqldatabasecatalogue.h" #include "util.h" + +QueryParamListController::QueryParamListController(QTableView *tv, + OpenDatabase *opendb, QWidget *parent) + : QObject(parent) + , paramTableView(tv) + , m_openDatabase(opendb) +{ + m_typeDelegate.setTypeSelectionModel(opendb->typeSelectionModel()); + + paramTableView->setModel(&m_paramList); + paramTableView->setItemDelegateForColumn(1, &m_typeDelegate); +} + +Pgsql::Params QueryParamListController::params() const +{ + Pgsql::Params params; + auto types = m_openDatabase->catalogue()->types(); + for (auto e : m_paramList) { + Oid oid = types->getByName(e.type).oid; + params.add(e.value, oid); + } + return params; +} + +void QueryParamListController::on_addParam() +{ + m_paramList.insertRows(m_paramList.rowCount(), 1); +} + +void QueryParamListController::on_removeParam() +{ + auto rc = m_paramList.rowCount(); + if (rc > 0) + m_paramList.removeRows(rc-1, 1); +} + + + QueryTab::QueryTab(MainWindow *win, QWidget *parent) : QWidget(parent), ui(new Ui::QueryTab), @@ -43,20 +82,16 @@ QueryTab::QueryTab(MainWindow *win, QWidget *parent) : ui->queryEdit->setFont(font); OpenDatabase* open_database = m_win->getDatabase(); - m_typeDelegate.setTypeSelectionModel(open_database->typeSelectionModel()); - auto cat = open_database->catalogue(); highlighter = new SqlSyntaxHighlighter(ui->queryEdit->document()); highlighter->setTypes(cat->types()); - 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(); -// ui->lblRowCount->clear(); + + m_queryParamListController = new QueryParamListController(ui->paramTableView, open_database, this); + connect(ui->addButton, &QPushButton::clicked, m_queryParamListController, &QueryParamListController::on_addParam); + connect(ui->removeButton, &QPushButton::clicked, m_queryParamListController, &QueryParamListController::on_removeParam); } QueryTab::~QueryTab() @@ -64,16 +99,12 @@ QueryTab::~QueryTab() m_dbConnection.closeConnection(); m_dbConnection.setStateCallback(nullptr); -// delete m_pgTypes; delete ui; } void QueryTab::setConfig(const ConnectionConfig &config) { m_config = config; -// QString title = "pglab - "; -// title += m_config.name().c_str(); -// setWindowTitle(title); m_win->QueueTask([this]() { startConnect(); }); } @@ -89,30 +120,6 @@ bool QueryTab::canClose() return can_close; } -//void QueryTab::open() -//{ -// if (m_queryTextChanged && !continueWithoutSavingWarning()) { -// return; -// } - -// QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory); -// QString file_name = QFileDialog::getOpenFileName(this, -// tr("Open sql query"), home_dir, tr("SQL files (*.sql *.txt)")); -// if ( ! file_name.isEmpty()) { -// QFile file(file_name); -// if (file.open(QIODevice::ReadWrite)) { -// QTextStream stream(&file); -// ui->queryEdit->clear(); -// while (!stream.atEnd()){ -// QString line = stream.readLine(); -// ui->queryEdit->appendPlainText(line); -// } -// m_queryTextChanged = false; -// setFileName(file_name); -// } -// } -//} - void QueryTab::newdoc() { ui->queryEdit->clear(); @@ -183,6 +190,7 @@ void QueryTab::execute() std::string cmd = getCommand(); m_stopwatch.start(); m_dbConnection.send(cmd, + m_queryParamListController->params(), [this](std::shared_ptr res, qint64 elapsedms) { m_win->QueueTask([this, res, elapsedms]() { query_ready(res, elapsedms); }); @@ -295,26 +303,6 @@ 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; -// } -// addLog(status_str); - QTabWidget *tabwidget = getTabWidget(); if (tabwidget) { int i = tabwidget->indexOf(this); @@ -334,13 +322,6 @@ void QueryTab::connectionStateChanged(ASyncDBConnection::State state) } tabwidget->setTabIcon(i, QIcon(iconname)); } - - // statusBar()->showMessage(status_str); - -// bool connected = ASyncDBConnection::State::Connected == state; -// ui->actionExecute_SQL->setEnabled(connected); -// ui->actionExplain_Analyze->setEnabled(connected); -// ui->actionCancel->setEnabled(ASyncDBConnection::State::QuerySend == state); } @@ -488,16 +469,9 @@ void QueryTab::query_ready(std::shared_ptr dbres, qint64 elapsedm if (resultList.size() == 1) ui->tabWidget->setCurrentWidget(trw); - -// ui->lblRowCount->setText(rowcount_str); -// resultModel.reset(new QueryResultModel(nullptr , dbres)); -// ui->ResultView->setModel(resultModel.get()); -// ui->tabWidget->setCurrentWidget(ui->dataTab); - //statusBar()->showMessage(tr("Query ready.")); } else { if (st == PGRES_COMMAND_OK) { -// statusBar()->showMessage(tr("Command OK.")); int tuples_affected = dbres->tuplesAffected(); QString msg; if (tuples_affected >= 0) @@ -548,18 +522,14 @@ void QueryTab::query_ready(std::shared_ptr dbres, qint64 elapsedm else { m_stopwatch.stop(); addLog("query_ready with NO result"); -// statusBar()->showMessage(tr("Query cancelled.")); } } void QueryTab::clearResult() { -// ui->ResultView->setModel(nullptr); -// resultModel.reset(); for (auto e : resultList) delete e; resultList.clear(); -// ui->lblRowCount->clear(); } void QueryTab::copyQueryAsCString() diff --git a/src/QueryTab.h b/src/QueryTab.h index 1aa3456..c298f3b 100644 --- a/src/QueryTab.h +++ b/src/QueryTab.h @@ -16,6 +16,8 @@ namespace Ui { class QueryTab; } +class QTableView; + class QTabWidget; class MainWindow; class SqlSyntaxHighlighter; @@ -23,14 +25,29 @@ class ExplainRoot; class QueryResultModel; class QueryExplainModel; class PgTypeContainer; +class OpenDatabase; - -class QueryTab : public QWidget -{ +class QueryParamListController : public QObject { Q_OBJECT - public: - QueryTab(MainWindow *win, QWidget *parent = 0); + QueryParamListController(QTableView *tv, OpenDatabase *opendb, QWidget *parent); + + Pgsql::Params params() const; +public slots: + void on_addParam(); + void on_removeParam(); +private: + QTableView *paramTableView; + OpenDatabase *m_openDatabase; + ParamListModel m_paramList; + ParamTypeDelegate m_typeDelegate; +}; + + +class QueryTab : public QWidget { + Q_OBJECT +public: + QueryTab(MainWindow *win, QWidget *parent = nullptr); ~QueryTab(); void setConfig(const ConnectionConfig &config); @@ -70,8 +87,8 @@ private: SqlSyntaxHighlighter* highlighter; ConnectionConfig m_config; StopWatch m_stopwatch; - ParamListModel m_paramList; - ParamTypeDelegate m_typeDelegate; + + QueryParamListController *m_queryParamListController = nullptr; QString m_fileName; ///< use setFileName function to set bool m_queryTextChanged = false; diff --git a/src/QueryTab.ui b/src/QueryTab.ui index fa809bb..8be3be5 100644 --- a/src/QueryTab.ui +++ b/src/QueryTab.ui @@ -13,123 +13,199 @@ Form - + - - - Qt::Vertical - - - - Qt::Horizontal - + + - - - true + + + + + QFrame::StyledPanel - - - - - 1 - - - - Messages - - + + QFrame::Raised + + - 2 + 0 - 2 + 0 - 2 + 0 - 2 + 0 - - - - true + + + + QFrame::StyledPanel + + QFrame::Raised + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Add + + + + + + + Remove + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - - Explain - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QAbstractItemView::NoEditTriggers - - - false - + + true - - 10 - - - false - - - false - - - - - - - - - - - Log - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - - + + + + + + + 1 + + + + Messages + + + + 2 + + + 2 + + + 2 + + + 2 + + + + + true + + + + + + + + Explain + + + + 2 + + + 2 + + + 2 + + + 2 + + + + + QAbstractItemView::NoEditTriggers + + + false + + + true + + + 10 + + + false + + + false + + + + + + + + + + + + + + + Log + + + + 2 + + + 2 + + + 2 + + + 2 + + + + + diff --git a/src/typeselectionitemmodel.cpp b/src/typeselectionitemmodel.cpp index 4af4699..a6de817 100644 --- a/src/typeselectionitemmodel.cpp +++ b/src/typeselectionitemmodel.cpp @@ -32,8 +32,8 @@ QVariant TypeSelectionItemModel::data(const QModelIndex &index, int role) const int row = index.row(); int column = index.column(); if (role == Qt::DisplayRole) { + const PgType &tp = m_types->getByIdx(row); if (column == 0) { - const PgType &tp = m_types->getByIdx(row); result = tp.typname; // switch (row) {