From 7181c7f1e784d318f9cd4ee77673cc490f43684c Mon Sep 17 00:00:00 2001 From: Eelke Klein Date: Sun, 15 Jan 2017 12:27:36 +0100 Subject: [PATCH] The list of connections is now saved and loaded on program shutdown and start. --- Ivory.pro | 8 +-- connectionconfig.cpp | 8 +-- connectionconfig.h | 6 +-- connectionlistmodel.cpp | 100 ++++++++++++++++++++++++++++++------ connectionlistmodel.h | 17 +++++- connectionmanagerwindow.cpp | 27 +++++----- connectionmanagerwindow.h | 2 +- main.cpp | 4 +- 8 files changed, 128 insertions(+), 44 deletions(-) diff --git a/Ivory.pro b/Ivory.pro index f5c2af8..94da07d 100644 --- a/Ivory.pro +++ b/Ivory.pro @@ -6,7 +6,7 @@ QT += core gui -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets sql TARGET = Ivory TEMPLATE = app @@ -33,7 +33,7 @@ SOURCES += main.cpp\ databasewindow.cpp \ connectionmanagerwindow.cpp \ connectionlistmodel.cpp \ - connectionconfig.cpp +connectionconfig.cpp HEADERS += mainwindow.h \ serverproperties.h \ @@ -51,7 +51,9 @@ HEADERS += mainwindow.h \ databasewindow.h \ connectionmanagerwindow.h \ connectionlistmodel.h \ - connectionconfig.h + connectionconfig.h \ + scopeguard.h \ + expected.h FORMS += mainwindow.ui \ serverproperties.ui \ diff --git a/connectionconfig.cpp b/connectionconfig.cpp index 5d4ba51..bce1b6b 100644 --- a/connectionconfig.cpp +++ b/connectionconfig.cpp @@ -56,14 +56,14 @@ ConnectionConfig::ConnectionConfig() , m_values(s_keywords.size(), nullptr) {} -void ConnectionConfig::setDescription(std::string desc) +void ConnectionConfig::setName(std::string desc) { - m_description = std::move(desc); + m_name = std::move(desc); } -const std::string& ConnectionConfig::description() const +const std::string& ConnectionConfig::name() const { - return m_description; + return m_name; } void ConnectionConfig::setHost(std::string host) diff --git a/connectionconfig.h b/connectionconfig.h index f33d20b..9412ddf 100644 --- a/connectionconfig.h +++ b/connectionconfig.h @@ -17,8 +17,8 @@ class ConnectionConfig { public: ConnectionConfig(); - void setDescription(std::string desc); - const std::string& description() const; + void setName(std::string desc); + const std::string& name() const; void setHost(std::string host); const std::string& host() const; @@ -57,7 +57,7 @@ public: const char * const * getValues() const; private: - std::string m_description; + std::string m_name; std::string m_host; std::string m_hostaddr; std::string m_port = "5432"; diff --git a/connectionlistmodel.cpp b/connectionlistmodel.cpp index 0f349ce..30f567c 100644 --- a/connectionlistmodel.cpp +++ b/connectionlistmodel.cpp @@ -1,6 +1,8 @@ #include "connectionlistmodel.h" +#include +#include #include - +#include "scopeguard.h" inline QString stdStrToQ(const std::string &s) { @@ -24,7 +26,7 @@ Before calling this you may want to call beginGroup. */ void SaveConnectionConfig(QSettings &settings, const ConnectionConfig &cc) { - settings.setValue("description", stdStrToQ(cc.description())); + settings.setValue("name", stdStrToQ(cc.name())); settings.setValue("host", stdStrToQ(cc.host())); settings.setValue("hostaddr", stdStrToQ(cc.hostAddr())); settings.setValue("port", cc.port()); @@ -40,7 +42,7 @@ void SaveConnectionConfig(QSettings &settings, const ConnectionConfig &cc) void LoadConnectionConfig(QSettings &settings, ConnectionConfig &cc) { - cc.setDescription(qvarToStdStr(settings.value("description"))); + cc.setName(qvarToStdStr(settings.value("name"))); cc.setHost(qvarToStdStr(settings.value("host"))); cc.setHostAddr(qvarToStdStr(settings.value("hostaddr"))); cc.setPort(settings.value("port", 5432).toInt()); @@ -58,7 +60,9 @@ void LoadConnectionConfig(QSettings &settings, ConnectionConfig &cc) ConnectionListModel::ConnectionListModel(QObject *parent) : QAbstractListModel(parent) -{} +{ + load(); +} int ConnectionListModel::rowCount(const QModelIndex &parent) const { @@ -67,7 +71,7 @@ int ConnectionListModel::rowCount(const QModelIndex &parent) const int ConnectionListModel::columnCount(const QModelIndex &/*parent*/) const { - return 4; + return 7; } QVariant ConnectionListModel::data(const QModelIndex &index, int role) const @@ -76,13 +80,13 @@ QVariant ConnectionListModel::data(const QModelIndex &index, int role) const if (role == Qt::DisplayRole || role == Qt::EditRole) { int row = index.row(); int col = index.column(); - const ConnectionConfig& cfg = m_connections.at(row); + const ConnectionConfig& cfg = m_connections.at(row).m_config; switch (col) { case 0: result = makeLongDescription(cfg); break; case 1: - result = stdStrToQ(cfg.description()); + result = stdStrToQ(cfg.name()); break; case 2: result = stdStrToQ(cfg.host()); @@ -90,7 +94,15 @@ QVariant ConnectionListModel::data(const QModelIndex &index, int role) const case 3: result = cfg.port(); break; - + case 4: + result = stdStrToQ(cfg.user()); + break; + case 5: + result = stdStrToQ(cfg.password()); + break; + case 6: + result = stdStrToQ(cfg.dbname()); + break; } } @@ -99,29 +111,41 @@ QVariant ConnectionListModel::data(const QModelIndex &index, int role) const bool ConnectionListModel::setData(const QModelIndex &index, const QVariant &value, int role) { - + bool result = false; if (role == Qt::EditRole) { int row = index.row(); int col = index.column(); - ConnectionConfig& cfg = m_connections.at(row); + ConnectionConfig& cfg = m_connections.at(row).m_config; + if (col > 0) { + result = true; + } switch (col) { case 0: break; case 1: - cfg.setDescription( qStrToStd(value.toString()) ); - emit dataChanged(index, index); + cfg.setName( qStrToStd(value.toString()) ); break; case 2: cfg.setHost( qStrToStd(value.toString()) ); - emit dataChanged(index, index); break; case 3: cfg.setPort( value.toInt() ); - emit dataChanged(index, index); + break; + case 4: + cfg.setUser( qStrToStd(value.toString()) ); + break; + case 5: + cfg.setPassword( qStrToStd(value.toString()) ); + break; + case 6: + cfg.setDbname( qStrToStd(value.toString()) ); break; } } - return true; + if (result) { + emit dataChanged(index, index); + } + return result; } Qt::ItemFlags ConnectionListModel::flags(const QModelIndex &index) const @@ -132,7 +156,7 @@ Qt::ItemFlags ConnectionListModel::flags(const QModelIndex &index) const QString ConnectionListModel::makeLongDescription(const ConnectionConfig &cfg) { - std::string result(cfg.description()); + std::string result(cfg.name()); result += " ("; result += cfg.user(); result += "@"; @@ -147,8 +171,50 @@ QString ConnectionListModel::makeLongDescription(const ConnectionConfig &cfg) void ConnectionListModel::add(const ConnectionConfig &cfg) { - m_connections.push_back(cfg); + m_connections.emplace_back(QUuid::createUuid(), cfg); auto idx = createIndex(m_connections.size()-1, 0); emit dataChanged(idx, idx); } +/// \todo should return an expected as creation of the folder can fail +QString ConnectionListModel::iniFileName() +{ + QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + QDir dir(path); + if (!dir.exists()) { + dir.mkpath("."); + } + path += "/connections.ini"; + return path; +} + + +void ConnectionListModel::load() +{ + QString file_name = iniFileName(); + QSettings settings(file_name, QSettings::IniFormat); + auto groups = settings.childGroups(); + for (auto grp : groups) { + QUuid uuid(grp); + if ( ! uuid.isNull() ) { + settings.beginGroup(grp); + SCOPE_EXIT { settings.endGroup(); }; + + ConnectionConfig cc; + LoadConnectionConfig(settings, cc); + m_connections.emplace_back(uuid, cc); + } + } +} + +void ConnectionListModel::save() +{ + QString file_name = iniFileName(); + QSettings settings(file_name, QSettings::IniFormat); + for (auto e : m_connections) { + settings.beginGroup(e.m_uuid.toString()); + SCOPE_EXIT { settings.endGroup(); }; + + SaveConnectionConfig(settings, e.m_config); + } +} diff --git a/connectionlistmodel.h b/connectionlistmodel.h index 4f2e963..8dfce0e 100644 --- a/connectionlistmodel.h +++ b/connectionlistmodel.h @@ -5,6 +5,7 @@ #include #include +#include #include "connectionconfig.h" @@ -23,10 +24,24 @@ public: void add(const ConnectionConfig &cfg); + void load(); + void save(); private: - using t_Connections = std::vector; + class LijstElem { + public: + QUuid m_uuid; + ConnectionConfig m_config; + + LijstElem(const QUuid id, const ConnectionConfig &cfg) + : m_uuid(id), m_config(cfg) + {} + }; + + using t_Connections = std::vector; t_Connections m_connections; + static QString iniFileName(); + static QString makeLongDescription(const ConnectionConfig &cfg); }; diff --git a/connectionmanagerwindow.cpp b/connectionmanagerwindow.cpp index 467ec87..b7db899 100644 --- a/connectionmanagerwindow.cpp +++ b/connectionmanagerwindow.cpp @@ -12,18 +12,9 @@ ConnectionManagerWindow::ConnectionManagerWindow(QWidget *parent) { ui->setupUi(this); - ConnectionConfig c; - c.setDescription("test"); - m_listModel->add(c); - ui->listView->setModel(m_listModel); - m_mapper = new QDataWidgetMapper(this); - m_mapper->setModel(m_listModel); - m_mapper->addMapping(ui->edtName, 1); - m_mapper->addMapping(ui->edtHost, 2); - m_mapper->addMapping(ui->spinPort, 3); - m_mapper->toFirst(); + setupWidgetMappings(); connect(ui->listView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), @@ -33,6 +24,8 @@ ConnectionManagerWindow::ConnectionManagerWindow(QWidget *parent) ConnectionManagerWindow::~ConnectionManagerWindow() { + m_listModel->save(); + delete ui; delete m_listModel; delete m_mapper; @@ -41,7 +34,7 @@ ConnectionManagerWindow::~ConnectionManagerWindow() void ConnectionManagerWindow::on_actionAdd_Connection_triggered() { ConnectionConfig c; - c.setDescription("new"); + c.setName("new"); m_listModel->add(c); } @@ -71,7 +64,15 @@ void ConnectionManagerWindow::on_actionDelete_connection_triggered() } -void ConnectionManagerWindow::controlsToConfig(ConnectionConfig &cfg) +void ConnectionManagerWindow::setupWidgetMappings() { -// ui-> + m_mapper = new QDataWidgetMapper(this); + m_mapper->setModel(m_listModel); + m_mapper->addMapping(ui->edtName, 1); + m_mapper->addMapping(ui->edtHost, 2); + m_mapper->addMapping(ui->spinPort, 3); + m_mapper->addMapping(ui->edtUser, 4); + m_mapper->addMapping(ui->edtPassword, 5); + m_mapper->addMapping(ui->edtDbname, 6); + m_mapper->toFirst(); } diff --git a/connectionmanagerwindow.h b/connectionmanagerwindow.h index b9838ad..b6145be 100644 --- a/connectionmanagerwindow.h +++ b/connectionmanagerwindow.h @@ -30,7 +30,7 @@ private: ConnectionListModel *m_listModel = nullptr; QDataWidgetMapper *m_mapper = nullptr; - void controlsToConfig(ConnectionConfig &cfg); + void setupWidgetMappings(); }; #endif // CONNECTIONMANAGERWINDOW_H diff --git a/main.cpp b/main.cpp index 2697488..84b3800 100644 --- a/main.cpp +++ b/main.cpp @@ -20,9 +20,9 @@ int main(int argc, char *argv[]) QApplication a(argc, argv); - QCoreApplication::setOrganizationName("MySoft"); + QCoreApplication::setOrganizationName("pglab"); QCoreApplication::setOrganizationDomain("eelkeklein.nl"); - QCoreApplication::setApplicationName("Ivory"); + QCoreApplication::setApplicationName("pglab"); ConnectionManagerWindow w; w.show();