mirror of
https://github.com/wownero/wowlet.git
synced 2026-10-27 11:18:43 +01:00
Plugins
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef PLUGIN_H
|
||||
#define PLUGIN_H
|
||||
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#include <QTabWidget>
|
||||
|
||||
#include "libwalletqt/Wallet.h"
|
||||
|
||||
class Plugin : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum PluginType {
|
||||
TAB = 0,
|
||||
WIDGET
|
||||
};
|
||||
|
||||
virtual QString id() = 0;
|
||||
|
||||
// Used for sorting
|
||||
virtual int idx() const = 0;
|
||||
|
||||
// id of parent plugin, plugin is only loaded if parent is available
|
||||
virtual QString parent() = 0;
|
||||
virtual QString displayName() = 0;
|
||||
virtual QString description() = 0;
|
||||
virtual QString icon() = 0;
|
||||
|
||||
// register expected websocket data
|
||||
virtual QStringList socketData() = 0;
|
||||
virtual PluginType type() = 0;
|
||||
virtual QWidget* tab() = 0;
|
||||
|
||||
virtual bool configurable() {return false;}
|
||||
virtual QDialog* configDialog(QWidget *parent) {return nullptr;}
|
||||
|
||||
// the plugin is automatically enabled if it has any enabled children
|
||||
virtual bool implicitEnable() {return false;}
|
||||
virtual bool requiresWebsocket() {return true;}
|
||||
|
||||
// insert tab to the left of standard tabs
|
||||
virtual bool insertFirst() {return false;}
|
||||
virtual void addSubPlugin(Plugin* plugin) {}
|
||||
|
||||
virtual void initialize(Wallet *wallet, QObject *parent) = 0;
|
||||
|
||||
bool hasParent() {return !parent().isEmpty();}
|
||||
|
||||
signals:
|
||||
void setStatusText(const QString &text, bool override, int timeout);
|
||||
void fillSendTab(const QString &address, const QString &description);
|
||||
|
||||
public slots:
|
||||
virtual void skinChanged() {}
|
||||
virtual void uiSetup() {}
|
||||
virtual void aboutToQuit() {}
|
||||
|
||||
protected:
|
||||
Wallet* m_wallet = nullptr;
|
||||
};
|
||||
|
||||
#endif //PLUGIN_H
|
||||
@@ -0,0 +1,79 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef PLUGINREGISTRY_H
|
||||
#define PLUGINREGISTRY_H
|
||||
|
||||
#include "Plugin.h"
|
||||
#include "utils/config.h"
|
||||
|
||||
class PluginRegistry {
|
||||
public:
|
||||
static void registerPlugin(Plugin* plugin) {
|
||||
getInstance().plugins.append(plugin);
|
||||
getInstance().pluginMap[plugin->id()] = plugin;
|
||||
|
||||
std::sort(getInstance().plugins.begin(), getInstance().plugins.end(), [](Plugin *a, Plugin *b) {
|
||||
return a->idx() < b->idx();
|
||||
});
|
||||
}
|
||||
|
||||
void registerPluginCreator(const std::function<Plugin*()>& creator) {
|
||||
plugin_creators.append(creator);
|
||||
}
|
||||
|
||||
static const QList<Plugin*>& getPlugins() {
|
||||
return getInstance().plugins;
|
||||
}
|
||||
|
||||
static Plugin* getPlugin(const QString& id) {
|
||||
return getInstance().pluginMap.value(id, nullptr);
|
||||
}
|
||||
|
||||
static const QList<std::function<Plugin*()>>& getPluginCreators() {
|
||||
return getInstance().plugin_creators;
|
||||
}
|
||||
|
||||
bool isPluginEnabled(const QString &id) {
|
||||
if (!pluginMap.contains(id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Plugin* plugin = pluginMap[id];
|
||||
|
||||
// Don't load plugins that require the websocket connection if it is disabled
|
||||
bool websocketDisabled = conf()->get(Config::disableWebsocket).toBool();
|
||||
if (websocketDisabled && plugin->requiresWebsocket()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList enabledPlugins = conf()->get(Config::enabledPlugins).toStringList();
|
||||
if (enabledPlugins.contains(id) && !plugin->implicitEnable()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool enabled = false;
|
||||
if (plugin->implicitEnable()) {
|
||||
for (const auto& child : plugins) {
|
||||
if (child->parent() == plugin->id() && enabledPlugins.contains(child->id())) {
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
private:
|
||||
QMap<QString, Plugin*> pluginMap;
|
||||
QList<Plugin*> plugins;
|
||||
QList<std::function<Plugin*()>> plugin_creators;
|
||||
|
||||
public:
|
||||
static PluginRegistry& getInstance() {
|
||||
static PluginRegistry instance;
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //PLUGINREGISTRY_H
|
||||
@@ -50,15 +50,23 @@ QVariant BountiesModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
QSharedPointer<BountyEntry> post = m_bounties.at(index.row());
|
||||
|
||||
if(role == Qt::DisplayRole) {
|
||||
if(role == Qt::DisplayRole || role == Qt::UserRole) {
|
||||
switch(index.column()) {
|
||||
case Votes:
|
||||
case Votes: {
|
||||
if (role == Qt::UserRole) {
|
||||
return post->votes;
|
||||
}
|
||||
return QString::number(post->votes);
|
||||
}
|
||||
case Title:
|
||||
return post->title;
|
||||
case Status:
|
||||
return post->status;
|
||||
case Bounty: {
|
||||
if (role == Qt::UserRole) {
|
||||
return post->bountyAmount;
|
||||
}
|
||||
|
||||
if (post->bountyAmount > 0) {
|
||||
return QString("%1 XMR").arg(QString::number(post->bountyAmount, 'f', 5));
|
||||
}
|
||||
@@ -90,7 +98,7 @@ QVariant BountiesModel::headerData(int section, Qt::Orientation orientation, int
|
||||
{
|
||||
switch(section) {
|
||||
case Votes:
|
||||
return QString(" 🡅 ");
|
||||
return QString("Score ");
|
||||
case Title:
|
||||
return QString("Title");
|
||||
case Status:
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "BountiesPlugin.h"
|
||||
|
||||
#include "plugins/PluginRegistry.h"
|
||||
#include "BountiesWidget.h"
|
||||
|
||||
BountiesPlugin::BountiesPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
void BountiesPlugin::initialize(Wallet *wallet, QObject *parent) {
|
||||
this->setParent(parent);
|
||||
m_tab = new BountiesWidget(nullptr);
|
||||
connect(m_tab, &BountiesWidget::donate, this, &Plugin::fillSendTab);
|
||||
}
|
||||
|
||||
QString BountiesPlugin::id() {
|
||||
return "bounties";
|
||||
}
|
||||
|
||||
int BountiesPlugin::idx() const {
|
||||
return 20;
|
||||
}
|
||||
|
||||
QString BountiesPlugin::parent() {
|
||||
return "home";
|
||||
}
|
||||
|
||||
QString BountiesPlugin::displayName() {
|
||||
return "Bounties";
|
||||
}
|
||||
|
||||
QString BountiesPlugin::description() {
|
||||
return "";
|
||||
}
|
||||
|
||||
QString BountiesPlugin::icon() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList BountiesPlugin::socketData() {
|
||||
return {"bounties"};
|
||||
}
|
||||
|
||||
Plugin::PluginType BountiesPlugin::type() {
|
||||
return Plugin::PluginType::TAB;
|
||||
}
|
||||
|
||||
QWidget* BountiesPlugin::tab() {
|
||||
return m_tab;
|
||||
}
|
||||
|
||||
const bool BountiesPlugin::registered = [] {
|
||||
PluginRegistry::registerPlugin(BountiesPlugin::create());
|
||||
PluginRegistry::getInstance().registerPluginCreator(&BountiesPlugin::create);
|
||||
return true;
|
||||
}();
|
||||
@@ -0,0 +1,36 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef BOUNTIESPLUGIN_H
|
||||
#define BOUNTIESPLUGIN_H
|
||||
|
||||
#include "plugins/Plugin.h"
|
||||
#include "BountiesWidget.h"
|
||||
|
||||
class BountiesPlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BountiesPlugin();
|
||||
|
||||
QString id() override;
|
||||
int idx() const override;
|
||||
QString parent() override;
|
||||
QString displayName() override;
|
||||
QString description() override;
|
||||
QString icon() override;
|
||||
QStringList socketData() override;
|
||||
PluginType type() override;
|
||||
QWidget* tab() override;
|
||||
|
||||
void initialize(Wallet *wallet, QObject *parent) override;
|
||||
|
||||
static BountiesPlugin* create() { return new BountiesPlugin(); }
|
||||
|
||||
private:
|
||||
BountiesWidget* m_tab = nullptr;
|
||||
static const bool registered;
|
||||
};
|
||||
|
||||
|
||||
#endif //BOUNTIESPLUGIN_H
|
||||
@@ -0,0 +1,10 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "BountiesProxyModel.h"
|
||||
|
||||
BountiesProxyModel::BountiesProxyModel(QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
setSortRole(Qt::UserRole);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef BOUNTIESPROXYMODEL_H
|
||||
#define BOUNTIESPROXYMODEL_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class BountiesProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BountiesProxyModel(QObject* parent = nullptr);
|
||||
};
|
||||
|
||||
#endif //BOUNTIESPROXYMODEL_H
|
||||
@@ -4,13 +4,12 @@
|
||||
#include "BountiesWidget.h"
|
||||
#include "ui_BountiesWidget.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QStandardItemModel>
|
||||
#include <QTableWidget>
|
||||
|
||||
#include "BountiesModel.h"
|
||||
#include "utils/Utils.h"
|
||||
#include "utils/config.h"
|
||||
#include "utils/WebsocketNotifier.h"
|
||||
|
||||
BountiesWidget::BountiesWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
@@ -19,7 +18,13 @@ BountiesWidget::BountiesWidget(QWidget *parent)
|
||||
, m_contextMenu(new QMenu(this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tableView->setModel(m_model);
|
||||
|
||||
m_proxyModel = new BountiesProxyModel(this);
|
||||
m_proxyModel->setSourceModel(m_model);
|
||||
|
||||
ui->tableView->setModel(m_proxyModel);
|
||||
ui->tableView->setSortingEnabled(true);
|
||||
ui->tableView->sortByColumn(3, Qt::DescendingOrder);
|
||||
this->setupTable();
|
||||
|
||||
m_contextMenu->addAction("View Bounty", this, &BountiesWidget::linkClicked);
|
||||
@@ -28,15 +33,32 @@ BountiesWidget::BountiesWidget(QWidget *parent)
|
||||
|
||||
connect(ui->tableView, &QTableView::doubleClicked, this, &BountiesWidget::linkClicked);
|
||||
|
||||
connect(websocketNotifier(), &WebsocketNotifier::dataReceived, this, [this](const QString &type, const QJsonValue &json) {
|
||||
if (type == "bounties") {
|
||||
QJsonArray bounties_data = json.toArray();
|
||||
QList<QSharedPointer<BountyEntry>> l;
|
||||
|
||||
for (const auto& entry : bounties_data) {
|
||||
QJsonObject obj = entry.toObject();
|
||||
auto bounty = new BountyEntry(obj.value("votes").toInt(),
|
||||
obj.value("title").toString(),
|
||||
obj.value("amount").toDouble(),
|
||||
obj.value("link").toString(),
|
||||
obj.value("address").toString(),
|
||||
obj.value("status").toString());
|
||||
QSharedPointer<BountyEntry> b = QSharedPointer<BountyEntry>(bounty);
|
||||
l.append(b);
|
||||
}
|
||||
|
||||
m_model->updateBounties(l);
|
||||
}
|
||||
});
|
||||
|
||||
ui->tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
}
|
||||
|
||||
BountiesModel * BountiesWidget::model() {
|
||||
return m_model;
|
||||
}
|
||||
|
||||
void BountiesWidget::linkClicked() {
|
||||
QModelIndex index = ui->tableView->currentIndex();
|
||||
QModelIndex index = m_proxyModel->mapToSource(ui->tableView->currentIndex());
|
||||
auto post = m_model->post(index.row());
|
||||
|
||||
if (post)
|
||||
@@ -44,7 +66,7 @@ void BountiesWidget::linkClicked() {
|
||||
}
|
||||
|
||||
void BountiesWidget::donateClicked() {
|
||||
QModelIndex index = ui->tableView->currentIndex();
|
||||
QModelIndex index = m_proxyModel->mapToSource(ui->tableView->currentIndex());
|
||||
auto bounty = m_model->post(index.row());
|
||||
|
||||
if (bounty) {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <QWidget>
|
||||
|
||||
#include "BountiesModel.h"
|
||||
#include "BountiesProxyModel.h"
|
||||
|
||||
namespace Ui {
|
||||
class BountiesWidget;
|
||||
@@ -21,7 +22,6 @@ class BountiesWidget : public QWidget
|
||||
public:
|
||||
explicit BountiesWidget(QWidget *parent = nullptr);
|
||||
~BountiesWidget() override;
|
||||
BountiesModel* model();
|
||||
|
||||
public slots:
|
||||
void linkClicked();
|
||||
@@ -38,6 +38,7 @@ private:
|
||||
|
||||
QScopedPointer<Ui::BountiesWidget> ui;
|
||||
BountiesModel *m_model;
|
||||
BountiesProxyModel *m_proxyModel;
|
||||
QMenu *m_contextMenu;
|
||||
};
|
||||
|
||||
|
||||
@@ -31,6 +31,12 @@
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "CalcConfigDialog.h"
|
||||
#include "ui_CalcConfigDialog.h"
|
||||
|
||||
#include "utils/AppData.h"
|
||||
#include "utils/config.h"
|
||||
|
||||
CalcConfigDialog::CalcConfigDialog(QWidget *parent)
|
||||
: WindowModalDialog(parent)
|
||||
, ui(new Ui::CalcConfigDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
this->fillListWidgets();
|
||||
|
||||
connect(ui->btn_selectAll, &QPushButton::clicked, this, &CalcConfigDialog::selectAll);
|
||||
connect(ui->btn_deselectAll, &QPushButton::clicked, this, &CalcConfigDialog::deselectAll);
|
||||
|
||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, [this]{
|
||||
conf()->set(Config::fiatSymbols, this->checkedFiat());
|
||||
conf()->set(Config::cryptoSymbols, this->checkedCrypto());
|
||||
this->accept();
|
||||
});
|
||||
|
||||
this->adjustSize();
|
||||
}
|
||||
|
||||
QStringList CalcConfigDialog::checkedFiat() {
|
||||
return this->getChecked(ui->list_fiat);
|
||||
}
|
||||
|
||||
QStringList CalcConfigDialog::checkedCrypto() {
|
||||
return this->getChecked(ui->list_crypto);
|
||||
}
|
||||
|
||||
void CalcConfigDialog::selectAll() {
|
||||
this->setCheckState(this->getVisibleListWidget(), Qt::Checked);
|
||||
}
|
||||
|
||||
void CalcConfigDialog::deselectAll() {
|
||||
this->setCheckState(this->getVisibleListWidget(), Qt::Unchecked);
|
||||
}
|
||||
|
||||
void CalcConfigDialog::setCheckState(QListWidget *widget, Qt::CheckState checkState) {
|
||||
QListWidgetItem *item;
|
||||
for (int i=0; i < widget->count(); i++) {
|
||||
item = widget->item(i);
|
||||
item->setCheckState(checkState);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList CalcConfigDialog::getChecked(QListWidget *widget) {
|
||||
QStringList checked;
|
||||
QListWidgetItem *item;
|
||||
for (int i=0; i < widget->count(); i++) {
|
||||
item = widget->item(i);
|
||||
if (item->checkState() == Qt::Checked) {
|
||||
checked.append(item->text());
|
||||
}
|
||||
}
|
||||
return checked;
|
||||
}
|
||||
|
||||
QListWidget* CalcConfigDialog::getVisibleListWidget() {
|
||||
if (ui->tabWidget->currentIndex() == 0) {
|
||||
return ui->list_fiat;
|
||||
} else {
|
||||
return ui->list_crypto;
|
||||
}
|
||||
}
|
||||
|
||||
void CalcConfigDialog::fillListWidgets() {
|
||||
QStringList cryptoCurrencies = appData()->prices.markets.keys();
|
||||
QStringList fiatCurrencies = appData()->prices.rates.keys();
|
||||
|
||||
QStringList checkedCryptoCurrencies = conf()->get(Config::cryptoSymbols).toStringList();
|
||||
QStringList checkedFiatCurrencies = conf()->get(Config::fiatSymbols).toStringList();
|
||||
|
||||
ui->list_crypto->addItems(cryptoCurrencies);
|
||||
ui->list_fiat->addItems(fiatCurrencies);
|
||||
|
||||
auto setChecked = [](QListWidget *widget, const QStringList &checked){
|
||||
QListWidgetItem *item;
|
||||
for (int i=0; i < widget->count(); i++) {
|
||||
item = widget->item(i);
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
if (checked.contains(item->text())) {
|
||||
item->setCheckState(Qt::Checked);
|
||||
} else {
|
||||
item->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setChecked(ui->list_crypto, checkedCryptoCurrencies);
|
||||
setChecked(ui->list_fiat, checkedFiatCurrencies);
|
||||
}
|
||||
|
||||
CalcConfigDialog::~CalcConfigDialog() = default;
|
||||
@@ -0,0 +1,41 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef FEATHER_CALCCONFIGDIALOG_H
|
||||
#define FEATHER_CALCCONFIGDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QListWidget>
|
||||
|
||||
#include "components.h"
|
||||
|
||||
namespace Ui {
|
||||
class CalcConfigDialog;
|
||||
}
|
||||
|
||||
class CalcConfigDialog : public WindowModalDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CalcConfigDialog(QWidget *parent = nullptr);
|
||||
~CalcConfigDialog() override;
|
||||
|
||||
QStringList checkedFiat();
|
||||
QStringList checkedCrypto();
|
||||
|
||||
private slots:
|
||||
void selectAll();
|
||||
void deselectAll();
|
||||
|
||||
private:
|
||||
void setCheckState(QListWidget *widget, Qt::CheckState checkState);
|
||||
QStringList getChecked(QListWidget *widget);
|
||||
void fillListWidgets();
|
||||
QListWidget* getVisibleListWidget();
|
||||
|
||||
QScopedPointer<Ui::CalcConfigDialog> ui;
|
||||
};
|
||||
|
||||
|
||||
#endif //FEATHER_CALCCONFIGDIALOG_H
|
||||
@@ -0,0 +1,153 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CalcConfigDialog</class>
|
||||
<widget class="QDialog" name="CalcConfigDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>509</width>
|
||||
<height>574</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Calc config</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Fiat</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<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="QListWidget" name="list_fiat"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Crypto</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<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="QListWidget" name="list_crypto"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_selectAll">
|
||||
<property name="text">
|
||||
<string>Select all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_deselectAll">
|
||||
<property name="text">
|
||||
<string>Deselect all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</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>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>CalcConfigDialog</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>CalcConfigDialog</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>
|
||||
@@ -0,0 +1,70 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "CalcPlugin.h"
|
||||
#include "CalcConfigDialog.h"
|
||||
|
||||
#include "plugins/PluginRegistry.h"
|
||||
|
||||
CalcPlugin::CalcPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
void CalcPlugin::initialize(Wallet *wallet, QObject *parent) {
|
||||
this->setParent(parent);
|
||||
m_tab = new CalcWidget(nullptr);
|
||||
}
|
||||
|
||||
QString CalcPlugin::id() {
|
||||
return "calc";
|
||||
}
|
||||
|
||||
int CalcPlugin::idx() const {
|
||||
return 60;
|
||||
}
|
||||
|
||||
QString CalcPlugin::parent() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString CalcPlugin::displayName() {
|
||||
return "Calc";
|
||||
}
|
||||
|
||||
QString CalcPlugin::description() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString CalcPlugin::icon() {
|
||||
return "gnome-calc.png";
|
||||
}
|
||||
|
||||
QStringList CalcPlugin::socketData() {
|
||||
return {};
|
||||
}
|
||||
|
||||
Plugin::PluginType CalcPlugin::type() {
|
||||
return Plugin::PluginType::TAB;
|
||||
}
|
||||
|
||||
QWidget* CalcPlugin::tab() {
|
||||
return m_tab;
|
||||
}
|
||||
|
||||
bool CalcPlugin::configurable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
QDialog* CalcPlugin::configDialog(QWidget *parent) {
|
||||
return new CalcConfigDialog{parent};
|
||||
}
|
||||
|
||||
void CalcPlugin::skinChanged() {
|
||||
m_tab->skinChanged();
|
||||
}
|
||||
|
||||
const bool CalcPlugin::registered = [] {
|
||||
PluginRegistry::registerPlugin(CalcPlugin::create());
|
||||
PluginRegistry::getInstance().registerPluginCreator(&CalcPlugin::create);
|
||||
return true;
|
||||
}();
|
||||
@@ -0,0 +1,41 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef CALCPLUGIN_H
|
||||
#define CALCPLUGIN_H
|
||||
|
||||
#include "plugins/Plugin.h"
|
||||
#include "CalcWidget.h"
|
||||
|
||||
class CalcPlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CalcPlugin();
|
||||
|
||||
QString id() override;
|
||||
int idx() const override;
|
||||
QString parent() override;
|
||||
QString displayName() override;
|
||||
QString description() override;
|
||||
QString icon() override;
|
||||
QStringList socketData() override;
|
||||
PluginType type() override;
|
||||
QWidget* tab() override;
|
||||
bool configurable() override;
|
||||
QDialog* configDialog(QWidget *parent) override;
|
||||
|
||||
void initialize(Wallet *wallet, QObject *parent) override;
|
||||
|
||||
static CalcPlugin* create() { return new CalcPlugin(); }
|
||||
|
||||
public slots:
|
||||
void skinChanged() override;
|
||||
|
||||
private:
|
||||
CalcWidget* m_tab = nullptr;
|
||||
static const bool registered;
|
||||
};
|
||||
|
||||
|
||||
#endif //CALCPLUGIN_H
|
||||
@@ -0,0 +1,170 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "CalcWidget.h"
|
||||
#include "ui_CalcWidget.h"
|
||||
|
||||
#include <QList>
|
||||
|
||||
#include "CalcConfigDialog.h"
|
||||
#include "utils/AppData.h"
|
||||
#include "utils/ColorScheme.h"
|
||||
#include "utils/config.h"
|
||||
#include "utils/WebsocketNotifier.h"
|
||||
|
||||
CalcWidget::CalcWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::CalcWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->imageExchange->setBackgroundRole(QPalette::Base);
|
||||
ui->imageExchange->setAssets(":/assets/images/exchange.png", ":/assets/images/exchange_white.png");
|
||||
ui->imageExchange->setScaledContents(true);
|
||||
ui->imageExchange->setFixedSize(26, 26);
|
||||
|
||||
// validator/locale for input
|
||||
QString amount_rx = R"(^\d{0,8}[\.]\d{0,12}$)";
|
||||
QRegularExpression rx;
|
||||
rx.setPattern(amount_rx);
|
||||
QValidator *validator = new QRegularExpressionValidator(rx, this);
|
||||
ui->lineFrom->setValidator(validator);
|
||||
ui->lineTo->setValidator(validator);
|
||||
|
||||
connect(&appData()->prices, &Prices::fiatPricesUpdated, this, &CalcWidget::onPricesReceived);
|
||||
connect(&appData()->prices, &Prices::cryptoPricesUpdated, this, &CalcWidget::onPricesReceived);
|
||||
|
||||
connect(ui->lineFrom, &QLineEdit::textEdited, this, [this]{this->convert(false);});
|
||||
connect(ui->lineTo, &QLineEdit::textEdited, this, [this]{this->convert(true);});
|
||||
|
||||
connect(ui->comboCalcFrom, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]{this->convert(false);});
|
||||
connect(ui->comboCalcTo, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]{this->convert(false);});
|
||||
|
||||
connect(ui->btn_configure, &QPushButton::clicked, this, &CalcWidget::showCalcConfigureDialog);
|
||||
|
||||
QTimer::singleShot(1, [this]{
|
||||
this->skinChanged();
|
||||
});
|
||||
|
||||
m_statusTimer.start(5000);
|
||||
connect(&m_statusTimer, &QTimer::timeout, this, &CalcWidget::updateStatus);
|
||||
QPixmap warningIcon = QPixmap(":/assets/images/warning.png");
|
||||
ui->icon_warning->setPixmap(warningIcon.scaledToWidth(32, Qt::SmoothTransformation));
|
||||
|
||||
this->updateStatus();
|
||||
}
|
||||
|
||||
void CalcWidget::convert(bool reverse) {
|
||||
if (!m_comboBoxInit)
|
||||
return;
|
||||
|
||||
auto lineFrom = reverse ? ui->lineTo : ui->lineFrom;
|
||||
auto lineTo = reverse ? ui->lineFrom : ui->lineTo;
|
||||
|
||||
auto comboFrom = reverse ? ui->comboCalcTo : ui->comboCalcFrom;
|
||||
auto comboTo = reverse ? ui->comboCalcFrom : ui->comboCalcTo;
|
||||
|
||||
QString symbolFrom = comboFrom->itemText(comboFrom->currentIndex());
|
||||
QString symbolTo = comboTo->itemText(comboTo->currentIndex());
|
||||
|
||||
if (symbolFrom == symbolTo) {
|
||||
lineTo->setText(lineFrom->text());
|
||||
}
|
||||
|
||||
QString amountStr = lineFrom->text();
|
||||
double amount = amountStr.toDouble();
|
||||
double result = appData()->prices.convert(symbolFrom, symbolTo, amount);
|
||||
|
||||
int precision = 10;
|
||||
if (appData()->prices.rates.contains(symbolTo))
|
||||
precision = 2;
|
||||
|
||||
lineTo->setText(QString::number(result, 'f', precision));
|
||||
}
|
||||
|
||||
void CalcWidget::onPricesReceived() {
|
||||
if (m_comboBoxInit)
|
||||
return;
|
||||
|
||||
QList<QString> cryptoKeys = appData()->prices.markets.keys();
|
||||
QList<QString> fiatKeys = appData()->prices.rates.keys();
|
||||
if (cryptoKeys.empty() || fiatKeys.empty())
|
||||
return;
|
||||
|
||||
ui->btn_configure->setEnabled(true);
|
||||
this->initComboBox();
|
||||
m_comboBoxInit = true;
|
||||
this->updateStatus();
|
||||
}
|
||||
|
||||
void CalcWidget::initComboBox() {
|
||||
QList<QString> cryptoKeys = appData()->prices.markets.keys();
|
||||
QList<QString> fiatKeys = appData()->prices.rates.keys();
|
||||
|
||||
QStringList enabledCrypto = conf()->get(Config::cryptoSymbols).toStringList();
|
||||
QStringList filteredCryptoKeys;
|
||||
for (const auto& symbol : cryptoKeys) {
|
||||
if (enabledCrypto.contains(symbol)) {
|
||||
filteredCryptoKeys.append(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList enabledFiat = conf()->get(Config::fiatSymbols).toStringList();
|
||||
auto preferredFiat = conf()->get(Config::preferredFiatCurrency).toString();
|
||||
if (!enabledFiat.contains(preferredFiat) && fiatKeys.contains(preferredFiat)) {
|
||||
enabledFiat.append(preferredFiat);
|
||||
conf()->set(Config::fiatSymbols, enabledFiat);
|
||||
}
|
||||
QStringList filteredFiatKeys;
|
||||
for (const auto &symbol : fiatKeys) {
|
||||
if (enabledFiat.contains(symbol)) {
|
||||
filteredFiatKeys.append(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
this->setupComboBox(ui->comboCalcFrom, filteredCryptoKeys, filteredFiatKeys);
|
||||
this->setupComboBox(ui->comboCalcTo, filteredCryptoKeys, filteredFiatKeys);
|
||||
|
||||
ui->comboCalcFrom->setCurrentIndex(ui->comboCalcFrom->findText("XMR"));
|
||||
|
||||
if (!preferredFiat.isEmpty()) {
|
||||
ui->comboCalcTo->setCurrentIndex(ui->comboCalcTo->findText(preferredFiat));
|
||||
} else {
|
||||
ui->comboCalcTo->setCurrentIndex(ui->comboCalcTo->findText("USD"));
|
||||
}
|
||||
}
|
||||
|
||||
void CalcWidget::skinChanged() {
|
||||
ui->imageExchange->setMode(ColorScheme::hasDarkBackground(this));
|
||||
}
|
||||
|
||||
void CalcWidget::showCalcConfigureDialog() {
|
||||
CalcConfigDialog dialog{this};
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
this->initComboBox();
|
||||
}
|
||||
}
|
||||
|
||||
void CalcWidget::setupComboBox(QComboBox *comboBox, const QStringList &crypto, const QStringList &fiat) {
|
||||
comboBox->clear();
|
||||
comboBox->addItems(crypto);
|
||||
comboBox->insertSeparator(comboBox->count());
|
||||
comboBox->addItems(fiat);
|
||||
}
|
||||
|
||||
void CalcWidget::updateStatus() {
|
||||
if (!m_comboBoxInit) {
|
||||
ui->label_warning->setText("Waiting on exchange data.");
|
||||
ui->frame_warning->show();
|
||||
}
|
||||
else if (websocketNotifier()->stale(10)) {
|
||||
ui->label_warning->setText("No new exchange rates received for over 10 minutes.");
|
||||
ui->frame_warning->show();
|
||||
}
|
||||
else {
|
||||
ui->frame_warning->hide();
|
||||
}
|
||||
}
|
||||
|
||||
CalcWidget::~CalcWidget() = default;
|
||||
@@ -0,0 +1,41 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef FEATHER_CALCWIDGET_H
|
||||
#define FEATHER_CALCWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QComboBox>
|
||||
#include <QTimer>
|
||||
|
||||
namespace Ui {
|
||||
class CalcWidget;
|
||||
}
|
||||
|
||||
class CalcWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CalcWidget(QWidget *parent = nullptr);
|
||||
~CalcWidget() override;
|
||||
|
||||
public slots:
|
||||
void skinChanged();
|
||||
|
||||
private slots:
|
||||
void initComboBox();
|
||||
void showCalcConfigureDialog();
|
||||
void onPricesReceived();
|
||||
|
||||
private:
|
||||
void convert(bool reverse);
|
||||
void setupComboBox(QComboBox *comboBox, const QStringList &crypto, const QStringList &fiat);
|
||||
void updateStatus();
|
||||
|
||||
QScopedPointer<Ui::CalcWidget> ui;
|
||||
bool m_comboBoxInit = false;
|
||||
QTimer m_statusTimer;
|
||||
};
|
||||
|
||||
#endif // FEATHER_CALCWIDGET_H
|
||||
@@ -0,0 +1,187 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CalcWidget</class>
|
||||
<widget class="QWidget" name="CalcWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>366</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_warning">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="icon_warning">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>icon</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Maximum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_warning">
|
||||
<property name="text">
|
||||
<string>Warning text</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="horizontalSpacing">
|
||||
<number>18</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineFrom">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>From...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboCalcFrom"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="DoublePixmapLabel" name="imageExchange">
|
||||
<property name="text">
|
||||
<string>exchange image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineTo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>To...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboCalcTo"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_configure">
|
||||
<property name="text">
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>DoublePixmapLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>components.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<slots>
|
||||
<slot>fromChanged(QString)</slot>
|
||||
<slot>toChanged(QString)</slot>
|
||||
<slot>toComboChanged(QString)</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "CalcWindow.h"
|
||||
#include "ui_CalcWindow.h"
|
||||
|
||||
#include "utils/AppData.h"
|
||||
#include "utils/Icons.h"
|
||||
|
||||
CalcWindow::CalcWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::CalcWindow)
|
||||
{
|
||||
Qt::WindowFlags flags = this->windowFlags();
|
||||
this->setWindowFlags(flags|Qt::WindowStaysOnTopHint); // on top
|
||||
|
||||
ui->setupUi(this);
|
||||
this->setWindowIcon(icons()->icon("gnome-calc.png"));
|
||||
}
|
||||
|
||||
CalcWindow::~CalcWindow() = default;
|
||||
@@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef FEATHER_CALCWINDOW_H
|
||||
#define FEATHER_CALCWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
namespace Ui {
|
||||
class CalcWindow;
|
||||
}
|
||||
|
||||
class CalcWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CalcWindow(QWidget *parent = nullptr);
|
||||
~CalcWindow() override;
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::CalcWindow> ui;
|
||||
};
|
||||
|
||||
#endif // FEATHER_CALCWINDOW_H
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CalcWindow</class>
|
||||
<widget class="QMainWindow" name="CalcWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>520</width>
|
||||
<height>108</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Calculator</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="CalcWidget" name="calcWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>CalcWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>plugins/calc/CalcWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<slots>
|
||||
<slot>stayOnTop(int)</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
@@ -1,64 +0,0 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "CCSWidget.h"
|
||||
#include "ui_CCSWidget.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QStandardItemModel>
|
||||
#include <QTableWidget>
|
||||
|
||||
#include "CCSProgressDelegate.h"
|
||||
#include "utils/Utils.h"
|
||||
|
||||
CCSWidget::CCSWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::CSSWidget)
|
||||
, m_model(new CCSModel(this))
|
||||
, m_contextMenu(new QMenu(this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->treeView->setModel(m_model);
|
||||
|
||||
m_contextMenu->addAction("View proposal", this, &CCSWidget::linkClicked);
|
||||
m_contextMenu->addAction("Donate", this, &CCSWidget::donateClicked);
|
||||
|
||||
connect(ui->treeView, &QHeaderView::customContextMenuRequested, this, &CCSWidget::showContextMenu);
|
||||
connect(ui->treeView, &QTreeView::doubleClicked, this, &CCSWidget::linkClicked);
|
||||
|
||||
ui->treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
ui->treeView->header()->setSectionResizeMode(CCSModel::Title, QHeaderView::Stretch);
|
||||
}
|
||||
|
||||
CCSModel* CCSWidget::model() {
|
||||
return m_model;
|
||||
}
|
||||
|
||||
void CCSWidget::linkClicked() {
|
||||
QModelIndex index = ui->treeView->currentIndex();
|
||||
auto entry = m_model->entry(index.row());
|
||||
|
||||
if (entry) {
|
||||
Utils::externalLinkWarning(this, entry->url);
|
||||
}
|
||||
}
|
||||
|
||||
void CCSWidget::donateClicked() {
|
||||
QModelIndex index = ui->treeView->currentIndex();
|
||||
auto entry = m_model->entry(index.row());
|
||||
|
||||
if (entry)
|
||||
emit selected(*entry);
|
||||
}
|
||||
|
||||
void CCSWidget::showContextMenu(const QPoint &pos) {
|
||||
QModelIndex index = ui->treeView->indexAt(pos);
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_contextMenu->exec(ui->treeView->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
CCSWidget::~CCSWidget() = default;
|
||||
@@ -78,7 +78,7 @@ QVariant CCSModel::headerData(int section, Qt::Orientation orientation, int role
|
||||
case Title:
|
||||
return QString("Proposal");
|
||||
case Organizer:
|
||||
return QString("Organizer");
|
||||
return QString("Organizer ");
|
||||
case Author:
|
||||
return QString("Author");
|
||||
case Progress:
|
||||
@@ -0,0 +1,102 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "CCSWidget.h"
|
||||
#include "ui_CCSWidget.h"
|
||||
|
||||
#include <QTableWidget>
|
||||
|
||||
#include "CCSProgressDelegate.h"
|
||||
#include "utils/Utils.h"
|
||||
#include "utils/WebsocketNotifier.h"
|
||||
|
||||
CCSWidget::CCSWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::CSSWidget)
|
||||
, m_model(new CCSModel(this))
|
||||
, m_contextMenu(new QMenu(this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->treeView->setModel(m_model);
|
||||
|
||||
m_contextMenu->addAction("View proposal", this, &CCSWidget::linkClicked);
|
||||
m_contextMenu->addAction("Donate", this, &CCSWidget::donateClicked);
|
||||
|
||||
connect(ui->treeView, &QHeaderView::customContextMenuRequested, this, &CCSWidget::showContextMenu);
|
||||
connect(ui->treeView, &QTreeView::doubleClicked, this, &CCSWidget::linkClicked);
|
||||
|
||||
ui->treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
ui->treeView->header()->setSectionResizeMode(CCSModel::Title, QHeaderView::Stretch);
|
||||
|
||||
connect(websocketNotifier(), &WebsocketNotifier::dataReceived, this, [this](const QString& type, const QJsonValue& json) {
|
||||
if (type == "ccs") {
|
||||
QJsonArray ccs_data = json.toArray();
|
||||
QList<QSharedPointer<CCSEntry>> l;
|
||||
|
||||
for (const auto& entry: ccs_data) {
|
||||
auto obj = entry.toObject();
|
||||
auto c = QSharedPointer<CCSEntry>(new CCSEntry());
|
||||
|
||||
if (obj.value("state").toString() != "FUNDING-REQUIRED")
|
||||
continue;
|
||||
|
||||
c->state = obj.value("state").toString();
|
||||
c->address = obj.value("address").toString();
|
||||
c->author = obj.value("author").toString();
|
||||
c->date = obj.value("date").toString();
|
||||
c->title = obj.value("title").toString();
|
||||
c->target_amount = obj.value("target_amount").toDouble();
|
||||
c->raised_amount = obj.value("raised_amount").toDouble();
|
||||
c->percentage_funded = obj.value("percentage_funded").toDouble();
|
||||
c->contributions = obj.value("contributions").toInt();
|
||||
c->organizer = obj.value("organizer").toString();
|
||||
c->currency = obj.value("currency").toString();
|
||||
|
||||
QString urlpath = obj.value("urlpath").toString();
|
||||
if (c->organizer == "CCS") {
|
||||
c->url = QString("https://ccs.getmonero.org/%1").arg(urlpath);
|
||||
}
|
||||
else if (c->organizer == "MAGIC") {
|
||||
c->url = QString("https://monerofund.org/%1").arg(urlpath);
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
|
||||
l.append(c);
|
||||
}
|
||||
|
||||
m_model->updateEntries(l);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CCSWidget::linkClicked() {
|
||||
QModelIndex index = ui->treeView->currentIndex();
|
||||
auto entry = m_model->entry(index.row());
|
||||
|
||||
if (entry) {
|
||||
Utils::externalLinkWarning(this, entry->url);
|
||||
}
|
||||
}
|
||||
|
||||
void CCSWidget::donateClicked() {
|
||||
QModelIndex index = ui->treeView->currentIndex();
|
||||
auto entry = m_model->entry(index.row());
|
||||
|
||||
if (entry) {
|
||||
emit fillSendTab(entry->address, QString("Donation to %1: %2").arg(entry->organizer, entry->title));
|
||||
}
|
||||
}
|
||||
|
||||
void CCSWidget::showContextMenu(const QPoint &pos) {
|
||||
QModelIndex index = ui->treeView->indexAt(pos);
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_contextMenu->exec(ui->treeView->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
CCSWidget::~CCSWidget() = default;
|
||||
@@ -24,10 +24,9 @@ Q_OBJECT
|
||||
public:
|
||||
explicit CCSWidget(QWidget *parent = nullptr);
|
||||
~CCSWidget();
|
||||
CCSModel *model();
|
||||
|
||||
signals:
|
||||
void selected(CCSEntry entry);
|
||||
void fillSendTab(const QString &address, const QString &description);
|
||||
|
||||
public slots:
|
||||
void donateClicked();
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "CrowdfundingPlugin.h"
|
||||
|
||||
#include "plugins/PluginRegistry.h"
|
||||
#include "CCSWidget.h"
|
||||
|
||||
CrowdfundingPlugin::CrowdfundingPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
void CrowdfundingPlugin::initialize(Wallet *wallet, QObject *parent) {
|
||||
this->setParent(parent);
|
||||
m_tab = new CCSWidget(nullptr);
|
||||
connect(m_tab, &CCSWidget::fillSendTab, this, &Plugin::fillSendTab);
|
||||
}
|
||||
|
||||
QString CrowdfundingPlugin::id() {
|
||||
return "crowdfunding";
|
||||
}
|
||||
|
||||
int CrowdfundingPlugin::idx() const {
|
||||
return 10;
|
||||
}
|
||||
|
||||
QString CrowdfundingPlugin::parent() {
|
||||
return "home";
|
||||
}
|
||||
|
||||
QString CrowdfundingPlugin::displayName() {
|
||||
return "Crowdfunding";
|
||||
}
|
||||
|
||||
QString CrowdfundingPlugin::description() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString CrowdfundingPlugin::icon() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList CrowdfundingPlugin::socketData() {
|
||||
return {"ccs"};
|
||||
}
|
||||
|
||||
Plugin::PluginType CrowdfundingPlugin::type() {
|
||||
return Plugin::PluginType::TAB;
|
||||
}
|
||||
|
||||
QWidget* CrowdfundingPlugin::tab() {
|
||||
return m_tab;
|
||||
}
|
||||
|
||||
const bool CrowdfundingPlugin::registered = [] {
|
||||
PluginRegistry::registerPlugin(CrowdfundingPlugin::create());
|
||||
PluginRegistry::getInstance().registerPluginCreator(&CrowdfundingPlugin::create);
|
||||
return true;
|
||||
}();
|
||||
@@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef CROWDFUNDINGPLUGIN_H
|
||||
#define CROWDFUNDINGPLUGIN_H
|
||||
|
||||
#include "plugins/Plugin.h"
|
||||
#include "CCSWidget.h"
|
||||
|
||||
class CrowdfundingPlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CrowdfundingPlugin();
|
||||
|
||||
QString id() override;
|
||||
int idx() const override;
|
||||
QString parent() override;
|
||||
QString displayName() override;
|
||||
QString description() override;
|
||||
QString icon() override;
|
||||
QStringList socketData() override;
|
||||
PluginType type() override;
|
||||
QWidget* tab() override;
|
||||
|
||||
void initialize(Wallet *wallet, QObject *parent) override;
|
||||
|
||||
static CrowdfundingPlugin* create() { return new CrowdfundingPlugin(); }
|
||||
|
||||
private:
|
||||
CCSWidget* m_tab = nullptr;
|
||||
static const bool registered;
|
||||
};
|
||||
|
||||
#endif //CROWDFUNDINGPLUGIN_H
|
||||
@@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "ExchangePlugin.h"
|
||||
|
||||
#include "plugins/PluginRegistry.h"
|
||||
|
||||
ExchangePlugin::ExchangePlugin()
|
||||
{
|
||||
}
|
||||
|
||||
void ExchangePlugin::initialize(Wallet *wallet, QObject *parent) {
|
||||
this->setParent(parent);
|
||||
m_tab = new ExchangeWidget(nullptr);
|
||||
}
|
||||
|
||||
QString ExchangePlugin::id() {
|
||||
return "exchange";
|
||||
}
|
||||
|
||||
int ExchangePlugin::idx() const {
|
||||
return 50;
|
||||
}
|
||||
|
||||
QString ExchangePlugin::parent() {
|
||||
return "";
|
||||
}
|
||||
|
||||
QString ExchangePlugin::displayName() {
|
||||
return "Exchange";
|
||||
}
|
||||
|
||||
QString ExchangePlugin::description() {
|
||||
return {};
|
||||
}
|
||||
QString ExchangePlugin::icon() {
|
||||
return "update.png";
|
||||
}
|
||||
|
||||
QStringList ExchangePlugin::socketData() {
|
||||
return {};
|
||||
}
|
||||
|
||||
Plugin::PluginType ExchangePlugin::type() {
|
||||
return Plugin::PluginType::TAB;
|
||||
}
|
||||
|
||||
QWidget* ExchangePlugin::tab() {
|
||||
return m_tab;
|
||||
}
|
||||
|
||||
void ExchangePlugin::addSubPlugin(Plugin* plugin) {
|
||||
m_tab->addTab(plugin);
|
||||
}
|
||||
|
||||
bool ExchangePlugin::implicitEnable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool ExchangePlugin::registered = [] {
|
||||
PluginRegistry::registerPlugin(ExchangePlugin::create());
|
||||
PluginRegistry::getInstance().registerPluginCreator(&ExchangePlugin::create);
|
||||
return true;
|
||||
}();
|
||||
@@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef EXCHANGEPLUGIN_H
|
||||
#define EXCHANGEPLUGIN_H
|
||||
|
||||
#include "plugins/Plugin.h"
|
||||
#include "ExchangeWidget.h"
|
||||
|
||||
class ExchangePlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ExchangePlugin();
|
||||
|
||||
QString id() override;
|
||||
int idx() const override;
|
||||
QString parent() override;
|
||||
QString displayName() override;
|
||||
QString description() override;
|
||||
QString icon() override;
|
||||
QStringList socketData() override;
|
||||
PluginType type() override;
|
||||
QWidget* tab() override;
|
||||
bool implicitEnable() override;
|
||||
void addSubPlugin(Plugin* plugin) override;
|
||||
|
||||
void initialize(Wallet *wallet, QObject *parent) override;
|
||||
|
||||
static ExchangePlugin* create() { return new ExchangePlugin(); }
|
||||
|
||||
private:
|
||||
ExchangeWidget* m_tab = nullptr;
|
||||
static const bool registered;
|
||||
};
|
||||
|
||||
|
||||
#endif //EXCHANGEPLUGIN_H
|
||||
@@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "ExchangeWidget.h"
|
||||
#include "ui_ExchangeWidget.h"
|
||||
|
||||
#include "utils/Icons.h"
|
||||
|
||||
ExchangeWidget::ExchangeWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::ExchangeWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
void ExchangeWidget::addTab(Plugin *plugin) {
|
||||
QWidget* tab = plugin->tab();
|
||||
auto icon = icons()->icon(plugin->icon());
|
||||
QString name = plugin->displayName();
|
||||
|
||||
ui->tabWidget->addTab(tab, icon, name);
|
||||
}
|
||||
|
||||
ExchangeWidget::~ExchangeWidget() = default;
|
||||
@@ -0,0 +1,31 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef EXCHANGEWIDGET_H
|
||||
#define EXCHANGEWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTabWidget>
|
||||
|
||||
#include "plugins/Plugin.h"
|
||||
|
||||
namespace Ui {
|
||||
class ExchangeWidget;
|
||||
}
|
||||
|
||||
class ExchangeWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ExchangeWidget(QWidget *parent = nullptr);
|
||||
~ExchangeWidget();
|
||||
|
||||
void addTab(Plugin *plugin);
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::ExchangeWidget> ui;
|
||||
};
|
||||
|
||||
|
||||
#endif //EXCHANGEWIDGET_H
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ExchangeWidget</class>
|
||||
<widget class="QWidget" name="ExchangeWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<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="QTabWidget" name="tabWidget"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,76 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "HomePlugin.h"
|
||||
|
||||
#include "plugins/PluginRegistry.h"
|
||||
|
||||
HomePlugin::HomePlugin()
|
||||
{
|
||||
}
|
||||
|
||||
void HomePlugin::initialize(Wallet *wallet, QObject *parent) {
|
||||
this->setParent(parent);
|
||||
m_tab = new HomeWidget(nullptr);
|
||||
}
|
||||
|
||||
QString HomePlugin::id() {
|
||||
return "home";
|
||||
}
|
||||
|
||||
int HomePlugin::idx() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString HomePlugin::parent() {
|
||||
return "";
|
||||
}
|
||||
|
||||
QString HomePlugin::displayName() {
|
||||
return "Home";
|
||||
}
|
||||
|
||||
QString HomePlugin::description() {
|
||||
return {};
|
||||
}
|
||||
QString HomePlugin::icon() {
|
||||
return "tab_home.png";
|
||||
}
|
||||
|
||||
QStringList HomePlugin::socketData() {
|
||||
return {};
|
||||
}
|
||||
|
||||
Plugin::PluginType HomePlugin::type() {
|
||||
return Plugin::PluginType::TAB;
|
||||
}
|
||||
|
||||
QWidget* HomePlugin::tab() {
|
||||
return m_tab;
|
||||
}
|
||||
|
||||
void HomePlugin::addSubPlugin(Plugin* plugin) {
|
||||
m_tab->addPlugin(plugin);
|
||||
}
|
||||
|
||||
bool HomePlugin::implicitEnable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HomePlugin::insertFirst() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void HomePlugin::aboutToQuit() {
|
||||
m_tab->aboutToQuit();
|
||||
}
|
||||
|
||||
void HomePlugin::uiSetup() {
|
||||
m_tab->uiSetup();
|
||||
}
|
||||
|
||||
const bool HomePlugin::registered = [] {
|
||||
PluginRegistry::registerPlugin(HomePlugin::create());
|
||||
PluginRegistry::getInstance().registerPluginCreator(&HomePlugin::create);
|
||||
return true;
|
||||
}();
|
||||
@@ -0,0 +1,43 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef HOMEPLUGIN_H
|
||||
#define HOMEPLUGIN_H
|
||||
|
||||
#include "plugins/Plugin.h"
|
||||
#include "HomeWidget.h"
|
||||
|
||||
class HomePlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit HomePlugin();
|
||||
|
||||
QString id() override;
|
||||
int idx() const override;
|
||||
QString parent() override;
|
||||
QString displayName() override;
|
||||
QString description() override;
|
||||
QString icon() override;
|
||||
QStringList socketData() override;
|
||||
PluginType type() override;
|
||||
QWidget* tab() override;
|
||||
bool implicitEnable() override;
|
||||
bool insertFirst() override;
|
||||
void addSubPlugin(Plugin* plugin) override;
|
||||
|
||||
void initialize(Wallet *wallet, QObject *parent) override;
|
||||
|
||||
static HomePlugin* create() { return new HomePlugin(); }
|
||||
|
||||
public slots:
|
||||
void aboutToQuit() override;
|
||||
void uiSetup() override;
|
||||
|
||||
private:
|
||||
HomeWidget* m_tab = nullptr;
|
||||
static const bool registered;
|
||||
};
|
||||
|
||||
|
||||
#endif //HOMEPLUGIN_H
|
||||
@@ -0,0 +1,34 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "HomeWidget.h"
|
||||
#include "ui_HomeWidget.h"
|
||||
|
||||
#include "utils/config.h"
|
||||
|
||||
HomeWidget::HomeWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::HomeWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
void HomeWidget::addPlugin(Plugin *plugin)
|
||||
{
|
||||
if (plugin->type() == Plugin::TAB) {
|
||||
ui->tabHomeWidget->addTab(plugin->tab(), plugin->displayName());
|
||||
}
|
||||
else if (plugin->type() == Plugin::WIDGET) {
|
||||
ui->widgetLayout->addWidget(plugin->tab());
|
||||
}
|
||||
}
|
||||
|
||||
void HomeWidget::uiSetup() {
|
||||
ui->tabHomeWidget->setCurrentIndex(conf()->get(Config::homeWidget).toInt());
|
||||
}
|
||||
|
||||
void HomeWidget::aboutToQuit() {
|
||||
conf()->set(Config::homeWidget, ui->tabHomeWidget->currentIndex());
|
||||
}
|
||||
|
||||
HomeWidget::~HomeWidget() = default;
|
||||
@@ -0,0 +1,31 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef HOMEWIDGET_H
|
||||
#define HOMEWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "plugins/Plugin.h"
|
||||
|
||||
namespace Ui {
|
||||
class HomeWidget;
|
||||
}
|
||||
|
||||
class HomeWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit HomeWidget(QWidget *parent = nullptr);
|
||||
~HomeWidget();
|
||||
|
||||
void addPlugin(Plugin *plugin);
|
||||
void aboutToQuit();
|
||||
void uiSetup();
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::HomeWidget> ui;
|
||||
};
|
||||
|
||||
#endif //HOMEWIDGET_H
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>HomeWidget</class>
|
||||
<widget class="QWidget" name="HomeWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>743</width>
|
||||
<height>460</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="topMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="widgetLayout"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabHomeWidget">
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="documentMode">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "LocalMoneroPlugin.h"
|
||||
|
||||
LocalMoneroPlugin::LocalMoneroPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
void LocalMoneroPlugin::initialize(Wallet *wallet, QObject *parent) {
|
||||
this->setParent(parent);
|
||||
m_tab = new LocalMoneroWidget(nullptr, wallet);
|
||||
}
|
||||
|
||||
QString LocalMoneroPlugin::id() {
|
||||
return "localmonero";
|
||||
}
|
||||
|
||||
int LocalMoneroPlugin::idx() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString LocalMoneroPlugin::parent() {
|
||||
return "exchange";
|
||||
}
|
||||
|
||||
QString LocalMoneroPlugin::displayName() {
|
||||
return "LocalMonero";
|
||||
}
|
||||
|
||||
QString LocalMoneroPlugin::description() {
|
||||
return {};
|
||||
}
|
||||
QString LocalMoneroPlugin::icon() {
|
||||
return "localMonero_logo.png";
|
||||
}
|
||||
|
||||
QStringList LocalMoneroPlugin::socketData() {
|
||||
return {"localmonero_countries", "localmonero_currencies", "localmonero_payment_methods"};
|
||||
}
|
||||
|
||||
Plugin::PluginType LocalMoneroPlugin::type() {
|
||||
return Plugin::PluginType::TAB;
|
||||
}
|
||||
|
||||
QWidget* LocalMoneroPlugin::tab() {
|
||||
return m_tab;
|
||||
}
|
||||
|
||||
void LocalMoneroPlugin::skinChanged() {
|
||||
m_tab->skinChanged();
|
||||
}
|
||||
|
||||
const bool LocalMoneroPlugin::registered = [] {
|
||||
PluginRegistry::registerPlugin(LocalMoneroPlugin::create());
|
||||
PluginRegistry::getInstance().registerPluginCreator(&LocalMoneroPlugin::create);
|
||||
return true;
|
||||
}();
|
||||
@@ -0,0 +1,40 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef LOCALMONEROPLUGIN_H
|
||||
#define LOCALMONEROPLUGIN_H
|
||||
|
||||
#include "plugins/Plugin.h"
|
||||
#include "LocalMoneroWidget.h"
|
||||
#include "plugins/PluginRegistry.h"
|
||||
|
||||
class LocalMoneroPlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LocalMoneroPlugin();
|
||||
|
||||
QString id() override;
|
||||
int idx() const override;
|
||||
QString parent() override;
|
||||
QString displayName() override;
|
||||
QString description() override;
|
||||
QString icon() override;
|
||||
QStringList socketData() override;
|
||||
PluginType type() override;
|
||||
QWidget* tab() override;
|
||||
|
||||
void initialize(Wallet *wallet, QObject *parent) override;
|
||||
|
||||
static LocalMoneroPlugin* create() { return new LocalMoneroPlugin(); }
|
||||
|
||||
public slots:
|
||||
void skinChanged() override;
|
||||
|
||||
private:
|
||||
LocalMoneroWidget* m_tab = nullptr;
|
||||
static const bool registered;
|
||||
};
|
||||
|
||||
|
||||
#endif //LOCALMONEROPLUGIN_H
|
||||
@@ -50,14 +50,18 @@ QVariant RedditModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
QSharedPointer<RedditPost> post = m_posts.at(index.row());
|
||||
|
||||
if(role == Qt::DisplayRole) {
|
||||
if(role == Qt::DisplayRole || role == Qt::UserRole) {
|
||||
switch(index.column()) {
|
||||
case Title:
|
||||
return post->title;
|
||||
case Author:
|
||||
return post->author;
|
||||
case Comments:
|
||||
case Comments: {
|
||||
if (role == Qt::UserRole) {
|
||||
return post->comments;
|
||||
}
|
||||
return QString::number(post->comments);
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "RedditPlugin.h"
|
||||
|
||||
#include "plugins/PluginRegistry.h"
|
||||
#include "RedditWidget.h"
|
||||
|
||||
RedditPlugin::RedditPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
void RedditPlugin::initialize(Wallet *wallet, QObject *parent) {
|
||||
this->setParent(parent);
|
||||
m_redditWidget = new RedditWidget(nullptr);
|
||||
connect(m_redditWidget, &RedditWidget::setStatusText, this, &Plugin::setStatusText);
|
||||
}
|
||||
|
||||
QString RedditPlugin::id() {
|
||||
return "reddit";
|
||||
}
|
||||
|
||||
int RedditPlugin::idx() const {
|
||||
return 30;
|
||||
}
|
||||
|
||||
QString RedditPlugin::parent() {
|
||||
return "home";
|
||||
}
|
||||
|
||||
QString RedditPlugin::displayName() {
|
||||
return "Reddit";
|
||||
}
|
||||
|
||||
QString RedditPlugin::description() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString RedditPlugin::icon() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList RedditPlugin::socketData() {
|
||||
return {"reddit"};
|
||||
}
|
||||
|
||||
Plugin::PluginType RedditPlugin::type() {
|
||||
return Plugin::PluginType::TAB;
|
||||
}
|
||||
|
||||
QWidget* RedditPlugin::tab() {
|
||||
return m_redditWidget;
|
||||
}
|
||||
|
||||
const bool RedditPlugin::registered = [] {
|
||||
PluginRegistry::registerPlugin(RedditPlugin::create());
|
||||
PluginRegistry::getInstance().registerPluginCreator(&RedditPlugin::create);
|
||||
return true;
|
||||
}();
|
||||
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef REDDITPLUGIN_H
|
||||
#define REDDITPLUGIN_H
|
||||
|
||||
#include "plugins/Plugin.h"
|
||||
#include "RedditWidget.h"
|
||||
#include "plugins/PluginRegistry.h"
|
||||
|
||||
class RedditPlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RedditPlugin();
|
||||
|
||||
QString id() override;
|
||||
int idx() const override;
|
||||
QString parent() override;
|
||||
QString displayName() override;
|
||||
QString description() override;
|
||||
QString icon() override;
|
||||
QStringList socketData() override;
|
||||
PluginType type() override;
|
||||
QWidget* tab() override;
|
||||
|
||||
void initialize(Wallet *wallet, QObject *parent) override;
|
||||
|
||||
static RedditPlugin* create() { return new RedditPlugin(); }
|
||||
|
||||
private:
|
||||
RedditWidget* m_redditWidget = nullptr;
|
||||
static const bool registered;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //REDDITPLUGIN_H
|
||||
@@ -0,0 +1,10 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "RedditProxyModel.h"
|
||||
|
||||
RedditProxyModel::RedditProxyModel(QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
setSortRole(Qt::UserRole);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef REDDITPROXYMODEL_H
|
||||
#define REDDITPROXYMODEL_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class RedditProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RedditProxyModel(QObject* parent = nullptr);
|
||||
};
|
||||
|
||||
#endif //REDDITPROXYMODEL_H
|
||||
@@ -4,13 +4,12 @@
|
||||
#include "RedditWidget.h"
|
||||
#include "ui_RedditWidget.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QStandardItemModel>
|
||||
#include <QTableWidget>
|
||||
|
||||
#include "RedditModel.h"
|
||||
#include "utils/Utils.h"
|
||||
#include "utils/config.h"
|
||||
#include "utils/WebsocketNotifier.h"
|
||||
|
||||
RedditWidget::RedditWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
@@ -19,7 +18,13 @@ RedditWidget::RedditWidget(QWidget *parent)
|
||||
, m_contextMenu(new QMenu(this))
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tableView->setModel(m_model);
|
||||
|
||||
m_proxyModel = new RedditProxyModel(this);
|
||||
m_proxyModel->setSourceModel(m_model);
|
||||
|
||||
ui->tableView->setModel(m_proxyModel);
|
||||
ui->tableView->setSortingEnabled(true);
|
||||
ui->tableView->sortByColumn(2, Qt::DescendingOrder);
|
||||
this->setupTable();
|
||||
|
||||
m_contextMenu->addAction("View thread", this, &RedditWidget::linkClicked);
|
||||
@@ -29,14 +34,30 @@ RedditWidget::RedditWidget(QWidget *parent)
|
||||
connect(ui->tableView, &QTableView::doubleClicked, this, &RedditWidget::linkClicked);
|
||||
|
||||
ui->tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
}
|
||||
|
||||
RedditModel* RedditWidget::model() {
|
||||
return m_model;
|
||||
connect(websocketNotifier(), &WebsocketNotifier::dataReceived, this, [this](const QString& type, const QJsonValue& json) {
|
||||
if (type == "reddit") {
|
||||
QJsonArray reddit_data = json.toArray();
|
||||
QList<QSharedPointer<RedditPost>> l;
|
||||
|
||||
for (auto &&entry: reddit_data) {
|
||||
auto obj = entry.toObject();
|
||||
auto redditPost = new RedditPost(
|
||||
obj.value("title").toString(),
|
||||
obj.value("author").toString(),
|
||||
obj.value("permalink").toString(),
|
||||
obj.value("comments").toInt());
|
||||
QSharedPointer<RedditPost> r = QSharedPointer<RedditPost>(redditPost);
|
||||
l.append(r);
|
||||
}
|
||||
|
||||
m_model->updatePosts(l);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void RedditWidget::linkClicked() {
|
||||
QModelIndex index = ui->tableView->currentIndex();
|
||||
QModelIndex index = m_proxyModel->mapToSource(ui->tableView->currentIndex());
|
||||
auto post = m_model->post(index.row());
|
||||
|
||||
if (post)
|
||||
@@ -44,7 +65,7 @@ void RedditWidget::linkClicked() {
|
||||
}
|
||||
|
||||
void RedditWidget::copyUrl() {
|
||||
QModelIndex index = ui->tableView->currentIndex();
|
||||
QModelIndex index = m_proxyModel->mapToSource(ui->tableView->currentIndex());
|
||||
auto post = m_model->post(index.row());
|
||||
|
||||
if (post) {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <QWidget>
|
||||
|
||||
#include "RedditModel.h"
|
||||
#include "RedditProxyModel.h"
|
||||
|
||||
namespace Ui {
|
||||
class RedditWidget;
|
||||
@@ -21,7 +22,6 @@ class RedditWidget : public QWidget
|
||||
public:
|
||||
explicit RedditWidget(QWidget *parent = nullptr);
|
||||
~RedditWidget();
|
||||
RedditModel* model();
|
||||
|
||||
public slots:
|
||||
void linkClicked();
|
||||
@@ -37,6 +37,7 @@ private:
|
||||
|
||||
QScopedPointer<Ui::RedditWidget> ui;
|
||||
RedditModel* const m_model;
|
||||
RedditProxyModel* m_proxyModel;
|
||||
QMenu *m_contextMenu;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "RevuoPlugin.h"
|
||||
|
||||
#include "plugins/PluginRegistry.h"
|
||||
#include "RevuoWidget.h"
|
||||
|
||||
RevuoPlugin::RevuoPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
void RevuoPlugin::initialize(Wallet *wallet, QObject *parent) {
|
||||
this->setParent(parent);
|
||||
m_tab = new RevuoWidget(nullptr);
|
||||
connect(m_tab, &RevuoWidget::donate, this, &Plugin::fillSendTab);
|
||||
}
|
||||
|
||||
QString RevuoPlugin::id() {
|
||||
return "revuo";
|
||||
}
|
||||
|
||||
int RevuoPlugin::idx() const {
|
||||
return 40;
|
||||
}
|
||||
|
||||
QString RevuoPlugin::parent() {
|
||||
return "home";
|
||||
}
|
||||
|
||||
QString RevuoPlugin::displayName() {
|
||||
return "Revuo";
|
||||
}
|
||||
|
||||
QString RevuoPlugin::description() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString RevuoPlugin::icon() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList RevuoPlugin::socketData() {
|
||||
return {"revuo"};
|
||||
}
|
||||
|
||||
Plugin::PluginType RevuoPlugin::type() {
|
||||
return Plugin::PluginType::TAB;
|
||||
}
|
||||
|
||||
QWidget* RevuoPlugin::tab() {
|
||||
return m_tab;
|
||||
}
|
||||
|
||||
void RevuoPlugin::skinChanged() {
|
||||
m_tab->skinChanged();
|
||||
}
|
||||
|
||||
const bool RevuoPlugin::registered = [] {
|
||||
PluginRegistry::registerPlugin(RevuoPlugin::create());
|
||||
PluginRegistry::getInstance().registerPluginCreator(&RevuoPlugin::create);
|
||||
return true;
|
||||
}();
|
||||
@@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef REVUOPLUGIN_H
|
||||
#define REVUOPLUGIN_H
|
||||
|
||||
#include "plugins/Plugin.h"
|
||||
#include "RevuoWidget.h"
|
||||
|
||||
class RevuoPlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RevuoPlugin();
|
||||
|
||||
QString id() override;
|
||||
int idx() const override;
|
||||
QString parent() override;
|
||||
QString displayName() override;
|
||||
QString description() override;
|
||||
QString icon() override;
|
||||
QStringList socketData() override;
|
||||
PluginType type() override;
|
||||
QWidget* tab() override;
|
||||
|
||||
void initialize(Wallet *wallet, QObject *parent) override;
|
||||
|
||||
static RevuoPlugin* create() { return new RevuoPlugin(); }
|
||||
|
||||
public slots:
|
||||
void skinChanged() override;
|
||||
|
||||
private:
|
||||
RevuoWidget* m_tab = nullptr;
|
||||
static const bool registered;
|
||||
};
|
||||
|
||||
#endif //REVUOPLUGIN_H
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "utils/ColorScheme.h"
|
||||
#include "Utils.h"
|
||||
#include "utils/WebsocketNotifier.h"
|
||||
|
||||
RevuoWidget::RevuoWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
@@ -27,6 +28,32 @@ RevuoWidget::RevuoWidget(QWidget *parent)
|
||||
|
||||
connect(ui->listWidget, &QListWidget::currentTextChanged, this, &RevuoWidget::onSelectItem);
|
||||
connect(ui->listWidget, &QListWidget::customContextMenuRequested, this, &RevuoWidget::showContextMenu);
|
||||
|
||||
connect(websocketNotifier(), &WebsocketNotifier::dataReceived, this, [this](const QString& type, const QJsonValue& json) {
|
||||
if (type == "revuo") {
|
||||
QJsonArray revuo_data = json.toArray();
|
||||
QList<QSharedPointer<RevuoItem>> l;
|
||||
|
||||
for (const auto &entry: revuo_data) {
|
||||
auto obj = entry.toObject();
|
||||
|
||||
QStringList newsbytes;
|
||||
for (const auto &n : obj.value("newsbytes").toArray()) {
|
||||
newsbytes.append(n.toString());
|
||||
}
|
||||
|
||||
auto revuoItem = new RevuoItem(
|
||||
obj.value("title").toString(),
|
||||
obj.value("url").toString(),
|
||||
newsbytes);
|
||||
|
||||
QSharedPointer<RevuoItem> r = QSharedPointer<RevuoItem>(revuoItem);
|
||||
l.append(r);
|
||||
}
|
||||
|
||||
this->updateItems(l);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void RevuoWidget::updateItems(const QList<QSharedPointer<RevuoItem>> &items) {
|
||||
@@ -48,6 +75,7 @@ void RevuoWidget::updateItems(const QList<QSharedPointer<RevuoItem>> &items) {
|
||||
ui->listWidget->clear();
|
||||
ui->listWidget->addItems(titles);
|
||||
ui->listWidget->setCurrentRow(0);
|
||||
ui->listWidget->setMinimumWidth(ui->listWidget->sizeHintForColumn(0) + 10);
|
||||
}
|
||||
|
||||
void RevuoWidget::onSelectItem(const QString &item) {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "TickersConfigAddDialog.h"
|
||||
#include "ui_TickersConfigAddDialog.h"
|
||||
|
||||
#include "utils/AppData.h"
|
||||
#include "utils/config.h"
|
||||
|
||||
TickersConfigAddDialog::TickersConfigAddDialog(QWidget *parent)
|
||||
: WindowModalDialog(parent)
|
||||
, ui(new Ui::TickersConfigAddDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
QStringList cryptoCurrencies = appData()->prices.markets.keys();
|
||||
QStringList fiatCurrencies = appData()->prices.rates.keys();
|
||||
|
||||
QStringList allCurrencies;
|
||||
allCurrencies << cryptoCurrencies << fiatCurrencies;
|
||||
|
||||
ui->comboTicker->addItems(cryptoCurrencies);
|
||||
ui->comboRatio1->addItems(cryptoCurrencies);
|
||||
ui->comboRatio2->addItems(cryptoCurrencies);
|
||||
|
||||
connect(ui->combo_type, &QComboBox::currentIndexChanged, [this](int index) {
|
||||
ui->stackedWidget->setCurrentIndex(index);
|
||||
});
|
||||
|
||||
this->adjustSize();
|
||||
}
|
||||
|
||||
QString TickersConfigAddDialog::getTicker() {
|
||||
int type = ui->combo_type->currentIndex();
|
||||
|
||||
if (type == TickersType::TICKER) {
|
||||
return ui->comboTicker->currentText();
|
||||
}
|
||||
|
||||
if (type == TickersType::RATIO) {
|
||||
return QString("%1/%2").arg(ui->comboRatio1->currentText(), ui->comboRatio2->currentText());
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
TickersConfigAddDialog::~TickersConfigAddDialog() = default;
|
||||
@@ -0,0 +1,36 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef TICKERSCONFIGADDDIALOG_H
|
||||
#define TICKERSCONFIGADDDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QListWidget>
|
||||
|
||||
#include "components.h"
|
||||
|
||||
namespace Ui {
|
||||
class TickersConfigAddDialog;
|
||||
}
|
||||
|
||||
class TickersConfigAddDialog : public WindowModalDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TickersConfigAddDialog(QWidget *parent = nullptr);
|
||||
~TickersConfigAddDialog() override;
|
||||
|
||||
enum TickersType {
|
||||
TICKER = 0,
|
||||
RATIO
|
||||
};
|
||||
|
||||
QString getTicker();
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::TickersConfigAddDialog> ui;
|
||||
TickersType m_type;
|
||||
};
|
||||
|
||||
#endif //TICKERSCONFIGADDDIALOG_H
|
||||
@@ -0,0 +1,165 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TickersConfigAddDialog</class>
|
||||
<widget class="QDialog" name="TickersConfigAddDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>431</width>
|
||||
<height>122</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Add ticker</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="combo_type">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Ticker</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Ratio</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="pageTicker">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<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>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboTicker"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="pageRatio">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<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>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboRatio1"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>/</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboRatio2"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_3"/>
|
||||
</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>TickersConfigAddDialog</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>TickersConfigAddDialog</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>
|
||||
@@ -0,0 +1,61 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "TickersConfigDialog.h"
|
||||
#include "ui_TickersConfigDialog.h"
|
||||
|
||||
#include "utils/config.h"
|
||||
|
||||
#include "TickersConfigAddDialog.h"
|
||||
|
||||
TickersConfigDialog::TickersConfigDialog(QWidget *parent)
|
||||
: WindowModalDialog(parent)
|
||||
, ui(new Ui::TickersConfigDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
QStringList tickers = conf()->get(Config::tickers).toStringList();
|
||||
ui->tickerList->addItems(tickers);
|
||||
|
||||
ui->check_showFiatBalance->setChecked(conf()->get(Config::tickersShowFiatBalance).toBool());
|
||||
connect(ui->check_showFiatBalance, &QCheckBox::toggled, [this](bool toggled) {
|
||||
conf()->set(Config::tickersShowFiatBalance, toggled);
|
||||
});
|
||||
|
||||
connect(ui->btn_addTicker, &QPushButton::clicked, this, &TickersConfigDialog::addTicker);
|
||||
connect(ui->btn_removeTicker, &QPushButton::clicked, this, &TickersConfigDialog::removeTicker);
|
||||
|
||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &TickersConfigDialog::saveConfig);
|
||||
|
||||
this->adjustSize();
|
||||
}
|
||||
|
||||
void TickersConfigDialog::addTicker() {
|
||||
auto dialog = new TickersConfigAddDialog{this};
|
||||
switch (dialog->exec()) {
|
||||
case Accepted: {
|
||||
ui->tickerList->addItem(dialog->getTicker());
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TickersConfigDialog::removeTicker() {
|
||||
int currentRow = ui->tickerList->currentRow();
|
||||
if (currentRow < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->tickerList->takeItem(currentRow);
|
||||
}
|
||||
|
||||
void TickersConfigDialog::saveConfig() {
|
||||
QStringList tickers;
|
||||
for (int i = 0; i < ui->tickerList->count(); i++) {
|
||||
tickers << ui->tickerList->item(i)->text();
|
||||
}
|
||||
conf()->set(Config::tickers, tickers);
|
||||
}
|
||||
|
||||
TickersConfigDialog::~TickersConfigDialog() = default;
|
||||
@@ -0,0 +1,32 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef TICKERCONFIGDIALOG_H
|
||||
#define TICKERCONFIGDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QListWidget>
|
||||
|
||||
#include "components.h"
|
||||
|
||||
namespace Ui {
|
||||
class TickersConfigDialog;
|
||||
}
|
||||
|
||||
class TickersConfigDialog : public WindowModalDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TickersConfigDialog(QWidget *parent = nullptr);
|
||||
~TickersConfigDialog() override;
|
||||
|
||||
private:
|
||||
void addTicker();
|
||||
void removeTicker();
|
||||
void saveConfig();
|
||||
|
||||
QScopedPointer<Ui::TickersConfigDialog> ui;
|
||||
};
|
||||
|
||||
#endif //TICKERCONFIGDIALOG_H
|
||||
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TickersConfigDialog</class>
|
||||
<widget class="QDialog" name="TickersConfigDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>426</width>
|
||||
<height>392</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Tickers config</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QListWidget" name="tickerList">
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="check_showFiatBalance">
|
||||
<property name="text">
|
||||
<string>Show fiat balance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_removeTicker">
|
||||
<property name="text">
|
||||
<string>Remove Ticker</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_addTicker">
|
||||
<property name="text">
|
||||
<string>Add Ticker</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>TickersConfigDialog</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>TickersConfigDialog</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>
|
||||
@@ -0,0 +1,67 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "TickersPlugin.h"
|
||||
|
||||
#include "plugins/PluginRegistry.h"
|
||||
|
||||
#include "TickersConfigDialog.h"
|
||||
|
||||
TickersPlugin::TickersPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
void TickersPlugin::initialize(Wallet *wallet, QObject *parent) {
|
||||
this->setParent(parent);
|
||||
m_tab = new TickersWidget(nullptr, wallet);
|
||||
}
|
||||
|
||||
QString TickersPlugin::id() {
|
||||
return "tickers";
|
||||
}
|
||||
|
||||
int TickersPlugin::idx() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString TickersPlugin::parent() {
|
||||
return "home";
|
||||
}
|
||||
|
||||
QString TickersPlugin::displayName() {
|
||||
return "Tickers";
|
||||
}
|
||||
|
||||
QString TickersPlugin::description() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString TickersPlugin::icon() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList TickersPlugin::socketData() {
|
||||
return {};
|
||||
}
|
||||
|
||||
Plugin::PluginType TickersPlugin::type() {
|
||||
return Plugin::PluginType::WIDGET;
|
||||
}
|
||||
|
||||
QWidget* TickersPlugin::tab() {
|
||||
return m_tab;
|
||||
}
|
||||
|
||||
bool TickersPlugin::configurable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
QDialog* TickersPlugin::configDialog(QWidget *parent) {
|
||||
return new TickersConfigDialog{parent};
|
||||
}
|
||||
|
||||
const bool TickersPlugin::registered = [] {
|
||||
PluginRegistry::registerPlugin(TickersPlugin::create());
|
||||
PluginRegistry::getInstance().registerPluginCreator(&TickersPlugin::create);
|
||||
return true;
|
||||
}();
|
||||
@@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef TICKERPLUGIN_H
|
||||
#define TICKERPLUGIN_H
|
||||
|
||||
#include "plugins/Plugin.h"
|
||||
#include "TickersWidget.h"
|
||||
|
||||
class TickersPlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TickersPlugin();
|
||||
|
||||
QString id() override;
|
||||
int idx() const override;
|
||||
QString parent() override;
|
||||
QString displayName() override;
|
||||
QString description() override;
|
||||
QString icon() override;
|
||||
QStringList socketData() override;
|
||||
PluginType type() override;
|
||||
QWidget* tab() override;
|
||||
bool configurable() override;
|
||||
QDialog* configDialog(QWidget *parent) override;
|
||||
|
||||
void initialize(Wallet *wallet, QObject *parent) override;
|
||||
|
||||
static TickersPlugin* create() { return new TickersPlugin(); }
|
||||
|
||||
private:
|
||||
TickersWidget* m_tab = nullptr;
|
||||
static const bool registered;
|
||||
};
|
||||
|
||||
|
||||
#endif //TICKERPLUGIN_H
|
||||
@@ -0,0 +1,76 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "TickersWidget.h"
|
||||
#include "ui_TickersWidget.h"
|
||||
|
||||
#include "utils/config.h"
|
||||
#include "WindowManager.h"
|
||||
|
||||
TickersWidget::TickersWidget(QWidget *parent, Wallet *wallet)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::TickersWidget)
|
||||
, m_wallet(wallet)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->setup();
|
||||
|
||||
// TODO: this is a hack: find a better way to route settings signals to plugins
|
||||
connect(windowManager(), &WindowManager::updateBalance, this, &TickersWidget::updateBalance);
|
||||
connect(windowManager(), &WindowManager::preferredFiatCurrencyChanged, this, &TickersWidget::updateDisplay);
|
||||
connect(windowManager(), &WindowManager::pluginConfigured, [this](const QString &id) {
|
||||
if (id == "tickers") {
|
||||
this->setup();
|
||||
}
|
||||
});
|
||||
this->updateBalance();
|
||||
}
|
||||
|
||||
void TickersWidget::setup() {
|
||||
QStringList tickers = conf()->get(Config::tickers).toStringList();
|
||||
|
||||
Utils::clearLayout(ui->tickerLayout);
|
||||
Utils::clearLayout(ui->fiatTickerLayout);
|
||||
|
||||
m_tickerWidgets.clear();
|
||||
m_balanceTickerWidget.reset(nullptr);
|
||||
|
||||
for (const auto &ticker : tickers) {
|
||||
if (ticker.contains("/")) { // ratio
|
||||
QStringList symbols = ticker.split("/");
|
||||
if (symbols.length() != 2) {
|
||||
qWarning() << "Invalid ticker in config: " << ticker;
|
||||
}
|
||||
auto* tickerWidget = new RatioTickerWidget(this, m_wallet, symbols[0], symbols[1]);
|
||||
m_tickerWidgets.append(tickerWidget);
|
||||
ui->tickerLayout->addWidget(tickerWidget);
|
||||
} else {
|
||||
auto* tickerWidget = new PriceTickerWidget(this, m_wallet, ticker);
|
||||
m_tickerWidgets.append(tickerWidget);
|
||||
ui->tickerLayout->addWidget(tickerWidget);
|
||||
}
|
||||
}
|
||||
|
||||
if (conf()->get(Config::tickersShowFiatBalance).toBool()) {
|
||||
m_balanceTickerWidget.reset(new BalanceTickerWidget(this, m_wallet, false));
|
||||
ui->fiatTickerLayout->addWidget(m_balanceTickerWidget.data());
|
||||
}
|
||||
|
||||
this->updateBalance();
|
||||
this->updateDisplay();
|
||||
}
|
||||
|
||||
void TickersWidget::updateBalance() {
|
||||
ui->frame_fiatTickerLayout->setHidden(conf()->get(Config::hideBalance).toBool());
|
||||
}
|
||||
|
||||
void TickersWidget::updateDisplay() {
|
||||
for (const auto &widget : m_tickerWidgets) {
|
||||
widget->updateDisplay();
|
||||
}
|
||||
if (m_balanceTickerWidget) {
|
||||
m_balanceTickerWidget->updateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
TickersWidget::~TickersWidget() = default;
|
||||
@@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef TICKERSWIDGET_H
|
||||
#define TICKERSWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "Wallet.h"
|
||||
#include "widgets/TickerWidget.h"
|
||||
|
||||
namespace Ui {
|
||||
class TickersWidget;
|
||||
}
|
||||
|
||||
class TickersWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TickersWidget(QWidget *parent, Wallet *wallet);
|
||||
~TickersWidget() override;
|
||||
|
||||
private slots:
|
||||
void updateBalance();
|
||||
void updateDisplay();
|
||||
|
||||
private:
|
||||
void setup();
|
||||
|
||||
QScopedPointer<Ui::TickersWidget> ui;
|
||||
Wallet *m_wallet;
|
||||
|
||||
QList<TickerWidgetBase*> m_tickerWidgets;
|
||||
QScopedPointer<BalanceTickerWidget> m_balanceTickerWidget;
|
||||
};
|
||||
|
||||
#endif //TICKERSWIDGET_H
|
||||
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TickersWidget</class>
|
||||
<widget class="QWidget" name="TickersWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>618</width>
|
||||
<height>161</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<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>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="tickerLayout"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_fiatTickerLayout">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="fiatTickerLayout">
|
||||
<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>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,62 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#include "XMRigPlugin.h"
|
||||
|
||||
#include "plugins/PluginRegistry.h"
|
||||
|
||||
XMRigPlugin::XMRigPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void XMRigPlugin::initialize(Wallet *wallet, QObject *parent) {
|
||||
this->setParent(parent);
|
||||
m_tab = new XMRigWidget(wallet, nullptr);
|
||||
}
|
||||
|
||||
QString XMRigPlugin::id() {
|
||||
return "xmrig";
|
||||
}
|
||||
|
||||
int XMRigPlugin::idx() const {
|
||||
return 70;
|
||||
}
|
||||
|
||||
QString XMRigPlugin::parent() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString XMRigPlugin::displayName() {
|
||||
return "Mining";
|
||||
}
|
||||
|
||||
QString XMRigPlugin::description() {
|
||||
return {};
|
||||
}
|
||||
|
||||
QString XMRigPlugin::icon() {
|
||||
return "mining.png";
|
||||
}
|
||||
|
||||
QStringList XMRigPlugin::socketData() {
|
||||
return {"xmrig"};
|
||||
}
|
||||
|
||||
Plugin::PluginType XMRigPlugin::type() {
|
||||
return Plugin::PluginType::TAB;
|
||||
}
|
||||
|
||||
QWidget* XMRigPlugin::tab() {
|
||||
return m_tab;
|
||||
}
|
||||
|
||||
bool XMRigPlugin::requiresWebsocket() {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool XMRigPlugin::registered = [] {
|
||||
PluginRegistry::registerPlugin(XMRigPlugin::create());
|
||||
PluginRegistry::getInstance().registerPluginCreator(&XMRigPlugin::create);
|
||||
return true;
|
||||
}();
|
||||
@@ -0,0 +1,36 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
|
||||
|
||||
#ifndef XMRIGPLUGIN_H
|
||||
#define XMRIGPLUGIN_H
|
||||
|
||||
#include "plugins/Plugin.h"
|
||||
#include "XMRigWidget.h"
|
||||
|
||||
class XMRigPlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit XMRigPlugin();
|
||||
|
||||
QString id() override;
|
||||
int idx() const override;
|
||||
QString parent() override;
|
||||
QString displayName() override;
|
||||
QString description() override;
|
||||
QString icon() override;
|
||||
QStringList socketData() override;
|
||||
PluginType type() override;
|
||||
QWidget* tab() override;
|
||||
bool requiresWebsocket() override;
|
||||
|
||||
void initialize(Wallet *wallet, QObject *parent) override;
|
||||
|
||||
static XMRigPlugin* create() { return new XMRigPlugin(); }
|
||||
|
||||
private:
|
||||
XMRigWidget* m_tab = nullptr;
|
||||
static const bool registered;
|
||||
};
|
||||
|
||||
#endif //XMRIGPLUGIN_H
|
||||
@@ -11,8 +11,10 @@
|
||||
#include <QStandardItemModel>
|
||||
#include <QTableWidget>
|
||||
|
||||
#include "WebsocketNotifier.h"
|
||||
#include "utils/Icons.h"
|
||||
#include "utils/Utils.h"
|
||||
#include "WindowManager.h"
|
||||
|
||||
XMRigWidget::XMRigWidget(Wallet *wallet, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
@@ -128,6 +130,14 @@ XMRigWidget::XMRigWidget(Wallet *wallet, QWidget *parent)
|
||||
ui->label_status->hide();
|
||||
|
||||
this->printConsoleInfo();
|
||||
|
||||
connect(windowManager(), &WindowManager::websocketStatusChanged, this, &XMRigWidget::setDownloadsTabEnabled);
|
||||
connect(websocketNotifier(), &WebsocketNotifier::dataReceived, this, [this](const QString &type, const QJsonValue &json) {
|
||||
if (type == "xmrig") {
|
||||
QJsonObject xmrig_data = json.toObject();
|
||||
this->onDownloads(xmrig_data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool XMRigWidget::isMining() {
|
||||
|
||||
Reference in New Issue
Block a user