HAL
selection_details_widget.cpp
Go to the documentation of this file.
18 
19 #include "gui/gui_def.h"
20 
21 #include "gui/gui_globals.h"
22 #include "hal_core/netlist/gate.h"
23 #include "hal_core/netlist/net.h"
26 #include "gui/toolbar/toolbar.h"
27 #include "gui/gui_utils/graphics.h"
28 #include "gui/gui_utils/netlist.h"
29 
30 #include <QHeaderView>
31 #include <QInputDialog>
32 #include <QLabel>
33 #include <QPushButton>
34 #include <QStackedWidget>
35 #include <QTableWidget>
36 #include <QVBoxLayout>
37 #include <QShortcut>
38 #include <QSplitter>
39 #include <QListWidget>
40 #include <QLineEdit>
41 #include <QMenu>
42 #include <QAction>
43 
44 
45 namespace hal
46 {
47  const QString SelectionDetailsWidget::sAddToGrouping("Add to grouping ");
48 
49  SettingsItemCheckbox* SelectionDetailsWidget::sSettingHideEmpty =
50  new SettingsItemCheckbox(
51  "Hide Empty Section",
52  "selection_details/hide_empty_sections",
53  false,
54  "Appearance:Selection Details",
55  "Specifies wheter empty sections are hidden or shown in the Selection Details Widget."
56  );
57 
59  : ContentWidget("Selection Details", parent), mNumberSelectedItems(0),
60  mSelectionToGrouping(new QAction),
61  mSelectionToModule(new QAction)
62  {
63  //needed to load the properties
65 
66  mSplitter = new QSplitter(Qt::Horizontal, this);
67  //mSplitter->setStretchFactor(0,5); /* Doesn't do anything? */
68  //mSplitter->setStretchFactor(1,10);
69 
70  //container for left side of splitter containing a selection tree view and a searchbar
71  QWidget* treeViewContainer = new QWidget(mSplitter);
72  //treeViewContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); /*Does not work, but should?*/
73  treeViewContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); /*Kinda works? Does not give as much space as previous implementation without container.*/
74 
75  QVBoxLayout* containerLayout = new QVBoxLayout(treeViewContainer);
76 
77 
78 
79 
80 
81  mSelectionTreeView = new SelectionTreeView(treeViewContainer);
82 
83  mModuleModel = new ModuleModel(this);
84  mSelectionTreeProxyModel = new SelectionTreeProxyModel(this);
85  mSelectionTreeProxyModel->setSourceModel(mModuleModel);
86  mSelectionTreeView->setModel(mSelectionTreeProxyModel);
87 
88  //mSelectionTreeProxyModel->setSourceModel(mSelectionTreeView->model());
89  //mSelectionTreeView->setModel(mSelectionTreeProxyModel);
90 
92  mSelectionTreeView->setMinimumWidth(280);
93  mSelectionTreeView->hide();
94 
95  mSearchbar = new Searchbar(treeViewContainer);
96  mSearchbar->hide();
97  mSearchbar->setColumnNames(mSelectionTreeProxyModel->getColumnNames());
98 
99  containerLayout->addWidget(mSelectionTreeView);
100  containerLayout->addWidget(mSearchbar);
101  containerLayout->setSpacing(0);
102  containerLayout->setContentsMargins(0,0,0,0);
103 
104  mStackedWidget = new QStackedWidget(mSplitter);
105 
106  mGateDetailsTabs = new GateDetailsTabWidget(mStackedWidget);
107  mStackedWidget->addWidget(mGateDetailsTabs);
108 
109  mNetDetailsTabs = new NetDetailsTabWidget(mStackedWidget);
110  mStackedWidget->addWidget(mNetDetailsTabs);
111 
112  mModuleDetailsTabs = new ModuleDetailsTabWidget();
113  mStackedWidget->addWidget(mModuleDetailsTabs);
114 
115  mItemDeletedLabel = new QLabel(mStackedWidget);
116  mItemDeletedLabel->setText("Currently selected item has been removed. Please consider relayouting the Graph.");
117  mItemDeletedLabel->setWordWrap(true);
118  mItemDeletedLabel->setAlignment(Qt::AlignmentFlag::AlignTop);
119  mStackedWidget->addWidget(mItemDeletedLabel);
120 
121  mNoSelectionLabel = new QLabel(mStackedWidget);
122  mNoSelectionLabel->setText("No Selection");
123  mNoSelectionLabel->setWordWrap(true);
124  mNoSelectionLabel->setAlignment(Qt::AlignmentFlag::AlignCenter);
125  mStackedWidget->addWidget(mNoSelectionLabel);
126 
127  mStackedWidget->setCurrentWidget(mNoSelectionLabel);
128 
129  mContentLayout->addWidget(mSplitter);
130 
131  // m_table_widget->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
132  // m_table_widget->setEditTriggers(QAbstractItemView::NoEditTriggers);
133  // m_table_widget->setSelectionBehavior(QAbstractItemView::SelectRows);
134  // m_table_widget->setSelectionMode(QAbstractItemView::NoSelection);
135  // m_table_widget->setShowGrid(false);
136  // m_table_widget->setAlternatingRowColors(true);
137  // m_table_widget->horizontalHeader()->setStretchLastSection(true);
138  // m_table_widget->viewport()->setFocusPolicy(Qt::NoFocus);
139  mSelectionToGrouping->setToolTip("Assign to grouping");
140  mSelectionToModule->setToolTip("Move to module");
141  mSelectionToGrouping->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mToGroupingIconPath));
142  mSelectionToModule->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mToModuleIconPath));
143  canMoveToModule(0);
144 
145  mSearchAction->setToolTip("Search");
146  enableSearchbar(false); // enable upon first non-zero selection
147  mSelectionToGrouping->setDisabled(true);
148  mSelectionToModule->setDisabled(true);
149 
150  gSelectionRelay->registerSender(this, "SelectionDetailsWidget");
151  connect(mSelectionToGrouping, &QAction::triggered, this, &SelectionDetailsWidget::selectionToGrouping);
153  connect(mSearchAction, &QAction::triggered, this, &SelectionDetailsWidget::toggleSearchbar);
156 
157  connect(mSearchbar, &Searchbar::triggerNewSearch, this, &SelectionDetailsWidget::updateSearchIcon);
158  connect(mSearchbar, &Searchbar::triggerNewSearch, mSelectionTreeProxyModel, &SelectionTreeProxyModel::startSearch);
159  }
160 
161  void SelectionDetailsWidget::selectionToGrouping()
162  {
163  GroupingDialog gd(this);
164  if (gd.exec() != QDialog::Accepted) return;
165  if (gd.isNewGrouping())
166  {
168  return;
169  }
170  QString groupName = QString::fromStdString(gNetlist->get_grouping_by_id(gd.groupId())->get_name());
171  selectionToGroupingAction(groupName);
172  }
173 
175  {
176  Grouping* assignedGrouping = nullptr;
177  QSet<u32> mods, gats, nets;
178  Module* mod;
179  Gate* gat;
180  Net* net;
181  switch(obj.type()) {
183  mod = gNetlist->get_module_by_id(obj.id());
184  if (mod) assignedGrouping = mod->get_grouping();
185  mods.insert(mod->get_id());
186  break;
188  gat = gNetlist->get_gate_by_id(obj.id());
189  if (gat) assignedGrouping = gat->get_grouping();
190  gats.insert(gat->get_id());
191  break;
193  net = gNetlist->get_net_by_id(obj.id());
194  if (net) assignedGrouping = net->get_grouping();
195  nets.insert(net->get_id());
196  break;
197  default:
198  break;
199  }
200  if (!assignedGrouping) return nullptr; // nothing to do
201  ActionRemoveItemsFromObject* retval = new ActionRemoveItemsFromObject(mods,gats,nets);
202  retval->setObject(UserActionObject(assignedGrouping->get_id(),
204  retval->setObjectLock(true);
205  return retval;
206  }
207 
209  {
210  UserActionCompound* compound = new UserActionCompound;
211  u32 grpId = 0;
212  if (existingGrpName.isEmpty())
213  {
215  compound->setUseCreatedObject();
216  }
217  else
218  {
220  getModel()->groupingByName(existingGrpName);
221  if (grp) grpId = grp->get_id();
222  }
224  {
226  if (act) compound->addAction(act);
227  }
228 
229  //get selected items from Model
230  QSet<u32> mods = {};
231  QSet<u32> gates = {};
232  QSet<u32> nets = {};
233  auto* sourceModel = static_cast<ModuleModel*>(mSelectionTreeProxyModel->sourceModel());
234 
235  //check each row for its Itemtype and append the ID to the corresponding QSet {mods, gates, nets}
236  for(int i = 0; i < mSelectionTreeProxyModel->rowCount(); i++){
237 
238  QModelIndex sourceModelIndex = mSelectionTreeProxyModel->mapToSource(mSelectionTreeProxyModel->index(i,0));
239  ModuleItem* item = dynamic_cast<ModuleItem*>(sourceModel->getItemFromIndex(sourceModelIndex));
240  switch (item->getType())
241  {
243  mods.insert(item->id());
244  break;
245 
247  gates.insert(item->id());
248  break;
249 
251  nets.insert(item->id());
252  break;
253  default:
254  break;
255  }
256  }
258  gates,
259  nets);
260 
261 
263  compound->addAction(act);
264  compound->addAction(new ActionSetSelectionFocus);
265  compound->exec();
266  }
267 
268  void SelectionDetailsWidget::enableSearchbar(bool enable)
269  {
270  QString iconStyle = enable ? mSearchIconStyle : mDisabledIconStyle;
272  if (!enable && mSearchbar->isVisible())
273  {
274  mSearchbar->hide();
275  setFocus();
276  }
277  mSearchAction->setEnabled(enable);
278  }
279  void SelectionDetailsWidget::canMoveToModule(int nodes)
280  {
281  QString iconStyle = nodes > 0
282  ? mToModuleIconStyle
283  : mDisabledIconStyle;
284  mSelectionToModule->setIcon(gui_utility::getStyledSvgIcon(iconStyle, mToModuleIconPath));
285  mSelectionToModule->setEnabled(gContentManager->getGraphTabWidget()->isSelectMode()
286  && nodes > 0);
287  }
288 
290  {
291  //called update methods with id = 0 to reset widget to the internal state of not updating because its not mVisible
292  //when all details widgets are finished maybe think about more elegant way
293 
294  if (sender == this)
295  {
296  return;
297  }
298 
299  SelectionTreeProxyModel* proxy = static_cast<SelectionTreeProxyModel*>(mSelectionTreeView->model());
300  mSelectionTreeView->setModel(mSelectionTreeProxyModel);
301  if (proxy->isGraphicsBusy()) return;
302  if (!mSearchbar->getCurrentText().isEmpty())
303  {
304  mSearchbar->clear();
305  updateSearchIcon();
306  }
307 
308  mNumberSelectedItems = gSelectionRelay->numberSelectedItems();
309  QVector<const ModuleItem*> defaultHighlight;
310 
311  if (mNumberSelectedItems)
312  {
313  // more than 1 item selected, populate and make mVisible
314  mSelectionTreeView->populate(true);
315  defaultHighlight.append(mSelectionTreeView->itemFromIndex());
316 
317  canMoveToModule(gSelectionRelay->numberSelectedNodes());
318  enableSearchbar(true);
319 
320  bool toModuleEnabled = gContentManager->getGraphTabWidget()->isSelectMode();
321  mSelectionToGrouping->setEnabled(true);
322  mSelectionToModule->setEnabled(toModuleEnabled);
323  mSelectionToGrouping->setIcon(gui_utility::getStyledSvgIcon(mToGroupingIconStyle, mToGroupingIconPath));
324  mSelectionToModule->setIcon(gui_utility::getStyledSvgIcon(toModuleEnabled
325  ? mToModuleIconStyle
326  : mDisabledIconStyle,
327  mToModuleIconPath));
328  }
329  else
330  {
331  // nothing selected
332  singleSelectionInternal(nullptr);
333  // clear and hide tree
334  mSelectionTreeView->populate(false);
335  canMoveToModule(0);
336  enableSearchbar(false);
337  mSelectionToGrouping->setDisabled(true);
338  mSelectionToModule->setDisabled(true);
339  mSelectionToGrouping->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mToGroupingIconPath));
340  mSelectionToModule->setIcon(gui_utility::getStyledSvgIcon(mDisabledIconStyle, mToModuleIconPath));
341 
342  return;
343  }
344 
345 
347  {
349  singleSelectionInternal(&sti);
350  }
352  {
354  singleSelectionInternal(&sti);
355  }
357  {
359  singleSelectionInternal(&sti);
360  }
361 
362  Q_EMIT triggerHighlight(defaultHighlight);
363  }
364 
366  {
367  singleSelectionInternal(sti);
368  QVector<const ModuleItem*> highlight;
369  if (sti) highlight.append(sti);
370  Q_EMIT triggerHighlight(highlight);
371  }
372 
373  void SelectionDetailsWidget::showNoSelection()
374  {
375  if(mStackedWidget->currentWidget() == mModuleDetailsTabs)
376  mModuleDetailsTabs->clear();
377  mStackedWidget->setCurrentWidget(mNoSelectionLabel);
378  }
379 
380  void SelectionDetailsWidget::singleSelectionInternal(const ModuleItem *sti)
381  {
382  if(!sti){
383  showNoSelection();
384  return;
385  }
386 
387  switch (sti->getType()) {
389  if (Module* m = gNetlist->get_module_by_id(sti->id()); m)
390  {
391  mModuleDetailsTabs->setModule(m);
392  mStackedWidget->setCurrentWidget(mModuleDetailsTabs);
393  // if (mNumberSelectedItems==1) set_name("Module Details");
394  }
395  else
396  showNoSelection();
397 
398  break;
399 
401  showNoSelection();
402  if (Gate* g = gNetlist->get_gate_by_id(sti->id()); g)
403  {
404  mGateDetailsTabs->setGate(g);
405  mStackedWidget->setCurrentWidget(mGateDetailsTabs);
406  // if (mNumberSelectedItems==1) set_name("Gate Details");
407  }
408  break;
410  showNoSelection();
411  if (Net* n = gNetlist->get_net_by_id(sti->id()); n)
412  {
413  mNetDetailsTabs->setNet(n);
414  mStackedWidget->setCurrentWidget(mNetDetailsTabs);
415  // if (mNumberSelectedItems==1) set_name("Net Details");
416  }
417  break;
418  default:
419  break;
420  }
421  }
422 
424  {
427 
428  QList<QShortcut*> list;
429  list.append(mSearchShortcut);
430 
431  return list;
432  }
433 
434  void SelectionDetailsWidget::toggleSearchbar()
435  {
436  if (!mSearchAction->isEnabled())
437  return;
438 
439  if (mSearchbar->isHidden())
440  {
441  mSearchbar->show();
442  mSearchbar->setFocus();
443  }
444  else
445  {
446  mSearchbar->hide();
447  setFocus();
448  }
449  }
450 
451  void SelectionDetailsWidget::updateSearchIcon()
452  {
453  if (mSearchbar->filterApplied() && mSearchbar->isVisible())
454  mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchActiveIconStyle, mSearchIconPath));
455  else
456  mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchIconStyle, mSearchIconPath));
457  }
458 
460  {
461  toolbar->addAction(mSelectionToGrouping);
462  toolbar->addAction(mSelectionToModule);
463  toolbar->addAction(mSearchAction);
464  }
465 
467  {
468  return mSelectionTreeView;
469  }
470 
472  {
473  return mDisabledIconStyle;
474  }
475 
477  {
478  mDisabledIconStyle = style;
479  }
480 
482  {
483  return mSearchIconPath;
484  }
485 
487  {
488  return mSearchIconStyle;
489  }
490 
492  {
493  return mSearchActiveIconStyle;
494  }
495 
497  {
498  mSearchIconPath = path;
499  }
500 
502  {
503  mSearchIconStyle = style;
504  }
505 
507  {
508  mSearchActiveIconStyle = style;
509  }
510 
512  {
513  return mToGroupingIconPath;
514  }
515 
517  {
518  return mToGroupingIconStyle;
519  }
520 
522  {
523  mToGroupingIconPath = path;
524  }
525 
527  {
528  mToGroupingIconStyle = style;
529  }
530 
532  {
533  return mToModuleIconPath;
534  }
535 
537  {
538  return mToModuleIconStyle;
539  }
540 
542  {
543  mToModuleIconPath = path;
544  }
545 
547  {
548  mToModuleIconStyle = style;
549  }
550 }
Adds an item to a module or grouping.
Removes an item from a Module or Grouping.
Set the selection and focus.
GraphTabWidget * getGraphTabWidget()
Get hal's graph tab widget.
GroupingManagerWidget * getGroupingManagerWidget()
Abstract class for Widgets within HAL's ContentArea.
QKeySequence mSearchKeysequence
QShortcut * mSearchShortcut
QVBoxLayout * mContentLayout
The DetailsTabWidget that is responsible for showing Gate details.
Definition: gate.h:58
Grouping * get_grouping() const
Definition: gate.cpp:204
u32 get_id() const
Definition: gate.cpp:95
bool isSelectMode() const
std::string get_name() const
Definition: grouping.cpp:42
u32 get_id() const
Definition: grouping.cpp:22
The DetailsTabWidget that is responsible for showing Module details.
Grouping * get_grouping() const
Definition: module.cpp:120
u32 get_id() const
Definition: module.cpp:82
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
The DetailsTabWidget that is responsible for showing Module details.
Definition: net.h:58
Gate * get_gate_by_id(const u32 gate_id) const
Definition: netlist.cpp:193
Module * get_module_by_id(u32 module_id) const
Definition: netlist.cpp:613
Net * get_net_by_id(u32 net_id) const
Definition: netlist.cpp:353
Grouping * get_grouping_by_id(u32 grouping_id) const
Definition: netlist.cpp:691
void addToModuleDialog(const Node &node=Node())
virtual QList< QString > getColumnNames()
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
QString getCurrentText()
Definition: searchbar.cpp:166
void triggerNewSearch(const QString &text, int searchOptions)
SelectionDetailsWidget(QWidget *parent=nullptr)
void setSearchIconPath(const QString &path)
void setToModuleIconPath(const QString &path)
void setSearchIconStyle(const QString &style)
QList< QShortcut * > createShortcuts() override
void handleTreeSelection(const ModuleItem *sti)
void setToGroupingIconStyle(const QString &style)
void setToGroupingIconPath(const QString &path)
void setToModuleIconStyle(const QString &style)
void selectionToGroupingAction(const QString &existingGrpName=QString())
void setDisabledIconStyle(const QString &style)
UserAction * groupingUnassignActionFactory(const UserActionObject &obj) const
virtual void setupToolbar(Toolbar *toolbar) override
void setSearchActiveIconStyle(const QString &style)
void triggerHighlight(QVector< const ModuleItem * > highlight)
int numberSelectedGates() const
QList< UserActionObject > toUserActionObject() const
int numberSelectedItems() const
void selectionChanged(void *sender)
int numberSelectedNets() const
QList< u32 > selectedModulesList() const
QList< u32 > selectedNetsList() const
int numberSelectedModules() const
QList< u32 > selectedGatesList() const
int numberSelectedNodes() const
void registerSender(void *sender, QString name)
Enables filtering of the SelectionTreeModel.
void startSearch(QString text, int options) override
Displays the current selection.
void populate(bool mVisible, u32 groupingId=0)
ModuleItem * itemFromIndex(const QModelIndex &index=QModelIndex()) const
void triggerSelection(const ModuleItem *sti)
Toolbar for all ContentFrames and ContentWidgets.
Definition: toolbar.h:39
void addAction(UserAction *act)
The UserAction class is the abstract base class for user interactions.
Definition: user_action.h:57
virtual void setObject(const UserActionObject &obj)
Definition: user_action.cpp:32
void setObjectLock(bool lock)
Definition: user_action.h:166
The UserActionObject class represents a single object used in UserAction.
UserActionObjectType::ObjectType type() const
QIcon getStyledSvgIcon(const QString &from_to_colors_enabled, const QString &svg_path, QString from_to_colors_disabled=QString())
Definition: graphics.cpp:60
ContentManager * gContentManager
Definition: plugin_gui.cpp:78
SelectionRelay * gSelectionRelay
Definition: plugin_gui.cpp:83
Netlist * gNetlist
Definition: plugin_gui.cpp:80
NetlistRelay * gNetlistRelay
Definition: plugin_gui.cpp:81
n
Definition: test.py:6
quint32 u32
Net * net
QAbstractItemModel * model() const const
void setEnabled(bool)
void setIcon(const QIcon &icon)
void setDisabled(bool b)
void setToolTip(const QString &tip)
void trigger()
void triggered(bool checked)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
void setSpacing(int spacing)
void setAlignment(Qt::Alignment)
void setText(const QString &)
void setWordWrap(bool on)
void setContentsMargins(int left, int top, int right, int bottom)
void append(const T &value)
const T & at(int i) const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * sender() const const
QSet::iterator insert(const T &value)
void activated()
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const const override
virtual int rowCount(const QModelIndex &parent) const const override
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
int addWidget(QWidget *widget)
QWidget * currentWidget() const const
void setCurrentWidget(QWidget *widget)
QString fromStdString(const std::string &str)
bool isEmpty() const const
Horizontal
QAction * addAction(const QString &text)
virtual void setModel(QAbstractItemModel *model) override
void append(const T &value)
QWidget(QWidget *parent, Qt::WindowFlags f)
void ensurePolished() const const
void hide()
bool isHidden() const const
void setMinimumWidth(int minw)
void setFocus()
void show()
void setSizePolicy(QSizePolicy)
QStyle * style() const const
bool isVisible() const const