HAL
context_tree_model.cpp
Go to the documentation of this file.
3 #include "gui/gui_globals.h"
6 
7 #include <limits>
8 #include <QApplication>
9 
10 namespace hal
11 {
13  {
14  json["parentId"] = (int) mParentId;
15  json["id"] = (int) mId;
16  json["name"] = mName;
17  }
18 
20  BaseTreeItem(),
21  mContext(context),
22  mDirectory(nullptr)
23  {
24  }
25 
27  BaseTreeItem(),
28  mContext(nullptr),
29  mDirectory(directory)
30  {
31  }
32 
34  {
35  if (mDirectory) return mDirectory->id();
36  if (mContext) return mContext->id();
37  return 0;
38  }
39 
41  {
42  if (mDirectory) return mDirectory->name();
43  if (mContext) return mContext->name();
44  return QString();
45  }
46 
48  {
49  if (mContext) return mContext->getTimestamp();
50  return QDateTime();
51  }
52 
54  {
55  if(isDirectory())
56  {
57  switch(column)
58  {
59  case 0:
60  return mDirectory->name();
61  case 1:
62  return mDirectory->id();
63  default:
64  return "";
65  }
66  }
67  if(isContext())
68  {
69  switch(column)
70  {
71  case 0:
72  return mContext->getNameWithDirtyState();
73  case 1:
74  return mContext->id();
75  case 2:
77  }
78  }
79  return QVariant();
80  }
81 
83  {
84  return mContext;
85  }
86 
88  {
89  return mDirectory;
90  }
91 
93  {
94 
95  }
96 
98  {
99 
100  }
101 
103  {
104 
105  }
106 
108  {
109  return 3;
110  }
111 
113  {
114  BaseTreeItem* parent = getParent();
115  if (!parent) return 0;
116  return parent->getRowForChild(this);
117  }
118 
120  {
121  return mDirectory != nullptr;
122  }
123 
125  {
126  return mContext != nullptr;
127  }
128 
129  ContextTreeModel::ContextTreeModel(QObject* parent) : BaseTreeModel(parent), mCurrentDirectory(nullptr)
130  {
131  setHeaderLabels(QStringList() << "View Name" << "ID" << "Timestamp");
132  }
133 
134  QVariant ContextTreeModel::data(const QModelIndex& index, int role) const
135  {
136  if (!index.isValid())
137  return QVariant();
138 
139  ContextTreeItem* item = static_cast<ContextTreeItem*>(index.internalPointer());
140 
141  if (!item)
142  return QVariant();
143 
144  switch (role)
145  {
146  case Qt::DecorationRole:
147  {
148  if (index.column()) return QVariant(); // decorator only for first column
149  if (item->isDirectory())
151  const GraphContext* ctx = item->context();
152  u32 mid = 0;
153  if (ctx && (mid=ctx->getExclusiveModuleId()) != 0)
156  }
157 
158  case Qt::DisplayRole:
159  return item->getData(index.column());
160 
161  case Qt::BackgroundRole:
162  // must declare color in dark/light style
163  return QVariant();
164 
165  default:
166  return QVariant();
167  }
168 
169  return QVariant();
170  }
171 
173  {
175  return baseFlags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
176  ContextTreeItem* item = dynamic_cast<ContextTreeItem*>(getItemFromIndex(index));
177  if (!item)
178  return baseFlags | Qt::ItemIsDropEnabled; // root item
179 
180  if (item->isContext())
181  return baseFlags | Qt::ItemIsDragEnabled;
182 
183  if (item->isDirectory())
184  return baseFlags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
185 
186  Q_ASSERT(1==0);
187  return baseFlags;
188  }
189 
191  {
192  QStringList types;
193  types << "contexttreemodel/item";
194  return types;
195  }
196 
198  {
199  return getItemInternal(mRootItem, directoryId, true);
200  }
201 
203  {
204  return getItemInternal(mRootItem, contextId, false);
205  }
206 
207  BaseTreeItem* ContextTreeModel::getItemInternal(BaseTreeItem *parentItem, u32 id, bool isDirectory) const
208  {
209  for (BaseTreeItem* childItem : parentItem->getChildren())
210  {
211  ContextTreeItem* ctxItem = static_cast<ContextTreeItem*>(childItem);
212  if (ctxItem->isDirectory())
213  {
214  if (ctxItem->getId() == id && isDirectory)
215  return ctxItem;
216  BaseTreeItem* bti = getItemInternal(childItem, id, isDirectory);
217  if (bti)
218  return bti;
219  }
220  else if (ctxItem->isContext() && !isDirectory)
221  {
222  if (ctxItem->getId() == id)
223  return ctxItem;
224  }
225  }
226  return nullptr;
227  }
228 
230  {
231  if (!parentItem)
232  parentItem = mCurrentDirectory;
233  if (!parentItem)
234  parentItem = mRootItem;
235 
236  ContextDirectory* directory = new ContextDirectory(name, (parentItem != mRootItem) ? static_cast<ContextTreeItem*>(parentItem)->directory()->id() : 0, id);
237 
238  ContextTreeItem* item = new ContextTreeItem(directory);
239 
240 
241  QModelIndex index = getIndexFromItem(parentItem);
242 
243  mCurrentDirectory = item;
244 
245  int row = parentItem->getChildCount();
246  beginInsertRows(index, row, row);
247  parentItem->appendChild(item);
248  endInsertRows();
249 
250  mDirectoryList.push_back(directory);
251 
253 
254  return directory;
255  }
256 
258  {
259  beginResetModel();
260 
262  mContextMap.clear();
263 
264  endResetModel();
265  }
266 
268  {
269  ContextTreeItem* item = new ContextTreeItem(context);
270 
271  BaseTreeItem* finalParent;
272  if (parent)
273  finalParent = parent;
274  else if(mCurrentDirectory)
275  finalParent = mCurrentDirectory;
276  else
277  finalParent = mRootItem;
278 
279 
280  QModelIndex index = getIndexFromItem(finalParent);
281 
282  int row = finalParent->getChildCount();
283  beginInsertRows(index, row, row);
284  finalParent->appendChild(item);
285  endInsertRows();
286 
287  mContextMap.insert({context, item});
288 
289  connect(context, &GraphContext::dataChanged, this, [item, this]() {
291  });
292  }
293 
295  {
296  ContextTreeItem* item = mContextMap.find(context)->second;
297  ContextTreeItem* parent = static_cast<ContextTreeItem*>(item->getParent());
298  assert(item);
299  assert(parent);
300 
302 
303  int row = item->row();
304 
305  beginRemoveRows(index, row, row);
306  parent->removeChild(item);
307  endRemoveRows();
308 
309  delete item;
310 
311  std::map<GraphContext *,ContextTreeItem *>::iterator it;
312  it = mContextMap.find(context);
313  mContextMap.erase(it);
314  }
315 
317  {
318  ContextTreeItem* item = static_cast<ContextTreeItem *>(getDirectory(directory->id()));
319 
320  if(item == mCurrentDirectory) {
321  mCurrentDirectory = nullptr;
322  }
323 
324  QList<BaseTreeItem *> childCopy = item->getChildren();
325 
326  for (int i = 0; i < childCopy.length(); i++) {
327  ContextTreeItem* child = static_cast<ContextTreeItem*>(childCopy[i]);
328 
329  if (child->isContext()) {
332  act->exec();
333  }
334  else if (child->isDirectory()) {
337  act->exec();
338  }
339  }
340 
341  BaseTreeItem* parent = item->getParent();
342  assert(item);
343  assert(parent);
344 
346 
347  int row = item->row();
348 
349  beginRemoveRows(index, row, row);
350  parent->removeChild(item);
351  endRemoveRows();
352 
353  auto it = std::find(mDirectoryList.begin(), mDirectoryList.end(), directory);
354  if (it != mDirectoryList.end()) {
355  mDirectoryList.erase(it);
356  }
357 
358  delete item;
359  }
360 
362  {
363  return getIndexFromItem(mContextMap.find(context)->second);
364  }
365 
367  {
369 
370  if (static_cast<ContextTreeItem*>(item)->isDirectory()) return nullptr;
371  GraphContext* context = nullptr;
372  for (auto &i : mContextMap) {
373  if (i.second == item) {
374  context = i.first;
375  break;
376  }
377  }
378  return context;
379  }
380 
382  {
383  mContextList.clear();
384  for (auto it = mContextMap.begin(); it != mContextMap.end(); ++it) {
385  mContextList.push_back(it->first);
386  }
387  return mContextList;
388  }
389 
391  {
392  return mDirectoryList;
393  }
394 
395 
397  {
398  if(currentItem == nullptr)
399  mCurrentDirectory = nullptr; // top-level directory
400  else if(currentItem->isContext())
401  mCurrentDirectory = (currentItem->getParent() == mRootItem) ? nullptr : static_cast<ContextTreeItem*>(currentItem->getParent());
402 
403  else if (currentItem->isDirectory())
404  mCurrentDirectory = currentItem;
405  }
406 
408  {
409  return mCurrentDirectory;
410  }
411 
412  bool ContextTreeModel::moveItem(ContextTreeItem* itemToMove, BaseTreeItem *newParent, int row)
413  {
414  if (!itemToMove || !newParent ) return false;
415  if (newParent != mRootItem)
416  {
417  ContextTreeItem* cti = dynamic_cast<ContextTreeItem*>(newParent);
418  if (!cti || !cti->isDirectory()) return false;
419  }
420 
421  BaseTreeItem* oldParent = itemToMove->getParent();
422  if (!oldParent) return false;
423 
424  int currentRow = itemToMove->row();
425  beginRemoveRows(getIndexFromItem(oldParent), currentRow, currentRow);
426  oldParent->removeChild(itemToMove);
427  endRemoveRows();
428 
429  insertChildItem(itemToMove, newParent, row);
430 
431  // dumpRecursion();
432  return true;
433  }
434 
435  void ContextTreeModel::dumpRecursion(ContextTreeItem *parent, int level) const
436  {
437  BaseTreeItem* bti = parent;
438  for (int i=0; i<level; i++)
439  std::cerr << " ";
440  if (parent)
441  {
442  if (parent->isDirectory())
443  std::cerr << parent->directory()->name().toStdString() << std::endl;
444  else
445  std::cerr << "[" << parent->context()->name().toStdString() << "] " << parent->context()->id() << std::endl;
446  }
447  if (!parent) bti = mRootItem;
448  for (BaseTreeItem* cld : bti->getChildren())
449  dumpRecursion(dynamic_cast<ContextTreeItem*>(cld), level+1);
450  }
451 
452  std::vector<u32> ContextTreeModel::getChildDirectoriesOf(u32 directoryId)
453  {
454  BaseTreeItem* directoryItem = getDirectory(directoryId);
455  if(!directoryItem)
456  directoryItem = getRootItem();
457 
458  QList<BaseTreeItem*> children = directoryItem->getChildren();
459  std::vector<u32> ids;
460 
461  for(BaseTreeItem* child : children)
462  {
463  ContextTreeItem* cti = dynamic_cast<ContextTreeItem*>(child);
464  if(cti->isDirectory())
465  ids.push_back(cti->getId());
466  }
467 
468  return ids;
469  }
470 
471  std::vector<u32> ContextTreeModel::getChildContextsOf(u32 directoryId)
472  {
473  BaseTreeItem* directoryItem = getDirectory(directoryId);
474  if(!directoryItem)
475  directoryItem = getRootItem();
476 
477  QList<BaseTreeItem*> children = directoryItem->getChildren();
478  std::vector<u32> ids;
479 
480  for(BaseTreeItem* child : children)
481  {
482  ContextTreeItem* cti = dynamic_cast<ContextTreeItem*>(child);
483  if(cti->isContext())
484  ids.push_back(cti->getId());
485  }
486 
487  return ids;
488  }
489 }
(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 setDataAtIndex(int index, 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.
quint32 u32
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)
QString toString(Qt::DateFormat format) const const
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
SystemLocaleShortDate
DecorationRole
typedef ItemFlags