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());
450 bpif =
load(pluginName, info.absoluteFilePath());
453 log_warning(
"gui",
"GuiPluginManager: loading of '{}' failed, is it really a HAL plugin?", pluginName.
toStdString());
458 if (bpif->get_name().empty() || bpif->get_version().empty())
460 log_warning(
"gui",
"GuiPluginManager: '{}' has empty name or version, plugin ignored.", pluginName.
toStdString());
465 log_info(
"gui",
"GuiPluginManager: '{}' loaded to retrieve information about plugin features.", pluginName.
toStdString());
466 gpe->updateFromLoaded(bpif,
false, info.lastModified());
475 if (!gpe || gpe->isLoaded())
continue;
479 gpe->updateFromLoaded(bpif,
false,info.exists()?info.lastModified():
QDateTime());
485 auto it = pluginEntries.
begin();
486 while (it != pluginEntries.
end())
489 GuiPluginEntry* gpe = it.value();
490 if (gpe->isFileFound())
494 mLookup.
insert(gpe->mName,mEntries.size());
495 mEntries.append(gpe);
502 else if (gpe->mExternalPath.isEmpty() || !gpe->requestLoad() )
511 if (info.exists() && info.isReadable())
513 mLookup.
insert(gpe->mName,mEntries.size());
514 mEntries.append(gpe);
515 BasePluginInterface* bpif =
load(gpe->mName, info.absoluteFilePath());
518 log_warning(
"gui",
"GuiPluginManager: loading of requested plugin '{}' failed.", gpe->mName.toStdString());
523 gpe->updateFromLoaded(bpif,
true, info.lastModified());
524 log_info(
"gui",
"GuiPluginManager: '{}' loaded external plugin upon user request.", gpe->mName.toStdString());
533 it = pluginEntries.
erase(it);
544 int n = mEntries.size();
547 mEntries.append(gpe);
560 gpe = mEntries.takeLast();
572 if (mWaitForRefresh)
return;
578 if (mWaitForRefresh)
return;
584 int irow = mLookup.
value(pluginName,-1);
585 if (irow < 0 || irow >= mEntries.size())
return;
627 pluginMap.
insert(
".hal",
"HAL progress files ");
631 reStr =
"Default (.*) Parser";
633 reStr =
"Default (.*) Writer";
638 if (pluginMap.
size() > 1)
642 if (!retval.
isEmpty()) retval +=
" ";
646 retval.
prepend(
"All supported files (");
656 formatMap[fileFmt] +=
" *" + it.
key();
658 formatMap[fileFmt] =
"*" + it.
key();
662 if (!retval.
isEmpty()) retval +=
";;";
663 retval += it.key() +
"(" + it.value() +
")";
675 bool extensionFound =
false;
680 extensionFound =
true;
684 if (!extensionFound)
continue;
696 log_warning(
"gui",
"Error loading plugin '{}' from location '{}'",
739 void GuiPluginTable::clearMemory()
754 return mEntries.size();
768 case 0:
return "Name";
769 case 1:
return "Description";
770 case 2:
return "Filename";
771 case 3:
return "Timestamp";
772 case 4:
return "Dependencies";
773 case 5:
return "Category";
774 case 6:
return "Extensions";
775 case 7:
return "GUI";
776 case 8:
return "CLI";
777 case 9:
return "State";
787 return mEntries.at(irow);
792 if (mWaitForRefresh)
return;
794 int irow = buttonIndex.
row();
795 if (irow >= mEntries.size())
return;
797 switch (buttonIndex.
column())
800 if (gpe->
mName ==
"hal_gui")
return;
809 if (gpe->
mName ==
"hal_gui")
return;
811 bool success =
false;
822 QString(
"Unload of plugin %1\nrefused by plugin_manager")
828 QString(
"Cannot unload plugin %1\nwhich is required by %2")
841 QString(
"Could not load plugin %1\nplease check plugin_manager log")
856 if (mEntries.at(
index.
row())->isLoaded())
860 if (mEntries.at(
index.
row())->isLoaded())
871 return (v.
toBool() ?
"X" :
" ");
877 if (
index.
row() >= mEntries.size())
return false;
878 return mEntries.at(
index.
row())->mName ==
"hal_gui";
884 return mEntries.at(
index.
row())->mGuiExtensionState;
889 int irow = mLookup.
value(pluginName,-1);
890 if (irow < 0 || irow >= mEntries.size())
return;
891 mEntries.at(irow)->mGuiExtensionState =
state;
897 if (
index.
row() >= mEntries.size())
return false;
898 return !mEntries.at(
index.
row())->mCliOptions.isEmpty();
903 if (
index.
row() >= mEntries.size())
return false;
904 return mEntries.at(
index.
row())->isLoaded();
912 if (gpe->
mName == pluginName)
continue;
914 if (dep == pluginName)
927 : mLoadState(NotAPlugin), mName(info.baseName()),
928 mFilePath(info.absoluteFilePath()),
929 mFileModified(info.lastModified()),
931 mUserInterface(false),
932 mGuiExtensionState(Unknown),
940 case 0:
return mName;
956 return "Other HAL plugin";
961 case 9:
if (!
isLoaded())
return "-";
963 else return "EXTERN";
1038 for (std::string arg : feature.args)
1066 for (
int i=0; i<3; i++)
1085 for (
int i=0; i<3; i++)
1086 delete mTemplateButton[i];
1095 bool drawIcon =
true;
1100 button.iconSize =
QSize(w-4,w-4);
1128 button.icon = mIconDisableGuiContribution;
1131 button.icon = mIconEnableGuiContribution;
1136 button.iconSize =
QSize(w-4,w-4);
1138 button.icon = mIconCliOptions;
1148 button.icon = mIconUnload;
1150 button.icon = mIconLoad;
1151 button.iconSize =
QSize(w-12,w-12);
1159 State stat = Normal;
1161 if (mMouseIndex.
isValid() && mMouseIndex == index)
1171 button.rect =
QRect(x,y,w,h);
1182 return QSize(30,30);
1188 if (!mev)
return false;
1189 switch (mev->
type())
1192 mMousePos = mev->
pos();
1193 mMouseIndex = index;
1196 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.1.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