Query window has now buttons with icons made in the designer for better looks. Depending on received responses from the database the tabcontrol with the message, data and explain tab now switches to the appropriate tab.
251 lines
6.1 KiB
C++
251 lines
6.1 KiB
C++
#include "connectionlistmodel.h"
|
|
#include <QDir>
|
|
#include <QStandardPaths>
|
|
#include <QSettings>
|
|
#include "scopeguard.h"
|
|
|
|
inline QString stdStrToQ(const std::string &s)
|
|
{
|
|
return QString::fromUtf8(s.c_str());
|
|
}
|
|
|
|
inline std::string qStrToStd(const QString &s)
|
|
{
|
|
return std::string(s.toUtf8().data());
|
|
}
|
|
|
|
inline std::string qvarToStdStr(const QVariant &c)
|
|
{
|
|
return qStrToStd(c.toString());
|
|
}
|
|
|
|
|
|
/** Saves a connection configuration.
|
|
|
|
Before calling this you may want to call beginGroup.
|
|
*/
|
|
void SaveConnectionConfig(QSettings &settings, const ConnectionConfig &cc)
|
|
{
|
|
settings.setValue("name", stdStrToQ(cc.name()));
|
|
settings.setValue("host", stdStrToQ(cc.host()));
|
|
settings.setValue("hostaddr", stdStrToQ(cc.hostAddr()));
|
|
settings.setValue("port", cc.port());
|
|
settings.setValue("user", stdStrToQ(cc.user()));
|
|
settings.setValue("password", stdStrToQ(cc.password()));
|
|
settings.setValue("dbname", stdStrToQ(cc.dbname()));
|
|
settings.setValue("sslmode", (int)cc.sslMode());
|
|
settings.setValue("sslcert", stdStrToQ(cc.sslCert()));
|
|
settings.setValue("sslkey", stdStrToQ(cc.sslKey()));
|
|
settings.setValue("sslrootcert", stdStrToQ(cc.sslRootCert()));
|
|
settings.setValue("sslcrl", stdStrToQ(cc.sslCrl()));
|
|
}
|
|
|
|
void LoadConnectionConfig(QSettings &settings, ConnectionConfig &cc)
|
|
{
|
|
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());
|
|
cc.setUser(qvarToStdStr(settings.value("user")));
|
|
cc.setPassword(qvarToStdStr(settings.value("password")));
|
|
cc.setDbname(qvarToStdStr(settings.value("dbname")));
|
|
cc.setSslMode((SslMode)settings.value("sslmode").toInt());
|
|
cc.setSslCert(qvarToStdStr(settings.value("sslcert")));
|
|
cc.setSslKey(qvarToStdStr(settings.value("sslkey")));
|
|
cc.setSslRootCert(qvarToStdStr(settings.value("sslrootcert")));
|
|
cc.setSslCrl(qvarToStdStr(settings.value("sslcrl")));
|
|
}
|
|
|
|
|
|
|
|
ConnectionListModel::ConnectionListModel(QObject *parent)
|
|
: QAbstractListModel(parent)
|
|
{
|
|
load();
|
|
}
|
|
|
|
int ConnectionListModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
int result = 0;
|
|
if (parent == QModelIndex()) {
|
|
result = m_connections.size();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int ConnectionListModel::columnCount(const QModelIndex &/*parent*/) const
|
|
{
|
|
return 7;
|
|
}
|
|
|
|
QVariant ConnectionListModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
QVariant result;
|
|
if (role == Qt::DisplayRole || role == Qt::EditRole) {
|
|
int row = index.row();
|
|
int col = index.column();
|
|
const ConnectionConfig& cfg = m_connections.at(row).m_config;
|
|
switch (col) {
|
|
case 0:
|
|
result = makeLongDescription(cfg);
|
|
break;
|
|
case 1:
|
|
result = stdStrToQ(cfg.name());
|
|
break;
|
|
case 2:
|
|
result = stdStrToQ(cfg.host());
|
|
break;
|
|
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;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
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).m_config;
|
|
if (col > 0) {
|
|
result = true;
|
|
}
|
|
switch (col) {
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
cfg.setName( qStrToStd(value.toString()) );
|
|
break;
|
|
case 2:
|
|
cfg.setHost( qStrToStd(value.toString()) );
|
|
break;
|
|
case 3:
|
|
cfg.setPort( value.toInt() );
|
|
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;
|
|
}
|
|
}
|
|
if (result) {
|
|
emit dataChanged(index, index);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
Qt::ItemFlags ConnectionListModel::flags(const QModelIndex &index) const
|
|
{
|
|
Qt::ItemFlags result;
|
|
int row = index.row();
|
|
if (row >= 0 && row < m_connections.size()) {
|
|
result = Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
QString ConnectionListModel::makeLongDescription(const ConnectionConfig &cfg)
|
|
{
|
|
std::string result(cfg.name());
|
|
result += " (";
|
|
result += cfg.user();
|
|
result += "@";
|
|
result += cfg.host();
|
|
result += ":";
|
|
result += std::to_string(cfg.port());
|
|
result += "/";
|
|
result += cfg.dbname();
|
|
result += ")";
|
|
return stdStrToQ(result);
|
|
}
|
|
|
|
void ConnectionListModel::add(const ConnectionConfig &cfg)
|
|
{
|
|
m_connections.emplace_back(QUuid::createUuid(), cfg);
|
|
auto idx = createIndex(m_connections.size()-1, 0);
|
|
emit dataChanged(idx, idx);
|
|
}
|
|
|
|
Expected<ConnectionConfig> ConnectionListModel::get(int row)
|
|
{
|
|
if (row >= 0 && row < m_connections.size()) {
|
|
return m_connections.at(row).m_config;
|
|
}
|
|
else {
|
|
return Expected<ConnectionConfig>::fromException(std::out_of_range("Invalid row"));
|
|
}
|
|
}
|
|
|
|
//void ConnectionListModel::del(const int idx)
|
|
bool ConnectionListModel::removeRows(int row, int count, const QModelIndex &parent)
|
|
{
|
|
bool result = false;
|
|
if (row >= 0 && row < m_connections.size()) {
|
|
auto f = m_connections.begin() + row;
|
|
m_connections.erase(f, f + count);
|
|
result = true;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// \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);
|
|
}
|
|
}
|