HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
logic_evaluator_select_gates.cpp
Go to the documentation of this file.
7 #include "gui/gui_globals.h"
8 #include <QGridLayout>
9 #include <QDialogButtonBox>
10 #include <QPushButton>
11 #include <QVector>
12 
13 namespace hal {
15  {
16  const SelectGateItem* item = dynamic_cast<const SelectGateItem*>(getItemFromIndex(index));
17 
18  switch (role)
19  {
20  case Qt::ForegroundRole:
21  if (item && item->getType() == ModuleItem::TreeItemType::Gate && item->state() == Qt::Checked)
22  {
23  if (mParentDialog)
24  return mParentDialog->selForeground();
25  else
26  return ModuleModel::data(index, role);
27  }
28  break;
29  case Qt::BackgroundRole:
30  if (item && item->getType() == ModuleItem::TreeItemType::Gate && item->state() == Qt::Checked)
31  {
32  if (mParentDialog)
33  return mParentDialog->selBackground();
34  else
35  return ModuleModel::data(index, role);
36  }
37  break;
38  case Qt::CheckStateRole:
39  if (!item->isSelectable()) return QVariant();
40  if (item && !index.column()) return item->state();
41  break;
42  }
43  return ModuleModel::data(index, role);
44  }
45 
46  bool SelectGateModel::setData(const QModelIndex& index, const QVariant& value, int role)
47  {
48  if (role != Qt::CheckStateRole) return false;
49  SelectGateItem* item = dynamic_cast<SelectGateItem*>(getItemFromIndex(index));
50  if (!item) return false;
51  switch(item->getType()) {
53  setModuleStateRecursion(item, (Qt::CheckState) value.toInt());
54  break;
56  item->setState((Qt::CheckState) value.toInt());
57  setCheckedRecursion(false, mRootItem);
58  break;
60  Q_ASSERT(1==0);
61  break;
62  }
63  bool stateWasEmpty = mSelectedGates.empty();
64  setSelectedGatesRecursion();
65  if (stateWasEmpty != mSelectedGates.empty())
66  Q_EMIT selectionStateChanged(mSelectedGates.empty());
67  return true;
68  }
69 
70  void SelectGateModel::setModuleStateRecursion(SelectGateItem* item, Qt::CheckState stat)
71  {
72  item->setState(stat);
73  QModelIndex inx0 = getIndexFromItem(item);
74  QModelIndex inx1 = createIndex(inx0.row(), 2, inx0.internalPointer());
75  Q_EMIT dataChanged(inx0,inx1);
76  for (BaseTreeItem* bti : item->getChildren())
77  {
78  SelectGateItem* child = dynamic_cast<SelectGateItem*>(bti);
79  if (!child->isSelectable()) continue;
80  setModuleStateRecursion(child,stat);
81  }
82  }
83 
84 
86  : mParentDialog(dynamic_cast<LogicEvaluatorSelectGates*>(parent))
87  {
88  insertModuleRecursion(gNetlist->get_top_module());
89  }
90 
91  int SelectGateModel::insertModuleRecursion(const Module* mod, SelectGateItem* parentItem)
92  {
93  int countCheckable = 0;
95  for (const Module* subm : mod->get_submodules())
96  countCheckable += insertModuleRecursion(subm, child);
97  for (const Gate* g : mod->get_gates(nullptr, false))
98  {
100  child->appendChild(new SelectGateItem(g->get_id(), ModuleItem::TreeItemType::Gate, this, isSel));
101  if (isSel) ++countCheckable;
102  }
103  if (!countCheckable) child->setSelectable(false);
104  if (parentItem)
105  parentItem->appendChild(child);
106  else
107  mRootItem->appendChild(child);
108  return countCheckable;
109  }
110 
111  QPair<bool,bool> SelectGateModel::setCheckedRecursion(bool applySet, BaseTreeItem *parentItem, const QSet<u32> &selectedGateIds)
112  {
113  bool hasChecked = false;
114  bool hasUnchecked = false;
115  for (BaseTreeItem* bti : parentItem->getChildren())
116  {
117  QPair<bool,bool> res = setCheckedRecursion(applySet, bti, selectedGateIds);
118  if (res.first) hasChecked = true;
119  if (res.second) hasUnchecked = true;
120  }
121  SelectGateItem* item = dynamic_cast<SelectGateItem*>(parentItem);
122  if (item)
123  {
124  if (!item->isSelectable()) return QPair<bool,bool>(false,false);
125  Qt::CheckState lastState;
126  switch (item->getType()) {
128  lastState = item->state();
129  if (hasChecked && hasUnchecked)
130  item->setState(Qt::PartiallyChecked);
131  else if (hasChecked)
132  item->setState(Qt::Checked);
133  else
134  item->setState(Qt::Unchecked);
135  if (!applySet && item->state() != lastState)
136  {
137  QModelIndex inx = getIndexFromItem(item);
138  Q_EMIT dataChanged(inx,inx);
139  }
140  break;
142  if (applySet)
143  {
144  if (selectedGateIds.contains(item->id()))
145  {
146  item->setState(Qt::Checked);
147  hasChecked = true;
148  }
149  else
150  {
151  item->setState(Qt::Unchecked);
152  hasUnchecked = true;
153  }
154  }
155  else
156  {
157  if (item->state() == Qt::Checked)
158  hasChecked = true;
159  else
160  hasUnchecked = true;
161  }
162  break;
164  Q_ASSERT(1==0);
165  break;
166  }
167  }
168  return QPair<bool,bool>(hasChecked,hasUnchecked);
169  }
170 
171  void SelectGateModel::setSelectedGatesRecursion(SelectGateItem* item)
172  {
173  if (!item)
174  mSelectedGates.clear();
175 
176  BaseTreeItem* parentItem = nullptr;
177  if (item)
178  {
179  if (!item->isSelectable()) return;
180  switch (item->getType()) {
182  parentItem = item;
183  break;
185  if (item->state() == Qt::Checked)
186  {
187  Gate*g = gNetlist->get_gate_by_id(item->id());
188  if (g) mSelectedGates.push_back(g);
189  }
190  break;
192  Q_ASSERT(1==0);
193  break;
194  }
195  }
196  else
197  parentItem = mRootItem;
198 
199  if (parentItem)
200  for (BaseTreeItem* childItem : parentItem->getChildren())
201  setSelectedGatesRecursion(static_cast<SelectGateItem*>(childItem));
202  }
203 
204  void SelectGateModel::setChecked(const std::vector<Gate *> &gates)
205  {
206  QSet<u32> selectedGateIds;
207 
208  for (const Gate* g : gates)
209  selectedGateIds.insert(g->get_id());
210 
211  setCheckedRecursion(true, mRootItem, selectedGateIds);
212  setSelectedGatesRecursion();
213  }
214 
216  {
218  if (index.column()) return retval;
219  const SelectGateItem* item = dynamic_cast<const SelectGateItem*>(getItemFromIndex(index));
220  if (!item->isSelectable()) return Qt::NoItemFlags;
221  return retval | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
222  }
223 
224  LogicEvaluatorSelectGates::LogicEvaluatorSelectGates(const std::vector<Gate *>& gates, QWidget* parent)
225  : QDialog(parent)
226  {
227  setWindowTitle("Select combinatorical gates for logic evaluator");
228  QGridLayout* layout = new QGridLayout(this);
229  mTreeView = new QTreeView(this);
230  mSelectGateModel = new SelectGateModel(this);
231  mProxyModel = new ModuleProxyModel(this);
232  mProxyModel->setSourceModel(mSelectGateModel);
233  mProxyModel->toggleFilterGates();
234  mSelectGateModel->setChecked(gates);
235  mTreeView->setModel(mProxyModel);
237  mTreeView->expandAll();
238  mTreeView->setColumnWidth(0,250);
239  mTreeView->setColumnWidth(1,40);
240  mTreeView->setColumnWidth(2,110);
241 
243  connect(mButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
244  connect(mButtonBox, &QDialogButtonBox::rejected, this , &QDialog::reject);
246  connect(mSelectGateModel, &SelectGateModel::selectionStateChanged, this, &LogicEvaluatorSelectGates::handleSelectionStateChanged);
247  mButtonBox->button(QDialogButtonBox::Ok)->setDisabled(mSelectGateModel->selectedGates().empty());
248 
249  mSearchbar = new Searchbar(this);
251 
252  mCompile = new QCheckBox("Compile selected logic", this);
253  mCompile->setChecked(true);
254 
255  layout->addWidget(mTreeView,0,0,1,2);
256  layout->addWidget(mSearchbar, 1,0,1,2);
257  layout->addWidget(mCompile, 2,0,1,2);
258  layout->addWidget(mButtonBox, 3,1);
259  mTreeView->setMinimumWidth(400);
260 
261  QStyle* s = style();
262  s->unpolish(this);
263  s->polish(this);
264  }
265 
266  void LogicEvaluatorSelectGates::handleSelectionStateChanged(bool empty)
267  {
268  mButtonBox->button(QDialogButtonBox::Ok)->setDisabled(empty);
269  }
270 
272  {
273  LogicEvaluatorDialog* led = new LogicEvaluatorDialog(mSelectGateModel->selectedGates(),!mCompile->isChecked());
274  led->show();
275  led->raise();
276  QDialog::accept();
277  }
278 }
(Future) Base class for all tree models related to the details widget.
virtual QList< BaseTreeItem * > getChildren() const
virtual void appendChild(BaseTreeItem *child)
QModelIndex getIndexFromItem(BaseTreeItem *item) const
RootTreeItem * mRootItem
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
BaseTreeItem * getItemFromIndex(QModelIndex index) const
Definition: gate.h:58
static bool acceptGate(const Gate *g)
LogicEvaluatorSelectGates(const std::vector< Gate * > &gates, QWidget *parent=nullptr)
const std::vector< Gate * > & get_gates() const
Definition: module.cpp:393
std::vector< Module * > get_submodules(const std::function< bool(Module *)> &filter=nullptr, bool recursive=false) const
Definition: module.cpp:261
u32 get_id() const
Definition: module.cpp:82
TreeItemType getType() const
Qt::ItemFlags flags(const QModelIndex &index) const override
QVariant data(const QModelIndex &index, int role) const override
Enables filtering in the ModuleModel.
void startSearch(QString text, int options) override
Module * get_top_module() const
Definition: netlist.cpp:608
Gate * get_gate_by_id(const u32 gate_id) const
Definition: netlist.cpp:193
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)
Qt::CheckState state() const
void setState(Qt::CheckState stat)
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
const std::vector< Gate * > & selectedGates() const
void selectionStateChanged(bool empty)
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
void setChecked(const std::vector< Gate * > &gates)
SelectGateModel(QObject *parent=nullptr)
Qt::ItemFlags flags(const QModelIndex &index) const override
Definition: defines.h:45
Netlist * gNetlist
Definition: gui_globals.h:69
void setChecked(bool)
QModelIndex createIndex(int row, int column, void *ptr) const const
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector< int > &roles)
virtual void accept()
virtual void reject()
QPushButton * button(QDialogButtonBox::StandardButton which) const const
void addWidget(QWidget *w)
int column() const const
void * internalPointer() 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)
bool contains(const T &value) const const
QSet::iterator insert(const T &value)
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
virtual void polish(QWidget *widget)
virtual void unpolish(QWidget *widget)
ForegroundRole
typedef ItemFlags
void expandAll()
void setColumnWidth(int column, int width)
virtual void setModel(QAbstractItemModel *model) override
int toInt(bool *ok) const const
QLayout * layout() const const
void setMinimumWidth(int minw)
void raise()
void setDisabled(bool disable)
void show()
void setSizePolicy(QSizePolicy)
QStyle * style() const const
void setWindowTitle(const QString &)