HAL  v4.5.0-131-gda71a6012
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
module_select_model.cpp
Go to the documentation of this file.
2 
6 #include "gui/gui_globals.h"
11 
12 #include <QApplication>
13 #include <QHeaderView>
14 #include <QMessageBox>
15 #include <QSortFilterProxyModel>
16 
17 #include <QDebug>
18 
19 namespace hal
20 {
21  //---------------- HISTORY ----------------------------------------
22  const int ModuleSelectHistory::sMaxEntries = 10;
23 
24  ModuleSelectHistory* ModuleSelectHistory::inst = nullptr;
25 
27  {
28  if (!inst)
29  inst = new ModuleSelectHistory;
30  return inst;
31  }
32 
34  {
35  removeAll(id);
36  prepend(id);
37  while (size() > sMaxEntries) takeLast();
38  }
39 
40  //---------------- ENTRY ------------------------------------------
42  {
43  mId = m->get_id();
44  mName = QString::fromStdString(m->get_name());
45  mType = QString::fromStdString(m->get_type());
46  mColor = gNetlistRelay->getModuleColor(mId);
47  }
48 
50  {
51  switch (icol)
52  {
53  case 0:
54  return mColor;
55  case 1:
56  return mId;
57  case 2:
58  return mName;
59  case 3:
60  return mType;
61  }
62  return QVariant();
63  }
64 
65  //---------------- MODEL ------------------------------------------
67  {
68 
69  }
70 
72  {
73  if (history)
74  {
76  {
78  if (m && mExcl.isAccepted(m->get_id()))
79  mEntries.append(ModuleSelectEntry(m));
80  }
81  }
82  else
83  {
84  for (Module* m : gNetlist->get_modules())
85  {
86  if (mExcl.isAccepted(m->get_id()))
87  {
88  mEntries.append(ModuleSelectEntry(m));
89  }
90  }
91  }
92  }
93 
94  int ModuleSelectModel::rowCount(const QModelIndex& parent) const
95  {
96  Q_UNUSED(parent);
97 
98  return mEntries.size();
99  }
100 
102  {
103  Q_UNUSED(parent);
104 
105  return 4;
106  }
107 
108  QVariant ModuleSelectModel::headerData(int section, Qt::Orientation orientation, int role) const
109  {
110  if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
111  return QVariant();
112  switch (section)
113  {
114  case 1:
115  return "ID";
116  case 2:
117  return "Name";
118  case 3:
119  return "Type";
120  }
121  return QVariant();
122  }
123 
125  {
126  if (!index.isValid() || index.row() >= mEntries.size())
127  return QVariant();
128  const ModuleSelectEntry& mod = mEntries.at(index.row());
129 
130  switch (role)
131  {
132  case Qt::DecorationRole: {
133  if (index.column() == 0)
134  {
135  QString runIconStyle = "all->" + mod.color().name();
136  QString runIconPath = ":/icons/filled-circle";
137 
138  return gui_utility::getStyledSvgIcon(runIconStyle, runIconPath);
139  }
140  break;
141  }
142  case Qt::DisplayRole:
143  if (index.column() > 0)
144  return mod.data(index.column());
145  break;
146  }
147 
148  return QVariant();
149  }
150 
152  {
153  return mEntries.at(irow).id();
154  }
155 
157  {
158  return mEntries.at(irow).color();
159  }
160 
161  //---------------- PROXY ------------------------------------------
163  {
164  ;
165  }
166 
168  {
169  mSortMechanism = sortMechanism;
170  }
171 
172  bool ModuleSelectProxy::lessThan(const QColor& a, const QColor& b)
173  {
174  if (a.hue() < b.hue())
175  return true;
176  if (a.hue() > b.hue())
177  return false;
178  if (a.saturation() < b.saturation())
179  return true;
180  if (a.saturation() > b.saturation())
181  return false;
182  return (a.value() < b.value());
183  }
184 
185  bool ModuleSelectProxy::lessThan(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const
186  {
187  if (!sourceLeft.column() && !sourceRight.column())
188  {
189  const ModuleSelectModel* modl = static_cast<const ModuleSelectModel*>(sourceModel());
190  QColor cLeft = modl->moduleColor(sourceLeft.row());
191  QColor cRight = modl->moduleColor(sourceRight.row());
192  return lessThan(cLeft, cRight);
193  }
194  QString sLeft = sourceModel()->data(sourceLeft).toString();
195  QString sRight = sourceModel()->data(sourceRight).toString();
196  return gui_utility::compare(mSortMechanism, sLeft, sRight);
197  }
198 
199  void ModuleSelectProxy::startSearch(QString text, int options)
200  {
201  mSearchString = text;
202  mSearchOptions = SearchOptions(options);
204  }
205 
206  bool ModuleSelectProxy::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
207  {
208  return checkRow(source_row, source_parent, 1, 3, 1);
209  }
210 
211  //---------------- EXCLUDE ----------------------------------------
213  {
214  mModules = gSelectionRelay->selectedModulesList();
216  }
217 
219  {
220  QString retval;
221  if (!mModules.isEmpty())
222  {
223  retval += "module";
224  if (mModules.size() > 1)
225  retval += 's';
226  for (u32 modId : mModules)
227  {
228  Module* m = gNetlist->get_module_by_id(modId);
229  if (m)
230  retval += QString(" '%1'[%2]").arg(m->get_name().c_str()).arg(m->get_id());
231  }
232  }
233  if (!retval.isEmpty())
234  retval += ", ";
235  if (!mGates.isEmpty())
236  {
237  retval += "gate";
238  if (mGates.size() > 1)
239  retval += 's';
240  for (u32 modId : mGates)
241  {
242  Gate* g = gNetlist->get_gate_by_id(modId);
243  if (g)
244  retval += QString(" '%1'[%2]").arg(g->get_name().c_str()).arg(g->get_id());
245  }
246  }
247  return retval;
248  }
249 
251  {
252  return QtCompat::listToSet<u32>(mModules);
253  }
254 
256  {
257  return QtCompat::listToSet<u32>(mGates);
258  }
259 
260  //---------------- PICKER -----------------------------------------
261 
263  : QObject(parent)
264  {
270  }
271 
273  {
274  Q_UNUSED(sender);
275 
276  Module* firstAccepted = nullptr;
277  u32 notAccepted = 0;
278  bool terminate = true;
279 
280  for (u32 modId : gSelectionRelay->selectedModulesList())
281  {
282  if (mSelectExclude.isAccepted(modId))
283  {
284  Module* m = gNetlist->get_module_by_id(modId);
285  if (m)
286  {
287  firstAccepted = m;
288  break;
289  }
290  }
291  else
292  {
293  if (!notAccepted)
294  notAccepted = modId;
295  }
296  }
297 
298  if (firstAccepted)
299  {
300  mModulesSelected.insert(firstAccepted->get_id());
301  }
302  else if (notAccepted)
303  {
304  Module* mRefused = gNetlist->get_module_by_id(notAccepted);
305  if (mRefused)
306  QMessageBox::warning(qApp->activeWindow(), "Warning", QString("Cannot select module '%1' [id=%2]").arg(QString::fromStdString(mRefused->get_name())).arg(notAccepted));
307  else
308  QMessageBox::warning(qApp->activeWindow(), "Warning", QString("Module with id=%1 not found in netlist").arg(notAccepted));
309  }
310  else
311  terminate = gSelectionRelay->numberSelectedItems() > 0;
312 
313  if (terminate)
314  terminatePicker();
315  }
316 
318  {
321  Q_EMIT modulesPicked(mModulesSelected);
323  deleteLater();
324  }
325 
326  //---------------- VIEW -------------------------------------------
327  ModuleSelectView::ModuleSelectView(bool history, Searchbar* sbar, QSet<u32>* exclude_ids, QWidget* parent) : QTableView(parent)
328  {
331 
332  ModuleSelectProxy* prox = new ModuleSelectProxy(this);
334 
335  ModuleSelectModel* modl = new ModuleSelectModel(this);
336 
337  if (exclude_ids != nullptr)
338  {
339  modl->excludeModulesById(*exclude_ids);
340  }
341  modl->appendEntries(history);
342 
343  prox->setSourceModel(modl);
344  setModel(prox);
345 
346  connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, &ModuleSelectView::handleSelectionChanged);
347  connect(this, &QTableView::doubleClicked, this, &ModuleSelectView::handleDoubleClick);
348  setSortingEnabled(true);
349  sortByColumn(history ? -1 : 2, Qt::AscendingOrder);
352  verticalHeader()->hide();
353  }
354 
355  void ModuleSelectView::handleSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
356  {
357  if (selected.indexes().empty())
358  {
359  Q_EMIT(moduleSelected(0, false));
360  return;
361  }
362  Q_UNUSED(deselected);
363  const ModuleSelectProxy* prox = static_cast<const ModuleSelectProxy*>(model());
364  Q_ASSERT(prox);
365  const ModuleSelectModel* modl = static_cast<const ModuleSelectModel*>(prox->sourceModel());
366  QModelIndex sourceIndex = prox->mapToSource(selected.indexes().at(0));
367  u32 selModId = modl->moduleId(sourceIndex.row());
368  Q_EMIT(moduleSelected(selModId, false));
369  }
370 
371  void ModuleSelectView::handleDoubleClick(const QModelIndex& index)
372  {
373  const ModuleSelectProxy* prox = static_cast<const ModuleSelectProxy*>(model());
374  Q_ASSERT(prox);
375  const ModuleSelectModel* modl = static_cast<const ModuleSelectModel*>(prox->sourceModel());
376  QModelIndex sourceIndex = prox->mapToSource(index);
377  u32 selModId = modl->moduleId(sourceIndex.row());
378  Q_EMIT(moduleSelected(selModId, true));
379  }
380 
381 } // namespace hal
GraphTabWidget * getGraphTabWidget()
Get hal's graph tab widget.
Definition: gate.h:58
const std::string & get_name() const
Definition: gate.cpp:105
u32 get_id() const
Definition: gate.cpp:95
void setSelectCursor(int icurs)
void triggerTerminatePicker() const
std::string get_name() const
Definition: module.cpp:88
std::string get_type() const
Definition: module.cpp:107
u32 get_id() const
Definition: module.cpp:83
The ModuleSelectEntry class comprises a single entry of the module selection table.
QVariant data(int icol) const
data returns data from requested column
ModuleSelectEntry(Module *m)
QColor color() const
QString selectionToString() const
selectionToString function is used to generate selection as text for message box
bool isAccepted(u32 modId) const
The ModuleSelectHistory class singleton comprises a list of user selected modules.
static ModuleSelectHistory * instance()
The ModuleSelectModel class is the source model for module selection.
QColor moduleColor(int irow) const
void excludeModulesById(QSet< u32 > id_set)
void appendEntries(bool history)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
ModuleSelectModel(QObject *parent=nullptr)
ModuleSelectModel constructor.
u32 moduleId(int irow) const
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
void handleSelectionChanged(void *sender)
ModuleSelectPicker(ModuleSelectReceiver *receiver, QObject *parent=nullptr)
void modulesPicked(QSet< u32 > mods)
void triggerCursor(int icurs)
The ModuleSelectProxy class allows sorting and filtering of module tables.
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
void startSearch(QString text, int options) override
static bool lessThan(const QColor &a, const QColor &b)
ModuleSelectProxy(QObject *parent=nullptr)
void setSortMechanism(gui_utility::mSortMechanism sortMechanism)
virtual void handleModulesPicked(const QSet< u32 > &mods)=0
void moduleSelected(u32 modId, bool doubleClick)
ModuleSelectView(bool history, Searchbar *sbar, QSet< u32 > *exclude_ids, QWidget *parent=nullptr)
ModuleSelectView constructor.
Gate * get_gate_by_id(const u32 gate_id) const
Definition: netlist.cpp:195
const std::vector< Module * > & get_modules() const
Definition: netlist.cpp:626
Module * get_module_by_id(u32 module_id) const
Definition: netlist.cpp:615
QColor getModuleColor(const u32 id)
SearchOptions mSearchOptions
bool checkRow(int sourceRow, const QModelIndex &sourceParent, int startIndex, int endIndex, int offset=0) const
Should be called inside filterAcceptsRow function and returns true if the source_row,...
A QFrame with a QLineEdit that can be used to input a substring to search for.
Definition: searchbar.h:48
void triggerNewSearch(const QString &text, int searchOptions)
int numberSelectedItems() const
void selectionChanged(void *sender)
QList< u32 > selectedModulesList() const
QList< u32 > selectedGatesList() const
uint32_t u32
Definition: defines.h:41
QIcon getStyledSvgIcon(const QString &from_to_colors_enabled, const QString &svg_path, QString from_to_colors_disabled=QString())
Definition: graphics.cpp:60
int compare(mSortMechanism mechanism, QString a, QString b)
Definition: sort.cpp:153
Definition: defines.h:45
ContentManager * gContentManager
Definition: plugin_gui.cpp:79
SelectionRelay * gSelectionRelay
Definition: plugin_gui.cpp:84
Netlist * gNetlist
Definition: gui_globals.h:69
NetlistRelay * gNetlistRelay
Definition: gui_globals.h:74
void doubleClicked(const QModelIndex &index)
QAbstractItemModel * model() const const
void setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior)
void setSelectionMode(QAbstractItemView::SelectionMode mode)
QItemSelectionModel * selectionModel() const const
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
int hue() const const
QString name() const const
int saturation() const const
int value() const const
void setStretchLastSection(bool stretch)
QModelIndexList indexes() const const
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
bool isEmpty() const const
void prepend(const T &value)
int removeAll(const T &value)
int size() const const
QMessageBox::StandardButton warning(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
int column() const const
bool isValid() const const
int row() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void deleteLater()
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QObject * parent() const const
QObject * sender() const const
QSet::iterator insert(const T &value)
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromStdString(const std::string &str)
bool isEmpty() const const
DisplayRole
Orientation
AscendingOrder
void sortByColumn(int column)
QHeaderView * horizontalHeader() const const
void resizeColumnsToContents()
virtual void setModel(QAbstractItemModel *model) override
void setSortingEnabled(bool enable)
QHeaderView * verticalHeader() const const
void hide()