Can use the parameter list in the query window now.

Still requires extensive testing for all possible types.
This commit is contained in:
eelke 2017-02-19 11:12:43 +01:00
parent aefc9eb7ba
commit 3af26d915e
14 changed files with 461 additions and 242 deletions

View file

@ -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<std::mutex> 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<std::mutex> 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()

View file

@ -2,6 +2,7 @@
#define ASYNCDBCONNECTION_H
#include "PgsqlConn.h"
#include "Pgsql_Params.h"
#include "win32event.h"
#include "connectionconfig.h"
#include <QElapsedTimer>
@ -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

View file

@ -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<int>() << role);
return true;
emit dataChanged(index, index, QVector<int>() << 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)
//{

View file

@ -2,12 +2,29 @@
#define PARAMLISTMODEL_H
#include <QAbstractTableModel>
#include <vector>
#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<Param>;
t_ParamList m_paramList;
};
#endif // PARAMLISTMODEL_H

View file

@ -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 starRating = qvariant_cast<StarRating>(index.data());
// StarEditor *starEditor = qobject_cast<StarEditor *>(editor);
// starEditor->setStarRating(starRating);
// } else {
// QStyledItemDelegate::setEditorData(editor, index);
// }
if (index.column() == 1) {
QComboBox *cmbbx = dynamic_cast<QComboBox*>(editor);
if (cmbbx) {
auto data = index.data();
if (data.canConvert<QString>()) {
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<StarRating>()) {
// StarEditor *starEditor = qobject_cast<StarEditor *>(editor);
// model->setData(index, QVariant::fromValue(starEditor->starRating()));
// } else {
// QStyledItemDelegate::setModelData(editor, model, index);
// }
if (index.column() == 1) {
QComboBox *cmbbx = dynamic_cast<QComboBox*>(editor);
if (cmbbx) {
auto data = index.data();
if (data.canConvert<QString>()) {
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<StarEditor *>(sender());
// emit commitData(editor);
// emit closeEditor(editor);
}

View file

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

View file

@ -1,5 +1,6 @@
#include "PgsqlConn.h"
#include "Pgsql_declare.h"
#include "Pgsql_Params.h"
#include <stdexcept>
@ -158,6 +159,15 @@ bool Connection::sendQuery(const char *query)
return res == 1;
}
bool Connection::sendQueryParams(const char * command, const Params &params)
{
int res = PQsendQueryParams(conn, command, params.size(), params.types(),
params.values(), params.lengths(), params.formats(),
0); // text format
return res == 1;
}
std::shared_ptr<Result> Connection::getResult()
{
PGresult *r = PQgetResult(conn);

View file

@ -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 &params);
std::shared_ptr<Result> getResult();
bool consumeInput();

View file

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

View file

@ -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<const char *>;

View file

@ -4,6 +4,7 @@
#include "SqlSyntaxHighlighter.h"
#include <QStandardPaths>
#include <QPushButton>
#include <QFileDialog>
#include <QMessageBox>
#include <QTabWidget>
@ -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<Pgsql::Result> 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<Pgsql::Result> 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<Pgsql::Result> 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()

View file

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

View file

@ -13,123 +13,199 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPlainTextEdit" name="queryEdit"/>
<widget class="QTableView" name="paramTableView">
<property name="alternatingRowColors">
<bool>true</bool>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
</widget>
</widget>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="messageTab">
<attribute name="title">
<string>Messages</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>2</number>
<number>0</number>
</property>
<property name="topMargin">
<number>2</number>
<number>0</number>
</property>
<property name="rightMargin">
<number>2</number>
<number>0</number>
</property>
<property name="bottomMargin">
<number>2</number>
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QTextEdit" name="messagesEdit">
<property name="readOnly">
<bool>true</bool>
<item>
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>6</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>
<widget class="QPushButton" name="addButton">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeButton">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="explainTab">
<attribute name="title">
<string>Explain</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item row="1" column="0">
<widget class="QTreeView" name="explainTreeView">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<item>
<widget class="QTableView" name="paramTableView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="indentation">
<number>10</number>
</property>
<property name="uniformRowHeights">
<bool>false</bool>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblTimes">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="logTab">
<attribute name="title">
<string>Log</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QPlainTextEdit" name="edtLog"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="messageTab">
<attribute name="title">
<string>Messages</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QTextEdit" name="messagesEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="explainTab">
<attribute name="title">
<string>Explain</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item row="1" column="0">
<widget class="QTreeView" name="explainTreeView">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="indentation">
<number>10</number>
</property>
<property name="uniformRowHeights">
<bool>false</bool>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblTimes">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="logTab">
<attribute name="title">
<string>Log</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QPlainTextEdit" name="edtLog"/>
</item>
</layout>
</widget>
</widget>
</item>

View file

@ -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) {