HAL
module_widget.cpp
Go to the documentation of this file.
2 
5 #include "gui/gui_globals.h"
7 #include "gui/toolbar/toolbar.h"
10 #include "hal_core/netlist/gate.h"
12 #include "hal_core/netlist/net.h"
17 
18 #include <QApplication>
19 #include <QHeaderView>
20 #include <QItemSelectionModel>
21 #include <QMenu>
22 #include <QModelIndex>
23 #include <QRegExp>
24 #include <QScrollBar>
25 #include <QSet>
26 #include <QShortcut>
27 #include <QTreeView>
28 #include <QVBoxLayout>
29 #include <QInputDialog>
30 #include <QClipboard>
31 
32 namespace hal
33 {
35  : ContentWidget("Modules", parent),
36  mTreeView(new ModuleTreeView(this)),
37  mSearchbar(new Searchbar(this)),
38  mToggleNetsAction(new QAction(this)),
39  mToggleGatesAction(new QAction(this)),
40  mRenameAction(new QAction(this)),
41  mDeleteAction(new QAction(this)),
42  mToggleExpandTreeAction(new QAction(this)),
43  mModuleProxyModel(new ModuleProxyModel(this))
44 
45  {
47 
49 
50  mToggleNetsAction->setIcon(gui_utility::getStyledSvgIcon(mActiveIconStyle, mHideNetsIconPath));
51  mToggleGatesAction->setIcon(gui_utility::getStyledSvgIcon(mActiveIconStyle, mHideGatesIconPath));
52  mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchIconStyle, mSearchIconPath));
53  mRenameAction->setIcon(gui_utility::getStyledSvgIcon(mActiveIconStyle, mRenameIconPath));
54  mToggleExpandTreeAction->setIcon(gui_utility::getStyledSvgIcon(mActiveIconStyle, mExpandedIconPath));
55 
56  mToggleNetsAction->setToolTip("Toggle net visibility");
57  mToggleGatesAction->setToolTip("Toggle gate visibility");
58  mDeleteAction->setToolTip("Delete module");
59  mSearchAction->setToolTip("Search");
60  mRenameAction->setToolTip("Rename");
61  mToggleExpandTreeAction->setToolTip("Toggle expand all / collapse all");
62 
63  mModuleModel = new ModuleModel(this);
64  mModuleProxyModel->setSourceModel(mModuleModel);
65 
66  mTreeView->setModel(mModuleProxyModel);
67  mTreeView->setDefaultColumnWidth();
68  mTreeView->setSortingEnabled(true);
69  mTreeView->sortByColumn(0, Qt::AscendingOrder);
72  mTreeView->setFrameStyle(QFrame::NoFrame);
73  //mTreeView->header()->close();
74  mTreeView->setExpandsOnDoubleClick(false);
77  mContentLayout->addWidget(mTreeView);
78 
79  mSearchbar->setColumnNames(mModuleModel->headerLabels());
80  mContentLayout->addWidget(mSearchbar);
81  mSearchbar->hide();
82 
83  enableDeleteAction(false); // enable upon selected module
84  mIgnoreSelectionChange = false;
85 
87 
88  //connect(mSearchbar, &Searchbar::textEdited, this, &ModuleWidget::filter);
94 
96 
98  connect(mSearchbar, &Searchbar::triggerNewSearch, mModuleProxyModel, &ModuleProxyModel::startSearch);
99 
100  mShortCutDeleteItem = new QShortcut(ContentManager::sSettingDeleteItem->value().toString(), this);
101  mShortCutDeleteItem->setEnabled(false);
102 
104  connect(mShortCutDeleteItem, &QShortcut::activated, this, &ModuleWidget::deleteSelectedItem);
105  connect(mDeleteAction, &QAction::triggered, this, &ModuleWidget::deleteSelectedItem);
106 
107  connect(qApp, &QApplication::focusChanged, this, &ModuleWidget::handleDeleteShortcutOnFocusChanged);
108 
109 
110  connect(mToggleNetsAction, &QAction::triggered, this, &ModuleWidget::handleToggleNetsClicked);
111  connect(mToggleGatesAction, &QAction::triggered, this, &ModuleWidget::handleToggleGatesClicked);
112  connect(mToggleExpandTreeAction, &QAction::triggered, this, &ModuleWidget::handleToggleExpandTreeClicked);
113  connect(mRenameAction, &QAction::triggered, this, &ModuleWidget::handleRenameClicked);
114 
115  mModuleModel->populateTree({gNetlist->get_top_module()->get_id()});
116  mTreeView->expandAllModules();
117  }
118 
119  void ModuleWidget::enableDeleteAction(bool enable)
120  {
121  mDeleteAction->setEnabled(enable);
122  mDeleteAction->setIcon(gui_utility::getStyledSvgIcon(enable?mActiveIconStyle:mDisabledIconStyle, mDeleteIconPath));
123  }
124 
125  void ModuleWidget::handleToggleNetsClicked()
126  {
127  if(mModuleProxyModel->toggleFilterNets())
128  {
129  mToggleNetsAction->setIcon(gui_utility::getStyledSvgIcon(mActiveIconStyle, mHideNetsIconPath));
130  }
131  else
132  {
133  mToggleNetsAction->setIcon(gui_utility::getStyledSvgIcon(mActiveIconStyle, mShowNetsIconPath));
134  }
135  }
136 
137  void ModuleWidget::handleToggleGatesClicked()
138  {
139  if(mModuleProxyModel->toggleFilterGates())
140  {
141  mToggleGatesAction->setIcon(gui_utility::getStyledSvgIcon(mActiveIconStyle, mHideGatesIconPath));
142  }
143  else
144  {
145  mToggleGatesAction->setIcon(gui_utility::getStyledSvgIcon(mActiveIconStyle, mShowGatesIconPath));
146  }
147  }
148 
149  void ModuleWidget::handleToggleExpandTreeClicked()
150  {
151  if (mTreeView->toggleStateExpanded())
152  {
153  mTreeView->collapseAllModules();
154  mToggleExpandTreeAction->setIcon(gui_utility::getStyledSvgIcon(mActiveIconStyle, mCollapsedIconPath));
155  }
156  else
157  {
158  mTreeView->expandAllModules();
159  mToggleExpandTreeAction->setIcon(gui_utility::getStyledSvgIcon(mActiveIconStyle, mExpandedIconPath));
160  }
161  }
162 
163  void ModuleWidget::handleRenameClicked()
164  {
165  ModuleItem* item = getModuleItemFromIndex(mTreeView->currentIndex());
166  gNetlistRelay->changeElementNameDialog(item->getType(), item->id());
167  }
168 
170  {
171  toolbar->addAction(mToggleNetsAction);
172  toolbar->addAction(mToggleGatesAction);
173  toolbar->addAction(mRenameAction);
174  toolbar->addAction(mDeleteAction);
175  toolbar->addAction(mSearchAction);
176  toolbar->addAction(mToggleExpandTreeAction);
177  }
178 
180  {
183 
184  QList<QShortcut*> list;
185  list.append(mSearchShortcut);
186 
187  return list;
188  }
189 
191  {
192  if (!mSearchAction->isEnabled())
193  return;
194 
195  if (mSearchbar->isHidden())
196  {
197  mSearchbar->show();
198  mSearchbar->setFocus();
199  }
200  else
201  {
202  mSearchbar->hide();
203  setFocus();
204  }
205  }
206 
207  void ModuleWidget::filter(const QString& text)
208  {
209  QRegularExpression* regex = new QRegularExpression(text);
210  if (regex->isValid())
211  {
212  mModuleProxyModel->setFilterRegularExpression(*regex);
213  mTreeView->expandAllModules();
214  QString output = "navigation regular expression '" + text + "' entered.";
215  log_info("user", output.toStdString());
216  }
217  }
218 
220  {
221  QModelIndex index = mTreeView->indexAt(point);
222  if (!index.isValid())
223  return;
224 
225  ModuleItem* item = getModuleItemFromIndex(index);
227  u32 id = item->id();
228 
229  QMenu context_menu;
230 
232  ModuleContextMenu::addModuleSubmenu(&context_menu, id);
234  ModuleContextMenu::addGateSubmenu(&context_menu, id);
236  ModuleContextMenu::addNetSubmenu(&context_menu, id);
237 
239  type==ModuleItem::TreeItemType::Module ? std::vector<u32>({id}) : std::vector<u32>(),
240  type==ModuleItem::TreeItemType::Gate ? std::vector<u32>({id}) : std::vector<u32>(),
241  type==ModuleItem::TreeItemType::Net ? std::vector<u32>({id}) : std::vector<u32>());
242 
243  context_menu.exec(mTreeView->viewport()->mapToGlobal(point));
244  }
245 
247  {
248  UNUSED(module);
249  UNUSED(module_id);
250 
251  //prevents the execution of "handleTreeSelectionChanged"
252  //when a module is (re)moved the corresponding item in the tree is deleted and deselected, thus also triggering "handleTreeSelectionChanged"
253  //this call due to the selection model signals is unwanted behavior because "handleTreeSelectionChanged" is ment to only react to an "real" action performed by the user on the tree itself
254  mIgnoreSelectionChange = true;
255  }
256 
257  void ModuleWidget::handleCurrentChanged(const QModelIndex& current, const QModelIndex& previous)
258  {
259  Q_UNUSED(previous);
260  ModuleItem* mi = getModuleItemFromIndex(current);
261  if (!mi)
262  enableDeleteAction(false);
263  else
264  enableDeleteAction(mi->getType() == ModuleItem::TreeItemType::Module);
265  }
266 
268  {
269  Q_UNUSED(selected)
270  Q_UNUSED(deselected)
271 
272  if (mIgnoreSelectionChange || mModuleModel->isModifying())
273  return;
274 
276 
277  QModelIndexList current_selection = mTreeView->selectionModel()->selectedIndexes();
278 
279  QSet<int> selectedMods;
280  QSet<int> selectedGats;
281  for (const auto& index : current_selection)
282  {
283  ModuleItem* mi = getModuleItemFromIndex(index);
284  switch (mi->getType()) {
286  selectedMods.insert(mi->id());
287  gSelectionRelay->addModule(mi->id());
288  break;
290  selectedGats.insert(mi->id());
291  gSelectionRelay->addGate(mi->id());
292  break;
294  gSelectionRelay->addNet(mi->id());
295  break;
296  }
297  }
298 
299  if (selectedMods.size() == 1)
300  {
302  enableDeleteAction(true);
303  }
304  else if (selectedGats.size() == 1)
305  {
307  enableDeleteAction(false);
308  }
309  else
310  {
311  enableDeleteAction(false);
312  }
313 
315  }
316 
318  {
319  ModuleItem* mi = getModuleItemFromIndex(index);
320  switch(mi->getType()){
324  }
325  }
326 
328  {
329  if (sender == this)
330  return;
331 
332  mIgnoreSelectionChange = true;
333 
334  QItemSelection module_selection;
335 
336  for (auto module_id : gSelectionRelay->selectedModulesList())
337  {
338  for(ModuleItem* item : mModuleModel->getItems(module_id))
339  {
340  if(item)
341  {
342  QModelIndex index = mModuleProxyModel->mapFromSource(mModuleModel->getIndexFromItem(item));
343  module_selection.select(index, index);
344  }
345  }
346  }
347 
348  mTreeView->selectionModel()->select(module_selection, QItemSelectionModel::SelectionFlag::ClearAndSelect);
349 
350  mIgnoreSelectionChange = false;
351  }
352 
353  ModuleItem* ModuleWidget::getModuleItemFromIndex(const QModelIndex& index)
354  {
355  return mModuleModel->getItem(mModuleProxyModel->mapToSource(index));
356  }
357 
359  {
360  if (mSearchbar->filterApplied() && mSearchbar->isVisible())
361  mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchActiveIconStyle, mSearchIconPath));
362  else
363  mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchIconStyle, mSearchIconPath));
364  }
365 
367  {
368  return mModuleModel;
369  }
370 
372  {
373  return mDisabledIconStyle;
374  }
375 
377  {
378  return mActiveIconStyle;
379  }
380 
382  {
383  return mModuleProxyModel;
384  }
385 
387  {
388  return mShowNetsIconPath;
389  }
390 
392  {
393  return mHideNetsIconPath;
394  }
395 
397  {
398  return mShowGatesIconPath;
399  }
400 
402  {
403  return mHideGatesIconPath;
404  }
405 
407  {
408  return mSearchIconPath;
409  }
410 
412  {
413  return mSearchIconStyle;
414  }
415 
417  {
418  return mSearchActiveIconStyle;
419  }
420 
422  {
423  return mDeleteIconPath;
424  }
425 
427  {
428  return mRenameIconPath;
429  }
430 
432  {
433  return mExpandedIconPath;
434  }
435 
437  {
438  return mCollapsedIconPath;
439  }
440 
442  {
443  mDisabledIconStyle = style;
444  }
445 
447  {
448  mActiveIconStyle = style;
449  }
450 
452  {
453  mShowNetsIconPath = path;
454  }
455 
457  {
458  mHideNetsIconPath = path;
459  }
460 
462  {
463  mShowGatesIconPath = path;
464  }
465 
467  {
468  mHideGatesIconPath = path;
469  }
470 
472  {
473  mSearchIconPath = path;
474  }
475 
477  {
478  mSearchIconStyle = style;
479  }
480 
482  {
483  mSearchActiveIconStyle = style;
484  }
485 
487  {
488  mDeleteIconPath = path;
489  }
490 
492  {
493  mRenameIconPath = path;
494  }
495 
497  {
498  mExpandedIconPath = path;
499  }
500 
502  {
503  mCollapsedIconPath = path;
504  }
505 
506  void ModuleWidget::deleteSelectedItem()
507  {
508  if(!mTreeView->currentIndex().isValid())
509  {
510  return;
511  }
512 
513  ModuleItem* selectedItem = getModuleItemFromIndex(mTreeView->currentIndex());
514  if(selectedItem->getParent() != nullptr)
515  {
516  if (getModuleItemFromIndex(mTreeView->currentIndex())->getType() == ModuleItem::TreeItemType::Module)
517  {
518  auto module = gNetlist->get_module_by_id(selectedItem->id());
519  if(!module->is_top_module())
520  gNetlistRelay->deleteModule(getModuleItemFromIndex(mTreeView->currentIndex())->id());
521  }
522  }
523  }
524 
525  void ModuleWidget::handleDeleteShortcutOnFocusChanged(QWidget* oldWidget, QWidget* newWidget)
526  {
527  Q_UNUSED(oldWidget);
528  if(!newWidget) return;
529  if(newWidget->parent() == this)
530  {
531  mShortCutDeleteItem->setEnabled(true);
532  return;
533  }
534  else
535  {
536  mShortCutDeleteItem->setEnabled(false);
537  return;
538  }
539  }
540 }
QModelIndex getIndexFromItem(BaseTreeItem *item) const
QStringList headerLabels() const
static SettingsItemKeybind * sSettingDeleteItem
Abstract class for Widgets within HAL's ContentArea.
QKeySequence mSearchKeysequence
QShortcut * mSearchShortcut
QVBoxLayout * mContentLayout
void openModuleInView(u32 moduleId, bool unfold)
static void addPluginSubmenus(QMenu *contextMenu, Netlist *netlist, const std::vector< u32 > &modules, const std::vector< u32 > &gates, const std::vector< u32 > &nets)
static void addModuleSubmenu(QMenu *contextMenu, u32 id)
static void addGateSubmenu(QMenu *contextMenu, u32 id)
static void addNetSubmenu(QMenu *contextMenu, u32 id)
bool is_top_module() const
Definition: module.cpp:312
An item in the ModuleModel.
Definition: module_item.h:48
u32 id() const
TreeItemType getType() const
A model for displaying multiple netlist elements.
Definition: module_model.h:54
QList< ModuleItem * > getItems(const u32 id, ModuleItem::TreeItemType type=ModuleItem::TreeItemType::Module) const
ModuleItem * getItem(const QModelIndex &index) const
void populateTree(const QVector< u32 > &modIds={}, const QVector< u32 > &gatIds={}, const QVector< u32 > &netIds={})
Enables filtering in the ModuleModel.
void startSearch(QString text, int options) override
Wraps the QTreeView used for the ModuleWidget.
bool toggleStateExpanded() const
void handleTreeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
void setSearchIconPath(const QString &path)
QString renameIconPath
Definition: module_widget.h:70
QString searchIconStyle
Definition: module_widget.h:68
void setSearchIconStyle(const QString &style)
QString hideNetsIconPath
Definition: module_widget.h:64
void setExpandedIconPath(const QString &path)
void setHideGatesIconPath(const QString &path)
QString activeIconStyle
Definition: module_widget.h:62
void setDisabledIconStyle(const QString &style)
QString showGatesIconPath
Definition: module_widget.h:65
void filter(const QString &text)
QString disabledIconStyle
Definition: module_widget.h:61
void handleSelectionChanged(void *sender)
QString collapsedIconPath
Definition: module_widget.h:73
void setShowNetsIconPath(const QString &path)
void handleTreeViewContextMenuRequested(const QPoint &point)
void setDeleteIconPath(const QString &path)
virtual QList< QShortcut * > createShortcuts() override
ModuleProxyModel * proxyModel()
void setShowGatesIconPath(const QString &path)
void setCollapsedIconPath(const QString &path)
void handleItemDoubleClicked(const QModelIndex &index)
void handleCurrentChanged(const QModelIndex &current, const QModelIndex &previous=QModelIndex())
ModuleWidget(QWidget *parent=nullptr)
void setRenameIconPath(const QString &path)
QString deleteIconPath
Definition: module_widget.h:71
void setSearchActiveIconStyle(const QString &style)
void handleModuleRemoved(Module *module, u32 module_id)
void setHideNetsIconPath(const QString &path)
QString expandedIconPath
Definition: module_widget.h:72
QString showNetsIconPath
Definition: module_widget.h:63
QString searchActiveIconStyle
Definition: module_widget.h:69
void setActiveIconStyle(const QString &style)
ModuleModel * getModuleModel() const
QString searchIconPath
Definition: module_widget.h:67
QString hideGatesIconPath
Definition: module_widget.h:66
virtual void setupToolbar(Toolbar *toolbar) override
Module * get_top_module() const
Definition: netlist.cpp:608
Module * get_module_by_id(u32 module_id) const
Definition: netlist.cpp:613
void deleteModule(const u32 id)
void changeElementNameDialog(ModuleItem::TreeItemType type, u32 id)
void moduleSubmoduleRemoved(Module *m, const u32 removed_module) const
A QFrame with a QLineEdit that can be used to input a substring to search for.
Definition: searchbar.h:48
bool filterApplied()
Definition: searchbar.cpp:259
void setColumnNames(QList< QString > list)
Definition: searchbar.cpp:130
void triggerNewSearch(const QString &text, int searchOptions)
void setFocus(ItemType ftype, u32 fid, Subfocus sfoc=Subfocus::None, u32 sfinx=0)
void selectionChanged(void *sender)
void relaySelectionChanged(void *sender)
QList< u32 > selectedModulesList() const
void registerSender(void *sender, QString name)
void keySequenceChanged(QKeySequence value)
Toolbar for all ContentFrames and ContentWidgets.
Definition: toolbar.h:39
#define UNUSED(expr)
Definition: defines.h:49
#define log_info(channel,...)
Definition: log.h:70
const Module * module(const Gate *g, const NodeBoxes &boxes)
QIcon getStyledSvgIcon(const QString &from_to_colors_enabled, const QString &svg_path, QString from_to_colors_disabled=QString())
Definition: graphics.cpp:60
GraphContextManager * gGraphContextManager
Definition: plugin_gui.cpp:85
SelectionRelay * gSelectionRelay
Definition: plugin_gui.cpp:83
Netlist * gNetlist
Definition: plugin_gui.cpp:80
NetlistRelay * gNetlistRelay
Definition: plugin_gui.cpp:81
quint32 u32
PinType type
QModelIndex currentIndex() const const
void doubleClicked(const QModelIndex &index)
void setEditTriggers(QAbstractItemView::EditTriggers triggers)
void setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior)
void setSelectionMode(QAbstractItemView::SelectionMode mode)
QItemSelectionModel * selectionModel() const const
QWidget * viewport() const const
void setEnabled(bool)
void setIcon(const QIcon &icon)
void setToolTip(const QString &tip)
void trigger()
void triggered(bool checked)
void focusChanged(QWidget *old, QWidget *now)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
void setFrameStyle(int style)
void select(const QModelIndex &topLeft, const QModelIndex &bottomRight)
void currentChanged(const QModelIndex &current, const QModelIndex &previous)
virtual void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
void append(const T &value)
QAction * exec()
bool isValid() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
QObject * sender() const const
bool isValid() const const
QSet::iterator begin()
QSet::iterator insert(const T &value)
int size() const const
void activated()
void setEnabled(bool enable)
void setKey(const QKeySequence &key)
virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const const override
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const const override
void setFilterRegularExpression(const QString &pattern)
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
QueuedConnection
CustomContextMenu
AscendingOrder
QAction * addAction(const QString &text)
void sortByColumn(int column)
void setExpandsOnDoubleClick(bool enable)
virtual QModelIndex indexAt(const QPoint &point) const const override
virtual void setModel(QAbstractItemModel *model) override
void setSortingEnabled(bool enable)
void setContextMenuPolicy(Qt::ContextMenuPolicy policy)
void customContextMenuRequested(const QPoint &pos)
void ensurePolished() const const
void hide()
bool isHidden() const const
QPoint mapToGlobal(const QPoint &pos) const const
void setFocus()
void show()
QStyle * style() const const
bool isVisible() const const