QueryTool now uses the same DataGrid as the CRUD tool.
This commit is contained in:
parent
bbe52c9db8
commit
5e7fb68c55
15 changed files with 135 additions and 203 deletions
|
|
@ -30,9 +30,9 @@ set(PGLAB_SOURCES
|
||||||
codeeditor/GutterPainter.cpp
|
codeeditor/GutterPainter.cpp
|
||||||
crud/CrudModel.cpp
|
crud/CrudModel.cpp
|
||||||
crud/CrudTab.cpp
|
crud/CrudTab.cpp
|
||||||
|
crud/DataGridWidget.cpp
|
||||||
querytool/QueryExplainModel.cpp
|
querytool/QueryExplainModel.cpp
|
||||||
querytool/QueryParamListController.cpp
|
querytool/QueryParamListController.cpp
|
||||||
querytool/QueryResultModel.cpp
|
|
||||||
querytool/QueryTool.cpp
|
querytool/QueryTool.cpp
|
||||||
serverinspector/DatabasesPage.cpp
|
serverinspector/DatabasesPage.cpp
|
||||||
serverinspector/RolesPage.cpp
|
serverinspector/RolesPage.cpp
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include "CustomDataRole.h"
|
#include "CustomDataRole.h"
|
||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
|
#include <QBrush>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include "Pgsql_oids.h"
|
#include "Pgsql_oids.h"
|
||||||
#include "Pgsql_PgException.h"
|
#include "Pgsql_PgException.h"
|
||||||
|
|
@ -217,6 +218,8 @@ QVariant CrudModel::data(const QModelIndex &index, int role) const
|
||||||
if (value)
|
if (value)
|
||||||
return StringToVariant(value->c_str(), typ);
|
return StringToVariant(value->c_str(), typ);
|
||||||
}
|
}
|
||||||
|
else if (role == Qt::ForegroundRole && !m_wholeTable && columnIsReadOnly(index.column()))
|
||||||
|
return QBrush(Qt::gray);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,19 @@
|
||||||
#include "CrudModel.h"
|
#include "CrudModel.h"
|
||||||
#include "CustomDataRole.h"
|
#include "CustomDataRole.h"
|
||||||
#include "ResultTableModelUtil.h"
|
#include "ResultTableModelUtil.h"
|
||||||
#include "util/PgLabItemDelegate.h"
|
#include "DataGridWidget.h"
|
||||||
#include "IntegerRange.h"
|
#include "IntegerRange.h"
|
||||||
#include "OpenDatabase.h"
|
#include "OpenDatabase.h"
|
||||||
#include "catalog/PgClassContainer.h"
|
#include "catalog/PgClassContainer.h"
|
||||||
#include "catalog/PgDatabaseCatalog.h"
|
#include "catalog/PgDatabaseCatalog.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QHeaderView>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <QTableView>
|
||||||
|
|
||||||
|
|
||||||
CrudTab::CrudTab(IDatabaseWindow *context, QWidget *parent)
|
CrudTab::CrudTab(IDatabaseWindow *context, QWidget *parent)
|
||||||
|
|
@ -24,25 +27,18 @@ CrudTab::CrudTab(IDatabaseWindow *context, QWidget *parent)
|
||||||
|
|
||||||
m_db = context->openDatabase();
|
m_db = context->openDatabase();
|
||||||
|
|
||||||
SetTableViewDefault(ui->tableView);
|
|
||||||
|
|
||||||
auto delegate = new PgLabItemDelegate(ui->tableView);
|
|
||||||
ui->tableView->setItemDelegate(delegate);
|
|
||||||
|
|
||||||
m_crudModel = new CrudModel(nullptr);
|
m_crudModel = new CrudModel(nullptr);
|
||||||
|
|
||||||
m_SortFilterProxy = new QSortFilterProxyModel(this);
|
m_grid = new DataGridWidget(this);
|
||||||
m_SortFilterProxy->setSourceModel(m_crudModel);
|
ui->verticalLayout->addWidget(m_grid);
|
||||||
m_SortFilterProxy->setSortRole(CustomSortRole);
|
m_grid->setSourceModel(m_crudModel);
|
||||||
ui->tableView->setModel(m_SortFilterProxy);
|
m_grid->view()->verticalHeader()->setVisible(false);
|
||||||
ui->tableView->setSortingEnabled(true);
|
|
||||||
m_SortFilterProxy->sort(0, Qt::AscendingOrder);
|
|
||||||
|
|
||||||
ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
m_grid->view()->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
m_grid->view()->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
ui->tableView->addAction(ui->actionRemove_rows);
|
m_grid->view()->addAction(ui->actionRemove_rows);
|
||||||
|
|
||||||
auto horizontal_header = ui->tableView->horizontalHeader();
|
auto horizontal_header = m_grid->view()->horizontalHeader();
|
||||||
horizontal_header->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
|
horizontal_header->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
|
||||||
connect(horizontal_header, &QHeaderView::customContextMenuRequested,
|
connect(horizontal_header, &QHeaderView::customContextMenuRequested,
|
||||||
this, &CrudTab::headerCustomContextMenu);
|
this, &CrudTab::headerCustomContextMenu);
|
||||||
|
|
@ -70,7 +66,7 @@ void CrudTab::refresh()
|
||||||
void CrudTab::on_actionRemove_rows_triggered()
|
void CrudTab::on_actionRemove_rows_triggered()
|
||||||
{
|
{
|
||||||
std::set<IntegerRange<int>> row_ranges;
|
std::set<IntegerRange<int>> row_ranges;
|
||||||
auto selection = m_SortFilterProxy->mapSelectionToSource(ui->tableView->selectionModel()->selection());
|
auto selection = m_grid->proxy()->mapSelectionToSource(m_grid->view()->selectionModel()->selection());
|
||||||
for (auto& range : selection) {
|
for (auto& range : selection) {
|
||||||
row_ranges.emplace(range.top(), range.height());
|
row_ranges.emplace(range.top(), range.height());
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +106,7 @@ void CrudTab::headerCustomContextMenu(const QPoint &pos)
|
||||||
|
|
||||||
if (headerContextMenu)
|
if (headerContextMenu)
|
||||||
{
|
{
|
||||||
auto horizontal_header = ui->tableView->horizontalHeader();
|
auto horizontal_header = m_grid->view()->horizontalHeader();
|
||||||
headerContextMenu->popup(horizontal_header->mapToGlobal(pos));
|
headerContextMenu->popup(horizontal_header->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -122,9 +118,9 @@ void CrudTab::gotoColumn(QString column)
|
||||||
auto name = m_crudModel->headerData(i, Qt::Horizontal).toString();
|
auto name = m_crudModel->headerData(i, Qt::Horizontal).toString();
|
||||||
if (name == column)
|
if (name == column)
|
||||||
{
|
{
|
||||||
auto index = ui->tableView->currentIndex();
|
auto index = m_grid->view()->currentIndex();
|
||||||
index = ui->tableView->model()->index(index.row(), i);
|
index = m_grid->view()->model()->index(index.row(), i);
|
||||||
ui->tableView->setCurrentIndex(index);
|
m_grid->view()->setCurrentIndex(index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef CRUDTAB_H
|
#ifndef CRUDTAB_H
|
||||||
#define CRUDTAB_H
|
#define CRUDTAB_H
|
||||||
|
|
||||||
#include <QSortFilterProxyModel>
|
|
||||||
#include "catalog/PgClass.h"
|
#include "catalog/PgClass.h"
|
||||||
#include "IDatabaseWindow.h"
|
#include "IDatabaseWindow.h"
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
@ -14,6 +13,7 @@ namespace Ui {
|
||||||
|
|
||||||
class OpenDatabase;
|
class OpenDatabase;
|
||||||
class CrudModel;
|
class CrudModel;
|
||||||
|
class DataGridWidget;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
|
|
||||||
class CrudTab : public QWidget {
|
class CrudTab : public QWidget {
|
||||||
|
|
@ -33,7 +33,7 @@ private:
|
||||||
std::optional<PgClass> m_table;
|
std::optional<PgClass> m_table;
|
||||||
|
|
||||||
CrudModel *m_crudModel = nullptr;
|
CrudModel *m_crudModel = nullptr;
|
||||||
QSortFilterProxyModel *m_SortFilterProxy = nullptr;
|
DataGridWidget *m_grid = nullptr;
|
||||||
|
|
||||||
QMenu *headerContextMenu = nullptr;
|
QMenu *headerContextMenu = nullptr;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,7 @@
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout"/>
|
||||||
<item>
|
|
||||||
<widget class="QTableView" name="tableView">
|
|
||||||
<attribute name="verticalHeaderVisible">
|
|
||||||
<bool>false</bool>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
<action name="actionRemove_rows">
|
<action name="actionRemove_rows">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Remove rows</string>
|
<string>Remove rows</string>
|
||||||
|
|
|
||||||
34
pglab/crud/DataGridWidget.cpp
Normal file
34
pglab/crud/DataGridWidget.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include "DataGridWidget.h"
|
||||||
|
#include "CustomDataRole.h"
|
||||||
|
#include "ResultTableModelUtil.h"
|
||||||
|
#include "util/PgLabItemDelegate.h"
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
|
||||||
|
DataGridWidget::DataGridWidget(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
auto layout = new QVBoxLayout(this);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
m_view = new QTableView(this);
|
||||||
|
layout->addWidget(m_view);
|
||||||
|
|
||||||
|
SetTableViewDefault(m_view);
|
||||||
|
auto delegate = new PgLabItemDelegate(m_view);
|
||||||
|
m_view->setItemDelegate(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataGridWidget::setSourceModel(QAbstractItemModel *model)
|
||||||
|
{
|
||||||
|
if (!m_proxy) {
|
||||||
|
m_proxy = new QSortFilterProxyModel(this);
|
||||||
|
m_proxy->setSortRole(CustomSortRole);
|
||||||
|
}
|
||||||
|
m_proxy->setSourceModel(model);
|
||||||
|
m_view->setModel(m_proxy);
|
||||||
|
m_view->setSortingEnabled(true);
|
||||||
|
m_proxy->sort(0, Qt::AscendingOrder);
|
||||||
|
}
|
||||||
28
pglab/crud/DataGridWidget.h
Normal file
28
pglab/crud/DataGridWidget.h
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef DATAGRIDWIDGET_H
|
||||||
|
#define DATAGRIDWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QAbstractItemModel;
|
||||||
|
class QSortFilterProxyModel;
|
||||||
|
class QTableView;
|
||||||
|
|
||||||
|
/** Sortable and editable grid shared by the CRUD tab and the query result tab.
|
||||||
|
*/
|
||||||
|
class DataGridWidget : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DataGridWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
/// Sets the model to show, sorting is done by a proxy that uses CustomSortRole
|
||||||
|
void setSourceModel(QAbstractItemModel *model);
|
||||||
|
|
||||||
|
QTableView *view() const { return m_view; }
|
||||||
|
QSortFilterProxyModel *proxy() const { return m_proxy; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTableView *m_view = nullptr;
|
||||||
|
QSortFilterProxyModel *m_proxy = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DATAGRIDWIDGET_H
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
#include "QueryResultModel.h"
|
|
||||||
#include "ResultTableModelUtil.h"
|
|
||||||
#include "Pgsql_declare.h"
|
|
||||||
#include "Pgsql_oids.h"
|
|
||||||
#include "catalog/PgDatabaseCatalog.h"
|
|
||||||
#include "CustomDataRole.h"
|
|
||||||
#include <QBrush>
|
|
||||||
#include <QColor>
|
|
||||||
|
|
||||||
using namespace Pgsql;
|
|
||||||
|
|
||||||
QueryResultModel::QueryResultModel(QObject *parent, std::shared_ptr<Pgsql::Result> r
|
|
||||||
, std::shared_ptr<PgDatabaseCatalog> cat)
|
|
||||||
: QAbstractTableModel(parent)
|
|
||||||
, result(std::move(r))
|
|
||||||
, catalog(cat)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
int QueryResultModel::rowCount(const QModelIndex &) const
|
|
||||||
{
|
|
||||||
int r = result->rows();
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int QueryResultModel::columnCount(const QModelIndex &) const
|
|
||||||
{
|
|
||||||
int r = result->cols();
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant QueryResultModel::data(const QModelIndex &index, int role) const
|
|
||||||
{
|
|
||||||
// static const QString null_str("null");
|
|
||||||
QVariant v;
|
|
||||||
|
|
||||||
const int col = index.column();
|
|
||||||
const int rij = index.row();
|
|
||||||
const Oid oid = result->type(col);
|
|
||||||
if (role == Qt::DisplayRole || role == Qt::EditRole) {
|
|
||||||
if (result->null(col, rij)) {
|
|
||||||
//v = nullptr;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Value value = result->get(col, rij);
|
|
||||||
if (oid == bool_oid) {
|
|
||||||
bool b = value;
|
|
||||||
v = b;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
QString s = value;
|
|
||||||
v = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (role == CustomDataTypeRole) {
|
|
||||||
v = oid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant QueryResultModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
||||||
{
|
|
||||||
QVariant r;
|
|
||||||
if (role == Qt::DisplayRole) {
|
|
||||||
if (orientation == Qt::Horizontal) {
|
|
||||||
QString s(result->getColName(section));
|
|
||||||
s += "\n";
|
|
||||||
s += getTypeDisplayString(*catalog, result->type(section));
|
|
||||||
r = s;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
r = QString::number(section + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Qt::ItemFlags f;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::ItemFlags QueryResultModel::flags(const QModelIndex &) const
|
|
||||||
{
|
|
||||||
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
#ifndef QUERYRESULTMODEL_H
|
|
||||||
#define QUERYRESULTMODEL_H
|
|
||||||
|
|
||||||
#include <QAbstractTableModel>
|
|
||||||
#include "catalog/models/BaseTableModel.h"
|
|
||||||
#include "Pgsql_Connection.h"
|
|
||||||
|
|
||||||
class PgDatabaseCatalog;
|
|
||||||
|
|
||||||
class QueryResultModel : public QAbstractTableModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
QueryResultModel(QObject *parent, std::shared_ptr<Pgsql::Result> r, std::shared_ptr<PgDatabaseCatalog> cat);
|
|
||||||
|
|
||||||
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;
|
|
||||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
|
||||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
|
||||||
|
|
||||||
std::shared_ptr<const Pgsql::Result> GetPgsqlResult() const { return result; }
|
|
||||||
protected:
|
|
||||||
// virtual Oid getType(int column) const override;
|
|
||||||
// virtual QVariant getData(const QModelIndex &index) const override;
|
|
||||||
private:
|
|
||||||
std::shared_ptr<Pgsql::Result> result;
|
|
||||||
std::shared_ptr<PgDatabaseCatalog> catalog;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // QUERYRESULTMODEL_H
|
|
||||||
|
|
@ -476,10 +476,8 @@ void QueryTool::query_ready(std::shared_ptr<Pgsql::Result> dbres, qint64 elapsed
|
||||||
//int n_rows = dbres->getRows();
|
//int n_rows = dbres->getRows();
|
||||||
//QString rowcount_str = QString("rows: %1").arg(dbres->getRows());
|
//QString rowcount_str = QString("rows: %1").arg(dbres->getRows());
|
||||||
|
|
||||||
auto result_model = std::make_shared<QueryResultModel>(nullptr , dbres,
|
|
||||||
m_catalog);
|
|
||||||
TuplesResultWidget *trw = new TuplesResultWidget;
|
TuplesResultWidget *trw = new TuplesResultWidget;
|
||||||
trw->setResult(result_model, elapsedms);
|
trw->setResult(m_context->openDatabase(), dbres, elapsedms);
|
||||||
resultList.push_back(trw);
|
resultList.push_back(trw);
|
||||||
ui->tabWidget->addTab(trw, "Data");
|
ui->tabWidget->addTab(trw, "Data");
|
||||||
if (resultList.size() == 1)
|
if (resultList.size() == 1)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "ManagedPage.h"
|
#include "ManagedPage.h"
|
||||||
#include "ASyncDBConnection.h"
|
#include "ASyncDBConnection.h"
|
||||||
#include "QueryResultModel.h"
|
|
||||||
#include "QueryExplainModel.h"
|
#include "QueryExplainModel.h"
|
||||||
#include "stopwatch.h"
|
#include "stopwatch.h"
|
||||||
#include "tuplesresultwidget.h"
|
#include "tuplesresultwidget.h"
|
||||||
|
|
@ -26,7 +25,6 @@ class QTableView;
|
||||||
class QTabWidget;
|
class QTabWidget;
|
||||||
class SqlSyntaxHighlighter;
|
class SqlSyntaxHighlighter;
|
||||||
class ExplainRoot;
|
class ExplainRoot;
|
||||||
class QueryResultModel;
|
|
||||||
class QueryExplainModel;
|
class QueryExplainModel;
|
||||||
class PgTypeContainer;
|
class PgTypeContainer;
|
||||||
class OpenDatabase;
|
class OpenDatabase;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
#include "tuplesresultwidget.h"
|
#include "tuplesresultwidget.h"
|
||||||
#include "ui_tuplesresultwidget.h"
|
#include "ui_tuplesresultwidget.h"
|
||||||
#include "ResultTableModelUtil.h"
|
#include "ResultTableModelUtil.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "crud/CrudModel.h"
|
||||||
|
#include "crud/DataGridWidget.h"
|
||||||
|
#include "OpenDatabase.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include "util/PgLabItemDelegate.h"
|
#include <QTableView>
|
||||||
|
#include <QHeaderView>
|
||||||
|
|
||||||
|
|
||||||
TuplesResultWidget::TuplesResultWidget(QWidget *parent) :
|
TuplesResultWidget::TuplesResultWidget(QWidget *parent) :
|
||||||
|
|
@ -15,9 +19,13 @@ TuplesResultWidget::TuplesResultWidget(QWidget *parent) :
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->lblRowCount->setText(QString());
|
ui->lblRowCount->setText(QString());
|
||||||
|
|
||||||
SetTableViewDefault(ui->ResultView);
|
m_grid = new DataGridWidget(this);
|
||||||
auto delegate = new PgLabItemDelegate(ui->ResultView);
|
ui->verticalLayout->insertWidget(0, m_grid);
|
||||||
ui->ResultView->setItemDelegate(delegate);
|
m_grid->view()->setFont(QFont("Source Sans Pro", 10));
|
||||||
|
m_grid->view()->setAlternatingRowColors(true);
|
||||||
|
m_grid->view()->setWordWrap(false);
|
||||||
|
m_grid->view()->verticalHeader()->setDefaultSectionSize(21);
|
||||||
|
m_grid->view()->verticalHeader()->setMinimumSectionSize(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
TuplesResultWidget::~TuplesResultWidget()
|
TuplesResultWidget::~TuplesResultWidget()
|
||||||
|
|
@ -25,14 +33,17 @@ TuplesResultWidget::~TuplesResultWidget()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TuplesResultWidget::setResult(std::shared_ptr<QueryResultModel> res, float ms)
|
void TuplesResultWidget::setResult(std::shared_ptr<OpenDatabase> db, std::shared_ptr<Pgsql::Result> res, float ms)
|
||||||
{
|
{
|
||||||
resultModel = res;
|
m_result = res;
|
||||||
ui->ResultView->setModel(resultModel.get());
|
|
||||||
|
|
||||||
ui->ResultView->resizeColumnsToContents();
|
m_model = new CrudModel(m_grid);
|
||||||
|
m_model->setResult(db, res);
|
||||||
|
m_grid->setSourceModel(m_model);
|
||||||
|
|
||||||
QString rowcount_str = QString("rows: %1").arg(resultModel->rowCount());
|
m_grid->view()->resizeColumnsToContents();
|
||||||
|
|
||||||
|
QString rowcount_str = QString("rows: %1").arg(m_model->rowCount());
|
||||||
ui->lblRowCount->setText(rowcount_str);
|
ui->lblRowCount->setText(rowcount_str);
|
||||||
ui->lblElapsedTime->setText(msfloatToHumanReadableString(ms));
|
ui->lblElapsedTime->setText(msfloatToHumanReadableString(ms));
|
||||||
}
|
}
|
||||||
|
|
@ -42,8 +53,6 @@ void TuplesResultWidget::exportData(const QString &file_name) const
|
||||||
QFile file(file_name);
|
QFile file(file_name);
|
||||||
if (file.open(QIODevice::WriteOnly)) {
|
if (file.open(QIODevice::WriteOnly)) {
|
||||||
QTextStream out(&file);
|
QTextStream out(&file);
|
||||||
::exportTable(ui->ResultView, out);
|
::exportTable(m_grid->view(), out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,21 @@
|
||||||
#ifndef TUPLESRESULTWIDGET_H
|
#ifndef TUPLESRESULTWIDGET_H
|
||||||
#define TUPLESRESULTWIDGET_H
|
#define TUPLESRESULTWIDGET_H
|
||||||
|
|
||||||
#include "querytool/QueryResultModel.h"
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class TuplesResultWidget;
|
class TuplesResultWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Pgsql {
|
||||||
|
class Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
class OpenDatabase;
|
||||||
|
class CrudModel;
|
||||||
|
class DataGridWidget;
|
||||||
|
|
||||||
class TuplesResultWidget : public QWidget
|
class TuplesResultWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -16,14 +24,15 @@ public:
|
||||||
explicit TuplesResultWidget(QWidget *parent = 0);
|
explicit TuplesResultWidget(QWidget *parent = 0);
|
||||||
~TuplesResultWidget();
|
~TuplesResultWidget();
|
||||||
|
|
||||||
void setResult(std::shared_ptr<QueryResultModel> res, float ms);
|
void setResult(std::shared_ptr<OpenDatabase> db, std::shared_ptr<Pgsql::Result> res, float ms);
|
||||||
void exportData(const QString &file_name) const;
|
void exportData(const QString &file_name) const;
|
||||||
|
|
||||||
std::shared_ptr<const Pgsql::Result> GetPgsqlResult() const { return resultModel->GetPgsqlResult(); }
|
std::shared_ptr<const Pgsql::Result> GetPgsqlResult() const { return m_result; }
|
||||||
private:
|
private:
|
||||||
Ui::TuplesResultWidget *ui;
|
Ui::TuplesResultWidget *ui;
|
||||||
|
DataGridWidget *m_grid = nullptr;
|
||||||
std::shared_ptr<QueryResultModel> resultModel;
|
CrudModel *m_model = nullptr;
|
||||||
|
std::shared_ptr<Pgsql::Result> m_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TUPLESRESULTWIDGET_H
|
#endif // TUPLESRESULTWIDGET_H
|
||||||
|
|
|
||||||
|
|
@ -29,37 +29,6 @@
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>2</number>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
|
||||||
<widget class="QTableView" name="ResultView">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>Source Sans Pro</family>
|
|
||||||
<pointsize>10</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="editTriggers">
|
|
||||||
<set>QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
|
|
||||||
</property>
|
|
||||||
<property name="alternatingRowColors">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="verticalScrollMode">
|
|
||||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollMode">
|
|
||||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="verticalHeaderDefaultSectionSize">
|
|
||||||
<number>21</number>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="verticalHeaderMinimumSectionSize">
|
|
||||||
<number>16</number>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="widget" native="true">
|
<widget class="QWidget" name="widget" native="true">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Query results are now shown in the same grid as the table data tab. Columns
|
||||||
|
can be sorted by clicking their headers, and cells that belong to a table
|
||||||
|
with a primary key present in the result can be edited directly. Changes
|
||||||
|
are saved with an ``UPDATE`` by primary key.
|
||||||
|
other:
|
||||||
|
- |
|
||||||
|
Read-only cells in query results, such as expression columns or columns of
|
||||||
|
tables without a primary key in the result, are now shown in grey so they
|
||||||
|
can be told apart from editable cells.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue