From ad87ed30f08cd6429d59b2dd7ea8bf4d5a697858 Mon Sep 17 00:00:00 2001 From: andreidanila1 Date: Thu, 22 Aug 2024 15:31:35 +0300 Subject: [PATCH] plugingenerator: Last changes for pdk. Added init button, scopy preferences. Signed-off-by: andreidanila1 --- tools/plugingenerator/plugin_generator.py | 10 +- .../templates/pdk/pdk_cmake_template.mako | 1 + .../templates/pdk/pdk_cmakein_template.mako | 1 + .../templates/pdk/pdk_header_template.mako | 44 +- .../templates/pdk/pdk_src_template.mako | 434 ++++++++++++++---- 5 files changed, 399 insertions(+), 91 deletions(-) diff --git a/tools/plugingenerator/plugin_generator.py b/tools/plugingenerator/plugin_generator.py index fa4c8b423c..be646596a9 100644 --- a/tools/plugingenerator/plugin_generator.py +++ b/tools/plugingenerator/plugin_generator.py @@ -62,7 +62,7 @@ else: pdkPath = os.path.join(pdkPath, "ScopyPluginRunner") try: - os.mkdir(pdkPath, mode) + os.makedirs(pdkPath, mode) directoriesGenerated.append(pdkPath) except FileExistsError: print(pdkPath + " directory already exists!") @@ -122,6 +122,11 @@ ####################################################### pdk ################################################## if pdkSupport: + pdkPreferencesPath = os.path.join(pdkPath, "preferences.ini") + if not os.path.exists(pdkPreferencesPath): + pdkPreferences = open(pdkPreferencesPath, "w") + pdkPreferences.close() + pdkCmakeFuncFilePath = os.path.join(pdkPath, "PdkSupport.cmake") if not os.path.exists(pdkCmakeFuncFilePath): pdkCmakeFuncTemplate = Template( @@ -143,7 +148,8 @@ pdkCmakeContent = pdkCmakeTemplate.render( deps_path=generatorOptions["pdk"]["deps_path"], plugin_dir=pluginDirName, - plugin_name=pluginName + plugin_name=pluginName, + preferences_path = pdkPreferencesPath ) pdkCmakeFile = open(pdkCmakeFilePath, "w") pdkCmakeFile.write(pdkCmakeContent) diff --git a/tools/plugingenerator/templates/pdk/pdk_cmake_template.mako b/tools/plugingenerator/templates/pdk/pdk_cmake_template.mako index 6536d0dac6..d5feba4bd5 100644 --- a/tools/plugingenerator/templates/pdk/pdk_cmake_template.mako +++ b/tools/plugingenerator/templates/pdk/pdk_cmake_template.mako @@ -30,6 +30,7 @@ if(NOT EXISTS ${"${PDK_DEPS_LIB}"}) endif() set(PLUGIN_INSTALL_PATH ${"${CMAKE_CURRENT_BINARY_DIR}"}/plugin/${plugin_dir}/libscopy-${plugin_name}.so) +set(PATH_TO_INI ${preferences_path}) find_package(QT NAMES Qt5 REQUIRED COMPONENTS Widgets) find_package(Qt${"${QT_VERSION_MAJOR}"} REQUIRED COMPONENTS Widgets Core) diff --git a/tools/plugingenerator/templates/pdk/pdk_cmakein_template.mako b/tools/plugingenerator/templates/pdk/pdk_cmakein_template.mako index 040dd6be9c..dd26174d7c 100644 --- a/tools/plugingenerator/templates/pdk/pdk_cmakein_template.mako +++ b/tools/plugingenerator/templates/pdk/pdk_cmakein_template.mako @@ -2,5 +2,6 @@ #define PDK_UTIL_H_CMAKEIN #define PLUGIN_INSTALL_PATH "@PLUGIN_INSTALL_PATH@" +#define PATH_TO_INI "@PATH_TO_INI@" #endif // PDK_UTIL_H_CMAKEIN diff --git a/tools/plugingenerator/templates/pdk/pdk_header_template.mako b/tools/plugingenerator/templates/pdk/pdk_header_template.mako index eea49ca482..71f13571af 100644 --- a/tools/plugingenerator/templates/pdk/pdk_header_template.mako +++ b/tools/plugingenerator/templates/pdk/pdk_header_template.mako @@ -20,6 +20,8 @@ public: public Q_SLOTS: void onConnect(); void onDisconnect(); + void onInit(); + void onDeinit(); void onLoad(); void onUnload(); Q_SIGNALS: @@ -29,6 +31,8 @@ private: QTabWidget *m_tabWidget; QWidget *m_prefPage; QList m_toolList; + QList m_loadedTools; + QLabel *m_aboutPage = nullptr; MainWidget *m_mainWidget = nullptr; void initMainWindow(); @@ -37,7 +41,10 @@ private: void addPluginPrefPage(); void removePluginPrefPage(); QLabel *createTabLabel(QString name); - QWidget *addHorizontalTab(QWidget *w, QLabel *lbl); + QWidget *addHorizontalTab(QWidget *w, QLabel *lbl, bool tabEnabled = true); + QWidget *buildSaveSessionPreference(); + QWidget *generalPreferences(); + void initGeneralPreferences(); }; class MainWidget : public QWidget @@ -47,39 +54,59 @@ public: MainWidget(QWidget *parent); ~MainWidget(); + QString pluginAbout(); QWidget *pluginPrefPage(); QList getPluginTools(); Q_SIGNALS: void connected(); void disconnected(); + void init(); + void deinit(); void loaded(); void unloaded(); private Q_SLOTS: void onConnect(); void onDisconnect(); - void loadPlugin(); - void unloadPlugin(); + void deinitialize(); + void onInit(); + void onLoad(); + void onUnload(); void browseFile(QLineEdit *pluginPathEdit); + void deletePluginManager(); private: - void unloadPluginDetails(); - void loadPluginDetails(); + void unloadInfoPage(); + void loadInfoPage(); + void changeVisibility(QPushButton *btn1, QPushButton *btn2); + void enableBrowseInit(bool en); + void enableLoadConn(bool en); + void updateStatusLbl(QString msg); bool validConnection(QString uri, QString cat); bool isCompatible(QString uri, QString cat); PluginManager *m_pluginManager; + QLabel *m_statusLbl; QLineEdit *m_uriEdit; QLineEdit *m_pluginPathEdit; - QPushButton *m_connBtn; - QPushButton *m_disconnBtn; + QPushButton *m_browseBtn; + QPushButton *m_initBtn; QPushButton *m_loadBtn; QPushButton *m_unloadBtn; + QPushButton *m_connBtn; + QPushButton *m_disconnBtn; + QWidget *m_pluginIcon; scopy::MenuCombo *m_deviceTypeCb; QScrollArea *m_scrollArea; - bool m_connected; + QString m_currentPlugin; + enum State + { + Unloaded, + Loaded, + Connected + } m_state; }; class PluginManager : public QObject @@ -101,6 +128,7 @@ private: bool pluginCategory(QString category); scopy::Plugin *m_plugin = nullptr; + bool m_loaded; }; class ConnectionStrategy : public QObject diff --git a/tools/plugingenerator/templates/pdk/pdk_src_template.mako b/tools/plugingenerator/templates/pdk/pdk_src_template.mako index 5c37144ee7..44c9edb1d3 100644 --- a/tools/plugingenerator/templates/pdk/pdk_src_template.mako +++ b/tools/plugingenerator/templates/pdk/pdk_src_template.mako @@ -8,8 +8,13 @@ #include #include #include +#include +#include +#include #include "gui/stylehelper.h" +#include "gui/preferenceshelper.h" #include "pdk-util_config.h" +#include int main(int argc, char *argv[]) { @@ -40,14 +45,18 @@ PDKWindow::PDKWindow(QWidget *parent) layout()->setSpacing(6); scopy::StyleHelper::GetInstance()->initColorMap(); m_mainWidget = new MainWidget(this); + m_aboutPage = new QLabel(this); + m_aboutPage->setAlignment(Qt::AlignTop); initMainWindow(); initPreferencesPage(); addHorizontalTab(m_mainWidget, createTabLabel("Main")); - addHorizontalTab(new QWidget(), createTabLabel("About")); + addHorizontalTab(m_aboutPage, createTabLabel("About")); addHorizontalTab(m_prefPage, createTabLabel("Preferences")); connect(m_mainWidget, &MainWidget::connected, this, &PDKWindow::onConnect); connect(m_mainWidget, &MainWidget::disconnected, this, &PDKWindow::onDisconnect); + connect(m_mainWidget, &MainWidget::init, this, &PDKWindow::onInit); + connect(m_mainWidget, &MainWidget::deinit, this, &PDKWindow::onDeinit); connect(m_mainWidget, &MainWidget::loaded, this, &PDKWindow::onLoad); connect(m_mainWidget, &MainWidget::unloaded, this, &PDKWindow::onUnload); } @@ -62,6 +71,9 @@ PDKWindow::~PDKWindow() void PDKWindow::onConnect() { + if(!m_loadedTools.isEmpty()) { + onUnload(); + } QList tools = m_mainWidget->getPluginTools(); for(const scopy::ToolMenuEntry *t : qAsConst(tools)) { if(!t->tool()) @@ -90,9 +102,158 @@ void PDKWindow::onDisconnect() } } -void PDKWindow::onLoad() { addPluginPrefPage(); } +void PDKWindow::onInit() +{ + addPluginPrefPage(); + m_aboutPage->clear(); + m_aboutPage->setText(m_mainWidget->pluginAbout()); +} + +void PDKWindow::onDeinit() +{ + m_aboutPage->clear(); + removePluginPrefPage(); +} + +void PDKWindow::onLoad() +{ + QList tools = m_mainWidget->getPluginTools(); + for(const scopy::ToolMenuEntry *t : qAsConst(tools)) { + if(t->name().isEmpty()) + continue; + QLabel *lbl = createTabLabel(t->name()); + QWidget *tab = addHorizontalTab(new QWidget(), lbl, false); + m_loadedTools.append(tab); + } +} + +void PDKWindow::onUnload() +{ + if(m_loadedTools.isEmpty()) + return; + for(auto t : qAsConst(m_loadedTools)) { + int idx = m_tabWidget->indexOf(t); + m_tabWidget->removeTab(idx); + m_loadedTools.removeOne(t); + } +} + +QWidget *PDKWindow::buildSaveSessionPreference() +{ + scopy::Preferences *p = scopy::Preferences::GetInstance(); + QWidget *w = new QWidget(this); + QHBoxLayout *lay = new QHBoxLayout(w); + lay->setMargin(0); + + lay->addWidget(scopy::PreferencesHelper::addPreferenceCheckBox(p, "general_save_session", + "Save/Load Scopy session", this)); + lay->addSpacerItem(new QSpacerItem(40, 40, QSizePolicy::Expanding, QSizePolicy::Fixed)); + lay->addWidget(new QLabel("Settings files location ", this)); + QPushButton *navigateBtn = new QPushButton("Open", this); + scopy::StyleHelper::BlueButton(navigateBtn, "navigateBtn"); + navigateBtn->setMaximumWidth(80); + connect(navigateBtn, &QPushButton::clicked, this, + [=]() { QDesktopServices::openUrl(scopy::config::settingsFolderPath()); }); + lay->addWidget(navigateBtn); + return w; +} + +QWidget *PDKWindow::generalPreferences() +{ + QWidget *page = new QWidget(this); + QVBoxLayout *lay = new QVBoxLayout(page); + initGeneralPreferences(); + scopy::Preferences *p = scopy::Preferences::GetInstance(); -void PDKWindow::onUnload() { removePluginPrefPage(); } + lay->setMargin(0); + lay->setSpacing(10); + page->setLayout(lay); + + // General preferences + scopy::MenuSectionWidget *generalWidget = new scopy::MenuSectionWidget(page); + scopy::MenuCollapseSection *generalSection = + new scopy::MenuCollapseSection("General", scopy::MenuCollapseSection::MHCW_NONE, generalWidget); + generalWidget->contentLayout()->setSpacing(10); + generalWidget->contentLayout()->addWidget(generalSection); + generalSection->contentLayout()->setSpacing(10); + lay->addWidget(generalWidget); + lay->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + generalSection->contentLayout()->addWidget(buildSaveSessionPreference()); + generalSection->contentLayout()->addWidget(scopy::PreferencesHelper::addPreferenceCheckBox( + p, "general_save_attached", "Save/Load tool attached state", generalSection)); + generalSection->contentLayout()->addWidget(scopy::PreferencesHelper::addPreferenceCheckBox( + p, "general_doubleclick_attach", "Doubleclick to attach/detach tool", generalSection)); + generalSection->contentLayout()->addWidget(scopy::PreferencesHelper::addPreferenceCheckBox( + p, "general_doubleclick_ctrl_opens_menu", "Doubleclick control buttons to open menu", generalSection)); + generalSection->contentLayout()->addWidget(scopy::PreferencesHelper::addPreferenceCheckBox( + p, "general_use_opengl", "Enable OpenGL plotting", generalSection)); + generalSection->contentLayout()->addWidget(scopy::PreferencesHelper::addPreferenceCheckBox( + p, "general_use_animations", "Enable menu animations", generalSection)); + generalSection->contentLayout()->addWidget(scopy::PreferencesHelper::addPreferenceCheckBox( + p, "general_check_online_version", "Enable automatic online check for updates.", generalSection)); + generalSection->contentLayout()->addWidget(scopy::PreferencesHelper::addPreferenceCheckBox( + p, "general_show_status_bar", "Enable the status bar for displaying important messages.", + generalSection)); + generalSection->contentLayout()->addWidget( + scopy::PreferencesHelper::addPreferenceCheckBox(p, "show_grid", "Show Grid", generalSection)); + generalSection->contentLayout()->addWidget( + scopy::PreferencesHelper::addPreferenceCheckBox(p, "show_graticule", "Show Graticule", generalSection)); + generalSection->contentLayout()->addWidget(scopy::PreferencesHelper::addPreferenceCheckBox( + p, "iiowidgets_use_lazy_loading", "Use Lazy Loading", generalSection)); + generalSection->contentLayout()->addWidget(scopy::PreferencesHelper::addPreferenceCheckBox( + p, "plugins_use_debugger_v2", "Use Debugger V2 plugin", generalSection)); + generalSection->contentLayout()->addWidget(scopy::PreferencesHelper::addPreferenceCombo( + p, "general_theme", "Theme", {"default", "light"}, generalSection)); + + // Debug preferences + scopy::MenuSectionWidget *debugWidget = new scopy::MenuSectionWidget(page); + scopy::MenuCollapseSection *debugSection = + new scopy::MenuCollapseSection("Debug", scopy::MenuCollapseSection::MHCW_NONE, debugWidget); + debugWidget->contentLayout()->setSpacing(10); + debugWidget->contentLayout()->addWidget(debugSection); + debugSection->contentLayout()->setSpacing(10); + lay->addWidget(debugWidget); + lay->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + debugSection->contentLayout()->addWidget(scopy::PreferencesHelper::addPreferenceCheckBox( + p, "general_show_plot_fps", "Show plot FPS", debugSection)); + debugSection->contentLayout()->addWidget(scopy::PreferencesHelper::addPreferenceCombo( + p, "general_plot_target_fps", "Plot target FPS", {"15", "20", "30", "60"}, debugSection)); + + return page; +} + +void PDKWindow::initGeneralPreferences() +{ + scopy::Preferences *p = scopy::Preferences::GetInstance(); + p->setPreferencesFilename(PATH_TO_INI); + p->load(); + p->init("general_first_run", true); + p->init("general_save_session", true); + p->init("general_save_attached", true); + p->init("general_doubleclick_attach", true); +#if defined(__arm__) + p->init("general_use_opengl", false); +#else + p->init("general_use_opengl", true); +#endif + p->init("general_use_animations", true); + p->init("general_theme", "default"); + p->init("general_language", "en"); + p->init("show_grid", true); + p->init("show_graticule", false); + p->init("iiowidgets_use_lazy_loading", true); + p->init("plugins_use_debugger_v2", true); + p->init("general_plot_target_fps", "60"); + p->init("general_show_plot_fps", true); + p->init("general_use_native_dialogs", true); + p->init("general_additional_plugin_path", ""); + p->init("general_load_decoders", true); + p->init("general_doubleclick_ctrl_opens_menu", true); + p->init("general_check_online_version", false); + p->init("general_show_status_bar", true); +} void PDKWindow::initMainWindow() { @@ -112,7 +273,7 @@ void PDKWindow::initMainWindow() lay->addWidget(m_tabWidget); } -QWidget *PDKWindow::addHorizontalTab(QWidget *w, QLabel *lbl) +QWidget *PDKWindow::addHorizontalTab(QWidget *w, QLabel *lbl, bool tabEnabled) { QWidget *pane = new QWidget(m_tabWidget); pane->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); @@ -127,21 +288,30 @@ QWidget *PDKWindow::addHorizontalTab(QWidget *w, QLabel *lbl) lay->addWidget(scrollArea); // Hackish - so we don't override paint event - m_tabWidget->addTab(pane, ""); + int tabIdx = m_tabWidget->addTab(pane, ""); + m_tabWidget->setTabEnabled(tabIdx, tabEnabled); + QTabBar *tabbar = m_tabWidget->tabBar(); tabbar->setTabButton(tabbar->count() - 1, QTabBar::LeftSide, lbl); + tabbar->tabButton(tabbar->count() - 1, QTabBar::LeftSide)->setEnabled(tabEnabled); return pane; } void PDKWindow::initPreferencesPage() { m_prefPage = new QWidget(this); QGridLayout *lay = new QGridLayout(m_prefPage); - lay->setSpacing(0); + lay->setSpacing(6); lay->setMargin(0); - QLabel *title = new QLabel(m_prefPage); - title->setText("Plugin Preferences"); - scopy::StyleHelper::MenuHeaderLabel(title); - lay->addWidget(title, 0, 0, Qt::AlignTop | Qt::AlignLeft); + + scopy::MenuSectionWidget *generalWidget = new scopy::MenuSectionWidget(m_prefPage); + scopy::MenuCollapseSection *generalSection = new scopy::MenuCollapseSection( + "Scopy preferences", scopy::MenuCollapseSection::MHCW_NONE, generalWidget); + generalWidget->contentLayout()->setSpacing(10); + generalWidget->contentLayout()->addWidget(generalSection); + generalSection->contentLayout()->setSpacing(10); + generalSection->contentLayout()->addWidget(generalPreferences()); + + lay->addWidget(generalWidget, 0, 0); lay->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 2, 0); } @@ -150,7 +320,16 @@ void PDKWindow::addPluginPrefPage() QWidget *pluginPref = m_mainWidget->pluginPrefPage(); if(pluginPref) { QGridLayout *lay = dynamic_cast(m_prefPage->layout()); - lay->addWidget(pluginPref, 1, 0); + if(!lay) + return; + scopy::MenuSectionWidget *pluginWidget = new scopy::MenuSectionWidget(m_prefPage); + scopy::MenuCollapseSection *pluginSection = new scopy::MenuCollapseSection( + "Plugin preferences", scopy::MenuCollapseSection::MHCW_NONE, pluginWidget); + pluginWidget->contentLayout()->setSpacing(10); + pluginWidget->contentLayout()->addWidget(pluginSection); + pluginSection->contentLayout()->setSpacing(10); + pluginSection->contentLayout()->addWidget(pluginPref); + lay->addWidget(pluginWidget, 1, 0); } } @@ -180,50 +359,69 @@ MainWidget::MainWidget(QWidget *parent) : QWidget(parent) , m_pluginManager(nullptr) { + m_state = State::Unloaded; setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); this->setMinimumWidth(1024); QGridLayout *lay = new QGridLayout(this); lay->setMargin(9); lay->setSpacing(6); + m_statusLbl = new QLabel(this); + scopy::StyleHelper::WarningLabel(m_statusLbl); + m_statusLbl->setWordWrap(true); + // browse section - QPushButton *browseBtn = new QPushButton("Browse", this); - scopy::StyleHelper::BlueGrayButton(browseBtn); - browseBtn->setFixedWidth(128); + m_browseBtn = new QPushButton("Browse", this); + scopy::StyleHelper::BlueButton(m_browseBtn); + m_browseBtn->setFixedWidth(128); + m_browseBtn->setFixedHeight(40); m_pluginPathEdit = new QLineEdit(this); m_pluginPathEdit->setText(PLUGIN_INSTALL_PATH); m_pluginPathEdit->setPlaceholderText(PLUGIN_INSTALL_PATH); - connect(browseBtn, &QPushButton::clicked, this, [this]() { browseFile(m_pluginPathEdit); }); - + connect(m_browseBtn, &QPushButton::clicked, this, [this]() { + browseFile(m_pluginPathEdit); + enableLoadConn(false); + }); + + // init + m_initBtn = new QPushButton("Init", this); + scopy::StyleHelper::BlueButton(m_initBtn); + m_initBtn->setFixedWidth(128); + m_initBtn->setFixedHeight(40); + connect(m_initBtn, &QPushButton::clicked, this, &MainWidget::onInit); + + // load btn QWidget *loadBtns = new QWidget(this); loadBtns->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); loadBtns->setLayout(new QVBoxLayout(loadBtns)); loadBtns->layout()->setSpacing(0); loadBtns->layout()->setMargin(0); - // load section - m_loadBtn = new QPushButton("Load", loadBtns); - scopy::StyleHelper::BlueGrayButton(m_loadBtn); - m_loadBtn->setFixedWidth(128); - connect(m_loadBtn, &QPushButton::clicked, this, &MainWidget::loadPlugin); + m_loadBtn = new QPushButton("Load", this); + scopy::StyleHelper::BlueButton(m_loadBtn); + m_loadBtn->setFixedWidth(128); + m_loadBtn->setFixedHeight(40); + m_loadBtn->setEnabled(false); + connect(m_loadBtn, &QPushButton::clicked, this, &MainWidget::onLoad); - // unload - m_unloadBtn = new QPushButton("Unload", loadBtns); - scopy::StyleHelper::BlueGrayButton(m_unloadBtn); + m_unloadBtn = new QPushButton("Unload", this); + scopy::StyleHelper::BlueButton(m_unloadBtn); m_unloadBtn->setFixedWidth(128); + m_unloadBtn->setFixedHeight(40); m_unloadBtn->setVisible(false); - connect(m_unloadBtn, &QPushButton::clicked, this, &MainWidget::unloadPlugin); + connect(m_unloadBtn, &QPushButton::clicked, this, &MainWidget::onUnload); loadBtns->layout()->addWidget(m_loadBtn); loadBtns->layout()->addWidget(m_unloadBtn); + // connect section m_uriEdit = new QLineEdit(this); m_uriEdit->setPlaceholderText("URI"); m_uriEdit->setText("ip:127.0.0.1"); m_deviceTypeCb = new scopy::MenuCombo("category", this); - m_deviceTypeCb->setFixedHeight(45); + m_deviceTypeCb->setFixedHeight(40); m_deviceTypeCb->combo()->addItem("iio"); m_deviceTypeCb->combo()->addItem("test"); @@ -234,19 +432,22 @@ MainWidget::MainWidget(QWidget *parent) connBtns->layout()->setMargin(0); m_connBtn = new QPushButton("Connect", this); - scopy::StyleHelper::BlueGrayButton(m_connBtn); + scopy::StyleHelper::BlueButton(m_connBtn); m_connBtn->setFixedWidth(128); + m_connBtn->setFixedHeight(40); m_connBtn->setEnabled(false); connect(m_connBtn, &QPushButton::clicked, this, &MainWidget::onConnect); m_disconnBtn = new QPushButton("Disconnect", this); - scopy::StyleHelper::BlueGrayButton(m_disconnBtn); + scopy::StyleHelper::BlueButton(m_disconnBtn); m_disconnBtn->setFixedWidth(128); + m_disconnBtn->setFixedHeight(40); m_disconnBtn->setVisible(false); connect(m_disconnBtn, &QPushButton::clicked, this, &MainWidget::onDisconnect); connBtns->layout()->addWidget(m_connBtn); connBtns->layout()->addWidget(m_disconnBtn); + // plugin info QWidget *pluginPage = new QWidget(this); pluginPage->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -266,28 +467,43 @@ MainWidget::MainWidget(QWidget *parent) lay->addWidget(m_pluginPathEdit, 0, 0); lay->addWidget(m_deviceTypeCb, 1, 0); lay->addWidget(m_uriEdit, 2, 0); - lay->addWidget(pluginPage, 3, 0); - - lay->addWidget(browseBtn, 0, 1, Qt::AlignTop); - lay->addWidget(loadBtns, 1, 1, Qt::AlignTop); - lay->addWidget(connBtns, 2, 1, Qt::AlignTop); - lay->addWidget(m_pluginIcon, 3, 1, Qt::AlignCenter | Qt::AlignBottom); + lay->addWidget(m_statusLbl, 3, 0); + lay->addWidget(pluginPage, 4, 0); + + lay->addWidget(m_browseBtn, 0, 1, Qt::AlignTop); + lay->addWidget(m_initBtn, 1, 1, Qt::AlignTop); + lay->addWidget(loadBtns, 2, 1, Qt::AlignTop); + lay->addWidget(connBtns, 3, 1, Qt::AlignTop); + lay->addWidget(m_pluginIcon, 4, 1, Qt::AlignCenter | Qt::AlignBottom); } MainWidget::~MainWidget() { - if(m_pluginManager) { - unloadPlugin(); + if(m_state == State::Connected) { + onDisconnect(); } + if(m_state == State::Loaded) { + onUnload(); + } + if(!m_currentPlugin.isEmpty()) { + deinitialize(); + } +} + +QString MainWidget::pluginAbout() +{ + if(!m_pluginManager || !m_pluginManager->plugin()) + return ""; + return m_pluginManager->plugin()->about(); } QWidget *MainWidget::pluginPrefPage() { QWidget *prefPage = nullptr; m_pluginManager->plugin()->initPreferences(); - if(m_pluginManager->plugin()->loadPreferencesPage()) { + if(m_pluginManager->plugin()->loadPreferencesPage()) prefPage = m_pluginManager->plugin()->preferencesPage(); - } + return prefPage; } @@ -295,58 +511,114 @@ QList MainWidget::getPluginTools() { return m_pluginMana void MainWidget::onConnect() { + if(m_state == State::Unloaded) + onLoad(); + if(m_state != State::Loaded) + return; if(!m_pluginManager->plugin()->onConnect()) { + updateStatusLbl("Connection failed!"); return; } - m_disconnBtn->setVisible(true); - m_connBtn->setVisible(false); - m_connected = true; + changeVisibility(m_disconnBtn, m_connBtn); + enableBrowseInit(false); + m_unloadBtn->setEnabled(false); + m_state = State::Connected; + updateStatusLbl(""); Q_EMIT connected(); } void MainWidget::onDisconnect() { m_pluginManager->plugin()->onDisconnect(); - m_disconnBtn->setVisible(false); - m_connBtn->setVisible(true); + onUnload(); + changeVisibility(m_disconnBtn, m_connBtn); + m_unloadBtn->setEnabled(true); Q_EMIT disconnected(); } -void MainWidget::loadPlugin() +void MainWidget::changeVisibility(QPushButton *btn1, QPushButton *btn2) +{ + btn1->setVisible(!btn1->isVisible()); + btn2->setVisible(!btn2->isVisible()); +} + +void MainWidget::enableBrowseInit(bool en) +{ + m_initBtn->setEnabled(en); + m_browseBtn->setEnabled(en); +} + +void MainWidget::enableLoadConn(bool en) +{ + m_loadBtn->setEnabled(en); + m_connBtn->setEnabled(en); +} + +void MainWidget::updateStatusLbl(QString msg) +{ + m_statusLbl->clear(); + m_statusLbl->setText(msg); +} + +void MainWidget::deinitialize() +{ + if(m_pluginManager) { + QWidget *pluginIcon = m_pluginManager->plugin()->icon(); + if(pluginIcon) { + m_pluginIcon->layout()->removeWidget(pluginIcon); + delete pluginIcon; + } + } + deletePluginManager(); + Q_EMIT deinit(); +} + +void MainWidget::onInit() { - QString uri = m_uriEdit->text(); - QString cat = m_deviceTypeCb->combo()->currentText(); QString pluginPath = m_pluginPathEdit->text(); - if(!validConnection(uri, cat)) { - m_connBtn->setChecked(false); + if(pluginPath.compare(m_currentPlugin) == 0 && m_pluginManager) { + updateStatusLbl("The plugin is already initialized!"); return; } + deinitialize(); m_pluginManager = new PluginManager(pluginPath, this); - if(!isCompatible(uri, cat)) { - m_connBtn->setChecked(false); - delete m_pluginManager; - m_pluginManager = nullptr; + if(!m_pluginManager->plugin()) { + enableLoadConn(false); + deletePluginManager(); + updateStatusLbl("The plugin couldn't be accessed! Path: " + pluginPath); return; } - loadPluginDetails(); - m_loadBtn->setVisible(false); - m_unloadBtn->setVisible(true); - m_connBtn->setEnabled(true); - Q_EMIT loaded(); + if(m_pluginManager->plugin()->loadIcon()) { + m_pluginIcon->layout()->addWidget(m_pluginManager->plugin()->icon()); + } + m_currentPlugin = pluginPath; + enableLoadConn(true); + updateStatusLbl(""); + Q_EMIT init(); } -void MainWidget::unloadPlugin() +void MainWidget::onLoad() { - unloadPluginDetails(); - if(m_connected) { - onDisconnect(); + QString uri = m_uriEdit->text(); + QString cat = m_deviceTypeCb->combo()->currentText(); + if(!validConnection(uri, cat) || !isCompatible(uri, cat)) { + return; } + loadInfoPage(); + enableBrowseInit(false); + changeVisibility(m_unloadBtn, m_loadBtn); + m_state = State::Loaded; + updateStatusLbl(""); + Q_EMIT loaded(); +} + +void MainWidget::onUnload() +{ m_pluginManager->plugin()->unload(); - delete m_pluginManager; - m_pluginManager = nullptr; - m_unloadBtn->setVisible(false); - m_loadBtn->setVisible(true); - m_connBtn->setEnabled(false); + unloadInfoPage(); + enableBrowseInit(true); + changeVisibility(m_unloadBtn, m_loadBtn); + m_state = State::Unloaded; Q_EMIT unloaded(); } @@ -358,27 +630,27 @@ void MainWidget::browseFile(QLineEdit *pluginPathEdit) pluginPathEdit->setText(filePath); } -void MainWidget::unloadPluginDetails() +void MainWidget::deletePluginManager() +{ + if(m_pluginManager) { + delete m_pluginManager; + m_pluginManager = nullptr; + } +} + +void MainWidget::unloadInfoPage() { QWidget *pluginPage = m_pluginManager->plugin()->page(); if(pluginPage) { m_scrollArea->takeWidget(); } - QWidget *pluginIcon = m_pluginManager->plugin()->icon(); - if(pluginIcon) { - m_pluginIcon->layout()->removeWidget(pluginIcon); - delete pluginIcon; - } } -void MainWidget::loadPluginDetails() +void MainWidget::loadInfoPage() { if(m_pluginManager->plugin()->loadPage()) { m_scrollArea->setWidget(m_pluginManager->plugin()->page()); } - if(m_pluginManager->plugin()->loadIcon()) { - m_pluginIcon->layout()->addWidget(m_pluginManager->plugin()->icon()); - } } bool MainWidget::validConnection(QString uri, QString cat) @@ -387,8 +659,7 @@ bool MainWidget::validConnection(QString uri, QString cat) bool validConn = false; validConn = connStrategy->validConnection(cat); if(!validConn) { - m_uriEdit->clear(); - m_uriEdit->setText("Cannot connect to URI!"); + updateStatusLbl("Cannot connect to URI!"); } connStrategy->deleteLater(); return validConn; @@ -399,14 +670,14 @@ bool MainWidget::isCompatible(QString uri, QString cat) bool compatible = false; compatible = m_pluginManager->pluginCompatibility(uri, cat); if(!compatible) { - m_uriEdit->clear(); - m_uriEdit->setText("The plugin is not compatible with the device or doesn't exist!"); + updateStatusLbl("The plugin is not compatible with the device or doesn't exist!"); } return compatible; } PluginManager::PluginManager(QString pluginPath, QObject *parent) : QObject(parent) + , m_loaded(false) { loadPlugin(pluginPath); } @@ -421,7 +692,7 @@ PluginManager::~PluginManager() void PluginManager::initPlugin() { - if(!m_plugin) + if(!m_plugin || m_loaded) return; m_plugin->preload(); m_plugin->initMetadata(); @@ -429,6 +700,7 @@ void PluginManager::initPlugin() m_plugin->loadToolList(); m_plugin->loadExtraButtons(); m_plugin->postload(); + m_loaded = true; } bool PluginManager::pluginCategory(QString category)