Introduced the MasterController as part of working on loading catalogue information.
Need a central piece to manage the catalogue data per database to prevent loading this multiple times. MasterController is now also used to enable reopening the connection manager from a query window after the connection manager has been closed.
This commit is contained in:
parent
b6d986051b
commit
6370050204
36 changed files with 769 additions and 71 deletions
27
MasterController.cpp
Normal file
27
MasterController.cpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#include "MasterController.h"
|
||||
#include "connectionmanagerwindow.h"
|
||||
#include "connectionlistmodel.h"
|
||||
|
||||
|
||||
MasterController::MasterController(QObject *parent) : QObject(parent)
|
||||
{}
|
||||
|
||||
MasterController::~MasterController()
|
||||
{
|
||||
delete m_connectionManagerWindow;
|
||||
delete m_connectionListModel;
|
||||
}
|
||||
|
||||
void MasterController::init()
|
||||
{
|
||||
m_connectionListModel = new ConnectionListModel(this);
|
||||
|
||||
m_connectionManagerWindow = new ConnectionManagerWindow(this, nullptr);
|
||||
m_connectionManagerWindow->show();
|
||||
|
||||
}
|
||||
|
||||
void MasterController::showConnectionManager()
|
||||
{
|
||||
m_connectionManagerWindow->show();
|
||||
}
|
||||
36
MasterController.h
Normal file
36
MasterController.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef MASTERCONTROLLER_H
|
||||
#define MASTERCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <map>
|
||||
|
||||
class ConnectionConfig;
|
||||
class ConnectionListModel;
|
||||
class ConnectionManagerWindow;
|
||||
|
||||
class MasterController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MasterController(QObject *parent = 0);
|
||||
~MasterController();
|
||||
|
||||
void init();
|
||||
|
||||
ConnectionListModel *getConnectionListModel()
|
||||
{
|
||||
return m_connectionListModel;
|
||||
}
|
||||
|
||||
void showConnectionManager();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
ConnectionListModel *m_connectionListModel = nullptr;
|
||||
ConnectionManagerWindow *m_connectionManagerWindow = nullptr;
|
||||
};
|
||||
|
||||
#endif // MASTERCONTROLLER_H
|
||||
14
backupdialog.cpp
Normal file
14
backupdialog.cpp
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#include "backupdialog.h"
|
||||
#include "ui_backupdialog.h"
|
||||
|
||||
BackupDialog::BackupDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::BackupDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
BackupDialog::~BackupDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
22
backupdialog.h
Normal file
22
backupdialog.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef BACKUPDIALOG_H
|
||||
#define BACKUPDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class BackupDialog;
|
||||
}
|
||||
|
||||
class BackupDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BackupDialog(QWidget *parent = 0);
|
||||
~BackupDialog();
|
||||
|
||||
private:
|
||||
Ui::BackupDialog *ui;
|
||||
};
|
||||
|
||||
#endif // BACKUPDIALOG_H
|
||||
54
backupdialog.ui
Normal file
54
backupdialog.ui
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BackupDialog</class>
|
||||
<widget class="QDialog" name="BackupDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>645</width>
|
||||
<height>295</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Format</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="comboBox"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Filename</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -200,3 +200,13 @@ const char * const * ConnectionConfig::getValues() const
|
|||
|
||||
return m_values.data();
|
||||
}
|
||||
|
||||
bool ConnectionConfig::isSameDatabase(const ConnectionConfig &rhs) const
|
||||
{
|
||||
return m_host == rhs.m_host
|
||||
&& m_hostaddr == rhs.m_hostaddr
|
||||
&& m_port == rhs.m_port
|
||||
&& m_user == rhs.m_user
|
||||
&& m_password == rhs.m_password
|
||||
&& m_dbname == rhs.m_dbname;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ public:
|
|||
const char * const * getKeywords() const;
|
||||
const char * const * getValues() const;
|
||||
|
||||
bool isSameDatabase(const ConnectionConfig &rhs) const;
|
||||
private:
|
||||
std::string m_name;
|
||||
std::string m_host;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,22 @@
|
|||
#include "connectionmanagerwindow.h"
|
||||
#include "ui_connectionmanagerwindow.h"
|
||||
#include "mainwindow.h"
|
||||
#include "MasterController.h"
|
||||
#include <QDataWidgetMapper>
|
||||
#include <QMessageBox>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
#include "connectionlistmodel.h"
|
||||
|
||||
ConnectionManagerWindow::ConnectionManagerWindow(QWidget *parent)
|
||||
ConnectionManagerWindow::ConnectionManagerWindow(MasterController *master, QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::ConnectionManagerWindow)
|
||||
, m_listModel(new ConnectionListModel(this))
|
||||
// , m_listModel(new ConnectionListModel(this))
|
||||
, m_masterController(master)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->listView->setModel(m_listModel);
|
||||
ui->listView->setModel(m_masterController->getConnectionListModel());
|
||||
|
||||
setupWidgetMappings();
|
||||
|
||||
|
|
@ -26,10 +28,10 @@ ConnectionManagerWindow::ConnectionManagerWindow(QWidget *parent)
|
|||
|
||||
ConnectionManagerWindow::~ConnectionManagerWindow()
|
||||
{
|
||||
m_listModel->save();
|
||||
// m_listModel->save();
|
||||
|
||||
delete ui;
|
||||
delete m_listModel;
|
||||
// delete m_listModel;
|
||||
delete m_mapper;
|
||||
}
|
||||
|
||||
|
|
@ -37,10 +39,13 @@ void ConnectionManagerWindow::on_actionAdd_Connection_triggered()
|
|||
{
|
||||
ConnectionConfig c;
|
||||
c.setName("new");
|
||||
m_listModel->add(c);
|
||||
//m_listModel->add(c);
|
||||
|
||||
auto clm = m_masterController->getConnectionListModel();
|
||||
clm->add(c);
|
||||
|
||||
// Select the new row
|
||||
auto idx = m_listModel->index(m_listModel->rowCount() - 1, 0);
|
||||
auto idx = clm->index(clm->rowCount() - 1, 0);
|
||||
ui->listView->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::Select);
|
||||
}
|
||||
|
||||
|
|
@ -48,7 +53,8 @@ void ConnectionManagerWindow::on_currentChanged(const QModelIndex ¤t,
|
|||
const QModelIndex &previous)
|
||||
{
|
||||
int currow = current.row();
|
||||
m_listModel->save(prevSelection);
|
||||
auto clm = m_masterController->getConnectionListModel();
|
||||
clm->save(prevSelection);
|
||||
m_mapper->setCurrentIndex(currow);
|
||||
prevSelection = currow;
|
||||
}
|
||||
|
|
@ -57,15 +63,17 @@ void ConnectionManagerWindow::on_actionDelete_connection_triggered()
|
|||
{
|
||||
auto ci = ui->listView->selectionModel()->currentIndex();
|
||||
if (ci.isValid()) {
|
||||
m_listModel->removeRow(ci.row());
|
||||
auto clm = m_masterController->getConnectionListModel();
|
||||
clm->removeRow(ci.row());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConnectionManagerWindow::setupWidgetMappings()
|
||||
{
|
||||
auto clm = m_masterController->getConnectionListModel();
|
||||
m_mapper = new QDataWidgetMapper(this);
|
||||
m_mapper->setModel(m_listModel);
|
||||
m_mapper->setModel(clm);
|
||||
m_mapper->addMapping(ui->edtName, 1);
|
||||
m_mapper->addMapping(ui->edtHost, 2);
|
||||
m_mapper->addMapping(ui->spinPort, 3);
|
||||
|
|
@ -77,12 +85,19 @@ void ConnectionManagerWindow::setupWidgetMappings()
|
|||
|
||||
void ConnectionManagerWindow::on_actionConnect_triggered()
|
||||
{
|
||||
// Open a window for this connection, maybe we should first check the connection?
|
||||
// maybe we should first check the connection?
|
||||
|
||||
// Have we loaded the catalogue?
|
||||
// If not do so now
|
||||
|
||||
|
||||
auto clm = m_masterController->getConnectionListModel();
|
||||
// Open a window for this connection,
|
||||
auto ci = ui->listView->selectionModel()->currentIndex();
|
||||
auto cc = m_listModel->get(ci.row());
|
||||
m_listModel->save(ci.row());
|
||||
auto cc = clm->get(ci.row());
|
||||
clm->save(ci.row());
|
||||
if (cc.valid()) {
|
||||
auto w = new MainWindow;
|
||||
auto w = new MainWindow(m_masterController, nullptr);
|
||||
w->setAttribute( Qt::WA_DeleteOnClose );
|
||||
w->setConfig(cc.get());
|
||||
w->show();
|
||||
|
|
@ -99,3 +114,8 @@ void ConnectionManagerWindow::on_actionQuit_application_triggered()
|
|||
|
||||
//closeAllWindows();
|
||||
}
|
||||
|
||||
void ConnectionManagerWindow::on_actionBackup_database_triggered()
|
||||
{
|
||||
// BACKUP
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ namespace Ui {
|
|||
class ConnectionManagerWindow;
|
||||
}
|
||||
|
||||
class ConnectionListModel;
|
||||
class ConnectionConfig;
|
||||
class MasterController;
|
||||
class QDataWidgetMapper;
|
||||
class QStandardItemModel;
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ class ConnectionManagerWindow : public QMainWindow
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConnectionManagerWindow(QWidget *parent = 0);
|
||||
explicit ConnectionManagerWindow(MasterController *master, QWidget *parent = 0);
|
||||
~ConnectionManagerWindow();
|
||||
|
||||
private slots:
|
||||
|
|
@ -29,10 +29,12 @@ private slots:
|
|||
|
||||
void on_actionQuit_application_triggered();
|
||||
|
||||
void on_actionBackup_database_triggered();
|
||||
|
||||
private:
|
||||
Ui::ConnectionManagerWindow *ui;
|
||||
ConnectionListModel *m_listModel = nullptr;
|
||||
QDataWidgetMapper *m_mapper = nullptr;
|
||||
MasterController *m_masterController;
|
||||
|
||||
int prevSelection = -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>25</height>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
|
|
@ -225,6 +225,8 @@
|
|||
<addaction name="actionConnect"/>
|
||||
<addaction name="actionAdd_Connection"/>
|
||||
<addaction name="actionDelete_connection"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionBackup_database"/>
|
||||
</widget>
|
||||
<action name="actionAdd_Connection">
|
||||
<property name="icon">
|
||||
|
|
@ -262,6 +264,16 @@
|
|||
<string>Quit application</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionBackup_database">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normalon>:/icons/backups.png</normalon>
|
||||
</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Backup database</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources.qrc"/>
|
||||
|
|
|
|||
BIN
icons/16x16/document_green.png
Normal file
BIN
icons/16x16/document_green.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
icons/16x16/document_red.png
Normal file
BIN
icons/16x16/document_red.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
icons/16x16/document_yellow.png
Normal file
BIN
icons/16x16/document_yellow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
icons/backups.png
Normal file
BIN
icons/backups.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
10
main.cpp
10
main.cpp
|
|
@ -1,8 +1,7 @@
|
|||
//#include "mainwindow.h"
|
||||
//#include "databasewindow.h"
|
||||
#include "connectionmanagerwindow.h"
|
||||
#include "MasterController.h"
|
||||
#include <QApplication>
|
||||
#include <winsock2.h>
|
||||
#include <memory>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
|
@ -24,8 +23,9 @@ int main(int argc, char *argv[])
|
|||
QCoreApplication::setOrganizationDomain("eelkeklein.nl");
|
||||
QCoreApplication::setApplicationName("pglab");
|
||||
|
||||
ConnectionManagerWindow w;
|
||||
w.show();
|
||||
auto master_controller = std::make_unique<MasterController>();
|
||||
master_controller->init();
|
||||
|
||||
|
||||
int result = a.exec();
|
||||
|
||||
|
|
|
|||
|
|
@ -14,14 +14,15 @@
|
|||
#include <QCloseEvent>
|
||||
#include <querytab.h>
|
||||
#include "util.h"
|
||||
|
||||
#include "MasterController.h"
|
||||
|
||||
namespace pg = Pgsql;
|
||||
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
MainWindow::MainWindow(MasterController *master, QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::MainWindow)
|
||||
, m_masterController(master)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
|
@ -132,7 +133,19 @@ void MainWindow::on_actionClose_triggered()
|
|||
|
||||
void MainWindow::on_actionAbout_triggered()
|
||||
{
|
||||
//
|
||||
QMessageBox::about(this, "pgLab 0.1", tr(
|
||||
"Copyrights 2016-2017, Eelke Klein, All Rights Reserved.\n"
|
||||
"\n"
|
||||
"The program is provided AS IS with NO WARRANTY OF ANY KIND,"
|
||||
" 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"
|
||||
"\n"
|
||||
"Icons by fatcow http://www.fatcow.com/free-icons provided under Creative Commons "
|
||||
"attribution 3.0 license\n"
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
#if false
|
||||
|
|
@ -231,5 +244,11 @@ void MainWindow::on_tabWidget_tabCloseRequested(int index)
|
|||
if (qt->canClose()) {
|
||||
ui->tabWidget->removeTab(index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionShow_connection_manager_triggered()
|
||||
{
|
||||
m_masterController->showConnectionManager();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,14 +27,14 @@ namespace Pgsql {
|
|||
}
|
||||
|
||||
class QueryTab;
|
||||
|
||||
class MasterController;
|
||||
class QCloseEvent;
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
explicit MainWindow(MasterController *master, QWidget *parent);
|
||||
~MainWindow();
|
||||
|
||||
void setConfig(const ConnectionConfig &config);
|
||||
|
|
@ -51,6 +51,8 @@ private:
|
|||
TSQueue m_taskQueue;
|
||||
ConnectionConfig m_config;
|
||||
|
||||
MasterController *m_masterController;
|
||||
|
||||
|
||||
QueryTab *GetActiveQueryTab();
|
||||
|
||||
|
|
@ -75,6 +77,7 @@ private slots:
|
|||
void on_actionNew_SQL_triggered();
|
||||
void on_tabWidget_tabCloseRequested(int index);
|
||||
void on_actionExplain_triggered();
|
||||
void on_actionShow_connection_manager_triggered();
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
|
|||
|
|
@ -77,8 +77,15 @@
|
|||
<addaction name="separator"/>
|
||||
<addaction name="actionCancel"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
<string>Window</string>
|
||||
</property>
|
||||
<addaction name="actionShow_connection_manager"/>
|
||||
</widget>
|
||||
<addaction name="menuTest"/>
|
||||
<addaction name="menuQuery"/>
|
||||
<addaction name="menuView"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="mainToolBar">
|
||||
|
|
@ -238,6 +245,11 @@
|
|||
<string>F7</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShow_connection_manager">
|
||||
<property name="text">
|
||||
<string>Show connection manager</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
|
|
|
|||
30
opendatabase.cpp
Normal file
30
opendatabase.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include "opendatabase.h"
|
||||
#include "pgsqldatabasecatalogue.h"
|
||||
|
||||
Expected<OpenDatabase*> OpenDatabase::createOpenDatabase(const ConnectionConfig &cfg)
|
||||
{
|
||||
OpenDatabase *odb = new OpenDatabase(cfg, nullptr);
|
||||
if (odb->Init()) {
|
||||
|
||||
return odb;
|
||||
}
|
||||
//return Expected<ConnectionConfig>::fromException(std::out_of_range("Invalid row"));
|
||||
}
|
||||
|
||||
OpenDatabase::OpenDatabase(const ConnectionConfig& cfg, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_config(cfg)
|
||||
, m_catalogue(new PgsqlDatabaseCatalogue)
|
||||
{
|
||||
}
|
||||
|
||||
OpenDatabase::~OpenDatabase()
|
||||
{
|
||||
delete m_catalogue;
|
||||
}
|
||||
|
||||
bool OpenDatabase::Init()
|
||||
{
|
||||
// m_catalogue->load(m_config);
|
||||
return true;
|
||||
}
|
||||
32
opendatabase.h
Normal file
32
opendatabase.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef OPENDATABASE_H
|
||||
#define OPENDATABASE_H
|
||||
|
||||
#include <QObject>
|
||||
#include "connectionconfig.h"
|
||||
#include "expected.h"
|
||||
|
||||
class PgsqlDatabaseCatalogue;
|
||||
|
||||
class OpenDatabase : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static Expected<OpenDatabase*> createOpenDatabase(const ConnectionConfig &cfg);
|
||||
|
||||
OpenDatabase(const OpenDatabase &) = delete;
|
||||
OpenDatabase& operator=(const OpenDatabase &) = delete;
|
||||
~OpenDatabase();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
ConnectionConfig m_config;
|
||||
PgsqlDatabaseCatalogue *m_catalogue;
|
||||
|
||||
OpenDatabase(const ConnectionConfig& cfg, QObject *parent = 0);
|
||||
bool Init();
|
||||
};
|
||||
|
||||
#endif // OPENDATABASE_H
|
||||
127
paramlistmodel.cpp
Normal file
127
paramlistmodel.cpp
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
#include "paramlistmodel.h"
|
||||
|
||||
ParamListModel::ParamListModel(QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant ParamListModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
// FIXME: Implement me!
|
||||
QVariant result;
|
||||
if (orientation == Qt::Horizontal) {
|
||||
if (role == Qt::DisplayRole) {
|
||||
if (section == 0) {
|
||||
// result = tr("$n");
|
||||
result = tr("Value");
|
||||
}
|
||||
else if (section == 1) {
|
||||
result = tr("Type");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (orientation == Qt::Vertical) {
|
||||
if (role == Qt::DisplayRole) {
|
||||
result = tr("$%1").arg(section + 1);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//bool ParamListModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
|
||||
//{
|
||||
// if (value != headerData(section, orientation, role)) {
|
||||
// // FIXME: Implement me!
|
||||
// emit headerDataChanged(orientation, section, section);
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
|
||||
|
||||
int ParamListModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
//if (parent.isValid())
|
||||
return 2;
|
||||
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
|
||||
int ParamListModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
//if (parent.isValid())
|
||||
return 2;
|
||||
|
||||
// FIXME: Implement me!
|
||||
}
|
||||
|
||||
QVariant ParamListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
QVariant result;
|
||||
if (index.isValid()) {
|
||||
int row = index.row();
|
||||
int col = index.column();
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch (col) {
|
||||
case 0: // value column
|
||||
result = tr("val, %1").arg(row);
|
||||
break;
|
||||
case 1: // type column
|
||||
result = 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!
|
||||
|
||||
emit dataChanged(index, index, QVector<int>() << role);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Qt::ItemFlags ParamListModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsEditable; // FIXME: Implement me!
|
||||
}
|
||||
|
||||
//bool ParamListModel::insertRows(int row, int count, const QModelIndex &parent)
|
||||
//{
|
||||
// beginInsertRows(parent, row, row + count - 1);
|
||||
// // FIXME: Implement me!
|
||||
// endInsertRows();
|
||||
// return false;
|
||||
//}
|
||||
|
||||
//bool ParamListModel::insertColumns(int column, int count, const QModelIndex &parent)
|
||||
//{
|
||||
// beginInsertColumns(parent, column, column + count - 1);
|
||||
// // FIXME: Implement me!
|
||||
// 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::removeColumns(int column, int count, const QModelIndex &parent)
|
||||
//{
|
||||
// beginRemoveColumns(parent, column, column + count - 1);
|
||||
// // FIXME: Implement me!
|
||||
// endRemoveColumns();
|
||||
//}
|
||||
41
paramlistmodel.h
Normal file
41
paramlistmodel.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef PARAMLISTMODEL_H
|
||||
#define PARAMLISTMODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
class ParamListModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ParamListModel(QObject *parent = 0);
|
||||
|
||||
// Header:
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
// bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
// Basic functionality:
|
||||
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;
|
||||
|
||||
// Editable:
|
||||
bool setData(const QModelIndex &index, const QVariant &value,
|
||||
int role = Qt::EditRole) override;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const 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;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // PARAMLISTMODEL_H
|
||||
29
paramtypedelegate.cpp
Normal file
29
paramtypedelegate.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include "paramtypedelegate.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include "TypeSelectionItemModel.h"
|
||||
|
||||
ParamTypeDelegate::ParamTypeDelegate()
|
||||
: m_typeSelectionModel(new TypeSelectionItemModel)
|
||||
{}
|
||||
|
||||
ParamTypeDelegate::~ParamTypeDelegate()
|
||||
{
|
||||
delete m_typeSelectionModel;
|
||||
}
|
||||
|
||||
QWidget *ParamTypeDelegate::createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
|
||||
{
|
||||
QWidget *w = nullptr;
|
||||
// if (index.data().canConvert<StarRating>()) {
|
||||
QComboBox *cmbbx = new QComboBox(parent);
|
||||
cmbbx->setModel(m_typeSelectionModel);
|
||||
w = cmbbx;
|
||||
// } else {
|
||||
// w = QStyledItemDelegate::createEditor(parent, option, index);
|
||||
// }
|
||||
return w;
|
||||
}
|
||||
25
paramtypedelegate.h
Normal file
25
paramtypedelegate.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef PARAMTYPEDELEGATE_H
|
||||
#define PARAMTYPEDELEGATE_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
class TypeSelectionItemModel;
|
||||
|
||||
/** Item delegate for supplying a combobox for selected the parameter type in
|
||||
* the parameter list.
|
||||
*/
|
||||
class ParamTypeDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ParamTypeDelegate();
|
||||
~ParamTypeDelegate();
|
||||
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
private:
|
||||
TypeSelectionItemModel* m_typeSelectionModel = nullptr;
|
||||
};
|
||||
|
||||
#endif // PARAMTYPEDELEGATE_H
|
||||
3
pgclass.cpp
Normal file
3
pgclass.cpp
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#include "pgclass.h"
|
||||
|
||||
PgClass::PgClass() = default;
|
||||
26
pgclass.h
Normal file
26
pgclass.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef PGCLASS_H
|
||||
#define PGCLASS_H
|
||||
|
||||
#include <QString>
|
||||
#include <pgsql/libpq-fe.h>
|
||||
|
||||
class PgClass {
|
||||
public:
|
||||
PgClass();
|
||||
|
||||
Oid oid = InvalidOid;
|
||||
QString relname;
|
||||
Oid relnamespace = InvalidOid;
|
||||
Oid reltype = InvalidOid;
|
||||
Oid reloftype = InvalidOid;
|
||||
Oid relowner = InvalidOid;
|
||||
Oid relam = InvalidOid;
|
||||
Oid relfilename = InvalidOid;
|
||||
Oid reltablespace = InvalidOid;
|
||||
int relpages_est = 0;
|
||||
float reltuples_est = 0;
|
||||
int relallvisible = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif // PGCLASS_H
|
||||
23
pglab.pro
23
pglab.pro
|
|
@ -43,7 +43,15 @@ SOURCES += main.cpp\
|
|||
pgtype.cpp \
|
||||
pgsqldatabasecatalogue.cpp \
|
||||
pgtypecontainer.cpp \
|
||||
tuplesresultwidget.cpp
|
||||
tuplesresultwidget.cpp \
|
||||
pgnamespace.cpp \
|
||||
pgclass.cpp \
|
||||
backupdialog.cpp \
|
||||
paramlistmodel.cpp \
|
||||
paramtypedelegate.cpp \
|
||||
typeselectionitemmodel.cpp \
|
||||
opendatabase.cpp \
|
||||
MasterController.cpp
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
serverproperties.h \
|
||||
|
|
@ -72,7 +80,15 @@ HEADERS += mainwindow.h \
|
|||
pgtype.h \
|
||||
pgsqldatabasecatalogue.h \
|
||||
pgtypecontainer.h \
|
||||
tuplesresultwidget.h
|
||||
tuplesresultwidget.h \
|
||||
pgnamespace.h \
|
||||
pgclass.h \
|
||||
backupdialog.h \
|
||||
paramlistmodel.h \
|
||||
paramtypedelegate.h \
|
||||
typeselectionitemmodel.h \
|
||||
opendatabase.h \
|
||||
MasterController.h
|
||||
|
||||
FORMS += mainwindow.ui \
|
||||
serverproperties.ui \
|
||||
|
|
@ -80,7 +96,8 @@ FORMS += mainwindow.ui \
|
|||
connectionmanagerwindow.ui \
|
||||
databaseinspectorwidget.ui \
|
||||
tuplesresultwidget.ui \
|
||||
querytab.ui
|
||||
querytab.ui \
|
||||
backupdialog.ui
|
||||
|
||||
RESOURCES += \
|
||||
resources.qrc
|
||||
|
|
|
|||
4
pgnamespace.cpp
Normal file
4
pgnamespace.cpp
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include "pgnamespace.h"
|
||||
|
||||
PgNamespace::PgNamespace() = default;
|
||||
|
||||
17
pgnamespace.h
Normal file
17
pgnamespace.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef PGNAMESPACE_H
|
||||
#define PGNAMESPACE_H
|
||||
|
||||
#include <QString>
|
||||
#include <pgsql/libpq-fe.h>
|
||||
|
||||
class PgNamespace
|
||||
{
|
||||
public:
|
||||
PgNamespace();
|
||||
|
||||
QString name;
|
||||
Oid owner = InvalidOid;
|
||||
QString acl;
|
||||
};
|
||||
|
||||
#endif // PGNAMESPACE_H
|
||||
|
|
@ -32,7 +32,6 @@ std::string PgTypeContainer::getLoadQuery()
|
|||
" typreceive, typsend, typmodin, typmodout, typanalyze, typalign, typstorage, typnotnull, \n"
|
||||
" typbasetype, typtypmod, typndims, typcollation, typdefaultbin, typdefault, typacl \n"
|
||||
"FROM pg_type";
|
||||
|
||||
}
|
||||
|
||||
void PgTypeContainer::load(const Pgsql::Result &res)
|
||||
|
|
|
|||
80
querytab.cpp
80
querytab.cpp
|
|
@ -13,6 +13,7 @@
|
|||
#include "explaintreemodelitem.h"
|
||||
#include "json/json.h"
|
||||
#include "mainwindow.h"
|
||||
#include "pgtypecontainer.h"
|
||||
#include "util.h"
|
||||
|
||||
QueryTab::QueryTab(MainWindow *win, QWidget *parent) :
|
||||
|
|
@ -39,6 +40,9 @@ QueryTab::QueryTab(MainWindow *win, QWidget *parent) :
|
|||
ui->queryEdit->setFont(font);
|
||||
highlighter.reset(new SqlHighlighter(ui->queryEdit->document()));
|
||||
|
||||
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();
|
||||
|
|
@ -49,6 +53,7 @@ QueryTab::~QueryTab()
|
|||
{
|
||||
m_dbConnection.closeConnection();
|
||||
m_dbConnection.setStateCallback(nullptr);
|
||||
// delete m_pgTypes;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
|
@ -279,26 +284,47 @@ 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;
|
||||
// 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);
|
||||
QString iconname;
|
||||
switch (state) {
|
||||
case ASyncDBConnection::State::NotConnected:
|
||||
case ASyncDBConnection::State::Connecting:
|
||||
iconname = ":/icons/16x16/document_red.png";
|
||||
break;
|
||||
case ASyncDBConnection::State::Connected:
|
||||
iconname = ":/icons/16x16/document_green.png";
|
||||
break;
|
||||
case ASyncDBConnection::State::QuerySend:
|
||||
case ASyncDBConnection::State::CancelSend:
|
||||
iconname = ":/icons/16x16/document_yellow.png";
|
||||
break;
|
||||
}
|
||||
tabwidget->setTabIcon(i, QIcon(iconname));
|
||||
}
|
||||
addLog(status_str);
|
||||
// statusBar()->showMessage(status_str);
|
||||
|
||||
// statusBar()->showMessage(status_str);
|
||||
|
||||
// bool connected = ASyncDBConnection::State::Connected == state;
|
||||
// ui->actionExecute_SQL->setEnabled(connected);
|
||||
|
|
@ -409,11 +435,17 @@ std::string QueryTab::getCommand() const
|
|||
return command.toUtf8().data();
|
||||
}
|
||||
|
||||
void QueryTab::setTabCaption(const QString &caption, const QString &tooltip)
|
||||
QTabWidget *QueryTab::getTabWidget()
|
||||
{
|
||||
QWidget * w = parentWidget();
|
||||
QWidget * p = w->parentWidget();
|
||||
QTabWidget *tabwidget = dynamic_cast<QTabWidget*>(p);
|
||||
QTabWidget *tw = dynamic_cast<QTabWidget*>(p);
|
||||
return tw;
|
||||
}
|
||||
|
||||
void QueryTab::setTabCaption(const QString &caption, const QString &tooltip)
|
||||
{
|
||||
QTabWidget *tabwidget = getTabWidget();
|
||||
if (tabwidget) {
|
||||
int i = tabwidget->indexOf(this);
|
||||
if (i >= 0) {
|
||||
|
|
@ -437,7 +469,11 @@ void QueryTab::query_ready(std::shared_ptr<Pgsql::Result> dbres, qint64 elapsedm
|
|||
TuplesResultWidget *trw = new TuplesResultWidget;
|
||||
trw->setResult(result_model, elapsedms);
|
||||
resultList.push_back(trw);
|
||||
ui->tabWidget->addTab(trw, "Data");
|
||||
ui->tabWidget->addTab(trw, "Data");
|
||||
if (resultList.size() == 1)
|
||||
ui->tabWidget->setCurrentWidget(trw);
|
||||
|
||||
|
||||
// ui->lblRowCount->setText(rowcount_str);
|
||||
// resultModel.reset(new QueryResultModel(nullptr , dbres));
|
||||
// ui->ResultView->setModel(resultModel.get());
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
#define QUERYTAB_H
|
||||
|
||||
#include "asyncdbconnection.h"
|
||||
#include "paramlistmodel.h"
|
||||
#include "paramtypedelegate.h"
|
||||
#include "queryresultmodel.h"
|
||||
#include "queryexplainmodel.h"
|
||||
#include "stopwatch.h"
|
||||
|
|
@ -14,11 +16,13 @@ namespace Ui {
|
|||
class QueryTab;
|
||||
}
|
||||
|
||||
class QTabWidget;
|
||||
class MainWindow;
|
||||
class SqlHighlighter;
|
||||
class ExplainRoot;
|
||||
class QueryResultModel;
|
||||
class QueryExplainModel;
|
||||
class PgTypeContainer;
|
||||
|
||||
|
||||
class QueryTab : public QWidget
|
||||
|
|
@ -60,6 +64,8 @@ private:
|
|||
std::unique_ptr<SqlHighlighter> highlighter;
|
||||
ConnectionConfig m_config;
|
||||
StopWatch m_stopwatch;
|
||||
ParamListModel m_paramList;
|
||||
ParamTypeDelegate m_typeDelegate;
|
||||
|
||||
QString m_fileName; ///< use setFileName function to set
|
||||
bool m_queryTextChanged = false;
|
||||
|
|
@ -83,8 +89,10 @@ private:
|
|||
void explain_ready(ExplainRoot::SPtr explain);
|
||||
void query_ready(std::shared_ptr<Pgsql::Result> dbres, qint64 elapsedms);
|
||||
|
||||
QTabWidget *getTabWidget();
|
||||
void setTabCaption(const QString &caption, const QString &tooltip);
|
||||
void clearResult();
|
||||
|
||||
private slots:
|
||||
|
||||
void queryTextChanged();
|
||||
|
|
|
|||
29
querytab.ui
29
querytab.ui
|
|
@ -14,27 +14,22 @@
|
|||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</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="QSplitter" name="splitter">
|
||||
<widget class="QSplitter" name="splitter_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QPlainTextEdit" name="queryEdit"/>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QPlainTextEdit" name="queryEdit"/>
|
||||
<widget class="QTableView" name="paramTableView">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
|
|
|
|||
|
|
@ -13,5 +13,9 @@
|
|||
<file>icons/page_white_delete.png</file>
|
||||
<file>icons/lightbulb_off.png</file>
|
||||
<file>icons/information.png</file>
|
||||
<file>icons/16x16/document_green.png</file>
|
||||
<file>icons/16x16/document_red.png</file>
|
||||
<file>icons/16x16/document_yellow.png</file>
|
||||
<file>icons/backups.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
|||
52
typeselectionitemmodel.cpp
Normal file
52
typeselectionitemmodel.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#include "typeselectionitemmodel.h"
|
||||
|
||||
TypeSelectionItemModel::TypeSelectionItemModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int TypeSelectionItemModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
int result = 10;
|
||||
// if (!parent.isValid()) {
|
||||
|
||||
// }
|
||||
return result;
|
||||
}
|
||||
|
||||
int TypeSelectionItemModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
int result = 1;
|
||||
// if (parent.isValid())
|
||||
// result = 1;
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QVariant TypeSelectionItemModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
QVariant result;
|
||||
if (index.isValid()) {
|
||||
int row = index.row();
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
21
typeselectionitemmodel.h
Normal file
21
typeselectionitemmodel.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef TYPESELECTIONITEMMODEL_H
|
||||
#define TYPESELECTIONITEMMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
class TypeSelectionItemModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TypeSelectionItemModel(QObject *parent = 0);
|
||||
|
||||
|
||||
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:
|
||||
};
|
||||
|
||||
#endif // TYPESELECTIONITEMMODEL_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue