HAL
module_select_model.cpp
Go to the documentation of this file.
2 
5 #include "gui/gui_globals.h"
10 
11 #include <QApplication>
12 #include <QHeaderView>
13 #include <QMessageBox>
14 #include <QSortFilterProxyModel>
15 
16 #include <QDebug>
17 
18 namespace hal
19 {
20  //---------------- HISTORY ----------------------------------------
21  const int ModuleSelectHistory::sMaxEntries = 10;
22 
23  ModuleSelectHistory* ModuleSelectHistory::inst = nullptr;
24 
26  {
27  if (!inst)
28  inst = new ModuleSelectHistory;
29  return inst;
30  }
31 
33  {
34  removeAll(id);
35  prepend(id);
36  while (size() > sMaxEntries) takeLast();
37  }
38 
39  //---------------- ENTRY ------------------------------------------
41  {
42  mId = m->get_id();
43  mName = QString::fromStdString(m->get_name());
44  mType = QString::fromStdString(m->get_type());
45  mColor = gNetlistRelay->getModuleColor(mId);
46  }
47 
49  {
50  switch (icol)
51  {
52  case 0:
53  return mColor;
54  case 1:
55  return mId;
56  case 2:
57  return mName;
58  case 3:
59  return mType;
60  }
61  return QVariant();
62  }
63 
64  //---------------- MODEL ------------------------------------------
66  {
67 
68  }
69 
71  {
72  if (history)
73  {
75  {
77  if (m && mExcl.isAccepted(m->get_id()))
78  mEntries.append(ModuleSelectEntry(m));
79  }
80  }
81  else
82  {
83  for (Module* m : gNetlist->get_modules())
84  {
85  if (mExcl.isAccepted(m->get_id()))
86  {
87  mEntries.append(ModuleSelectEntry(m));
88  }
89  }
90  }
91  }
92 
93  int ModuleSelectModel::rowCount(const QModelIndex& parent) const
94  {
95  Q_UNUSED(parent);
96 
97  return mEntries.size();
98  }
99 
101  {
102  Q_UNUSED(parent);
103 
104  return 4;
105  }
106 
107  QVariant ModuleSelectModel::headerData(int section, Qt::Orientation orientation, int role) const
108  {
109  if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
110  return QVariant();
111  switch (section)
112  {
113  case 1:
114  return "ID";
115  case 2:
116  return "Name";
117  case 3:
118  return "Type";
119  }
120  return QVariant();
121  }
122 
123  QVariant ModuleSelectModel::data(const QModelIndex& index, int role) const
124  {
125  if (!index.isValid() || index.row() >= mEntries.size())
126  return QVariant();
127  const ModuleSelectEntry& mod = mEntries.at(index.row());
128 
129  switch (role)
130  {
131  case Qt::DecorationRole: {
132  if (index.column() == 0)
133  {
134  QString runIconStyle = "all->" + mod.color().name();
135  QString runIconPath = ":/icons/filled-circle";
136 
137  return gui_utility::getStyledSvgIcon(runIconStyle, runIconPath);
138  }
139  break;
140  }
141  case Qt::DisplayRole:
142  if (index.column() > 0)
143  return mod.data(index.column());
144  break;
145  }
146 
147  return QVariant();
148  }
149 
151  {
152  return mEntries.at(irow).id();
153  }
154 
156  {
157  return mEntries.at(irow).color();
158  }
159 
160  //---------------- PROXY ------------------------------------------
162  {
163  ;
164  }
165 
167  {
168  mSortMechanism = sortMechanism;
169  }
170 
171  bool ModuleSelectProxy::lessThan(const QColor& a, const QColor& b)
172  {
173  if (a.hue() < b.hue())
174  return true;
175  if (a.hue() > b.hue())
176  return false;
177  if (a.saturation() < b.saturation())
178  return true;
179  if (a.saturation() > b.saturation())
180  return false;
181  return (a.value() < b.value());
182  }
183 
184  bool ModuleSelectProxy::lessThan(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const
185  {
186  if (!sourceLeft.column() && !sourceRight.column())
187  {
188  const ModuleSelectModel* modl = static_cast<const ModuleSelectModel*>(sourceModel());
189  QColor cLeft = modl->moduleColor(sourceLeft.row());
190  QColor cRight = modl->moduleColor(sourceRight.row());
191  return lessThan(cLeft, cRight);
192  }
193  QString sLeft = sourceModel()->data(sourceLeft).toString();
194  QString sRight = sourceModel()->data(sourceRight).toString();
195  return gui_utility::compare(mSortMechanism, sLeft, sRight);
196  }
197 
198  void ModuleSelectProxy::startSearch(QString text, int options)
199  {
200  mSearchString = text;
201  mSearchOptions = SearchOptions(options);
203  }
204 
205  bool ModuleSelectProxy::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
206  {
207  return checkRow(source_row, source_parent, 1, 3, 1);
208  }
209 
210  //---------------- EXCLUDE ----------------------------------------
212  {
213  mModules = gSelectionRelay->selectedModulesList();
215  }
216 
218  {
219  QString retval;
220  if (!mModules.isEmpty())
221  {
222  retval += "module";
223  if (mModules.size() > 1)
224  retval += 's';
225  for (u32 modId : mModules)
226  {
227  Module* m = gNetlist->get_module_by_id(modId);
228  if (m)
229  retval += QString(" '%1'[%2]").arg(m->get_name().c_str()).arg(m->get_id());
230  }
231  }
232  if (!retval.isEmpty())
233  retval += ", ";
234  if (!mGates.isEmpty())
235  {
236  retval += "gate";
237  if (mGates.size() > 1)
238  retval += 's';
239  for (u32 modId : mGates)
240  {
241  Gate* g = gNetlist->get_gate_by_id(modId);
242  if (g)
243  retval += QString(" '%1'[%2]").arg(g->get_name().c_str()).arg(g->get_id());
244  }
245  }
246  return retval;
247  }
248 
249  //---------------- PICKER -----------------------------------------
250 
252  : QObject(parent)
253  {
259  }
260 
262  {
263  Q_UNUSED(sender);
264 
265  Module* firstAccepted = nullptr;
266  u32 notAccepted = 0;
267  bool terminate = true;
268 
269  for (u32 modId : gSelectionRelay->selectedModulesList())
270  {
271  if (mSelectExclude.isAccepted(modId))
272  {
273  Module* m = gNetlist->get_module_by_id(modId);
274  if (m)
275  {
276  firstAccepted = m;
277  break;
278  }
279  }
280  else
281  {
282  if (!notAccepted)
283  notAccepted = modId;
284  }
285  }
286 
287  if (firstAccepted)
288  {
289  mModulesSelected.insert(firstAccepted->get_id());
290  }
291  else if (notAccepted)
292  {
293  Module* mRefused = gNetlist->get_module_by_id(notAccepted);
294  if (mRefused)
295  QMessageBox::warning(qApp->activeWindow(), "Warning", QString("Cannot select module '%1' [id=%2]").arg(QString::fromStdString(mRefused->get_name())).arg(notAccepted));
296  else
297  QMessageBox::warning(qApp->activeWindow(), "Warning", QString("Module with id=%1 not found in netlist").arg(notAccepted));
298  }
299  else
300  terminate = gSelectionRelay->numberSelectedItems() > 0;
301 
302  if (terminate)
303  terminatePicker();
304  }
305 
307  {
310  Q_EMIT modulesPicked(mModulesSelected);
312  deleteLater();
313  }
314 
315  //---------------- VIEW -------------------------------------------
316  ModuleSelectView::ModuleSelectView(bool history, Searchbar* sbar, QSet<u32>* exclude_ids, QWidget* parent) : QTableView(parent)
317  {
320 
321  ModuleSelectProxy* prox = new ModuleSelectProxy(this);
323 
324  ModuleSelectModel* modl = new ModuleSelectModel(this);
325 
326  if (exclude_ids != nullptr)
327  {
328  modl->excludeModulesById(*exclude_ids);
329  }
330  modl->appendEntries(history);
331 
332  prox->setSourceModel(modl);
333  setModel(prox);
334 
335  connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, &ModuleSelectView::handleSelectionChanged);
336  connect(this, &QTableView::doubleClicked, this, &ModuleSelectView::handleDoubleClick);
337  setSortingEnabled(true);
338  sortByColumn(history ? -1 : 2, Qt::AscendingOrder);
341  verticalHeader()->hide();
342  }
343 
344  void ModuleSelectView::handleSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
345  {
346  if (selected.indexes().empty())
347  {
348  Q_EMIT(moduleSelected(0, false));
349  return;
350  }
351  Q_UNUSED(deselected);
352  const ModuleSelectProxy* prox = static_cast<const ModuleSelectProxy*>(model());
353  Q_ASSERT(prox);
354  const ModuleSelectModel* modl = static_cast<const ModuleSelectModel*>(prox->sourceModel());
355  QModelIndex sourceIndex = prox->mapToSource(selected.indexes().at(0));
356  u32 selModId = modl->moduleId(sourceIndex.row());
357  Q_EMIT(moduleSelected(selModId, false));
358  }
359 
360  void ModuleSelectView::handleDoubleClick(const QModelIndex& index)
361  {
362  const ModuleSelectProxy* prox = static_cast<const ModuleSelectProxy*>(model());
363  Q_ASSERT(prox);
364  const ModuleSelectModel* modl = static_cast<const ModuleSelectModel*>(prox->sourceModel());
365  QModelIndex sourceIndex = prox->mapToSource(index);
366  u32 selModId = modl->moduleId(sourceIndex.row());
367  Q_EMIT(moduleSelected(selModId, true));
368  }
369 
370 } // namespace hal
GraphTabWidget * getGraphTabWidget()
Get hal's graph tab widget.
Definition: gate.h:58
void setSelectCursor(int icurs)
void triggerTerminatePicker() const
std::string get_name() const
Definition: module.cpp:87
std::string get_type() const
Definition: module.cpp:106
u32 get_id() const
Definition: module.cpp:82
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:193
const std::vector< Module * > & get_modules() const
Definition: netlist.cpp:624
Module * get_module_by_id(u32 module_id) const
Definition: netlist.cpp:613
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
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
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
quint32 u32
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()