diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 6f7344279..1df55edd5 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -114,6 +114,7 @@ QT_FORMS_UI = \ qt/forms/addpeerdialog.ui \ qt/forms/testpeerdialog.ui \ qt/forms/wrapping.ui \ + qt/forms/flightplans.ui \ qt/forms/sendcoinsdialog.ui \ qt/forms/sendcoinsentry.ui \ qt/forms/signverifymessagedialog.ui \ @@ -169,6 +170,7 @@ QT_MOC_CPP = \ qt/moc_recentrequeststablemodel.cpp \ qt/moc_rpcconsole.cpp \ qt/moc_wrapping.cpp \ + qt/moc_flightplans.cpp \ qt/moc_sendcoinsdialog.cpp \ qt/moc_sendcoinsentry.cpp \ qt/moc_signverifymessagedialog.cpp \ @@ -280,6 +282,7 @@ AVIAN_QT_H = \ qt/transactiontablemodel.h \ qt/transactionview.h \ qt/wrapping.h \ + qt/flightplans.h \ qt/utilitydialog.h \ qt/verticallabel.h \ qt/peerdialog.h \ @@ -487,6 +490,7 @@ AVIAN_QT_WALLET_CPP = \ qt/transactiontablemodel.cpp \ qt/transactionview.cpp \ qt/wrapping.cpp \ + qt/flightplans.cpp \ qt/verticallabel.cpp \ qt/peerdialog.cpp \ qt/walletframe.cpp \ diff --git a/src/flightplans/flightplans.cpp b/src/flightplans/flightplans.cpp index 883901b83..5184cae2b 100644 --- a/src/flightplans/flightplans.cpp +++ b/src/flightplans/flightplans.cpp @@ -3,8 +3,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -/* -Avian Flight Plans (smart contracts) are experimental and prone to bugs. +/** +Avian Flight Plans are experimental and prone to bugs. Please take precautions when using this feature. */ @@ -12,18 +12,20 @@ Please take precautions when using this feature. #include "avianlib.h" #include "util.h" +#include "fs.h" #include #include #include #include +#include #include "lua/lua.hpp" -FlightPlanResult AvianFlightPlans::run_file(const char* file, const char* func, std::vector args) +FlightPlanResult CAvianFlightPlans::RunFile(const char* file, const char* func, std::vector args) { - /* Warn user **/ - LogPrintf("Running flight plan -- Avian Flight Plans are experimental and prone to bugs. Please take precautions when using this feature.\n"); + // Warn user + LogPrintf("Running flight plan; Avian Flight Plans are experimental and prone to bugs. Please take precautions when using this feature.\n"); // Result object FlightPlanResult result; @@ -59,14 +61,14 @@ FlightPlanResult AvianFlightPlans::run_file(const char* file, const char* func, if (args.size() >= 1) { n = args.size(); - /* loop through each argument */ + // Loop through each argument for (int i = 0; i < n; i++) { /* push argument */ lua_pushstring(L, args[i].c_str()); } } - /* call the function with n arguments, return 1 result */ + // Call the function with n arguments, return 1 result status = lua_pcall(L, n, 1, 0); if (status != LUA_OK) { @@ -77,7 +79,7 @@ FlightPlanResult AvianFlightPlans::run_file(const char* file, const char* func, return result; } - /* get the result */ + // Get the result if (lua_isstring(L, -1)) { result.result = (char*)lua_tostring(L, -1); lua_pop(L, 1); @@ -96,3 +98,15 @@ FlightPlanResult AvianFlightPlans::run_file(const char* file, const char* func, return result; } + +std::vector CAvianFlightPlans::GetPlans() +{ + std::vector plans; + fs::path path = GetDataDir(false) / "flightplans"; + for (auto& file : fs::directory_iterator(path)) { + if (file.path().extension() == ".lua") { + plans.push_back(file.path().stem().string()); + } + } + return plans; +} diff --git a/src/flightplans/flightplans.h b/src/flightplans/flightplans.h index 33e6f0665..3ade8cb6e 100644 --- a/src/flightplans/flightplans.h +++ b/src/flightplans/flightplans.h @@ -18,10 +18,11 @@ class FlightPlanResult }; /* Avian Flightplans */ -class AvianFlightPlans +class CAvianFlightPlans { public: - FlightPlanResult run_file(const char* file, const char* func, std::vector args={}); + static FlightPlanResult RunFile(const char* file, const char* func, std::vector args={}); + static std::vector GetPlans(); }; #endif diff --git a/src/qt/aviangui.cpp b/src/qt/aviangui.cpp index 44c2b2e8a..bdf19d762 100644 --- a/src/qt/aviangui.cpp +++ b/src/qt/aviangui.cpp @@ -22,6 +22,7 @@ #include "optionsmodel.h" #include "platformstyle.h" #include "rpcconsole.h" +#include "flightplans.h" #include "utilitydialog.h" #include "validation.h" @@ -142,6 +143,7 @@ AvianGUI::AvianGUI(const PlatformStyle *_platformStyle, const NetworkStyle *netw openRPCConsoleAction(0), openAction(0), showHelpMessageAction(0), + openFlightplansAction(0), transferAssetAction(0), createAssetAction(0), manageAssetAction(0), @@ -159,6 +161,7 @@ AvianGUI::AvianGUI(const PlatformStyle *_platformStyle, const NetworkStyle *netw trayIconMenu(0), notificator(0), rpcConsole(0), + flightplans(0), helpMessageDialog(0), modalOverlay(0), prevBlocks(0), @@ -197,6 +200,7 @@ AvianGUI::AvianGUI(const PlatformStyle *_platformStyle, const NetworkStyle *netw #endif rpcConsole = new RPCConsole(_platformStyle, 0); + flightplans = new Flightplans(_platformStyle, 0); helpMessageDialog = new HelpMessageDialog(this, false); #ifdef ENABLE_WALLET if(enableWallet) @@ -550,6 +554,13 @@ void AvianGUI::createActions() showHelpMessageAction->setMenuRole(QAction::NoRole); showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Avian command-line options").arg(tr(PACKAGE_NAME))); + /** AVN START */ + openFlightplansAction = new QAction(platformStyle->TextColorIcon(":/icons/avian"), tr("&Manage Avian Flight Plans"), this); + openFlightplansAction->setMenuRole(QAction::NoRole); + openFlightplansAction->setStatusTip(tr("Manage and create Avian Flight Plans")); + connect(openFlightplansAction, SIGNAL(triggered()), this, SLOT(showFlightplans())); + /** AVN END */ + connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked())); connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); @@ -621,6 +632,14 @@ void AvianGUI::createMenuBar() } settings->addAction(optionsAction); + /** AVN START */ + + QMenu *extra = appMenuBar->addMenu(tr("&Extra")); + extra->addAction(openFlightplansAction); + extra->addSeparator(); + + /** AVN END */ + QMenu *help = appMenuBar->addMenu(tr("&Help")); if(walletFrame) { @@ -1026,6 +1045,18 @@ void AvianGUI::showHelpMessageClicked() helpMessageDialog->show(); } +/** AVN START */ + +void AvianGUI::showFlightplans() +{ + flightplans->showNormal(); + flightplans->show(); + flightplans->raise(); + flightplans->activateWindow(); +} + +/** AVN END */ + #ifdef ENABLE_WALLET void AvianGUI::openClicked() { diff --git a/src/qt/aviangui.h b/src/qt/aviangui.h index 7ead1c7b4..29cc5e1a3 100644 --- a/src/qt/aviangui.h +++ b/src/qt/aviangui.h @@ -27,6 +27,7 @@ class Notificator; class OptionsModel; class PlatformStyle; class RPCConsole; +class Flightplans; class SendCoinsRecipient; class UnitDisplayStatusBarControl; class WalletFrame; @@ -134,6 +135,7 @@ class AvianGUI : public QMainWindow QAction *getMyWordsAction; QAction *votingAction; QAction *restrictedAssetAction; + QAction *openFlightplansAction; QAction *wrapAction; QWidget *headerWidget; QLabel *labelCurrentMarket; @@ -141,6 +143,7 @@ class AvianGUI : public QMainWindow QTimer *pricingTimer; QNetworkAccessManager* networkManager; QNetworkRequest* request; + Flightplans *flightplans; /** AVN END */ QSystemTrayIcon *trayIcon; @@ -277,6 +280,10 @@ private Q_SLOTS: void trayIconActivated(QSystemTrayIcon::ActivationReason reason); #endif + /** AVN START */ + void showFlightplans(); + /** AVN END */ + /** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */ void showNormalIfMinimized(bool fToggleHidden = false); /** Simply calls showNormalIfMinimized(true) for use in SLOT() macro */ diff --git a/src/qt/flightplans.cpp b/src/qt/flightplans.cpp new file mode 100644 index 000000000..faa688536 --- /dev/null +++ b/src/qt/flightplans.cpp @@ -0,0 +1,72 @@ +// Copyright (c) 2022 The Avian Core developers +// Copyright (c) 2022 Shafil Alam +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#if defined(HAVE_CONFIG_H) +#include "config/avian-config.h" +#endif + +#include "flightplans.h" +#include "ui_flightplans.h" +#include "flightplans/flightplans.h" + +#include "guiutil.h" +#include "platformstyle.h" +#include "guiconstants.h" +#include "validation.h" +#include "util.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include + +Flightplans::Flightplans(const PlatformStyle *platformStyle, QWidget *parent) : + QDialog(parent), + ui(new Ui::Flightplans) +{ + ui->setupUi(this); + + // Set data dir label + ui->labelDatadir->setText(tr("List of flightplans in: ") + QString::fromStdString((GetDataDir() / "flightplans" ).string())); + + // Set warning + if (!AreFlightPlansDeployed()) { + ui->labelAlerts->setText(tr("Warning: Avian Flight Plans are not deployed.")); + } + + if (!gArgs.IsArgSet("-flightplans") && AreFlightPlansDeployed()) { + ui->labelAlerts->setText(tr("Warning: Avian Flight Plans are deployed but is disabled.")); + } + + if (gArgs.IsArgSet("-flightplans") && AreFlightPlansDeployed()) { + ui->labelAlerts->setText(tr("Warning: Avian Flight Plans are ACTIVE! Please exercise extreme caution.")); + } + + // List all flight plans + auto plans = CAvianFlightPlans::GetPlans(); + ui->listWidget->addItem(QString::fromStdString(std::string("There are ") + std::to_string(plans.size()) + std::string(" flightplans."))); + for(const std::string& plan : plans) { + ui->listWidget->addItem(QString::fromStdString(plan)); + } + + /** Connect signals */ + // connect(ui->wrapButton, SIGNAL(clicked()), this, SLOT(wrapped_clicked())); +} + +void Flightplans::wrapped_clicked() +{ + /** Show warning */ +} + +Flightplans::~Flightplans() +{ + delete ui; +} diff --git a/src/qt/flightplans.h b/src/qt/flightplans.h new file mode 100644 index 000000000..2220800dc --- /dev/null +++ b/src/qt/flightplans.h @@ -0,0 +1,33 @@ +// Copyright (c) 2022 The Avian Core developers +// Copyright (c) 2022 Shafil Alam +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef AVIAN_QT_FLIGHTPLANS_H +#define AVIAN_QT_FLIGHTPLANS_H + +#include +#include + +class PlatformStyle; + +namespace Ui { + class Flightplans; +} + +class Flightplans: public QDialog +{ + Q_OBJECT + +public: + explicit Flightplans(const PlatformStyle *platformStyle, QWidget *parent = 0); + ~Flightplans(); + +private Q_SLOTS: + void wrapped_clicked(); + +private: + Ui::Flightplans *ui; +}; + +#endif // AVIAN_QT_FLIGHTPLANS_H diff --git a/src/qt/forms/flightplans.ui b/src/qt/forms/flightplans.ui new file mode 100644 index 000000000..4d689d7c2 --- /dev/null +++ b/src/qt/forms/flightplans.ui @@ -0,0 +1,129 @@ + + + Flightplans + + + + 0 + 0 + 713 + 543 + + + + Avian Flight Plans + + + + 10 + + + 10 + + + 10 + + + 10 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + true + + + QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; } + + + + + + true + + + 3 + + + Qt::TextSelectableByMouse + + + + + + + + 18 + + + + Avian Flight Plans + + + + + + + List of flightplans in: + + + + + + + + + + 6 + + + 6 + + + + + View + + + + + + + Edit + + + + + + + Delete + + + + + + + Create new flightplan + + + + + + + + + + + + + + + diff --git a/src/rpc/flightplans.cpp b/src/rpc/flightplans.cpp index e6f5d1d73..49f3cff03 100644 --- a/src/rpc/flightplans.cpp +++ b/src/rpc/flightplans.cpp @@ -50,12 +50,9 @@ UniValue call_flightplan(const JSONRPCRequest& request) args.erase(args.begin()); args.erase(args.begin()); - auto flightplans = AvianFlightPlans(); - - // TODO: Make sure works on Windows and Linux fs::path path = GetDataDir(false) / "flightplans" / file.c_str(); - FlightPlanResult result = flightplans.run_file(path.string().c_str(), request.params[1].get_str().c_str(), args); + FlightPlanResult result = CAvianFlightPlans::RunFile(path.string().c_str(), request.params[1].get_str().c_str(), args); if (fs::exists(path)) { if (result.is_error) { @@ -90,10 +87,8 @@ UniValue list_flightplans(const JSONRPCRequest& request) if (gArgs.IsArgSet("-flightplans")) { UniValue plans(UniValue::VARR); - fs::path path = GetDataDir(false) / "flightplans"; - for (auto& file : fs::directory_iterator(path)) { - if (file.path().extension() == ".lua") - plans.push_back(file.path().stem().string()); + for (const std::string& plan : CAvianFlightPlans::GetPlans()) { + plans.push_back(plan); } return plans; } else { @@ -104,8 +99,8 @@ UniValue list_flightplans(const JSONRPCRequest& request) static const CRPCCommand commands[] = { // category name actor (function) argNames // --------------------- ------------------------ ----------------------- ---------- - {"flightplans", "call_flightplan", &call_flightplan, {"flightplan_name", "function", "args"}}, - {"flightplans", "list_flightplans", &list_flightplans, {}} + {"flightplans", "callflightplan", &call_flightplan, {"flightplan_name", "function", "args"}}, + {"flightplans", "listflightplans", &list_flightplans, {}} }; void RegisterFlightPlanRPCCommands(CRPCTable& t)