Flexible models
This commit is contained in:
parent
50cb21b6f9
commit
8b7bbec807
24 changed files with 333 additions and 51 deletions
10
pglab/CustomDataRole.h
Normal file
10
pglab/CustomDataRole.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef CUSTOMDATAROLE_H
|
||||
#define CUSTOMDATAROLE_H
|
||||
|
||||
#include <Qt>
|
||||
|
||||
enum CustomDataRole {
|
||||
CustomDataTypeRole = Qt::UserRole,
|
||||
};
|
||||
|
||||
#endif // CUSTOMDATAROLE_H
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include "PgIndexContainer.h"
|
||||
#include "Pgsql_oids.h"
|
||||
#include "ScopeGuard.h"
|
||||
#include "CustomDataRole.h"
|
||||
|
||||
void IndexModel::setData(std::shared_ptr<const PgDatabaseCatalog> cat, const PgClass &table)
|
||||
{
|
||||
|
|
@ -96,7 +97,7 @@ QVariant IndexModel::data(const QModelIndex &index, int role) const
|
|||
QVariant v;
|
||||
if (role == Qt::DisplayRole)
|
||||
v = getData(index);
|
||||
else if (role == Qt::UserRole)
|
||||
else if (role == CustomDataTypeRole)
|
||||
v = getType(index.column());
|
||||
return v;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ void PgLabItemDelegate::initStyleOption(QStyleOptionViewItem *option,
|
|||
Oid oid = InvalidOid;
|
||||
value = index.data(Qt::UserRole); // get OID
|
||||
if (value.isValid())
|
||||
oid = value.toInt(); //getType(index.column());
|
||||
oid = value.toUInt(); //getType(index.column());
|
||||
|
||||
value = index.data(Qt::DisplayRole);
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ void PgLabItemDelegate::initStyleOption(QStyleOptionViewItem *option,
|
|||
// option->backgroundBrush = qvariant_cast<QBrush>(index.data(Qt::BackgroundRole));
|
||||
|
||||
// disable style animations for checkboxes etc. within itemviews (QTBUG-30146)
|
||||
option->styleObject = 0;
|
||||
option->styleObject = nullptr;
|
||||
}
|
||||
|
||||
void PgLabItemDelegate::paint(QPainter *painter,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@
|
|||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
/** Delegate for rendering SQL data types in tableviews
|
||||
*
|
||||
* This delegate removes the need for the model to provide formatting information
|
||||
* which in many cases solely based on the datatype so this delegate can determine
|
||||
* on its own what the correct formatting is.
|
||||
*/
|
||||
class PgLabItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
104
pglab/PropertyProxyModel.cpp
Normal file
104
pglab/PropertyProxyModel.cpp
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#include "PropertyProxyModel.h"
|
||||
/*
|
||||
* Code borrowed from: https://stackoverflow.com/questions/21653253/how-to-change-orientation-of-qt-tableview
|
||||
*
|
||||
* Originally it was called Horizontal_proxy_model however some adjustments were made to it.
|
||||
* Instead of the column headers becoming row headers we now convert them to the first column.
|
||||
* The second column show the values of a single row from the source model. Which is determined
|
||||
* by the setActiveRow call.
|
||||
*/
|
||||
|
||||
|
||||
PropertyProxyModel::PropertyProxyModel(QObject *parent)
|
||||
: QIdentityProxyModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QModelIndex PropertyProxyModel::mapToSource(const QModelIndex &proxyIndex) const
|
||||
{
|
||||
if (sourceModel()) {
|
||||
if (activeRow >= 0) {
|
||||
if (proxyIndex.column() == valueColumn) {
|
||||
return sourceModel()->index(activeRow, proxyIndex.row());
|
||||
}
|
||||
}
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex PropertyProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
|
||||
{
|
||||
if (activeRow >= 0) {
|
||||
if (sourceIndex.row() == activeRow) {
|
||||
return index(sourceIndex.column(), valueColumn);
|
||||
}
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex PropertyProxyModel::index(int row, int column, const QModelIndex &) const
|
||||
{
|
||||
return createIndex(row, column, nullptr);
|
||||
}
|
||||
|
||||
QModelIndex PropertyProxyModel::parent(const QModelIndex &) const
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int PropertyProxyModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
return sourceModel() ? sourceModel()->columnCount() : 0;
|
||||
}
|
||||
|
||||
int PropertyProxyModel::columnCount(const QModelIndex &) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
QVariant PropertyProxyModel::headerData(
|
||||
int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
// if (!sourceModel()) {
|
||||
// return QVariant();
|
||||
// }
|
||||
// Qt::Orientation new_orientation = orientation == Qt::Horizontal ?
|
||||
// Qt::Vertical : Qt::Horizontal;
|
||||
// return sourceModel()->headerData(section, new_orientation, role);
|
||||
if (orientation == Qt::Horizontal) {
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch (section) {
|
||||
case 0:
|
||||
return tr("Property");
|
||||
case 1:
|
||||
return tr("Value");
|
||||
}
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant PropertyProxyModel::data(const QModelIndex &proxyIndex, int role) const
|
||||
{
|
||||
auto sm = sourceModel();
|
||||
if (sm) {
|
||||
switch (proxyIndex.column()) {
|
||||
case 0:
|
||||
// return source header data
|
||||
return sm->headerData(proxyIndex.row(), Qt::Horizontal, role);
|
||||
case 1:
|
||||
// return value if activeRow is set
|
||||
if (activeRow >= 0) {
|
||||
return QIdentityProxyModel::data(proxyIndex, role);
|
||||
}
|
||||
}
|
||||
}
|
||||
//return d->model->data(mapToSource(proxyIndex), role);
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void PropertyProxyModel::setActiveRow(const QModelIndex &row)
|
||||
{
|
||||
activeRow = row.isValid() ? row.row() : -1;
|
||||
emit dataChanged(index(0, valueColumn), index(rowCount(QModelIndex()), valueColumn), QVector<int>() << Qt::DisplayRole);
|
||||
}
|
||||
35
pglab/PropertyProxyModel.h
Normal file
35
pglab/PropertyProxyModel.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef HORIZONTALPROXYMODEL_H
|
||||
#define HORIZONTALPROXYMODEL_H
|
||||
|
||||
#include <QIdentityProxyModel>
|
||||
|
||||
class PropertyProxyModel : public QIdentityProxyModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PropertyProxyModel(QObject * parent = nullptr);
|
||||
QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
|
||||
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex &child) const;
|
||||
int rowCount(const QModelIndex &parent) const;
|
||||
int columnCount(const QModelIndex &parent) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
QVariant data(const QModelIndex &proxyIndex, int role) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
/** Updates the model (and view) to show the values for row
|
||||
*
|
||||
* The column part of the index is not used QModelIndex is used to make is eacy to connect to
|
||||
* QItemSelectionModel::currentRowChanged
|
||||
*/
|
||||
void setActiveRow(const QModelIndex &row);
|
||||
|
||||
private:
|
||||
enum Columns {
|
||||
propertyColumn = 0,
|
||||
valueColumn
|
||||
};
|
||||
int activeRow = -1;
|
||||
};
|
||||
|
||||
#endif // HORIZONTALPROXYMODEL_H
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
#include "ResultTableModelUtil.h"
|
||||
#include "ColumnTableModel.h"
|
||||
#include "ConstraintModel.h"
|
||||
//#include "NamespaceFilterWidget.h"
|
||||
#include "PropertyProxyModel.h"
|
||||
#include "IconColumnDelegate.h"
|
||||
#include "IndexModel.h"
|
||||
#include "SqlFormattingUtils.h"
|
||||
|
|
@ -24,9 +24,13 @@ TablesPage::TablesPage(MainWindow *parent)
|
|||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
auto pglab_delegate = new PgLabItemDelegate(this);
|
||||
auto icon_delegate = new IconColumnDelegate(this);
|
||||
|
||||
SetTableViewDefault(ui->tableListTable);
|
||||
m_tablesModel = new TablesTableModel(this);
|
||||
ui->tableListTable->setModel(m_tablesModel);
|
||||
ui->tableListTable->setItemDelegate(pglab_delegate);
|
||||
ui->tableListTable->setSortingEnabled(true);
|
||||
ui->tableListTable->sortByColumn(0, Qt::AscendingOrder);
|
||||
|
||||
|
|
@ -36,9 +40,8 @@ TablesPage::TablesPage(MainWindow *parent)
|
|||
|
||||
SetTableViewDefault(ui->constraintsTable);
|
||||
m_constraintModel = new ConstraintModel(this);
|
||||
auto delegate = new IconColumnDelegate(this);
|
||||
ui->constraintsTable->setModel(m_constraintModel);
|
||||
ui->constraintsTable->setItemDelegateForColumn(0, delegate);
|
||||
ui->constraintsTable->setItemDelegateForColumn(0, icon_delegate);
|
||||
|
||||
QFont font;
|
||||
font.setFamily("Source Code Pro");
|
||||
|
|
@ -50,8 +53,18 @@ TablesPage::TablesPage(MainWindow *parent)
|
|||
SetTableViewDefault(ui->indexesTable);
|
||||
m_indexModel = new IndexModel(this);
|
||||
ui->indexesTable->setModel(m_indexModel);
|
||||
ui->indexesTable->setItemDelegate(new PgLabItemDelegate(ui->indexesTable));
|
||||
ui->indexesTable->setItemDelegateForColumn(0, delegate);
|
||||
ui->indexesTable->setItemDelegate(pglab_delegate);
|
||||
ui->indexesTable->setItemDelegateForColumn(0, icon_delegate);
|
||||
|
||||
PropertyProxyModel* property_model = new PropertyProxyModel(this);
|
||||
property_model->setSourceModel(m_tablesModel);
|
||||
SetTableViewDefault(ui->tablePropertiesTable);
|
||||
ui->tablePropertiesTable->setModel(property_model);
|
||||
ui->tablePropertiesTable->setItemDelegate(pglab_delegate);
|
||||
|
||||
connect(ui->tableListTable->selectionModel(), &QItemSelectionModel::currentRowChanged,
|
||||
property_model, &PropertyProxyModel::setActiveRow);
|
||||
|
||||
|
||||
//m_namespaceFilterWidget = new NamespaceFilterWidget(this);
|
||||
//ui->verticalLayoutTableView->addWidget(m_namespaceFilterWidget);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TablesPage</class>
|
||||
<widget class="QWidget" name="TablesPage">
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
</widget>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="columnsTab">
|
||||
<attribute name="title">
|
||||
|
|
@ -90,6 +90,11 @@
|
|||
<attribute name="title">
|
||||
<string>Properties</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutProperties">
|
||||
<item>
|
||||
<widget class="QTableView" name="tablePropertiesTable"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="statisticsTab">
|
||||
<attribute name="title">
|
||||
|
|
|
|||
|
|
@ -5,13 +5,12 @@
|
|||
#include "PgNamespace.h"
|
||||
#include "PgNamespaceContainer.h"
|
||||
#include "Pgsql_declare.h"
|
||||
#include "CustomDataRole.h"
|
||||
#include <QBrush>
|
||||
|
||||
TablesTableModel::TablesTableModel(QObject *parent)
|
||||
: BaseTableModel(parent)
|
||||
{
|
||||
|
||||
}
|
||||
: QAbstractTableModel(parent)
|
||||
{}
|
||||
|
||||
void TablesTableModel::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
|
||||
{
|
||||
|
|
@ -166,11 +165,11 @@ QVariant TablesTableModel::getData(const QModelIndex &index) const
|
|||
v = getTablespaceDisplayString(*m_catalog, t.tablespace);
|
||||
break;
|
||||
case OptionsCol:
|
||||
v = t.options;
|
||||
//v = t.options;
|
||||
break;
|
||||
// case AclCol:
|
||||
// v = t.acl;
|
||||
// break;
|
||||
// case AclCol:
|
||||
// v = t.acl;
|
||||
// break;
|
||||
}
|
||||
|
||||
return v;
|
||||
|
|
@ -195,19 +194,9 @@ QString TablesTableModel::formatTableName(const PgClass &cls) const
|
|||
|
||||
QVariant TablesTableModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
|
||||
if (role == Qt::ForegroundRole) {
|
||||
|
||||
const auto &t = m_tables[index.row()];
|
||||
auto ns = m_catalog->namespaces()->getByKey(t.relnamespace);
|
||||
if (ns.isSystemCatalog()) {
|
||||
switch (index.column()) {
|
||||
case NameCol:
|
||||
case NamespaceCol:
|
||||
return QBrush(Qt::blue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return BaseTableModel::data(index, role);
|
||||
if (role == Qt::DisplayRole)
|
||||
return getData(index);
|
||||
else if (role == CustomDataTypeRole)
|
||||
return getType(index.column());
|
||||
return QVariant();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@
|
|||
class PgClass;
|
||||
class PgDatabaseCatalog;
|
||||
|
||||
class TablesTableModel: public BaseTableModel
|
||||
{
|
||||
class TablesTableModel: public QAbstractTableModel {
|
||||
public:
|
||||
enum e_Columns : int {
|
||||
NameCol, ///< either table, ns.table or table (ns) depending on settings/filters
|
||||
|
|
@ -38,9 +37,6 @@ public:
|
|||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
PgClass getTable(int row) const;
|
||||
Oid getTableOid(int row) const;
|
||||
protected:
|
||||
virtual Oid getType(int column) const override;
|
||||
virtual QVariant getData(const QModelIndex &index) const override;
|
||||
|
||||
private:
|
||||
using t_Tables = std::vector<PgClass>;
|
||||
|
|
@ -48,6 +44,8 @@ private:
|
|||
std::shared_ptr<const PgDatabaseCatalog> m_catalog;
|
||||
t_Tables m_tables;
|
||||
|
||||
Oid getType(int column) const;
|
||||
QVariant getData(const QModelIndex &index) const;
|
||||
QString formatTableName(const PgClass &cls) const;
|
||||
void doSort(int so);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ SOURCES += main.cpp\
|
|||
Module.cpp \
|
||||
EditorGutter.cpp \
|
||||
CodeEditor.cpp \
|
||||
PlgPage.cpp
|
||||
PlgPage.cpp \
|
||||
PropertyProxyModel.cpp
|
||||
|
||||
HEADERS += \
|
||||
QueryResultModel.h \
|
||||
|
|
@ -119,7 +120,9 @@ HEADERS += \
|
|||
EditorGutter.h \
|
||||
CodeEditor.h \
|
||||
PlgPage.h \
|
||||
AbstractCommand.h
|
||||
AbstractCommand.h \
|
||||
PropertyProxyModel.h \
|
||||
CustomDataRole.h
|
||||
|
||||
FORMS += mainwindow.ui \
|
||||
ConnectionManagerWindow.ui \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue