18 #include <QApplication>
20 #include <QPushButton>
21 #include <QMouseEvent>
22 #include <QVBoxLayout>
23 #include <QHBoxLayout>
24 #include <QHeaderView>
25 #include <QMessageBox>
26 #include <QFileDialog>
33 mDefaultTextColor(
Qt::lightGray),
34 mHilightTextColor(
Qt::yellow),
35 mHilightBackgroundColor(
Qt::black)
46 mGuiPluginView->
setModel(mGuiPluginTable);
58 QLabel* legendHeader =
new QLabel(
"Buttons used in table above:",
this);
62 new QLabel(
"Load HAL plugin and dependencies (if any)",
this),
63 new QLabel(
"Unload HAL plugin unless needed as dependency by other plugin",
this),
64 new QLabel(
"This plugin contributes CLI options. Click button for description of options.",
this),
65 new QLabel(
"Enable or disable plugin contributions to GUI context menu.",
this)};
67 for (
int i=0; i<4; i++)
70 mIconLegend[i] =
new QLabel(
this);
87 layout->addLayout(buttonLayout);
92 bool hasEntries =
false;
101 std::vector<PluginParameter> plugParams = geif->
get_parameter();
102 if (plugParams.empty())
106 if (label.
isEmpty()) label = it.key();
123 for (
int i=0; i<4; i++)
144 if (filename.
isEmpty())
return;
147 std::cerr <<
"library file opened <" << filename.
toStdString() <<
">" << std::endl;
149 std::cerr <<
"failed to load library file <" << filename.
toStdString() <<
">" << std::endl;
153 void GuiPluginManager::handleToggleGuiContribution(
const QString &pluginName)
165 void GuiPluginManager::handleShowCliOptions(
const QString &pluginName,
const QString &cliOptions)
174 return mLoadIconPath;
179 return mLoadIconStyle;
184 return mUnloadIconPath;
189 return mUnloadIconStyle;
199 return mCliIconStyle;
204 return mGuiIconEnabledPath;
209 return mGuiIconDisabledPath;
214 return mGuiIconEnabledStyle;
219 return mGuiIconDisabledStyle;
224 return mDefaultTextColor;
229 return mHilightTextColor;
234 return mHilightBackgroundColor;
254 mUnloadIconStyle = s;
269 mGuiIconEnabledPath = s;
274 mGuiIconDisabledPath = s;
279 mGuiIconEnabledStyle = s;
284 mGuiIconDisabledStyle = s;
289 mDefaultTextColor = c;
294 mHilightTextColor = c;
299 mHilightBackgroundColor = c;
303 const std::vector<u32>& modules,
304 const std::vector<u32>& gates,
305 const std::vector<u32>& nets)
307 bool addedSeparator =
false;
326 addedSeparator =
true;
330 QMenu *subMenu = contextMenu->
addMenu(
" " + (subMenuEntry.
isEmpty() ? it.key() : subMenuEntry));
335 {cmc.mContributer->execute_function(cmc.mTagname,
netlist, modules, gates, nets);}
352 mWaitForRefresh =
true;
353 populateTable(
false);
354 mWaitForRefresh =
false;
364 if (mWaitForRefresh)
return;
367 mWaitForRefresh =
true;
370 mWaitForRefresh =
false;
374 void GuiPluginTable::populateTable(
bool refresh)
383 for (
int i=0; i<nentry; i++)
394 if (!dir.exists())
continue;
395 for (
QFileInfo info : dir.entryInfoList())
397 if (!info.isFile())
continue;
400 QString pluginName = info.baseName();
401 GuiPluginEntry* gpe = pluginEntries.
value(pluginName);
402 bool needUpdate =
true;
405 needUpdate = gpe->mFileModified != info.lastModified();
406 gpe->setFileFound(
true);
410 gpe =
new GuiPluginEntry(info);
411 pluginEntries.
insert(pluginName,gpe);
415 if (bpif && !refresh)
418 bool alreadyLoaded = loadedPlugins.find(pluginName.
toStdString())!=loadedPlugins.end();
419 gpe->updateFromLoaded(bpif, alreadyLoaded);
423 else if (gpe->requestLoad())
426 bpif =
load(pluginName, info.absoluteFilePath());
430 log_warning(
"gui",
"GuiPluginManager: loading of requested plugin '{}' failed.", pluginName.
toStdString());
434 gpe->updateFromLoaded(bpif,
true, info.lastModified());
435 log_info(
"gui",
"GuiPluginManager: '{}' loaded upon user request.", pluginName.
toStdString());
442 log_debug(
"gui",
"GuiPluginManager: '{}' not modified, no update required.", pluginName.
toStdString());
452 bpif =
load(pluginName, info.absoluteFilePath());
455 log_warning(
"gui",
"GuiPluginManager: loading of '{}' failed, is it really a HAL plugin?", pluginName.
toStdString());
460 if (bpif->get_name().empty() || bpif->get_version().empty())
462 log_warning(
"gui",
"GuiPluginManager: '{}' has empty name or version, plugin ignored.", pluginName.
toStdString());
467 log_info(
"gui",
"GuiPluginManager: '{}' loaded to retrieve information about plugin features.", pluginName.
toStdString());
468 gpe->updateFromLoaded(bpif,
false, info.lastModified());
473 for (
int i=0; i<1000; i++)
475 auto it = pluginStateRestored.begin();
476 while (it != pluginStateRestored.end())
478 auto jt = pluginsBeforeLoad.find(*it);
479 if (jt != pluginsBeforeLoad.end())
480 it = pluginStateRestored.erase(it);
482 it = pluginStateRestored.erase(it);
486 if (pluginStateRestored.empty())
break;
488 for (
QString dep : gpe->mDependencies)
502 if (!gpe || gpe->isLoaded())
continue;
506 gpe->updateFromLoaded(bpif,
false,info.exists()?info.lastModified():
QDateTime());
512 auto it = pluginEntries.
begin();
513 while (it != pluginEntries.
end())
516 GuiPluginEntry* gpe = it.value();
517 if (gpe->isFileFound())
521 mLookup.
insert(gpe->mName,mEntries.size());
522 mEntries.append(gpe);
529 else if (gpe->mExternalPath.isEmpty() || !gpe->requestLoad() )
538 if (info.exists() && info.isReadable())
540 mLookup.
insert(gpe->mName,mEntries.size());
541 mEntries.append(gpe);
542 BasePluginInterface* bpif =
load(gpe->mName, info.absoluteFilePath());
545 log_warning(
"gui",
"GuiPluginManager: loading of requested plugin '{}' failed.", gpe->mName.toStdString());
550 gpe->updateFromLoaded(bpif,
true, info.lastModified());
551 log_info(
"gui",
"GuiPluginManager: '{}' loaded external plugin upon user request.", gpe->mName.toStdString());
560 it = pluginEntries.
erase(it);
571 int n = mEntries.size();
574 mEntries.append(gpe);
587 gpe = mEntries.takeLast();
599 if (mWaitForRefresh)
return;
605 if (mWaitForRefresh)
return;
611 int irow = mLookup.
value(pluginName,-1);
612 if (irow < 0 || irow >= mEntries.size())
return;
654 pluginMap.
insert(
".hal",
"HAL progress files ");
658 reStr =
"Default (.*) Parser";
660 reStr =
"Default (.*) Writer";
665 if (pluginMap.
size() > 1)
669 if (!retval.
isEmpty()) retval +=
" ";
673 retval.
prepend(
"All supported files (");
683 formatMap[fileFmt] +=
" *" + it.
key();
685 formatMap[fileFmt] =
"*" + it.
key();
689 if (!retval.
isEmpty()) retval +=
";;";
690 retval += it.key() +
"(" + it.value() +
")";
702 bool extensionFound =
false;
707 extensionFound =
true;
711 if (!extensionFound)
continue;
723 log_warning(
"gui",
"Error loading plugin '{}' from location '{}'",
766 void GuiPluginTable::clearMemory()
781 return mEntries.size();
795 case 0:
return "Name";
796 case 1:
return "Description";
797 case 2:
return "Filename";
798 case 3:
return "Timestamp";
799 case 4:
return "Dependencies";
800 case 5:
return "Category";
801 case 6:
return "Extensions";
802 case 7:
return "GUI";
803 case 8:
return "CLI";
804 case 9:
return "State";
814 return mEntries.at(irow);
819 if (mWaitForRefresh)
return;
821 int irow = buttonIndex.
row();
822 if (irow >= mEntries.size())
return;
824 switch (buttonIndex.
column())
827 if (gpe->
mName ==
"hal_gui")
return;
836 if (gpe->
mName ==
"hal_gui")
return;
838 bool success =
false;
849 QString(
"Unload of plugin %1\nrefused by plugin_manager")
855 QString(
"Cannot unload plugin %1\nwhich is required by %2")
868 QString(
"Could not load plugin %1\nplease check plugin_manager log")
883 if (mEntries.at(
index.
row())->isLoaded())
887 if (mEntries.at(
index.
row())->isLoaded())
898 return (v.
toBool() ?
"X" :
" ");
904 if (
index.
row() >= mEntries.size())
return false;
905 return mEntries.at(
index.
row())->mName ==
"hal_gui";
911 return mEntries.at(
index.
row())->mGuiExtensionState;
916 int irow = mLookup.
value(pluginName,-1);
917 if (irow < 0 || irow >= mEntries.size())
return;
918 mEntries.at(irow)->mGuiExtensionState =
state;
924 if (
index.
row() >= mEntries.size())
return false;
925 return !mEntries.at(
index.
row())->mCliOptions.isEmpty();
930 if (
index.
row() >= mEntries.size())
return false;
931 return mEntries.at(
index.
row())->isLoaded();
939 if (gpe->
mName == pluginName)
continue;
941 if (dep == pluginName)
954 : mLoadState(NotAPlugin), mName(info.baseName()),
955 mFilePath(info.absoluteFilePath()),
956 mFileModified(info.lastModified()),
958 mUserInterface(false),
959 mGuiExtensionState(Unknown),
967 case 0:
return mName;
983 return "Other HAL plugin";
988 case 9:
if (!
isLoaded())
return "-";
990 else return "EXTERN";
1065 for (std::string arg : feature.args)
1093 for (
int i=0; i<3; i++)
1112 for (
int i=0; i<3; i++)
1113 delete mTemplateButton[i];
1122 bool drawIcon =
true;
1127 button.iconSize =
QSize(w-4,w-4);
1155 button.icon = mIconDisableGuiContribution;
1158 button.icon = mIconEnableGuiContribution;
1163 button.iconSize =
QSize(w-4,w-4);
1165 button.icon = mIconCliOptions;
1175 button.icon = mIconUnload;
1177 button.icon = mIconLoad;
1178 button.iconSize =
QSize(w-12,w-12);
1186 State stat = Normal;
1188 if (mMouseIndex.
isValid() && mMouseIndex == index)
1198 button.rect =
QRect(x,y,w,h);
1209 return QSize(30,30);
1215 if (!mev)
return false;
1216 switch (mev->
type())
1219 mMousePos = mev->
pos();
1220 mMouseIndex = index;
1223 if ((mMousePos - mev->
pos()).manhattanLength()<4)
Copyright The Montserrat Project in Original or Modified may be sold by itself Original or Modified Versions of the Font Software may be redistributed and or sold with any provided that each copy contains the above copyright notice and this license These can be included either as stand alone text human readable headers or in the appropriate machine readable metadata fields within text or binary files as long as those fields can be easily viewed by the user No Modified Version of the Font Software may use the Reserved Font endorse or advertise any Modified except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 5) The Font Software
virtual std::set< std::string > get_dependencies() const
virtual std::string get_name() const =0
virtual std::string get_description() const
virtual std::string get_version() const =0
virtual std::vector< AbstractExtensionInterface * > get_extensions() const
virtual ProgramOptions get_cli_options() const =0
virtual std::vector< ContextMenuContribution > get_context_contribution(const Netlist *nl, const std::vector< u32 > &mods, const std::vector< u32 > &gats, const std::vector< u32 > &nets)
void set_contribution_enabled(bool enabled)
bool is_contribution_enabled() const
std::string contribution_top_label() const
virtual void netlist_loaded(Netlist *nl)
virtual std::vector< PluginParameter > get_parameter() const
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
GuiPluginDelegate(QObject *parent=nullptr)
void buttonPressed(QModelIndex index)
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override
void updateQss(GuiPluginManager *gpm)
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
GuiPluginEntry(const QFileInfo &info)
void persist(QSettings *settings) const
QStringList mFeatureArguments
QStringList mDependencies
FacExtensionInterface::Feature mFeature
QVariant data(int icol) const
GuiExtensionState enforceGuiExtensionState(GuiExtensionInterface *geif) const
enum hal::GuiPluginEntry::LoadState mLoadState
enum hal::GuiPluginEntry::GuiExtensionState mGuiExtensionState
void updateFromLoaded(const BasePluginInterface *bpif, bool isUser, const QDateTime &modified=QDateTime())
void setLoadIconStyle(const QString &s)
void setGuiIconEnabledPath(const QString &s)
void addPluginActions(QMenu *menu) const
void setDefaultTextColor(QColor &c)
void handleLoadExternalPlugin()
GuiPluginManager(QWidget *parent=nullptr)
void setHilightTextColor(QColor &c)
void setUnloadIconPath(const QString &s)
QString guiIconDisabledStyle
void setHilightBackgroundColor(QColor &c)
static void addPluginSubmenus(QMenu *contextMenu, Netlist *netlist, const std::vector< u32 > &modules, const std::vector< u32 > &gates, const std::vector< u32 > &nets)
QColor hilightBackgroundColor
void setGuiIconDisabledPath(const QString &s)
static QMap< QString, GuiExtensionInterface * > getGuiExtensions()
void setCliIconPath(const QString &s)
QString guiIconEnabledStyle
void setLoadIconPath(const QString &s)
void setGuiIconEnabledStyle(const QString &s)
void setCliIconStyle(const QString &s)
void handleButtonCancel()
QString guiIconDisabledPath
void setGuiIconDisabledStyle(const QString &s)
QString guiIconEnabledPath
void setUnloadIconStyle(const QString &s)
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
SupportedFileFormats listFacFeature(FacExtensionInterface::Feature ft) const
bool isHalGui(const QModelIndex &index) const
bool isLoaded(const QModelIndex &index) const
BasePluginInterface * load(const QString &pluginName, const QString &path) const
int rowCount(const QModelIndex &parent=QModelIndex()) const override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
GuiPluginEntry::GuiExtensionState guiExtensionState(const QModelIndex &index) const
GuiPluginTable(GuiPluginManager *parent=nullptr)
int addExternalPlugin(const QString &path)
void setGuiExtensionState(const QString &pluginName, GuiPluginEntry::GuiExtensionState state)
GuiPluginEntry * at(int irow) const
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
void handleButtonPressed(const QModelIndex &buttonIndex)
void handlePluginLoaded(const QString &pluginName, const QString &path)
void handlePluginUnloaded(const QString &pluginName, const QString &path)
void showCliOptions(QString pluginName, QString cliOptions)
void toggleEnableGuiContribution(QString pluginName)
void loadFeature(FacExtensionInterface::Feature ft, const QString &extension=QString())
bool hasCliExtension(const QModelIndex &index) const
QStringList neededBy(const QString &pluginName)
void removeEntry(int irow)
GuiPluginView(QWidget *parent=nullptr)
GuiPluginTable * mGuiPluginTable
void pluginUnloaded(const QString &name, const QString &path)
void pluginLoaded(const QString &name, const QString &path)
std::string get_options_string() const
#define log_debug(channel,...)
#define log_info(channel,...)
#define log_warning(channel,...)
QIcon getStyledSvgIcon(const QString &from_to_colors_enabled, const QString &svg_path, QString from_to_colors_disabled=QString())
bool has_valid_file_extension(std::filesystem::path file_name)
bool unload(const std::string &plugin_name)
std::set< std::string > get_plugin_names()
BasePluginInterface * get_plugin_instance(const std::string &plugin_name, bool initialize, bool silent)
std::filesystem::path get_plugin_path(std::string plugin_name)
std::vector< PluginFeature > get_plugin_features(std::string name)
bool load(const std::string &plugin_name, const std::filesystem::path &file_path_or_empty)
std::filesystem::path get_user_config_directory()
std::vector< std::filesystem::path > get_plugin_directories()
PluginRelay * gPluginRelay
option(PL_GUI "PL_GUI" ON) if(PL_GUI OR BUILD_ALL_PLUGINS) cmake_minimum_required(VERSION 3.5.0) if(APPLE AND CMAKE_HOST_APPLE AND NOT Qt5_DIR) set(Qt5_DIR "/usr/local/opt/qt@5/lib/cmake") endif(APPLE AND CMAKE_HOST_APPLE AND NOT Qt5_DIR) find_package(Qt5 COMPONENTS Core REQUIRED) find_package(Qt5 COMPONENTS Widgets REQUIRED) if(Qt5Widgets_FOUND) message(VERBOSE "Qt5Widgets_INCLUDE_DIRS
void beginInsertRows(const QModelIndex &parent, int first, int last)
void beginRemoveRows(const QModelIndex &parent, int first, int last)
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector< int > &roles)
void setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
void triggered(bool checked)
bool isValid() const const
bool isValid() const const
QString toString(Qt::DateFormat format) const const
QEvent::Type type() const const
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
QString baseName() const const
QString fileName() const const
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) const const
void setAlignment(Qt::Alignment)
void setPixmap(const QPixmap &)
bool setAlignment(QWidget *w, Qt::Alignment alignment)
void append(const T &value)
bool isEmpty() const const
QMap::const_iterator constBegin() const const
QMap::const_iterator constEnd() const const
bool contains(const Key &key) const const
QMap::iterator erase(QMap::iterator pos)
QMap::iterator insert(const Key &key, const T &value)
const Key key(const T &value, const Key &defaultKey) const const
QList< Key > keys() const const
int remove(const Key &key)
const T value(const Key &key, const T &defaultValue) const const
virtual int exec() override
QMessageBox::StandardButton warning(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
bool isValid() const const
const QAbstractItemModel * model() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
virtual bool event(QEvent *e)
void fillRect(const QRectF &rectangle, const QBrush &brush)
QString cap(int nth) const const
int indexIn(const QString &str, int offset, QRegExp::CaretMode caretMode) const const
int beginReadArray(const QString &prefix)
void beginWriteArray(const QString &prefix, int size)
void setArrayIndex(int i)
void setValue(const QString &key, const QVariant &value)
QVariant value(const QString &key, const QVariant &defaultValue) const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromStdString(const std::string &str)
bool isEmpty() const const
QString & prepend(QChar ch)
QString & remove(int position, int n)
std::string toStdString() const const
QString join(const QString &separator) const const
virtual void drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const=0
virtual void polish(QWidget *widget)
virtual void unpolish(QWidget *widget)
virtual void setModel(QAbstractItemModel *model) override
bool toBool() const const
QDateTime toDateTime() const const
int toInt(bool *ok) const const
QString toString() const const
QStringList toStringList() const const