mirror of
https://github.com/feather-wallet/feather.git
synced 2024-12-22 19:49:28 +00:00
Settings: allow configuring block explorer urls
This commit is contained in:
parent
a5ff6a3b67
commit
cf0c3b8d82
15 changed files with 397 additions and 95 deletions
|
@ -1237,7 +1237,11 @@ void MainWindow::payToMany() {
|
|||
}
|
||||
|
||||
void MainWindow::onViewOnBlockExplorer(const QString &txid) {
|
||||
QString blockExplorerLink = Utils::blockExplorerLink(conf()->get(Config::blockExplorer).toString(), constants::networkType, txid);
|
||||
QString blockExplorerLink = Utils::blockExplorerLink(txid);
|
||||
if (blockExplorerLink.isEmpty()) {
|
||||
Utils::showError(this, "Unable to open block explorer", "No block explorer configured", {"Go to Settings -> Misc -> Block explorer"});
|
||||
return;
|
||||
}
|
||||
Utils::externalLinkWarning(this, blockExplorerLink);
|
||||
}
|
||||
|
||||
|
|
|
@ -329,12 +329,7 @@ void Settings::setupPluginsTab() {
|
|||
|
||||
void Settings::setupMiscTab() {
|
||||
// [Block explorer]
|
||||
ui->comboBox_blockExplorer->setCurrentIndex(ui->comboBox_blockExplorer->findText(conf()->get(Config::blockExplorer).toString()));
|
||||
connect(ui->comboBox_blockExplorer, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]{
|
||||
QString blockExplorer = ui->comboBox_blockExplorer->currentText();
|
||||
conf()->set(Config::blockExplorer, blockExplorer);
|
||||
emit blockExplorerChanged(blockExplorer);
|
||||
});
|
||||
ui->blockExplorerConfigureWidget->setup("Block explorers", Config::blockExplorers, Config::blockExplorer, {"%txid%"});
|
||||
|
||||
// [Reddit frontend]
|
||||
ui->comboBox_redditFrontend->setCurrentIndex(ui->comboBox_redditFrontend->findText(conf()->get(Config::redditFrontend).toString()));
|
||||
|
|
|
@ -39,7 +39,6 @@ public:
|
|||
signals:
|
||||
void preferredFiatCurrencyChanged(QString currency);
|
||||
void skinChanged(QString skinName);
|
||||
void blockExplorerChanged(QString blockExplorer);
|
||||
void hideUpdateNotifications(bool hidden);
|
||||
void websocketStatusChanged(bool enabled);
|
||||
void proxySettingsChanged();
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>841</width>
|
||||
<width>908</width>
|
||||
<height>454</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -32,7 +32,7 @@
|
|||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>7</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_appearance">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
|
@ -1051,43 +1051,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_blockExplorer">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>exploremonero.com</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>xmrchain.net</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>melo.tools</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>moneroblocks.info</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>blockchair.info</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>blkchairbknpn73cfjhevhla7rkp4ed5gg2knctvv7it4lioy22defid.onion</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>127.0.0.1:31312</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="UrlListConfigureWidget" name="blockExplorerConfigureWidget" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_18">
|
||||
|
@ -1201,6 +1165,12 @@
|
|||
<header>widgets/PluginWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>UrlListConfigureWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>widgets/UrlListConfigureWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
|
|
39
src/dialog/MultiLineInputDialog.cpp
Normal file
39
src/dialog/MultiLineInputDialog.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
|
||||
|
||||
#include "MultiLineInputDialog.h"
|
||||
#include "ui_MultiLineInputDialog.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QFontMetrics>
|
||||
|
||||
#include "utils/Utils.h"
|
||||
|
||||
MultiLineInputDialog::MultiLineInputDialog(QWidget *parent, const QString &title, const QString &label, const QStringList &defaultList)
|
||||
: WindowModalDialog(parent)
|
||||
, ui(new Ui::MultiLineInputDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
this->setWindowTitle(title);
|
||||
ui->label->setText(label);
|
||||
|
||||
QFontMetrics metrics(ui->plainTextEdit->font());
|
||||
int maxWidth = 0;
|
||||
for (const QString &line : defaultList) {
|
||||
int width = metrics.boundingRect(line).width();
|
||||
maxWidth = qMax(maxWidth, width);
|
||||
}
|
||||
ui->plainTextEdit->setMinimumWidth(maxWidth + 10);
|
||||
|
||||
ui->plainTextEdit->setWordWrapMode(QTextOption::NoWrap);
|
||||
ui->plainTextEdit->setPlainText(defaultList.join("\n") + "\n");
|
||||
|
||||
this->adjustSize();
|
||||
}
|
||||
|
||||
QStringList MultiLineInputDialog::getList() {
|
||||
return ui->plainTextEdit->toPlainText().split("\n");
|
||||
}
|
||||
|
||||
MultiLineInputDialog::~MultiLineInputDialog() = default;
|
30
src/dialog/MultiLineInputDialog.h
Normal file
30
src/dialog/MultiLineInputDialog.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
|
||||
|
||||
#ifndef FEATHER_MULTILINEINPUTDIALOG_H
|
||||
#define FEATHER_MULTILINEINPUTDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "components.h"
|
||||
|
||||
namespace Ui {
|
||||
class MultiLineInputDialog;
|
||||
}
|
||||
|
||||
class MultiLineInputDialog : public WindowModalDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MultiLineInputDialog(QWidget *parent, const QString &title, const QString &label, const QStringList &defaultList);
|
||||
~MultiLineInputDialog() override;
|
||||
|
||||
QStringList getList();
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::MultiLineInputDialog> ui;
|
||||
};
|
||||
|
||||
|
||||
#endif //FEATHER_MULTILINEINPUTDIALOG_H
|
81
src/dialog/MultiLineInputDialog.ui
Normal file
81
src/dialog/MultiLineInputDialog.ui
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MultiLineInputDialog</class>
|
||||
<widget class="QDialog" name="MultiLineInputDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>663</width>
|
||||
<height>357</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="plainTextEdit">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>MultiLineInputDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>MultiLineInputDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -181,7 +181,14 @@ void TxInfoDialog::createTxProof() {
|
|||
}
|
||||
|
||||
void TxInfoDialog::viewOnBlockExplorer() {
|
||||
Utils::externalLinkWarning(this, Utils::blockExplorerLink(conf()->get(Config::blockExplorer).toString(), constants::networkType, m_txid));
|
||||
QString link = Utils::blockExplorerLink(m_txid);
|
||||
|
||||
if (link.isEmpty()) {
|
||||
Utils::showError(this, "Unable to open block explorer", "No block explorer configured", {"Go to Settings -> Misc -> Block explorer"});
|
||||
return;
|
||||
}
|
||||
|
||||
Utils::externalLinkWarning(this, link);
|
||||
}
|
||||
|
||||
TxInfoDialog::~TxInfoDialog() = default;
|
|
@ -461,53 +461,19 @@ QStandardItem *qStandardItem(const QString& text, QFont &font) {
|
|||
return item;
|
||||
}
|
||||
|
||||
QString blockExplorerLink(const QString &blockExplorer, NetworkType::Type nettype, const QString &txid) {
|
||||
if (blockExplorer == "exploremonero.com") {
|
||||
if (nettype == NetworkType::MAINNET) {
|
||||
return QString("https://exploremonero.com/transaction/%1").arg(txid);
|
||||
}
|
||||
}
|
||||
else if (blockExplorer == "moneroblocks.info") {
|
||||
if (nettype == NetworkType::MAINNET) {
|
||||
return QString("https://moneroblocks.info/tx/%1").arg(txid);
|
||||
}
|
||||
}
|
||||
else if (blockExplorer == "blockchair.com") {
|
||||
if (nettype == NetworkType::MAINNET) {
|
||||
return QString("https://blockchair.com/monero/transaction/%1").arg(txid);
|
||||
}
|
||||
}
|
||||
else if (blockExplorer == "melo.tools") {
|
||||
switch (nettype) {
|
||||
case NetworkType::MAINNET:
|
||||
return QString("https://melo.tools/explorer/mainnet/tx/%1").arg(txid);
|
||||
case NetworkType::STAGENET:
|
||||
return QString("https://melo.tools/explorer/stagenet/tx/%1").arg(txid);
|
||||
case NetworkType::TESTNET:
|
||||
return QString("https://melo.tools/explorer/testnet/tx/%1").arg(txid);
|
||||
}
|
||||
}
|
||||
else if (blockExplorer == "blkchairbknpn73cfjhevhla7rkp4ed5gg2knctvv7it4lioy22defid.onion") {
|
||||
if (nettype == NetworkType::MAINNET) {
|
||||
return QString("http://blkchairbknpn73cfjhevhla7rkp4ed5gg2knctvv7it4lioy22defid.onion/monero/transaction/%1").arg(txid);
|
||||
}
|
||||
}
|
||||
else if (blockExplorer == "127.0.0.1:31312") {
|
||||
if (nettype == NetworkType::MAINNET) {
|
||||
return QString("http://127.0.0.1:31312/tx?id=%1").arg(txid);
|
||||
}
|
||||
}
|
||||
|
||||
switch (nettype) {
|
||||
case NetworkType::MAINNET:
|
||||
return QString("https://xmrchain.net/tx/%1").arg(txid);
|
||||
case NetworkType::STAGENET:
|
||||
return QString("https://stagenet.xmrchain.net/tx/%1").arg(txid);
|
||||
case NetworkType::TESTNET:
|
||||
return QString("https://testnet.xmrchain.net/tx/%1").arg(txid);
|
||||
QString blockExplorerLink(const QString &txid) {
|
||||
QString link = conf()->get(Config::blockExplorer).toString();
|
||||
|
||||
QUrl url(link);
|
||||
if (url.scheme() != "http" && url.scheme() != "https") {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {};
|
||||
if (!link.contains("%txid%")) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return link.replace("%txid%", txid);
|
||||
}
|
||||
|
||||
void externalLinkWarning(QWidget *parent, const QString &url){
|
||||
|
|
|
@ -85,7 +85,7 @@ namespace Utils
|
|||
QStandardItem *qStandardItem(const QString &text);
|
||||
QStandardItem *qStandardItem(const QString &text, QFont &font);
|
||||
|
||||
QString blockExplorerLink(const QString &blockExplorer, NetworkType::Type nettype, const QString &txid);
|
||||
QString blockExplorerLink(const QString &txid);
|
||||
void externalLinkWarning(QWidget *parent, const QString &url);
|
||||
|
||||
QString displayAddress(const QString& address, int sections = 3, const QString & sep = " ");
|
||||
|
|
|
@ -93,7 +93,13 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
|
|||
{Config::writeStackTraceToDisk, {QS("writeStackTraceToDisk"), true}},
|
||||
{Config::writeRecentlyOpenedWallets, {QS("writeRecentlyOpenedWallets"), true}},
|
||||
|
||||
{Config::blockExplorer,{QS("blockExplorer"), "exploremonero.com"}},
|
||||
{Config::blockExplorers, {QS("blockExplorers"), QStringList{"https://xmrchain.net/tx/%txid%",
|
||||
"https://melo.tools/explorer/mainnet/tx/%txid%",
|
||||
"https://moneroblocks.info/tx/%txid%",
|
||||
"https://blockchair.com/monero/transaction/%txid%",
|
||||
"http://blkchairbknpn73cfjhevhla7rkp4ed5gg2knctvv7it4lioy22defid.onion/monero/transaction/%txid%",
|
||||
"http://127.0.0.1:31312/tx?id=%txid%"}}},
|
||||
{Config::blockExplorer,{QS("blockExplorer"), "https://xmrchain.net/tx/%txid%"}},
|
||||
{Config::redditFrontend, {QS("redditFrontend"), "old.reddit.com"}},
|
||||
{Config::localMoneroFrontend, {QS("localMoneroFrontend"), "https://localmonero.co"}},
|
||||
{Config::bountiesFrontend, {QS("bountiesFrontend"), "https://bounties.monero.social"}},
|
||||
|
|
|
@ -123,6 +123,7 @@ public:
|
|||
offlineTxSigningForceKISync,
|
||||
|
||||
// Misc
|
||||
blockExplorers,
|
||||
blockExplorer,
|
||||
redditFrontend,
|
||||
localMoneroFrontend,
|
||||
|
|
112
src/widgets/UrlListConfigureWidget.cpp
Normal file
112
src/widgets/UrlListConfigureWidget.cpp
Normal file
|
@ -0,0 +1,112 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
|
||||
|
||||
#include "UrlListConfigureWidget.h"
|
||||
#include "ui_UrlListConfigureWidget.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QWidget>
|
||||
#include <QInputDialog>
|
||||
|
||||
#include "dialog/MultiLineInputDialog.h"
|
||||
#include "utils/config.h"
|
||||
#include "utils/Utils.h"
|
||||
|
||||
UrlListConfigureWidget::UrlListConfigureWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::UrlListConfigureWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
void UrlListConfigureWidget::setup(const QString &what, Config::ConfigKey list, Config::ConfigKey preferred, const QStringList &keys) {
|
||||
m_what = what;
|
||||
m_listKey = list;
|
||||
m_preferredKey = preferred;
|
||||
m_keys = keys;
|
||||
|
||||
this->setupComboBox();
|
||||
|
||||
connect(ui->configure, &QPushButton::clicked, this, &UrlListConfigureWidget::onConfigureClicked);
|
||||
connect(ui->comboBox, &QComboBox::currentIndexChanged, this, &UrlListConfigureWidget::onUrlSelected);
|
||||
}
|
||||
|
||||
void UrlListConfigureWidget::onConfigureClicked() {
|
||||
QStringList list = conf()->get(m_listKey).toStringList();
|
||||
QStringList newList;
|
||||
|
||||
while (true) {
|
||||
auto input = MultiLineInputDialog(this, m_what, QString("Set %1 (one per line):").arg(m_what.toLower()), list);
|
||||
auto status = input.exec();
|
||||
|
||||
if (status == QDialog::Rejected) {
|
||||
break;
|
||||
}
|
||||
|
||||
newList = input.getList();
|
||||
newList.removeAll("");
|
||||
newList.removeDuplicates();
|
||||
|
||||
bool error = false;
|
||||
for (const auto& item : newList) {
|
||||
auto url = QUrl::fromUserInput(item);
|
||||
qDebug() << url.scheme();
|
||||
if (url.scheme() != "http" && url.scheme() != "https") {
|
||||
Utils::showError(this, QString("Invalid %1 entered").arg(m_what.toLower()), QString("Invalid URL: %1").arg(item));
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
for (const auto& key : m_keys) {
|
||||
if (!item.contains(key)) {
|
||||
Utils::showError(this, QString("Invalid %1 entered").arg(m_what.toLower()), QString("Key %1 missing from URL: %2").arg(key, item));
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
list = newList;
|
||||
continue;
|
||||
}
|
||||
|
||||
conf()->set(m_listKey, newList);
|
||||
this->setupComboBox();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UrlListConfigureWidget::setupComboBox() {
|
||||
m_urls = conf()->get(m_listKey).toStringList();
|
||||
|
||||
QStringList cleanList;
|
||||
for (const auto &item : m_urls) {
|
||||
QUrl url(item);
|
||||
cleanList << url.host();
|
||||
}
|
||||
|
||||
ui->comboBox->clear();
|
||||
ui->comboBox->insertItems(0, cleanList);
|
||||
|
||||
if (m_urls.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString preferred = conf()->get(m_preferredKey).toString();
|
||||
if (m_urls.contains(preferred)) {
|
||||
ui->comboBox->setCurrentIndex(m_urls.indexOf(preferred));
|
||||
}
|
||||
else {
|
||||
conf()->set(m_preferredKey, m_urls.at(0));
|
||||
}
|
||||
}
|
||||
|
||||
void UrlListConfigureWidget::onUrlSelected(int index) {
|
||||
if (index < 0 || index >= m_urls.length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
conf()->set(m_preferredKey, m_urls.at(index));
|
||||
}
|
||||
|
||||
UrlListConfigureWidget::~UrlListConfigureWidget() = default;
|
42
src/widgets/UrlListConfigureWidget.h
Normal file
42
src/widgets/UrlListConfigureWidget.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
|
||||
|
||||
#ifndef FEATHER_URLLISTCONFIGUREWIDGET_H
|
||||
#define FEATHER_URLLISTCONFIGUREWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTextEdit>
|
||||
|
||||
#include "utils/config.h"
|
||||
|
||||
namespace Ui {
|
||||
class UrlListConfigureWidget;
|
||||
}
|
||||
|
||||
class UrlListConfigureWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit UrlListConfigureWidget(QWidget *parent = nullptr);
|
||||
~UrlListConfigureWidget() override;
|
||||
|
||||
void setup(const QString &what, Config::ConfigKey list, Config::ConfigKey preferred, const QStringList& keys);
|
||||
|
||||
private slots:
|
||||
void onConfigureClicked();
|
||||
void onUrlSelected(int index);
|
||||
|
||||
private:
|
||||
void setupComboBox();
|
||||
|
||||
QScopedPointer<Ui::UrlListConfigureWidget> ui;
|
||||
|
||||
QString m_what;
|
||||
Config::ConfigKey m_listKey;
|
||||
Config::ConfigKey m_preferredKey;
|
||||
QStringList m_keys;
|
||||
QStringList m_urls;
|
||||
};
|
||||
|
||||
#endif //FEATHER_URLLISTCONFIGUREWIDGET_H
|
50
src/widgets/UrlListConfigureWidget.ui
Normal file
50
src/widgets/UrlListConfigureWidget.ui
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>UrlListConfigureWidget</class>
|
||||
<widget class="QWidget" name="UrlListConfigureWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>617</width>
|
||||
<height>27</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<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="QComboBox" name="comboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="configure">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
Reference in a new issue