You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wowlet/src/widgets/nodewidget.cpp

190 lines
6.1 KiB

// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include <QInputDialog>
#include <QTableWidget>
#include <QMessageBox>
#include <QDesktopServices>
#include "model/NodeModel.h"
#include "nodewidget.h"
#include "ui_nodewidget.h"
#include "mainwindow.h"
NodeWidget::NodeWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::NodeWidget)
{
ui->setupUi(this);
connect(ui->btn_add_custom, &QPushButton::clicked, this, &NodeWidget::onCustomAddClicked);
connect(ui->nodeBtnGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), [=](QAbstractButton *button) {
auto name = button->objectName();
if (name == "radioButton_websocket") {
emit nodeSourceChanged(NodeSource::websocket);
} else if (name == "radioButton_custom") {
emit nodeSourceChanged(NodeSource::custom);
}
});
m_contextActionRemove = new QAction("Remove", this);
m_contextActionConnect = new QAction(QIcon(":/assets/images/connect.svg"), "Connect to node", this);
m_contextActionOpenStatusURL = new QAction(QIcon(":/assets/images/network.png"), "Visit status page", this);
m_contextActionCopy = new QAction(QIcon(":/assets/images/copy.png"), "Copy", this);
connect(m_contextActionConnect, &QAction::triggered, this, &NodeWidget::onContextConnect);
connect(m_contextActionRemove, &QAction::triggered, this, &NodeWidget::onContextCustomNodeRemove);
connect(m_contextActionOpenStatusURL, &QAction::triggered, this, &NodeWidget::onContextStatusURL);
connect(m_contextActionCopy, &QAction::triggered, this, &NodeWidget::onContextNodeCopy);
connect(m_contextActionRemove, &QAction::triggered, this, &NodeWidget::onContextCustomNodeRemove);
ui->wsView->setContextMenuPolicy(Qt::CustomContextMenu);
ui->customView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->wsView, &QTreeView::customContextMenuRequested, this, &NodeWidget::onShowWSContextMenu);
connect(ui->customView, &QTreeView::customContextMenuRequested, this, &NodeWidget::onShowCustomContextMenu);
connect(ui->customView, &QTreeView::doubleClicked, this, &NodeWidget::onContextConnect);
connect(ui->wsView, &QTreeView::doubleClicked, this, &NodeWidget::onContextConnect);
}
void NodeWidget::onShowWSContextMenu(const QPoint &pos) {
m_activeView = ui->wsView;
WowletNode node = this->selectedNode();
if (node.full.isEmpty()) return;
this->showContextMenu(pos, node);
}
void NodeWidget::onShowCustomContextMenu(const QPoint &pos) {
m_activeView = ui->customView;
WowletNode node = this->selectedNode();
if (node.full.isEmpty()) return;
this->showContextMenu(pos, node);
}
void NodeWidget::showContextMenu(const QPoint &pos, const WowletNode &node) {
QMenu menu(this);
if (!node.isActive) {
menu.addAction(m_contextActionConnect);
}
menu.addAction(m_contextActionOpenStatusURL);
menu.addAction(m_contextActionCopy);
if (m_activeView == ui->customView)
menu.addAction(m_contextActionRemove);
menu.exec(m_activeView->viewport()->mapToGlobal(pos));
}
void NodeWidget::onContextConnect() {
//QObject *obj = sender();
WowletNode node = this->selectedNode();
if (!node.full.isEmpty())
emit connectToNode(node);
}
void NodeWidget::onContextStatusURL() {
WowletNode node = this->selectedNode();
if (!node.full.isEmpty())
Utils::externalLinkWarning(this, node.as_url());
}
void NodeWidget::onContextNodeCopy() {
WowletNode node = this->selectedNode();
Utils::copyToClipboard(node.full);
}
WowletNode NodeWidget::selectedNode() {
QModelIndex index = m_activeView->currentIndex();
if (!index.isValid()) return WowletNode();
WowletNode node;
if (m_activeView == ui->customView) {
node = m_customModel->node(index.row());
} else {
node = m_wsModel->node(index.row());
}
return node;
}
void NodeWidget::onContextCustomNodeRemove() {
QModelIndex index = ui->customView->currentIndex();
if (!index.isValid()) return;
WowletNode node = m_customModel->node(index.row());
auto nodes = m_ctx->nodes->customNodes();
QMutableListIterator<WowletNode> i(nodes);
while (i.hasNext())
if (i.next() == node)
i.remove();
m_ctx->nodes->setCustomNodes(nodes);
}
void NodeWidget::onCustomAddClicked(){
auto currentNodes = m_ctx->nodes->customNodes();
auto currentNodesText = QString("");
for(auto &entry: currentNodes)
currentNodesText += QString("%1\n").arg(entry.full);
bool ok;
QString text = QInputDialog::getMultiLineText(this, "Add custom node(s).", "E.g: user:password@127.0.0.1:18081", currentNodesText, &ok);
if (!ok || text.isEmpty())
return;
QList<WowletNode> nodesList;
auto newNodesList = text.split("\n");
for(auto &newNodeText: newNodesList) {
newNodeText = newNodeText.replace("\r", "").trimmed();
if(newNodeText.isEmpty())
continue;
auto node = WowletNode(newNodeText);
node.custom = true;
nodesList.append(node);
}
m_ctx->nodes->setCustomNodes(nodesList);
}
void NodeWidget::setupUI(AppContext *ctx) {
m_ctx = ctx;
auto nodeSource = m_ctx->nodes->source();
qCritical() << nodeSource;
if(nodeSource == NodeSource::websocket){
ui->radioButton_websocket->setChecked(true);
} else if(nodeSource == NodeSource::custom) {
ui->radioButton_custom->setChecked(true);
}
this->setWSModel(m_ctx->nodes->modelWebsocket);
this->setCustomModel(m_ctx->nodes->modelCustom);
}
void NodeWidget::setWSModel(NodeModel *model) {
m_wsModel = model;
ui->wsView->setModel(m_wsModel);
ui->wsView->header()->setSectionResizeMode(NodeModel::URL, QHeaderView::Stretch);
ui->wsView->header()->setSectionResizeMode(NodeModel::Height, QHeaderView::ResizeToContents);
}
void NodeWidget::setCustomModel(NodeModel *model) {
m_customModel = model;
ui->customView->setModel(m_customModel);
ui->customView->header()->setSectionResizeMode(NodeModel::URL, QHeaderView::Stretch);
}
NodeModel* NodeWidget::model() {
return m_wsModel;
}
NodeWidget::~NodeWidget() {
delete ui;
}