Browse Source

Manage connection

recurring
Aditya Kulkarni 6 years ago
parent
commit
1b4ced8c82
  1. 133
      src/connection.cpp
  2. 29
      src/connection.h
  3. 47
      src/connection.ui
  4. 28
      src/mainwindow.cpp
  5. 50
      src/rpc.cpp
  6. 7
      src/rpc.h
  7. 106
      src/settings.cpp
  8. 29
      src/settings.h
  9. 6
      src/settings.ui

133
src/connection.cpp

@ -7,7 +7,7 @@
#include "precompiled.h"
using json = nlohmann::json;
/*
class LoadingDialog : public QDialog {
//Q_OBJECT
public:
@ -22,11 +22,12 @@ LoadingDialog::~LoadingDialog() {}
void LoadingDialog::reject() {
//event->ignore();
}
ConnectionLoader::ConnectionLoader(MainWindow* main) {
*/
ConnectionLoader::ConnectionLoader(MainWindow* main, RPC* rpc) {
this->main = main;
this->rpc = rpc;
d = new LoadingDialog(main);
d = new QDialog(main);
connD = new Ui_ConnectionDialog();
connD->setupUi(d);
@ -44,84 +45,124 @@ ConnectionLoader::~ConnectionLoader() {
delete connD;
}
void ConnectionLoader::getConnection(std::function<void(RPC*)> cb) {
void ConnectionLoader::loadConnection() {
// Priority 1: Try to connect to detect zcash.conf and connect to it.
bool isZcashConfPresent = false;
auto conn = autoDetectZcashConf();
auto config = autoDetectZcashConf();
// If not autodetected, go and read the UI Settings
if (conn.get() != nullptr) {
if (config.get() != nullptr) {
isZcashConfPresent = true;
} else {
conn = loadFromSettings();
config = loadFromSettings();
if (conn.get() == nullptr) {
if (config.get() == nullptr) {
// Nothing configured, show an error
auto explanation = QString()
% "A zcash.conf was not found on this machine.\n\n"
% "If you are connecting to a remote/non-standard node "
% "please set the host/port and user/password in the File->Settings menu.";
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical);
connD->icon->setPixmap(icon.pixmap(64, 64));
connD->status->setText(explanation);
connD->progressBar->setValue(0);
showError(explanation);
rpc->setConnection(nullptr);
connD->buttonBox->setEnabled(true);
cb(nullptr);
return;
}
}
auto connection = makeConnection(config);
refreshZcashdState(connection);
}
Connection* ConnectionLoader::makeConnection(std::shared_ptr<ConnectionConfig> config) {
QNetworkAccessManager* client = new QNetworkAccessManager(main);
QUrl myurl;
myurl.setScheme("http");
myurl.setHost(Settings::getInstance()->getHost());
myurl.setPort(Settings::getInstance()->getPort().toInt());
myurl.setHost(config.get()->host);
myurl.setPort(config.get()->port.toInt());
QNetworkRequest* request = new QNetworkRequest();
request->setUrl(myurl);
request->setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");
QString headerData = "Basic " + Settings::getInstance()->getUsernamePassword().toLocal8Bit().toBase64();
request->setRawHeader("Authorization", headerData.toLocal8Bit());
QString userpass = config.get()->rpcuser % ":" % config.get()->rpcpassword;
QString headerData = "Basic " + userpass.toLocal8Bit().toBase64();
request->setRawHeader("Authorization", headerData.toLocal8Bit());
return new Connection(client, request, config);
}
auto connection = new Connection(client, request);
void ConnectionLoader::refreshZcashdState(Connection* connection) {
json payload = {
{"jsonrpc", "1.0"},
{"id", "someid"},
{"method", "getinfo"}
};
connection->doRPC(payload,
[=] (auto result) {
[=] (auto) {
// Success
d->close();
cb(new RPC(connection, main));
d->hide();
rpc->setConnection(connection);
},
[=] (auto err, auto res) {
// Failed
auto explanation = QString()
% (isZcashConfPresent ? "A zcash.conf file was found, but a" : "A")
% " connection to zcashd could not be established.\n\n"
% "If you are connecting to a remote/non-standard node "
% "please set the host/port and user/password in the File->Settings menu.";
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical);
connD->icon->setPixmap(icon.pixmap(64, 64));
connD->status->setText(explanation);
connD->progressBar->setValue(0);
connD->buttonBox->setEnabled(true);
// Failed, see what it is.
qDebug() << err << ":" << QString::fromStdString(res.dump());
if (err == QNetworkReply::NetworkError::ConnectionRefusedError) {
auto isZcashConfFound = connection->config.get()->usingZcashConf;
auto explanation = QString()
% (isZcashConfFound ? "A zcash.conf file was found, but a" : "A")
% " connection to zcashd could not be established.\n\n"
% "If you are connecting to a remote/non-standard node "
% "please set the host/port and user/password in the File->Settings menu";
showError(explanation);
} else if (err == QNetworkReply::NetworkError::AuthenticationRequiredError) {
auto explanation = QString()
% "Authentication failed. The username / password you specified was "
% "not accepted by zcashd. Try changing it in the File->Settings menu";
showError(explanation);
} else if (err == QNetworkReply::NetworkError::InternalServerError && !res.is_discarded()) {
// The server is loading, so just poll until it succeeds
QString status = QString::fromStdString(res["error"]["message"]);
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
connD->icon->setPixmap(icon.pixmap(128, 128));
connD->status->setText(status);
// Refresh after one second
QTimer::singleShot(1000, [=]() { this->refreshZcashdState(connection); });
}
}
);
}
void ConnectionLoader::showError(QString explanation) {
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical);
connD->icon->setPixmap(icon.pixmap(128, 128));
connD->status->setText(explanation);
connD->title->setText("");
connD->buttonBox->setEnabled(true);
}
/*
int ConnectionLoader::getProgressFromStatus(QString status) {
if (status.startsWith("Loading block")) return 20;
if (status.startsWith("Verifying")) return 40;
if (status.startsWith("Loading Wallet")) return 60;
if (status.startsWith("Activating")) return 80;
if (status.startsWith("Rescanning")) return 90;
return 0;
}
*/
/**
* Try to automatically detect a zcash.conf file in the correct location and load parameters
*/
std::shared_ptr<ConnectionConfig*> ConnectionLoader::autoDetectZcashConf() {
std::shared_ptr<ConnectionConfig> ConnectionLoader::autoDetectZcashConf() {
#ifdef Q_OS_LINUX
auto confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, ".zcash/zcash.conf");
@ -149,6 +190,9 @@ std::shared_ptr<ConnectionConfig*> ConnectionLoader::autoDetectZcashConf() {
auto zcashconf = new ConnectionConfig();
zcashconf->host = "127.0.0.1";
zcashconf->connType = ConnectionType::DetectedConfExternalZcashD;
zcashconf->usingZcashConf = true;
Settings::getInstance()->setUsingZcashConf(confLocation);
while (!in.atEnd()) {
QString line = in.readLine();
@ -177,13 +221,13 @@ std::shared_ptr<ConnectionConfig*> ConnectionLoader::autoDetectZcashConf() {
file.close();
return std::make_shared<ConnectionConfig*>(zcashconf);
return std::shared_ptr<ConnectionConfig>(zcashconf);
}
/**
* Load connection settings from the UI, which indicates an unknown, external zcashd
*/
std::shared_ptr<ConnectionConfig*> ConnectionLoader::loadFromSettings() {
std::shared_ptr<ConnectionConfig> ConnectionLoader::loadFromSettings() {
// Load from the QT Settings.
QSettings s;
@ -195,9 +239,9 @@ std::shared_ptr<ConnectionConfig*> ConnectionLoader::loadFromSettings() {
if (username.isEmpty() || password.isEmpty())
return nullptr;
auto uiConfig = new ConnectionConfig{ host, port, username, password, ConnectionType::UISettingsZCashD };
auto uiConfig = new ConnectionConfig{ host, port, username, password, false, ConnectionType::UISettingsZCashD };
return std::make_shared<ConnectionConfig*>(uiConfig);
return std::shared_ptr<ConnectionConfig>(uiConfig);
}
@ -207,9 +251,10 @@ std::shared_ptr<ConnectionConfig*> ConnectionLoader::loadFromSettings() {
Connection::Connection(QNetworkAccessManager* c, QNetworkRequest* r) {
Connection::Connection(QNetworkAccessManager* c, QNetworkRequest* r, std::shared_ptr<ConnectionConfig> conf) {
this->restclient = c;
this->request = r;
this->request = r;
this->config = conf;
}
Connection::~Connection() {

29
src/connection.h

@ -20,27 +20,37 @@ struct ConnectionConfig {
QString port;
QString rpcuser;
QString rpcpassword;
bool usingZcashConf;
ConnectionType connType;
};
class LoadingDialog;
class Connection;
class ConnectionLoader {
public:
ConnectionLoader(MainWindow* main);
ConnectionLoader(MainWindow* main, RPC* rpc);
~ConnectionLoader();
void getConnection(std::function<void(RPC*)> cb);
void loadConnection();
private:
std::shared_ptr<ConnectionConfig*> autoDetectZcashConf();
std::shared_ptr<ConnectionConfig*> loadFromSettings();
std::shared_ptr<ConnectionConfig> autoDetectZcashConf();
std::shared_ptr<ConnectionConfig> loadFromSettings();
LoadingDialog* d;
Connection* makeConnection(std::shared_ptr<ConnectionConfig> config);
void refreshZcashdState(Connection* connection);
int getProgressFromStatus(QString status);
void showError(QString explanation);
QDialog* d;
Ui_ConnectionDialog* connD;
MainWindow* main;
RPC* rpc;
};
/**
@ -49,12 +59,13 @@ private:
*/
class Connection {
public:
Connection(QNetworkAccessManager* c, QNetworkRequest* r);
Connection(QNetworkAccessManager* c, QNetworkRequest* r, std::shared_ptr<ConnectionConfig> conf);
~Connection();
QNetworkAccessManager* restclient;
QNetworkRequest* request;
QNetworkAccessManager* restclient;
QNetworkRequest* request;
std::shared_ptr<ConnectionConfig> config;
void doRPC(const json& payload, const std::function<void(json)>& cb,
const std::function<void(QNetworkReply::NetworkError, const json&)>& ne);

47
src/connection.ui

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>513</width>
<height>286</height>
<height>201</height>
</rect>
</property>
<property name="windowTitle">
@ -17,40 +17,69 @@
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1">
<item row="0" column="1">
<widget class="QLabel" name="title">
<property name="text">
<string>Your zcashd is still loading. Please wait...</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="1">
<widget class="QLabel" name="status">
<property name="text">
<string>Connection Status</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="icon">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="margin">
<number>20</number>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>24</number>
<item row="3" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>

28
src/mainwindow.cpp

@ -63,15 +63,9 @@ MainWindow::MainWindow(QWidget *parent) :
setupBalancesTab();
setupTurnstileDialog();
restoreSavedStates();
rpc = new RPC(this);
new ConnectionLoader(this).getConnection([=] (RPC* rpc) {
if (rpc == nullptr)
return;
this->rpc = rpc;
this->rpc->refreshZECPrice();
this->rpc->refresh(true); // Force refresh first time
});
restoreSavedStates();
}
@ -356,10 +350,11 @@ void MainWindow::setupSettingsModal() {
settings.port->setValidator(&validator);
// Load current values into the dialog
settings.hostname->setText(Settings::getInstance()->getHost());
settings.port->setText(Settings::getInstance()->getPort());
settings.rpcuser->setText(Settings::getInstance()->getUsernamePassword().split(":")[0]);
settings.rpcpassword->setText(Settings::getInstance()->getUsernamePassword().split(":")[1]);
auto conf = Settings::getInstance()->getSettings();
settings.hostname->setText(conf.host);
settings.port->setText(conf.port);
settings.rpcuser->setText(conf.rpcuser);
settings.rpcpassword->setText(conf.rpcpassword);
// If values are coming from zcash.conf, then disable all the fields
auto zcashConfLocation = Settings::getInstance()->getZcashdConfLocation();
@ -390,13 +385,8 @@ void MainWindow::setupSettingsModal() {
settings.rpcuser->text(),
settings.rpcpassword->text());
auto me = this;
ConnectionLoader(this).getConnection([&me] (auto newrpc) {
delete me->rpc;
me->rpc = newrpc;
// Then refresh everything.
me->rpc->refresh(true);
});
auto cl = new ConnectionLoader(this, rpc);
cl->loadConnection();
}
};
});

50
src/rpc.cpp

@ -6,8 +6,10 @@
using json = nlohmann::json;
RPC::RPC(Connection* conn, MainWindow* main) {
this->conn = conn;
RPC::RPC(MainWindow* main) {
auto cl = new ConnectionLoader(main, this);
cl->loadConnection();
this->main = main;
this->ui = main->ui;
@ -16,15 +18,11 @@ RPC::RPC(Connection* conn, MainWindow* main) {
// Setup balances table model
balancesTableModel = new BalancesTableModel(main->ui->balancesTable);
main->ui->balancesTable->setModel(balancesTableModel);
main->ui->balancesTable->setColumnWidth(0, 300);
// Setup transactions table model
transactionsTableModel = new TxTableModel(ui->transactionsTable);
main->ui->transactionsTable->setModel(transactionsTableModel);
main->ui->transactionsTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
main->ui->transactionsTable->setColumnWidth(1, 350);
main->ui->transactionsTable->setColumnWidth(2, 200);
main->ui->transactionsTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
// Set up timer to refresh Price
priceTimer = new QTimer(main);
@ -64,6 +62,14 @@ RPC::~RPC() {
delete conn;
}
void RPC::setConnection(Connection* c) {
if (c == nullptr) return;
delete conn;
this->conn = c;
refresh();
}
void RPC::doRPC(const json& payload, const std::function<void(json)>& cb) {
QNetworkReply *reply = conn->restclient->post(*conn->request, QByteArray::fromStdString(payload.dump()));
@ -349,8 +355,14 @@ void RPC::fillTxJsonParams(json& params, Tx tx) {
}
void RPC::noConnection() {
ui->statusBar->showMessage("No Connection to zcashd");
}
// Refresh received z txs by calling z_listreceivedbyaddress/gettransaction
void RPC::refreshReceivedZTrans(QList<QString> zaddrs) {
if (conn == nullptr)
return noConnection();
// We'll only refresh the received Z txs if settings allows us.
if (!Settings::getInstance()->getSaveZtxs()) {
@ -459,11 +471,17 @@ void RPC::refreshReceivedZTrans(QList<QString> zaddrs) {
/// This will refresh all the balance data from zcashd
void RPC::refresh(bool force) {
if (conn == nullptr)
return noConnection();
getInfoThenRefresh(force);
}
void RPC::getInfoThenRefresh(bool force) {
if (conn == nullptr)
return noConnection();
json payload = {
{"jsonrpc", "1.0"},
{"id", "someid"},
@ -526,6 +544,9 @@ void RPC::getInfoThenRefresh(bool force) {
}
void RPC::refreshAddresses() {
if (conn == nullptr)
return noConnection();
delete zaddresses;
zaddresses = new QList<QString>();
@ -591,6 +612,9 @@ bool RPC::processUnspent(const json& reply) {
};
void RPC::refreshBalances() {
if (conn == nullptr)
return noConnection();
// 1. Get the Balances
getBalance([=] (json reply) {
auto balT = QString::fromStdString(reply["transparent"]).toDouble();
@ -626,6 +650,9 @@ void RPC::refreshBalances() {
}
void RPC::refreshTransactions() {
if (conn == nullptr)
return noConnection();
getTransactions([=] (json reply) {
QList<TransactionItem> txdata;
@ -654,6 +681,9 @@ void RPC::refreshTransactions() {
// Read sent Z transactions from the file.
void RPC::refreshSentZTrans() {
if (conn == nullptr)
return noConnection();
auto sentZTxs = SentTxStore::readSentTxFile();
QList<QString> txids;
@ -694,13 +724,16 @@ void RPC::refreshSentZTrans() {
);
}
void RPC::addNewTxToWatch(Tx tx, const QString& newOpid) {
void RPC::addNewTxToWatch(Tx tx, const QString& newOpid) {
watchingOps.insert(newOpid, tx);
watchTxStatus();
}
void RPC::watchTxStatus() {
if (conn == nullptr)
return noConnection();
// Make an RPC to load pending operation statues
json payload = {
{"jsonrpc", "1.0"},
@ -767,6 +800,9 @@ void RPC::watchTxStatus() {
// Get the ZEC->USD price from coinmarketcap using their API
void RPC::refreshZECPrice() {
if (conn == nullptr)
return noConnection();
QUrl cmcURL("https://api.coinmarketcap.com/v1/ticker/");
QNetworkRequest req;

7
src/rpc.h

@ -28,9 +28,11 @@ struct TransactionItem {
class RPC
{
public:
RPC(Connection* conn, MainWindow* main);
RPC(MainWindow* main);
~RPC();
void setConnection(Connection* c);
void refresh(bool force = false);
void refreshAddresses();
@ -49,7 +51,6 @@ public:
void newZaddr(bool sapling, const std::function<void(json)>& cb);
void newTaddr(const std::function<void(json)>& cb);
void getZPrivKey(QString addr, const std::function<void(json)>& cb);
void getTPrivKey(QString addr, const std::function<void(json)>& cb);
void importZPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb);
@ -107,6 +108,8 @@ public:
private:
void noConnection();
void doRPC (const json& payload, const std::function<void(json)>& cb);
void doSendRPC(const json& payload, const std::function<void(json)>& cb);
void doSendRPC(const json& payload, const std::function<void(json)>& cb, const std::function<void(QString)>& err);

106
src/settings.cpp

@ -6,9 +6,6 @@
Settings* Settings::instance = nullptr;
Settings::~Settings() {
delete defaults;
delete zcashconf;
delete uisettings;
}
bool Settings::getSaveZtxs() {
@ -24,27 +21,6 @@ Settings* Settings::init() {
if (instance == nullptr)
instance = new Settings();
// There are 3 possible configurations
// 1. The defaults
instance->defaults = new Config{ "127.0.0.1", "8232", "", "" };
// 2. From the UI settings
auto settingsFound = instance->loadFromSettings();
// 3. From the zcash.conf file
auto confFound = instance->loadFromFile();
// zcash.conf (#3) is first priority if it exists
if (confFound) {
instance->currentConfig = instance->zcashconf;
}
else if (settingsFound) {
instance->currentConfig = instance->uisettings;
}
else {
instance->currentConfig = instance->defaults;
}
return instance;
}
@ -52,23 +28,7 @@ Settings* Settings::getInstance() {
return instance;
}
QString Settings::getHost() {
return currentConfig->host;
}
QString Settings::getPort() {
return currentConfig->port;
}
QString Settings::getUsernamePassword() {
return currentConfig->rpcuser % ":" % currentConfig->rpcpassword;
}
bool Settings::loadFromSettings() {
delete uisettings;
Config Settings::getSettings() {
// Load from the QT Settings.
QSettings s;
@ -77,9 +37,7 @@ bool Settings::loadFromSettings() {
auto username = s.value("connection/rpcuser").toString();
auto password = s.value("connection/rpcpassword").toString();
uisettings = new Config{host, port, username, password};
return !username.isEmpty();
return Config{host, port, username, password};
}
void Settings::saveSettings(const QString& host, const QString& port, const QString& username, const QString& password) {
@ -96,63 +54,9 @@ void Settings::saveSettings(const QString& host, const QString& port, const QStr
init();
}
bool Settings::loadFromFile() {
delete zcashconf;
#ifdef Q_OS_LINUX
confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, ".zcash/zcash.conf");
#elif defined(Q_OS_DARWIN)
confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, "/Library/Application Support/Zcash/zcash.conf");
#else
confLocation = QStandardPaths::locate(QStandardPaths::AppDataLocation, "../../Zcash/zcash.conf");
#endif
confLocation = QDir::cleanPath(confLocation);
if (confLocation.isNull()) {
// No zcash file, just return with nothing
return false;
}
QFile file(confLocation);
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << file.errorString();
return false;
}
QTextStream in(&file);
zcashconf = new Config();
zcashconf->host = defaults->host;
while (!in.atEnd()) {
QString line = in.readLine();
auto s = line.indexOf("=");
QString name = line.left(s).trimmed().toLower();
QString value = line.right(line.length() - s - 1).trimmed();
if (name == "rpcuser") {
zcashconf->rpcuser = value;
}
if (name == "rpcpassword") {
zcashconf->rpcpassword = value;
}
if (name == "rpcport") {
zcashconf->port = value;
}
if (name == "testnet" &&
value == "1" &&
zcashconf->port.isEmpty()) {
zcashconf->port = "18232";
}
}
// If rpcport is not in the file, and it was not set by the testnet=1 flag, then go to default
if (zcashconf->port.isEmpty()) zcashconf->port = defaults->port;
file.close();
return true;
void Settings::setUsingZcashConf(QString confLocation) {
if (!confLocation.isEmpty())
_confLocation = confLocation;
}
bool Settings::isTestnet() {

29
src/settings.h

@ -16,14 +16,8 @@ public:
static Settings* init();
static Settings* getInstance();
QString getUsernamePassword();
QString getHost();
QString getPort();
bool loadFromSettings();
bool loadFromFile();
void saveSettings(const QString& host, const QString& port, const QString& username, const QString& password);
Config getSettings();
void saveSettings(const QString& host, const QString& port, const QString& username, const QString& password);
bool isTestnet();
void setTestnet(bool isTestnet);
@ -43,11 +37,13 @@ public:
bool isSaplingActive();
const QString& getZcashdConfLocation() { return confLocation; }
void setUsingZcashConf(QString confLocation);
const QString& getZcashdConfLocation() { return _confLocation; }
void setZECPrice(double p) { zecPrice = p; }
double getZECPrice();
QString getUSDFormat (double bal);
QString getZECDisplayFormat (double bal);
QString getZECUSDDisplayFormat(double bal);
@ -59,17 +55,10 @@ private:
static Settings* instance;
Config* currentConfig;
Config* defaults = nullptr;
Config* zcashconf = nullptr;
Config* uisettings = nullptr;
QString confLocation;
bool _isTestnet = false;
bool _isSyncing = false;
int _blockNumber = 0;
QString _confLocation;
bool _isTestnet = false;
bool _isSyncing = false;
int _blockNumber = 0;
double zecPrice = 0.0;
};

6
src/settings.ui

@ -20,7 +20,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -60,7 +60,7 @@
<item>
<widget class="QLineEdit" name="hostname">
<property name="placeholderText">
<string>127.0.0.1</string>
<string/>
</property>
</widget>
</item>
@ -80,7 +80,7 @@
<item>
<widget class="QLineEdit" name="port">
<property name="placeholderText">
<string>8232</string>
<string/>
</property>
</widget>
</item>

Loading…
Cancel
Save