HAL
gate_select_model.cpp
Go to the documentation of this file.
1 
3 
6 #include "gui/gui_globals.h"
12 #include "hal_core/netlist/gate.h"
13 
14 #include <QApplication>
15 #include <QHeaderView>
16 #include <QMessageBox>
17 #include <QSortFilterProxyModel>
18 
19 namespace hal
20 {
21  //---------------- HISTORY ----------------------------------------
22  GateSelectHistory* GateSelectHistory::inst = nullptr;
23 
25  {
26  if (!inst)
27  inst = new GateSelectHistory;
28  return inst;
29  }
30 
32  {
33  removeAll(id);
34  prepend(id);
35  }
36 
37  //---------------- ENTRY ------------------------------------------
39  {
40  mId = g->get_id();
41  mName = QString::fromStdString(g->get_name());
42  mType = QString::fromStdString(g->get_type()->get_name());
43  }
44 
46  {
47  switch (icol)
48  {
49  case 0:
50  return mId;
51  case 1:
52  return mName;
53  case 2:
54  return mType;
55  }
56  return QVariant();
57  }
58 
59  //---------------- MODEL ------------------------------------------
60  GateSelectModel::GateSelectModel(bool history, const QSet<u32> &selectable, QObject* parent)
61  : QAbstractTableModel(parent), mSelectableGates(selectable)
62  {
63  if (history)
64  {
65  for (u32 id : *GateSelectHistory::instance())
66  {
67  Gate* g = gNetlist->get_gate_by_id(id);
68  if (g && isAccepted(g->get_id(),mSelectableGates))
69  mEntries.append(GateSelectEntry(g));
70  }
71  }
72  else
73  {
74  for (Gate* g : gNetlist->get_gates())
75  if (isAccepted(g->get_id(),mSelectableGates))
76  mEntries.append(GateSelectEntry(g));
77  }
78  }
79 
80  bool GateSelectModel::isAccepted(u32 gateId, const QSet<u32> &selectable)
81  {
82  if (selectable.isEmpty()) return true;
83  return selectable.contains(gateId);
84  }
85 
86  int GateSelectModel::rowCount(const QModelIndex& parent) const
87  {
88  Q_UNUSED(parent);
89 
90  return mEntries.size();
91  }
92 
93  int GateSelectModel::columnCount(const QModelIndex& parent) const
94  {
95  Q_UNUSED(parent);
96 
97  return 3;
98  }
99 
100  QVariant GateSelectModel::headerData(int section, Qt::Orientation orientation, int role) const
101  {
102  if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
103  return QVariant();
104  switch (section)
105  {
106  case 0:
107  return "ID";
108  case 1:
109  return "Name";
110  case 2:
111  return "Type";
112  }
113  return QVariant();
114  }
115 
116  QVariant GateSelectModel::data(const QModelIndex& index, int role) const
117  {
118  if (!index.isValid() || index.row() >= mEntries.size())
119  return QVariant();
120  const GateSelectEntry& mod = mEntries.at(index.row());
121 
122  if (role == Qt::DisplayRole)
123  return mod.data(index.column());
124 
125  return QVariant();
126  }
127 
128  u32 GateSelectModel::gateId(int irow) const
129  {
130  return mEntries.at(irow).id();
131  }
132 
133  //---------------- PROXY ------------------------------------------
135  {
136  ;
137  }
138 
140  {
141  mSortMechanism = sortMechanism;
142  }
143 
144  bool GateSelectProxy::lessThan(const QModelIndex& sourceLeft, const QModelIndex& sourceRight) const
145  {
146  if (!sourceLeft.column() && !sourceRight.column())
147  return sourceModel()->data(sourceLeft).toInt() < sourceModel()->data(sourceRight).toInt();
148 
149  QString sLeft = sourceModel()->data(sourceLeft).toString();
150  QString sRight = sourceModel()->data(sourceRight).toString();
151  return gui_utility::compare(mSortMechanism, sLeft, sRight);
152  }
153 
155  {
156  setFilterKeyColumn(-1);
158  }
159 
160  void GateSelectProxy::startSearch(QString text, int options)
161  {
162  mSearchString = text;
163  mSearchOptions = SearchOptions(options);
165  }
166 
167  bool GateSelectProxy::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
168  {
169  return checkRow(source_row, source_parent, 0, 2);
170  }
171 
172  //---------------- PICKER -----------------------------------------
174  : mSelectableGates(selectable)
175  {
181  }
182 
184  {
185  Q_UNUSED(sender);
186 
187  Gate* firstAccepted = nullptr;
188  u32 notAccepted = 0;
189  bool terminate = true;
190 
191  for (u32 gatId : gSelectionRelay->selectedGatesList())
192  {
193  if (GateSelectModel::isAccepted(gatId,mSelectableGates))
194  {
195  Gate* g = gNetlist->get_gate_by_id(gatId);
196  if (g)
197  {
198  firstAccepted = g;
199  break;
200  }
201  }
202  else
203  {
204  if (!notAccepted)
205  notAccepted = gatId;
206  }
207  }
208 
209  if (firstAccepted)
210  {
211  mGatesSelected.insert(firstAccepted->get_id());
212  }
213  else if (notAccepted)
214  {
215  Gate* g = gNetlist->get_gate_by_id(notAccepted);
216  if (g)
217  QMessageBox::warning(qApp->activeWindow(), "Warning", QString("Gate %1[%2] is no valid selection")
218  .arg(QString::fromStdString(g->get_name()))
219  .arg(notAccepted));
220  else
221  QMessageBox::warning(qApp->activeWindow(), "Warning", QString("Cannot select gate [%1]").arg(notAccepted));
222  }
223  else
224  terminate = gSelectionRelay->numberSelectedItems() > 0;
225 
226  if (terminate)
227  terminatePicker();
228  }
229 
231  {
234  Q_EMIT gatesPicked(mGatesSelected);
236  deleteLater();
237  }
238 
239  //---------------- VIEW -------------------------------------------
240  GateSelectView::GateSelectView(bool history, const QSet<u32> &selectable, QWidget* parent) : QTableView(parent)
241  {
244 
245  GateSelectProxy* prox = new GateSelectProxy(this);
246 
247  GateSelectModel* modl = new GateSelectModel(history, selectable, this);
248  prox->setSourceModel(modl);
249  setModel(prox);
250 
251  connect(selectionModel(), &QItemSelectionModel::currentChanged, this, &GateSelectView::handleCurrentChanged);
252  connect(this, &QTableView::doubleClicked, this, &GateSelectView::handleDoubleClick);
253  setSortingEnabled(true);
254  sortByColumn(history ? -1 : 2, Qt::AscendingOrder);
257  verticalHeader()->hide();
258  }
259 
260  void GateSelectView::handleCurrentChanged(const QModelIndex& current, const QModelIndex& previous)
261  {
262  Q_UNUSED(previous);
263  const GateSelectProxy* prox = static_cast<const GateSelectProxy*>(model());
264  Q_ASSERT(prox);
265  const GateSelectModel* modl = static_cast<const GateSelectModel*>(prox->sourceModel());
266  QModelIndex sourceIndex = prox->mapToSource(current);
267  u32 selGatId = modl->gateId(sourceIndex.row());
268  Q_EMIT(gateSelected(selGatId, false));
269  }
270 
271  void GateSelectView::handleDoubleClick(const QModelIndex& index)
272  {
273  const GateSelectProxy* prox = static_cast<const GateSelectProxy*>(model());
274  Q_ASSERT(prox);
275  const GateSelectModel* modl = static_cast<const GateSelectModel*>(prox->sourceModel());
276  QModelIndex sourceIndex = prox->mapToSource(index);
277  u32 selGatId = modl->gateId(sourceIndex.row());
278  Q_EMIT(gateSelected(selGatId, true));
279  }
280 
281 } // namespace hal
GraphTabWidget * getGraphTabWidget()
Get hal's graph tab widget.
Definition: gate.h:58
u32 get_id() const
Definition: gate.cpp:95
The GateSelectEntry class comprises a single entry of the module selection table.
QVariant data(int icol) const
data returns data from requested column
GateSelectEntry(Gate *g)
The GateSelectHistory class singleton comprises a list of user selected modules.
static GateSelectHistory * instance()
The GateSelectModel class is the source model for module selection.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
GateSelectModel(bool history, const QSet< u32 > &selectable=QSet< u32 >(), QObject *parent=nullptr)
GateSelectModel constructor.
u32 gateId(int irow) const
static bool isAccepted(u32 gateId, const QSet< u32 > &selectable)
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
GateSelectPicker(const QSet< u32 > &selectable, GateSelectReceiver *receiver)
void triggerCursor(int icurs)
void gatesPicked(QSet< u32 > gats)
void handleSelectionChanged(void *sender)
The GateSelectProxy class allows sorting and filtering of module tables.
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
void startSearch(QString text, int options)
GateSelectProxy(QObject *parent=nullptr)
void setSortMechanism(gui_utility::mSortMechanism sortMechanism)
void searchTextChanged(const QString &txt)
bool lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const override
virtual void handleGatesPicked(const QSet< u32 > &gats)=0
GateSelectView(bool history, const QSet< u32 > &selectable, QWidget *parent=nullptr)
GateSelectView constructor.
void gateSelected(u32 gatId, bool doubleClick)
void setSelectCursor(int icurs)
void triggerTerminatePicker() const
const std::vector< Gate * > & get_gates() const
Definition: netlist.cpp:204
Gate * get_gate_by_id(const u32 gate_id) const
Definition: netlist.cpp:193
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,...
int numberSelectedItems() const
void selectionChanged(void *sender)
QList< u32 > selectedGatesList() const
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
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
void setStretchLastSection(bool stretch)
void currentChanged(const QModelIndex &current, const QModelIndex &previous)
void prepend(const T &value)
int removeAll(const T &value)
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
bool contains(const T &value) const const
QSet::iterator insert(const T &value)
bool isEmpty() const const
void setFilterKeyColumn(int column)
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const const override
void setFilterRegularExpression(const QString &pattern)
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromStdString(const std::string &str)
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()