HAL
grouping_table_model.cpp
Go to the documentation of this file.
4 #include "gui/gui_globals.h"
5 
6 #include <QApplication>
7 #include <QHeaderView>
8 
9 namespace hal {
10 
12  {
13  return QColor::fromHsv(c.h,c.s,c.v);
14  }
15 
17  : mGrouping(nullptr)
18  {
19  mGrouping = gNetlist->create_grouping(n.toStdString());
20  }
21 
23  : mGrouping(nullptr)
24  {
25  mGrouping = gNetlist->get_grouping_by_id(existingId);
26  }
27 
29  {
30  if (!mGrouping) return 0;
31  return mGrouping->get_id();
32  }
33 
35  {
36  if (!mGrouping) return QString();
37  return QString::fromStdString(mGrouping->get_name());
38  }
39 
41  {
42  if (!mGrouping) return QString();
43  return toQColor(mGrouping->get_color());
44  }
45 
47  {
48  if (!mGrouping) return;
49  mGrouping->set_name(n.toStdString());
50  }
51 
53  {
54  if (!mGrouping) return;
55  mGrouping->set_color(utils::Color(c.hue(), c.saturation(), c.value()));
56  }
57 
59  : QAbstractTableModel(parent), mDisableEvents(false), mIsHistory(history)
60  {
61  if (history)
62  {
63  // if history is set to true, only load the groupings from GroupingTableHistory into the model
64  for(auto id : *GroupingTableHistory::instance())
65  {
66  mDisableEvents = true;
68  GroupingTableEntry gte(id);
69  int n = mGroupings.size();
70  mGroupings.append(gte);
72  mDisableEvents = false;
73 
74  QModelIndex inx = index(n, 0);
75  Q_EMIT newEntryAdded(inx);
76  }
77  }
78  else
79  {
80  // on creation load all already existing groupings from the netlist into the model
81  for(auto grp : gNetlist->get_groupings())
82  {
83  mDisableEvents = true;
85  GroupingTableEntry gte(grp->get_id());
86  int n = mGroupings.size();
87  mGroupings.append(gte);
89  mDisableEvents = false;
90 
91  QModelIndex inx = index(n, 0);
92  Q_EMIT newEntryAdded(inx);
93  }
94  }
95 
96 
101  }
102 
104  {
105  Q_UNUSED(parent)
106  return 3;
107  }
108 
109  int GroupingTableModel::rowCount(const QModelIndex &parent) const
110  {
111  Q_UNUSED(parent)
112  return mGroupings.size();
113  }
114 
115  QVariant GroupingTableModel::headerData(int section, Qt::Orientation orientation, int role) const
116  {
117  if(role != Qt::DisplayRole)
118  return QVariant();
119 
120  if(orientation == Qt::Horizontal)
121  {
122  switch(section)
123  {
124  case 0: return "Grouping Name";
125  case 1: return "ID";
126  case 2: return "Color";
127  default: break;
128  }
129  return QVariant();
130  }
131 
132  return section + 1;
133  }
134 
135  QVariant GroupingTableModel::data(const QModelIndex &index, int role) const
136  {
137  if (!index.isValid()) return QVariant();
138  const GroupingTableEntry& gte = mGroupings.at(index.row());
139 
140  switch (role) {
141  case Qt::BackgroundRole:
142  if (index.column()==2) return gte.color();
143  return QVariant();
144  case Qt::DisplayRole:
145  switch (index.column()) {
146  case 0:
147  return gte.name();
148  case 1:
149  return gte.id();
150  case 2:
151  return gte.color().name();
152  }
153  default:
154  break;
155  }
156  return QVariant();
157  }
158 
159  bool GroupingTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
160  {
161  if (role != Qt::EditRole) return false;
162  if (!index.isValid()) return false;
163  switch (index.column()) {
164  case 0:
165  mGroupings[index.row()].setName(value.toString().trimmed());
166  return true;
167  case 2:
168  mGroupings[index.row()].setColor(value.value<QColor>());
169  Q_EMIT groupingColorChanged(mGroupings.at(index.row()).grouping());
170  return true;
171  }
172  return false;
173  }
174 
175  bool GroupingTableModel::removeRows(int row, int count, const QModelIndex &parent)
176  {
177  Q_UNUSED(parent);
178  Q_UNUSED(count);
179 
180  mDisableEvents = true;
181  int nrows = mGroupings.size();
182  if (row >= nrows) return false;
183  Grouping* grp = mGroupings.at(row).grouping();
184  for (Module* m : grp->get_modules())
185  grp->remove_module(m);
186  for (Gate* g : grp->get_gates())
187  grp->remove_gate(g);
188  for (Net* n : grp->get_nets())
189  grp->remove_net(n);
192  mGroupings.removeAt(row);
194  mDisableEvents = false;
195  if (row >= nrows-1)
197  return true;
198  }
199 
201  {
202  if (input.isEmpty()) return false;
203  if (input == mAboutToRename) return true; // allow existing name on rename
204  for (const GroupingTableEntry& gte : mGroupings)
205  {
206  if (gte.name() == input.trimmed())
207  return false;
208  }
209  return true;
210  }
211 
213  {
214  QSet<QString> existingNames;
215  u32 maxId = 0;
216  for (const GroupingTableEntry& gte : mGroupings)
217  {
218  if (gte.id() > maxId) maxId = gte.id();
219  existingNames.insert(gte.name());
220  }
221 
222  mDisableEvents = true;
224  GroupingTableEntry gte(generateUniqueName(QString("grouping%1").arg(maxId+1), existingNames));
225  int n = mGroupings.size();
226  mGroupings.append(gte);
228  mDisableEvents = false;
229 
230  QModelIndex inx = index(n, 0);
231  Q_EMIT newEntryAdded(inx);
232  return gte.grouping();
233  }
234 
236  {
237  if (mDisableEvents) return;
238  for (auto it = mGroupings.begin(); it != mGroupings.end(); ++it)
239  if (it->grouping() == grp)
240  {
242  it = mGroupings.erase(it);
244  if (it == mGroupings.end()) Q_EMIT lastEntryDeleted();
245  return;
246  }
247  }
248 
250  {
251  if (mDisableEvents || mIsHistory) return;
253  int n = mGroupings.size();
254  mGroupings.append(GroupingTableEntry(grp));
256  QModelIndex inx = index(n, 0);
257  Q_EMIT newEntryAdded(inx);
258  }
259 
261  {
262  if (mDisableEvents) return;
263  int irow = 0;
264  for (auto it = mGroupings.begin(); it != mGroupings.end(); ++it)
265  {
266  if (it->grouping() == grp)
267  {
268  it->setName(QString::fromStdString(grp->get_name()));
269  QModelIndex inx = index(irow, 0);
270  Q_EMIT dataChanged(inx, inx);
271  }
272  ++irow;
273  }
274  }
275 
277  {
278  if (mDisableEvents) return;
279  mDisableEvents = true;
280  int irow = 0;
281  for (auto it = mGroupings.begin(); it != mGroupings.end(); ++it)
282  {
283  if (it->grouping() == grp)
284  {
285  it->setColor(toQColor(grp->get_color()));
286  QModelIndex inx = index(irow, 0);
287  Q_EMIT dataChanged(inx, inx);
288  }
289  ++irow;
290  }
291  mDisableEvents = false;
292  }
293 
295  {
296  for (int irow = 0; irow < mGroupings.size(); irow++)
297  {
298  if (mGroupings.at(irow).id() != id) continue;
299  mDisableEvents = true;
300  QString oldName = mGroupings.at(irow).name();
301  mGroupings[irow].setName(groupingName);
302  QModelIndex inx = index(irow, 0);
303  Q_EMIT dataChanged(inx, inx);
304  mDisableEvents = false;
305  return oldName;
306  }
307  return QString();
308  }
309 
311  {
312  for (int irow = 0; irow < mGroupings.size(); irow++)
313  {
314  if (mGroupings.at(irow).id() != id) continue;
315  mDisableEvents = true;
316  QColor oldColor = mGroupings.at(irow).color();
317  mGroupings[irow].setColor(c);
318  QModelIndex inx = index(irow, 2);
319  Q_EMIT dataChanged(inx, inx);
320  Q_EMIT groupingColorChanged(mGroupings.at(irow).grouping());
321  mDisableEvents = false;
322  return oldColor;
323  }
324  return QColor();
325  }
326 
327  QString GroupingTableModel::generateUniqueName(const QString& suggestion, const QSet<QString>& existingNames)
328  {
329  QString retval = suggestion;
330  int itry = 0;
331  while (existingNames.contains(retval) && itry < 27*26)
332  {
333  retval = suggestion;
334  if (itry >= 26) retval += (char) ('a' + itry/26 -1);
335  retval += (char) ('a' + itry%26);
336  ++itry;
337  }
338  return retval;
339  }
340 
342  {
343  Grouping* itemGrouping = nullptr;
344  const Module* m = nullptr;
345  const Gate* g = nullptr;
346  const Net* n = nullptr;
347  switch (itemType) {
348  case ItemType::Module:
349  m = gNetlist->get_module_by_id(itemId);
350  if (m) itemGrouping = m->get_grouping();
351  break;
352  case ItemType::Gate:
353  g = gNetlist->get_gate_by_id(itemId);
354  if (g) itemGrouping = g->get_grouping();
355  break;
356  case ItemType::Net:
357  n = gNetlist->get_net_by_id(itemId);
358  if (n) itemGrouping = n->get_grouping();
359  break;
360  default:
361  break;
362  }
363  if (itemGrouping)
364  {
365  for (const GroupingTableEntry& gte : mGroupings)
366  if (gte.grouping() == itemGrouping)
367  return gte.color();
368 
369  }
370  return QColor();
371  }
372 
374  {
375  if (grouping != nullptr)
376  {
377  for (const GroupingTableEntry& gte : mGroupings)
378  if (gte.grouping() == grouping)
379  return gte.color();
380 
381  }
382  return QColor();
383  }
384 
386  {
387  for (const GroupingTableEntry& gte : mGroupings)
388  if (gte.name() == name)
389  return gte.grouping();
390  return nullptr;
391  }
392 
394  {
395  QStringList retval;
396  for (const GroupingTableEntry& gte : mGroupings)
397  retval << gte.name();
398  return retval;
399  }
400 
401  //---------------- HISTORY ----------------------------------------
402  GroupingTableHistory* GroupingTableHistory::inst = nullptr;
403 
404  const int GroupingTableHistory::sMaxEntries = 10;
405 
407  {
408  if (!inst)
409  inst = new GroupingTableHistory;
410  return inst;
411  }
412 
414  {
415  removeAll(id);
416  prepend(id);
417  while (size() > sMaxEntries) takeLast();
418  }
419 
420  //---------------- VIEW -------------------------------------------
421  GroupingTableView::GroupingTableView(bool history, QWidget* parent) : QTableView(parent)
422  {
423  GroupingProxyModel* prox = new GroupingProxyModel(this);
424  GroupingTableModel* modl = new GroupingTableModel(history, this);
425  prox->setSourceModel(modl);
426  setModel(prox);
427 
430 
431  setSortingEnabled(true);
432  sortByColumn(0, Qt::SortOrder::AscendingOrder);
433 
436 
438  font.setBold(true);
444  verticalHeader()->hide();
445 
446  connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, &GroupingTableView::handleSelectionChanged);
447  connect(this, &QTableView::doubleClicked, this, &GroupingTableView::handleDoubleClick);
448  }
449 
450  void GroupingTableView::handleSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
451  {
452  Q_UNUSED(deselected);
453  if (selected.indexes().empty())
454  {
455  Q_EMIT(groupingSelected(0, false));
456  return;
457  }
458  const GroupingProxyModel* prox = static_cast<const GroupingProxyModel*>(model());
459  Q_ASSERT(prox);
460  const GroupingTableModel* modl = static_cast<const GroupingTableModel*>(prox->sourceModel());
461  QModelIndex sourceIndex = prox->mapToSource(selected.indexes().at(0));
462  u32 groupId = modl->groupingAt(sourceIndex.row()).id();
463  Q_EMIT(groupingSelected(groupId, false));
464  }
465 
466  void GroupingTableView::handleDoubleClick(const QModelIndex& index)
467  {
468  const GroupingProxyModel* prox = static_cast<const GroupingProxyModel*>(model());
469  Q_ASSERT(prox);
470  const GroupingTableModel* modl = static_cast<const GroupingTableModel*>(prox->sourceModel());
471  QModelIndex sourceIndex = prox->mapToSource(index);
472  u32 groupId = modl->groupingAt(sourceIndex.row()).id();
473  Q_EMIT(groupingSelected(groupId, true));
474  }
475 }
Definition: gate.h:58
Displays a colored box for the GroupingManagerWidget.
const std::vector< Gate * > & get_gates() const
Definition: grouping.cpp:85
utils::Color get_color() const
Definition: grouping.cpp:47
bool remove_net(Net *net)
Definition: grouping.cpp:212
void set_color(utils::Color c)
Definition: grouping.cpp:52
std::string get_name() const
Definition: grouping.cpp:42
bool remove_gate(Gate *gate)
Definition: grouping.cpp:125
void set_name(std::string name)
Definition: grouping.cpp:27
const std::vector< Net * > & get_nets() const
Definition: grouping.cpp:172
u32 get_id() const
Definition: grouping.cpp:22
const std::vector< Module * > & get_modules() const
Definition: grouping.cpp:259
bool remove_module(Module *module)
Definition: grouping.cpp:299
Helper model to make filtering available.
An entry within a GroupingTableModel.
Grouping * grouping() const
void setColor(const QColor &c)
QString name() const
void setName(const QString &n)
GroupingTableEntry(const QString &n)
QColor color() const
u32 id() const
static GroupingTableHistory * instance()
Table that holds information about all groupings.
QColor colorForGrouping(Grouping *grouping) const
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
GroupingTableModel(bool history, QObject *parent=nullptr)
QString renameGrouping(u32 id, const QString &groupingName)
bool validate(const QString &input)
bool setData(const QModelIndex &index, const QVariant &value, int role) override
void createGroupingEvent(Grouping *grp)
void groupingColorChangedEvent(Grouping *grp)
QVariant data(const QModelIndex &index, int role) const override
void groupingColorChanged(Grouping *grp)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Grouping * groupingByName(const QString &name) const
void groupingNameChangedEvent(Grouping *grp)
bool removeRows(int row, int count=1, const QModelIndex &parent=QModelIndex()) override
void newEntryAdded(QModelIndex &index)
QStringList groupingNames() const
QColor recolorGrouping(u32 id, const QColor &groupingColor)
void deleteGroupingEvent(Grouping *grp)
QColor colorForItem(ItemType itemType, u32 itemId) const
GroupingTableView(bool history, QWidget *parent=nullptr)
void groupingSelected(u32 id, bool doubleClick)
Grouping * get_grouping() const
Definition: module.cpp:120
Definition: net.h:58
Grouping * create_grouping(const u32 grouping_id, const std::string &name="")
Definition: netlist.cpp:671
Gate * get_gate_by_id(const u32 gate_id) const
Definition: netlist.cpp:193
bool delete_grouping(Grouping *grouping)
Definition: netlist.cpp:681
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
const std::vector< Grouping * > & get_groupings() const
Definition: netlist.cpp:702
Grouping * get_grouping_by_id(u32 grouping_id) const
Definition: netlist.cpp:691
void groupingColorChanged(Grouping *grp) const
void groupingCreated(Grouping *grp) const
void groupingRemoved(Grouping *grp) const
void groupingNameChanged(Grouping *grp) const
ItemType
The ItemType enum provides the enum type to classify graphic items into Modules, Gates or Nets....
Definition: gui_def.h:45
Netlist * gNetlist
Definition: plugin_gui.cpp:80
NetlistRelay * gNetlistRelay
Definition: plugin_gui.cpp:81
QColor toQColor(utils::Color c)
n
Definition: test.py:6
quint32 u32
std::string name
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector< int > &roles)
void layoutAboutToBeChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
void layoutChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
void doubleClicked(const QModelIndex &index)
QAbstractItemModel * model() const const
void setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior)
void setSelectionMode(QAbstractItemView::SelectionMode mode)
QItemSelectionModel * selectionModel() const const
void setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
QColor fromHsv(int h, int s, int v, int a)
int hue() const const
QString name() const const
int saturation() const const
int value() const const
void setDefaultAlignment(Qt::Alignment alignment)
void setSectionResizeMode(QHeaderView::ResizeMode mode)
QModelIndexList indexes() const const
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
void prepend(const T &value)
int removeAll(const T &value)
int size() const const
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)
QObject * parent() const const
bool contains(const T &value) const const
QSet::iterator insert(const T &value)
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
QString fromStdString(const std::string &str)
QString trimmed() const const
AlignHCenter
DisplayRole
Orientation
void sortByColumn(int column)
QHeaderView * horizontalHeader() const const
virtual void setModel(QAbstractItemModel *model) override
void setSortingEnabled(bool enable)
QHeaderView * verticalHeader() const const
QString toString() const const
T value() const const
void hide()
void setSizePolicy(QSizePolicy)