HAL
plugin_parameter_dialog.cpp
Go to the documentation of this file.
9 #include "gui/gui_globals.h"
10 #include <QDebug>
11 #include <QFormLayout>
12 #include <QGridLayout>
13 #include <QHBoxLayout>
14 #include <QLineEdit>
15 #include <QDialogButtonBox>
16 #include <QPushButton>
17 #include <QSpinBox>
18 #include <QCheckBox>
19 #include <QTabWidget>
20 #include <QFileDialog>
21 #include <QTableWidget>
22 #include <QComboBox>
23 
24 namespace hal {
26  : QDialog(parent), mPluginName(pname), mGuiExtensionInterface(geif)
27  {
28  setupHash();
29 
30  QDialogButtonBox* bbox = setupButtonBox();
31 
32  setWindowTitle("Settings for " + mPluginName + " plugin");
33 
34  if (mTabNames.isEmpty())
35  {
36  QFormLayout* layout = new QFormLayout(this);
37  setupForm(layout);
38  layout->addRow(bbox);
39  }
40  else
41  {
42  QGridLayout* grid = new QGridLayout(this);
43  QTabWidget* tabw = new QTabWidget(this);
44  for (auto it = mTabNames.constBegin(); it != mTabNames.constEnd(); ++it)
45  {
46  QWidget* tab = new QWidget(tabw);
47  QFormLayout* layout = new QFormLayout(tab);
48  setupForm(layout,it.key());
49  tabw->addTab(tab,it.value());
50  }
51  grid->addWidget(tabw,0,0,1,2);
52  grid->addWidget(bbox,1,1);
53  }
54  }
55 
56  QDialogButtonBox* PluginParameterDialog::setupButtonBox()
57  {
59  for (const PluginParameter& par : mParameterList)
60  {
61  if (par.get_type() != PluginParameter::PushButton || par.get_tagname().find('/') != std::string::npos) continue;
62  QPushButton* but = static_cast<QPushButton*>(mWidgetMap.value(QString::fromStdString(par.get_tagname())));
63  Q_ASSERT(but);
64  connect(but,&QPushButton::clicked,this,&PluginParameterDialog::handlePushbuttonClicked);
66  }
69  return retval;
70  }
71 
72  void PluginParameterDialog::setupHash()
73  {
74  if (!mGuiExtensionInterface) return;
75  for (PluginParameter par : mGuiExtensionInterface->get_parameter())
76  {
77  if (par.get_type() == PluginParameter::Absent) continue;
78  QString parTagname = QString::fromStdString(par.get_tagname());
79  QString parLabel = QString::fromStdString(par.get_label());
80  QString parDefault = QString::fromStdString(par.get_value());
81 
82  mParameterList.append(par);
83 
84  QStringList tabbed = parTagname.split('/');
85  if (tabbed.size() > 1)
86  {
87  QString tabTag = tabbed.at(0);
88  if (!mTabNames.contains(tabTag))
89  mTabNames[tabTag] = tabTag;
90  }
91 
92  switch (par.get_type())
93  {
95  mTabNames[parTagname] = parLabel;
96  break;
98  mWidgetMap[parTagname] = new QPushButton(parLabel,this);
99  break;
101  {
102  KeyValueTable* kvt = new KeyValueTable(parLabel,this);
103  kvt->setJson(par.get_value());
104  mWidgetMap[parTagname] = kvt;
105  break;
106  }
108  {
109  mWidgetMap[parTagname] = new ColorSelection(parDefault, parLabel, true);
110  break;
111  }
113  {
114  QCheckBox* check = new QCheckBox(parLabel,this);
115  check->setChecked(parDefault.toLower()=="true");
116  mWidgetMap[parTagname] = check;
117  break;
118  }
120  {
121  QSpinBox* intBox = new QSpinBox(this);
122  intBox->setMaximum(1000000000);
123  intBox->setValue(parDefault.toInt());
124  mWidgetMap[parTagname] = intBox;
125  break;
126  }
128  {
129  QDoubleSpinBox* floatBox = new QDoubleSpinBox(this);
130  floatBox->setMaximum(1.E99);
131  floatBox->setValue(parDefault.toDouble());
132  mWidgetMap[parTagname] = floatBox;
133  break;
134  }
136  {
137  QLabel* label = new QLabel(this);
138  label->setText(parDefault);
139  mWidgetMap[parTagname] = label;
140  break;
141  }
143  {
144  QLineEdit* ledit = new QLineEdit(this);
145  ledit->setText(parDefault);
146  mWidgetMap[parTagname] = ledit;
147  break;
148  }
152  mWidgetMap[parTagname] = new PluginParameterFileDialog(par,this);
153  break;
155  mWidgetMap[parTagname] = new PluginParameterNodeDialog(par,this);
156  break;
158  mWidgetMap[parTagname] = new PluginParameterNodeDialog(par,this);
159  break;
161  {
162  QComboBox* cbox = new QComboBox(this);
163  cbox->insertItems(0,QString::fromStdString(par.get_value()).split(';'));
164  if (!par.get_value().empty()) cbox->setCurrentIndex(0);
165  mWidgetMap[parTagname] = cbox;
166  break;
167  }
168  default:
169  break;
170  }
171  }
172  }
173 
174  void PluginParameterDialog::setupForm(QFormLayout* form, const QString& tabTag)
175  {
176  for (const PluginParameter& par : mParameterList)
177  {
178  QString parTagname = QString::fromStdString(par.get_tagname());
179  if (!tabTag.isEmpty() && !parTagname.startsWith(tabTag+ "/")) continue;
180  QWidget* widget = mWidgetMap.value(parTagname);
181  if (!widget) continue;
182 
183  switch (par.get_type())
184  {
185  // push button not in tab are located in button box
187  if (par.get_tagname().find('/')!=std::string::npos)
188  {
189  QPushButton* but = static_cast<QPushButton*>(widget);
190  Q_ASSERT(but);
191  connect(but,&QPushButton::clicked,this,&PluginParameterDialog::handlePushbuttonClicked);
192  form->addRow(but);
193  }
194  break;
195  // without label
198  form->addRow(widget);
199  break;
200  // label + widget
201  default:
202  QString parLabel = QString::fromStdString(par.get_label());
203  form->addRow(parLabel, widget);
204  break;
205  }
206  }
207  }
208 
210  {
211  if (!mGuiExtensionInterface) return;
212  std::vector<PluginParameter> settings;
213  std::string buttonClicked;
214  for (PluginParameter par : mParameterList)
215  {
216  const QWidget* w = mWidgetMap.value(QString::fromStdString(par.get_tagname()));
217  if (!w) continue;
218 
219  switch (par.get_type())
220  {
222  if (par.get_value() == "clicked")
223  {
224  buttonClicked = par.get_tagname();
225  }
226  break;
228  {
229  const KeyValueTable* kvt = static_cast<const KeyValueTable*>(w);
230  par.set_value(kvt->toJson());
231  break;
232  }
234  {
235  const ColorSelection* colsel = static_cast<const ColorSelection*>(w);
236  par.set_value(colsel->colorName().toStdString());
237  break;
238  }
240  {
241  const QCheckBox* check = static_cast<const QCheckBox*>(w);
242  par.set_value(check->checkState()==Qt::Checked ? "true" : "false");
243  break;
244  }
246  {
247  const QSpinBox* intBox = static_cast<const QSpinBox*>(w);
248  par.set_value(QString::number(intBox->value()).toStdString());
249  break;
250  }
252  {
253  const QDoubleSpinBox* floatBox = static_cast<const QDoubleSpinBox*>(w);
254  par.set_value(QString::number(floatBox->value()).toStdString());
255  break;
256  }
258  {
259  par.set_value(std::string());
260  break;
261  }
263  {
264  const QLineEdit* ledit = static_cast<const QLineEdit*>(w);
265  par.set_value(ledit->text().toStdString());
266  break;
267  }
271  {
272  const PluginParameterFileDialog* fileDlg = static_cast<const PluginParameterFileDialog*>(w);
273  par.set_value(fileDlg->getFilename().toStdString());
274  break;
275  }
278  {
279  const PluginParameterNodeDialog* nodeDlg = static_cast<const PluginParameterNodeDialog*>(w);
280  par.set_value(QString::number(nodeDlg->getNodeId()).toStdString());
281  break;
282  }
284  {
285  const QComboBox* cbox = static_cast<const QComboBox*>(w);
286  par.set_value(cbox->currentText().toStdString());
287  break;
288  }
289  default:
290  continue;
291  break;
292  }
293  settings.push_back(par);
294  }
295  QDialog::accept();
296  mGuiExtensionInterface->set_parameter(settings);
297 
298  if (!buttonClicked.empty())
299  {
301  if (gPythonContext->pythonThread())
302  gPythonContext->pythonThread()->unlock();
303  }
304  }
305 
306  void PluginParameterDialog::handlePushbuttonClicked()
307  {
308  for (PluginParameter& par : mParameterList)
309  if (par.get_type() == PluginParameter::PushButton)
310  {
311  const QWidget* w = mWidgetMap.value(QString::fromStdString(par.get_tagname()));
312  if (sender() == w)
313  {
314  par.set_value("clicked");
315  }
316  }
317  accept();
318  }
319 
321  : QWidget(parent), mParameter(par)
322  {
323  QGridLayout* layout = new QGridLayout(this);
324  QString parDefault = QString::fromStdString(mParameter.get_value());
325  mEditor = new QLineEdit(this);
327  mEditor->setMinimumWidth(320);
328  mEditor->setText(parDefault);
329  layout->addWidget(mEditor,0,0);
330 
331  QString iconPath = (mParameter.get_type() == PluginParameter::NewFile)
332  ? ":/icons/folder-down"
333  : ":/icons/folder";
334  mButton = new QPushButton(gui_utility::getStyledSvgIcon("all->#3192C5",iconPath),"",this);
336  connect(mButton,&QPushButton::clicked,this,&PluginParameterFileDialog::handleActivateFileDialog);
337  layout->addWidget(mButton,0,1);
338  }
339 
340  void PluginParameterFileDialog::handleActivateFileDialog()
341  {
342  QString parLabel = QString::fromStdString(mParameter.get_label());
343  QString parDefault = QString::fromStdString(mParameter.get_value());
344  QString dir = QFileInfo(parDefault).isDir() ? parDefault : QFileInfo(parDefault).path();
345  QString filename;
346  switch (mParameter.get_type()) {
348  filename = QFileDialog::getExistingDirectory(this,parLabel,dir);
349  break;
351  filename = QFileDialog::getOpenFileName(this,parLabel,dir);
352  break;
354  filename = QFileDialog::getSaveFileName(this,parLabel,dir);
355  break;
356  default:
357  Q_ASSERT (1==0); // should never happen
358  }
359  if (!filename.isEmpty())
360  mEditor->setText(filename);
361  }
362 
364  {
365  return mEditor->text();
366  }
367 
369  : QWidget(parent), mParameter(par)
370  {
371  QGridLayout* layout = new QGridLayout(this);
372  mNodeId = new QSpinBox(this);
374  layout->addWidget(mNodeId,0,0);
375  mNodeName = new QLabel(this);
377  mNodeName->setMinimumWidth(280);
378  layout->addWidget(mNodeName,0,1);
379 
380  mButton = new QPushButton("",this);
381 
382  u32 defaultId = QString::fromStdString(mParameter.get_value()).toUInt();
383  mNodeId->setValue(defaultId);
384 
385  QString iconPath;
386  switch (mParameter.get_type()) {
388  iconPath = ":/icons/ne_module";
389  setModule(defaultId);
390  connect(mButton,&QPushButton::clicked,this,&PluginParameterNodeDialog::handleActivateModuleDialog);
391  connect(mNodeId,static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),this,&PluginParameterNodeDialog::setModule);
392  mValidIds = gNetlist->get_used_module_ids();
393  break;
395  iconPath = ":/icons/ne_gate";
396  setGate(defaultId);
397  connect(mButton,&QPushButton::clicked,this,&PluginParameterNodeDialog::handleActivateGateDialog);
398  connect(mNodeId,static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),this,&PluginParameterNodeDialog::setGate);
399  mValidIds = gNetlist->get_used_gate_ids();
400  break;
401  default:
402  Q_ASSERT(1==0); // widget must not be created if parameter type not module or gate
403  break;
404  }
405 
406  u32 maxValue = 0;
407  for (u32 id : mValidIds)
408  if (id > maxValue)
409  maxValue = id;
410  mNodeId->setMaximum(maxValue);
411  if (defaultId > maxValue)
412  mNodeId->setValue(0);
413  mButton->setIcon(gui_utility::getStyledSvgIcon("all->#F0F0F1",iconPath));
415  layout->addWidget(mButton,0,2);
416  }
417 
418  void PluginParameterNodeDialog::setGate(int id)
419  {
420  if (!id || !isValidId(id))
421  {
422  mNodeName->setText("(no gate selected)");
423  return;
424  }
425  Gate* g = gNetlist->get_gate_by_id(id);
426  if (g) mNodeName->setText(QString::fromStdString(g->get_name()));
427  }
428 
429  void PluginParameterNodeDialog::setModule(int id)
430  {
431  if (!id || !isValidId(id))
432  {
433  mNodeName->setText("(no module selected)");
434  return;
435  }
436  Module* m = gNetlist->get_module_by_id(id);
437  if (m) mNodeName->setText(QString::fromStdString(m->get_name()));
438  }
439 
440  bool PluginParameterNodeDialog::isValidId(int id) const
441  {
442  return (mValidIds.find(id)!=mValidIds.end());
443  }
444 
445  void PluginParameterNodeDialog::handleActivateModuleDialog()
446  {
447  ModuleDialog md({}, "Select module", false, nullptr, this);
448  if (md.exec() == QDialog::Accepted)
449  {
450  setModule(md.selectedId());
451  mNodeId->setValue(md.selectedId());
452  }
453  }
454 
455  void PluginParameterNodeDialog::handleActivateGateDialog()
456  {
457  GateDialog gd({}, "Select gate", nullptr, this);
458  if (gd.exec() == QDialog::Accepted)
459  {
460  setGate(gd.selectedId());
461  mNodeId->setValue(gd.selectedId());
462  }
463  }
464 
466  {
467  return mNodeId->value();
468  }
469 }
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation and configuration files Object form shall mean any form resulting from mechanical transformation or translation of a Source form
QString colorName() const
virtual void execute_function(std::string tag, Netlist *nl, const std::vector< u32 > &mods, const std::vector< u32 > &gats, const std::vector< u32 > &nets)
virtual void set_parameter(const std::vector< PluginParameter > &params)
virtual std::vector< PluginParameter > get_parameter() const
std::string toJson() const
Gate * get_gate_by_id(const u32 gate_id) const
Definition: netlist.cpp:193
std::set< u32 > get_used_gate_ids() const
Definition: netlist.cpp:741
std::set< u32 > get_used_module_ids() const
Definition: netlist.cpp:801
Module * get_module_by_id(u32 module_id) const
Definition: netlist.cpp:613
PluginParameterDialog(const QString &pname, GuiExtensionInterface *geif, QWidget *parent=nullptr)
PluginParameterFileDialog(const PluginParameter &par, QWidget *parent=nullptr)
std::string get_label() const
std::string get_value() const
ParameterType get_type() const
PluginParameterNodeDialog(const PluginParameter &par, QWidget *parent=nullptr)
std::vector< u32 > selectedGatesVector() const
std::vector< u32 > selectedNetsVector() const
std::vector< u32 > selectedModulesVector() const
QIcon getStyledSvgIcon(const QString &from_to_colors_enabled, const QString &svg_path, QString from_to_colors_disabled=QString())
Definition: graphics.cpp:60
PythonContext * gPythonContext
Definition: plugin_gui.cpp:88
SelectionRelay * gSelectionRelay
Definition: plugin_gui.cpp:83
Netlist * gNetlist
Definition: plugin_gui.cpp:80
quint32 u32
i32 id
void setChecked(bool)
void clicked(bool checked)
void setIcon(const QIcon &icon)
Qt::CheckState checkState() const const
void setCurrentIndex(int index)
void insertItems(int index, const QStringList &list)
virtual void accept()
virtual void reject()
void addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role)
void setMaximum(double max)
void setValue(double val)
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
bool isDir() const const
QString path() const const
void addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment)
void setText(const QString &)
void addWidget(QWidget *w)
void setText(const QString &)
const T & at(int i) const const
int size() const const
QMap::const_iterator constBegin() const const
QMap::const_iterator constEnd() const const
bool contains(const Key &key) const const
bool isEmpty() const const
const T value(const Key &key, const T &defaultValue) const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * sender() const const
void setMaximum(int max)
void setValue(int val)
void valueChanged(int i)
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QString fromStdString(const std::string &str)
bool isEmpty() const const
QString number(int n, int base)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
double toDouble(bool *ok) const const
int toInt(bool *ok, int base) const const
QString toLower() const const
std::string toStdString() const const
uint toUInt(bool *ok, int base) const const
int addTab(QWidget *page, const QString &label)
QWidget(QWidget *parent, Qt::WindowFlags f)
QLayout * layout() const const
void setMinimumWidth(int minw)
void setSizePolicy(QSizePolicy)
void setWindowTitle(const QString &)