HAL  v4.5.0-133-g64838ea8d
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
context_tree_model.cpp
Go to the documentation of this file.
5 
6 #include <QApplication>
7 
8 namespace hal
9 {
11  {
12  json["parentId"] = (int) mParentId;
13  json["id"] = (int) mId;
14  json["name"] = mName;
15  }
16 
18  BaseTreeItem(),
19  mContext(context),
20  mDirectory(nullptr)
21  {
22  }
23 
25  BaseTreeItem(),
26  mContext(nullptr),
27  mDirectory(directory)
28  {
29  }
30 
32  {
33  if (mDirectory) return mDirectory->id();
34  if (mContext) return mContext->id();
35  return 0;
36  }
37 
39  {
40  if (mDirectory) return mDirectory->name();
41  if (mContext) return mContext->name();
42  return QString();
43  }
44 
46  {
47  if (mContext) return mContext->getTimestamp();
48  return QDateTime();
49  }
50 
52  {
53  if(isDirectory())
54  {
55  switch(column)
56  {
57  case 0:
58  return mDirectory->name();
59  case 1:
60  return mDirectory->id();
61  default:
62  return "";
63  }
64  }
65  if(isContext())
66  {
67  switch(column)
68  {
69  case 0:
70  return mContext->getNameWithDirtyState();
71  case 1:
72  return mContext->id();
73  case 2:
74  return QtCompat::dateToLocaleString(mContext->getTimestamp());
75  }
76  }
77  return QVariant();
78  }
79 
81  {
82  return mContext;
83  }
84 
86  {
87  return mDirectory;
88  }
89 
91  {
92 
93  }
94 
96  {
97  // TODO: implement
98  }
99 
101  {
102 
103  }
104 
106  {
107  return 3;
108  }
109 
111  {
112  BaseTreeItem* parent = getParent();
113  if (!parent) return 0;
114  return parent->getRowForChild(this);
115  }
116 
118  {
119  return mDirectory != nullptr;
120  }
121 
123  {
124  return mContext != nullptr;
125  }
126 
127  ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr)
128  {
129  setHeaderLabels(QStringList() << "View Name" << "ID" << "Timestamp");
130  }
131 
133  {
134  if (!index.isValid())
135  return QVariant();
136 
137  ContextTreeItem* item = static_cast<ContextTreeItem*>(index.internalPointer());
138 
139  if (!item)
140  return QVariant();
141 
142  switch (role)
143  {
144  case Qt::DecorationRole:
145  {
146  if (index.column()) return QVariant(); // decorator only for first column
147  if (item->isDirectory())
149  const GraphContext* ctx = item->context();
150  u32 mid = 0;
151  if (ctx && (mid=ctx->getExclusiveModuleId()) != 0)
154  }
155 
156  case Qt::DisplayRole:
157  return item->getData(index.column());
158 
159  case Qt::BackgroundRole:
160  // must declare color in dark/light style
161  return QVariant();
162 
163  default:
164  return QVariant();
165  }
166 
167  return QVariant();
168  }
169 
171  {
173  return baseFlags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
174  ContextTreeItem* item = dynamic_cast<ContextTreeItem*>(getItemFromIndex(index));
175  if (!item)
176  return baseFlags | Qt::ItemIsDropEnabled; // root item
177 
178  if (item->isContext())
179  return baseFlags | Qt::ItemIsDragEnabled;
180 
181  if (item->isDirectory())
182  return baseFlags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
183 
184  Q_ASSERT(1==0);
185  return baseFlags;
186  }
187 
189  {
190  QStringList types;
191  types << "contexttreemodel/item";
192  return types;
193  }
194 
196  {
197  return getItemInternal(mRootItem, directoryId, true);
198  }
199 
201  {
202  return getItemInternal(mRootItem, contextId, false);
203  }
204 
205  BaseTreeItem* ContextTreeModel::getItemInternal(BaseTreeItem *parentItem, u32 id, bool isDirectory) const
206  {
207  for (BaseTreeItem* childItem : parentItem->getChildren())
208  {
209  ContextTreeItem* ctxItem = static_cast<ContextTreeItem*>(childItem);
210  if (ctxItem->isDirectory())
211  {
212  if (ctxItem->getId() == id && isDirectory)
213  return ctxItem;
214  BaseTreeItem* bti = getItemInternal(childItem, id, isDirectory);
215  if (bti)
216  return bti;
217  }
218  else if (ctxItem->isContext() && !isDirectory)
219  {
220  if (ctxItem->getId() == id)
221  return ctxItem;
222  }
223  }
224  return nullptr;
225  }
226 
228  {
229  if (!parentItem)
230  parentItem = mCurrentDirectory;
231  if (!parentItem)
232  parentItem = mRootItem;
233 
234  ContextDirectory* directory = new ContextDirectory(name, (parentItem != mRootItem) ? static_cast<ContextTreeItem*>(parentItem)->directory()->id() : 0, id);
235 
236  ContextTreeItem* item = new ContextTreeItem(directory);
237 
238 
239  QModelIndex index = getIndexFromItem(parentItem);
240 
241  mCurrentDirectory = item;
242 
243  int row = parentItem->getChildCount();
244  beginInsertRows(index, row, row);
245  parentItem->appendChild(item);
246  endInsertRows();
247 
248  mDirectoryList.push_back(directory);
249 
251 
252  return directory;
253  }
254 
256  {
257  beginResetModel();
258 
260  mContextMap.clear();
261 
262  endResetModel();
263  }
264 
266  {
267  ContextTreeItem* item = new ContextTreeItem(context);
268 
269  BaseTreeItem* finalParent;
270  if (parent)
271  finalParent = parent;
272  else if(mCurrentDirectory)
273  finalParent = mCurrentDirectory;
274  else
275  finalParent = mRootItem;
276 
277 
278  QModelIndex index = getIndexFromItem(finalParent);
279 
280  int row = finalParent->getChildCount();
281  beginInsertRows(index, row, row);
282  finalParent->appendChild(item);
283  endInsertRows();
284 
285  mContextMap.insert({context, item});
286 
287  connect(context, &GraphContext::dataChanged, this, [item, this]() {
289  });
290  }
291 
293  {
294  ContextTreeItem* item = mContextMap.find(context)->second;
295  ContextTreeItem* parent = static_cast<ContextTreeItem*>(item->getParent());
296  assert(item);
297  assert(parent);
298 
300 
301  int row = item->row();
302 
303  beginRemoveRows(index, row, row);
304  parent->removeChild(item);
305  endRemoveRows();
306 
307  delete item;
308 
309  std::map<GraphContext *,ContextTreeItem *>::iterator it;
310  it = mContextMap.find(context);
311  mContextMap.erase(it);
312  }
313 
315  {
316  ContextTreeItem* item = static_cast<ContextTreeItem *>(getDirectory(directory->id()));
317 
318  if(item == mCurrentDirectory) {
319  mCurrentDirectory = nullptr;
320  }
321 
322  QList<BaseTreeItem *> childCopy = item->getChildren();
323 
324  for (int i = 0; i < childCopy.length(); i++) {
325  ContextTreeItem* child = static_cast<ContextTreeItem*>(childCopy[i]);
326 
327  if (child->isContext()) {
330  act->exec();
331  }
332  else if (child->isDirectory()) {
335  act->exec();
336  }
337  }
338 
339  BaseTreeItem* parent = item->getParent();
340  assert(item);
341  assert(parent);
342 
344 
345  int row = item->row();
346 
347  beginRemoveRows(index, row, row);
348  parent->removeChild(item);
349  endRemoveRows();
350 
351  auto it = std::find(mDirectoryList.begin(), mDirectoryList.end(), directory);
352  if (it != mDirectoryList.end()) {
353  mDirectoryList.erase(it);
354  }
355 
356  delete item;
357  }
358 
360  {
361  return getIndexFromItem(mContextMap.find(context)->second);
362  }
363 
365  {
367 
368  if (static_cast<ContextTreeItem*>(item)->isDirectory()) return nullptr;
369  GraphContext* context = nullptr;
370  for (auto &i : mContextMap) {
371  if (i.second == item) {
372  context = i.first;
373  break;
374  }
375  }
376  return context;
377  }
378 
380  {
381  mContextList.clear();
382  for (auto it = mContextMap.begin(); it != mContextMap.end(); ++it) {
383  mContextList.push_back(it->first);
384  }
385  return mContextList;
386  }
387 
389  {
390  return mDirectoryList;
391  }
392 
393 
395  {
396  if(currentItem == nullptr)
397  mCurrentDirectory = nullptr; // top-level directory
398  else if(currentItem->isContext())
399  mCurrentDirectory = (currentItem->getParent() == mRootItem) ? nullptr : static_cast<ContextTreeItem*>(currentItem->getParent());
400 
401  else if (currentItem->isDirectory())
402  mCurrentDirectory = currentItem;
403  }
404 
406  {
407  return mCurrentDirectory;
408  }
409 
410  bool ContextTreeModel::moveItem(ContextTreeItem* itemToMove, BaseTreeItem *newParent, int row)
411  {
412  if (!itemToMove || !newParent ) return false;
413  if (newParent != mRootItem)
414  {
415  ContextTreeItem* cti = dynamic_cast<ContextTreeItem*>(newParent);
416  if (!cti || !cti->isDirectory()) return false;
417  }
418 
419  BaseTreeItem* oldParent = itemToMove->getParent();
420  if (!oldParent) return false;
421 
422  int currentRow = itemToMove->row();
423  beginRemoveRows(getIndexFromItem(oldParent), currentRow, currentRow);
424  oldParent->removeChild(itemToMove);
425  endRemoveRows();
426 
427  insertChildItem(itemToMove, newParent, row);
428 
429  // dumpRecursion();
430  return true;
431  }
432 
433  void ContextTreeModel::dumpRecursion(ContextTreeItem *parent, int level) const
434  {
435  BaseTreeItem* bti = parent;
436  for (int i=0; i<level; i++)
437  std::cerr << " ";
438  if (parent)
439  {
440  if (parent->isDirectory())
441  std::cerr << parent->directory()->name().toStdString() << std::endl;
442  else
443  std::cerr << "[" << parent->context()->name().toStdString() << "] " << parent->context()->id() << std::endl;
444  }
445  if (!parent) bti = mRootItem;
446  for (BaseTreeItem* cld : bti->getChildren())
447  dumpRecursion(dynamic_cast<ContextTreeItem*>(cld), level+1);
448  }
449 
450  std::vector<u32> ContextTreeModel::getChildDirectoriesOf(u32 directoryId)
451  {
452  BaseTreeItem* directoryItem = getDirectory(directoryId);
453  if(!directoryItem)
454  directoryItem = getRootItem();
455 
456  QList<BaseTreeItem*> children = directoryItem->getChildren();
457  std::vector<u32> ids;
458 
459  for(BaseTreeItem* child : children)
460  {
461  ContextTreeItem* cti = dynamic_cast<ContextTreeItem*>(child);
462  if(cti->isDirectory())
463  ids.push_back(cti->getId());
464  }
465 
466  return ids;
467  }
468 
469  std::vector<u32> ContextTreeModel::getChildContextsOf(u32 directoryId)
470  {
471  BaseTreeItem* directoryItem = getDirectory(directoryId);
472  if(!directoryItem)
473  directoryItem = getRootItem();
474 
475  QList<BaseTreeItem*> children = directoryItem->getChildren();
476  std::vector<u32> ids;
477 
478  for(BaseTreeItem* child : children)
479  {
480  ContextTreeItem* cti = dynamic_cast<ContextTreeItem*>(child);
481  if(cti->isContext())
482  ids.push_back(cti->getId());
483  }
484 
485  return ids;
486  }
487 }
(Future) Base class for all tree models related to the details widget.
virtual int getRowForChild(const BaseTreeItem *child) const
virtual QList< BaseTreeItem * > getChildren() const
virtual bool removeChild(BaseTreeItem *child)
virtual BaseTreeItem * getParent() const
virtual int getChildCount() const
virtual void appendChild(BaseTreeItem *child)
The BaseTreeModel implements generic standard functions of a tree model.
QModelIndex getIndexFromItem(BaseTreeItem *item) const
RootTreeItem * mRootItem
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
virtual void clear()
virtual Qt::ItemFlags flags(const QModelIndex &index) const override
void insertChildItem(BaseTreeItem *childItem, BaseTreeItem *parentItem=nullptr, int row=-1)
BaseTreeItem * getRootItem() const
void setHeaderLabels(const QStringList &label)
BaseTreeItem * getItemFromIndex(QModelIndex index) const
void writeToFile(QJsonObject &json)
QVariant getData(int column) const override
QDateTime getTimestamp() const
ContextTreeItem(GraphContext *context)
int getColumnCount() const override
GraphContext * context() const
ContextDirectory * directory() const
void setData(QList< QVariant > data) override
void appendData(QVariant data) override
void setDataAtColumn(int column, QVariant &data) override
bool moveItem(ContextTreeItem *itemToMove, BaseTreeItem *newParent, int row=-1)
std::vector< u32 > getChildDirectoriesOf(u32 directoryId)
void removeDirectory(ContextDirectory *directory)
QStringList mimeTypes() const override
void setCurrentDirectory(ContextTreeItem *currentItem)
Qt::ItemFlags flags(const QModelIndex &index) const override
void directoryCreatedSignal(ContextTreeItem *item)
const QVector< GraphContext * > & list()
QVariant data(const QModelIndex &inddex, int role=Qt::DisplayRole) const override
std::vector< u32 > getChildContextsOf(u32 directoryId)
QModelIndex getIndexFromContext(GraphContext *context) const
BaseTreeItem * getDirectory(u32 directoryId) const
ContextTreeItem * getCurrentDirectory()
void removeContext(GraphContext *context)
ContextDirectory * addDirectory(QString name, BaseTreeItem *parentItem, u32 id)
void addContext(GraphContext *context, BaseTreeItem *parent=nullptr)
ContextTreeModel(QObject *parent=nullptr)
const QVector< ContextDirectory * > & directoryList()
BaseTreeItem * getContext(u32 contextId) const
Logical container for modules, gates, and nets.
Definition: graph_context.h:55
u32 getExclusiveModuleId() const
QDateTime getTimestamp() const
QString getNameWithDirtyState() const
QString name() const
static SelectionDetailsIconProvider * instance()
virtual void setObject(const UserActionObject &obj)
Definition: user_action.cpp:32
The UserActionObject class represents a single object used in UserAction.
uint32_t u32
Definition: defines.h:41
QString dateToLocaleString(const QDateTime &dt)
Definition: defines.h:45
std::string name
void beginInsertRows(const QModelIndex &parent, int first, int last)
void beginRemoveRows(const QModelIndex &parent, int first, int last)
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector< int > &roles)
int length() const const
int column() const const
void * internalPointer() const const
bool isValid() const const
Q_EMITQ_EMIT
const QObjectList & children() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
DecorationRole
typedef ItemFlags