HAL
module_model.cpp
Go to the documentation of this file.
2 
3 #include "gui/gui_globals.h"
4 
7 
9 #include "hal_core/netlist/net.h"
10 #include <QMimeData>
11 
12 namespace hal
13 {
15  {
16  // use root item to store header information
17  setHeaderLabels(QStringList() << "Name" << "ID" << "Type");
18  connect(gNetlistRelay, &NetlistRelay::moduleCreated, this, &ModuleModel::handleModuleCreated);
19  connect(gNetlistRelay, &NetlistRelay::moduleNameChanged, this, &ModuleModel::handleModuleNameChanged);
20  connect(gNetlistRelay, &NetlistRelay::moduleParentChanged, this, &ModuleModel::handleModuleParentChanged);
21  connect(gNetlistRelay, &NetlistRelay::moduleSubmoduleAdded, this, &ModuleModel::handleModuleSubmoduleAdded);
22  connect(gNetlistRelay, &NetlistRelay::moduleSubmoduleRemoved, this, &ModuleModel::handleModuleSubmoduleRemoved);
23  connect(gNetlistRelay, &NetlistRelay::moduleGateAssigned, this, &ModuleModel::handleModuleGateAssigned);
24  connect(gNetlistRelay, &NetlistRelay::moduleGatesAssignBegin, this, &ModuleModel::handleModuleGatesAssignBegin);
25  connect(gNetlistRelay, &NetlistRelay::moduleGatesAssignEnd, this, &ModuleModel::handleModuleGatesAssignEnd);
26  connect(gNetlistRelay, &NetlistRelay::moduleGateRemoved, this, &ModuleModel::handleModuleGateRemoved);
27  connect(gNetlistRelay, &NetlistRelay::moduleRemoved, this, &ModuleModel::handleModuleRemoved);
28  connect(gNetlistRelay, &NetlistRelay::gateNameChanged, this, &ModuleModel::handleGateNameChanged);
29  connect(gNetlistRelay, &NetlistRelay::netCreated, this, &ModuleModel::handleNetCreated);
30  connect(gNetlistRelay, &NetlistRelay::netRemoved, this, &ModuleModel::handleNetRemoved);
31  connect(gNetlistRelay, &NetlistRelay::netNameChanged, this, &ModuleModel::handleNetNameChanged);
32  connect(gNetlistRelay, &NetlistRelay::netSourceAdded, this, &ModuleModel::handleNetUpdated);
33  connect(gNetlistRelay, &NetlistRelay::netSourceRemoved, this, &ModuleModel::handleNetUpdated);
34  connect(gNetlistRelay, &NetlistRelay::netDestinationAdded, this, &ModuleModel::handleNetUpdated);
35  connect(gNetlistRelay, &NetlistRelay::netDestinationRemoved, this, &ModuleModel::handleNetUpdated);
36  }
37 
38  QVariant ModuleModel::data(const QModelIndex& index, int role) const
39  {
40  if (!index.isValid())
41  return QVariant();
42 
43  ModuleItem* item = static_cast<ModuleItem*>(index.internalPointer());
44 
45  if (!item)
46  return QVariant();
47 
48  switch (role)
49  {
50  case Qt::DecorationRole:
51  {
52  if (index.column() == 0)
53  {
54  switch(item->getType()){
61  }
62  }
63  break;
64  }
65  case Qt::DisplayRole:
66  {
67  return item->getData(index.column());
68  }
69  case Qt::ForegroundRole:
70  {
71  if (item->highlighted())
72  return QColor(QColor(255, 221, 0)); // USE STYLESHEETS
73  else
74  return QColor(QColor(255, 255, 255)); // USE STYLESHEETS
75  }
77  return index.column() == 1
79  : Qt::AlignLeft;
80  default:
81  return QVariant();
82  }
83  return QVariant();
84  }
85 
86  QMimeData* ModuleModel::mimeData(const QModelIndexList &indexes) const
87  {
88  QMimeData* retval = new QMimeData;
89  // only single row allowed
90  int row = -1;
91  for (const QModelIndex& inx : indexes)
92  {
93  if (row < 0)
94  row = inx.row();
95  else if (row != inx.row())
96  return retval;
97  }
98  if (row < 0)
99  return retval;
100 
101  QModelIndex firstIndex = indexes.at(0);
102  BaseTreeItem* bti = getItemFromIndex(firstIndex);
103  row = firstIndex.row();
104  BaseTreeItem* parentItem = bti->getParent();
105  ModuleItem* item = dynamic_cast<ModuleItem*>(bti);
106  if (!item)
107  {
108  qDebug() << "cannot cast" << indexes.at(0);
109  return retval;
110  }
111  QByteArray encodedData;
112  QDataStream stream(&encodedData, QIODevice::WriteOnly);
113  QString moveText;
114  int id = item->id();
115 
116  switch (item->getType())
117  {
119  moveText = PyCodeProvider::pyCodeModule(id);
120  break;
122  moveText = PyCodeProvider::pyCodeGate(id);
123  break;
125  moveText = PyCodeProvider::pyCodeNet(id);
126  break;
127  }
128 
129  stream << item->getType() << id << row << (quintptr) parentItem;
130  retval->setText(moveText);
131  retval->setData("modulemodel/item", encodedData);
132  return retval;
133 
134  }
135 
137  {
138  if (!index.isValid())
139  return 0;
140 
142  }
143 
145  {
146  if (index.isValid())
147  return static_cast<ModuleItem*>(index.internalPointer());
148  else
149  return nullptr;
150  }
151 
153  {
154  return mModuleItemMaps[(int)type]->value(id);
155  }
156 
158  {
159  return mModuleItemMaps[(int)type]->values(id);
160  }
161 
163  {
164  beginResetModel();
165 
167  mModuleMap.clear();
168  mGateMap.clear();
169  mNetMap.clear();
170  endResetModel();
171  }
172 
173  void ModuleModel::populateFromGatelist(const std::vector<Gate *> &gates)
174  {
175  setIsModifying(true);
176  beginResetModel();
177  clear();
178 
179  QMap<Module*,ModuleItem*> parentMap;
180  for (const Gate* g : gates)
181  {
182  Module* parentModule = g->get_module();
183  ModuleItem* parentItem;
184  bool insertToRoot = true;
185  ModuleItem* childItem = new ModuleItem(g->get_id(), ModuleItem::TreeItemType::Gate, this);
186 
187  while (parentModule && insertToRoot)
188  {
189  parentItem = parentMap.value(parentModule);
190  if (!parentItem)
191  {
192  parentItem = new ModuleItem(parentModule->get_id(), ModuleItem::TreeItemType::Module, this);
193  parentMap.insert(parentModule, parentItem);
194  }
195  else
196  {
197  insertToRoot = false;
198  }
199  parentItem->appendChild(childItem);
200  parentModule = parentModule->get_parent_module();
201  childItem = parentItem;
202  }
203 
204  if (insertToRoot)
205  {
206  mRootItem->appendChild(parentItem);
207  }
208  }
209 
210  setIsModifying(false);
211  endResetModel();
212  }
213 
214  void ModuleModel::populateTree(const QVector<u32>& modIds, const QVector<u32>& gateIds, const QVector<u32>& netIds)
215  {
216  setIsModifying(true);
217  beginResetModel();
218  // Might want to add parameter for container of moduleIds that don't get recursively inserted.
219  clear();
220 
221  QList<ModuleItem*> newRootList;
222  for(u32 id : modIds)
225 
226  for(u32 id : gateIds)
227  newRootList.append(new ModuleItem(id, ModuleItem::TreeItemType::Gate, this));
228 
229  for(u32 id : netIds)
230  newRootList.append(new ModuleItem(id, ModuleItem::TreeItemType::Net, this));
231 
232  for(auto item : newRootList)
233  mRootItem->appendChild(item);
234  setIsModifying(false);
235  endResetModel();
236  }
237 
238  void ModuleModel::addModule(u32 id, u32 parentId)
239  {
240  Q_ASSERT(gNetlist->get_module_by_id(id));
241  Q_ASSERT(gNetlist->get_module_by_id(parentId));
242 
243  for (auto it = mModuleMap.lowerBound(parentId); it != mModuleMap.upperBound(parentId); ++it)
244  {
245  ModuleItem* parentItem = it.value();
247  }
248  }
249 
250  void ModuleModel::addGate(u32 id, u32 parentId)
251  {
252  Q_ASSERT(gNetlist->get_gate_by_id(id));
253  Q_ASSERT(gNetlist->get_module_by_id(parentId));
254 
255 
256  for (auto it = mModuleMap.lowerBound(parentId); it != mModuleMap.upperBound(parentId); ++it)
257  {
259  }
260  }
261 
262  void ModuleModel::addNet(u32 id, u32 parentId)
263  {
264  Q_ASSERT(gNetlist->get_net_by_id(id));
265  Q_ASSERT(gNetlist->get_module_by_id(parentId));
266 
267  for (auto it = mModuleMap.lowerBound(parentId); it != mModuleMap.upperBound(parentId); ++it)
268  {
270  }
271  }
272 
274  {
275  Q_ASSERT(module);
276  ModuleItem* moduleItem = createChildItem(module->get_id(), ModuleItem::TreeItemType::Module, parentItem ? parentItem : mRootItem);
277  Q_ASSERT(moduleItem);
278  for(const Module* subModule : module->get_submodules())
279  addRecursively(subModule, moduleItem);
280 
281  for(const Gate* g : module->get_gates())
282  createChildItem(g->get_id(), ModuleItem::TreeItemType::Gate, moduleItem);
283  }
284 
286  {
287  QList<ModuleItem*> trashcan; // access items to delete without map
288 
289  for (auto it = mModuleMap.lowerBound(id); it != mModuleMap.upperBound(id); ++it)
290  trashcan.append(it.value());
291 
292  for (ModuleItem* item : trashcan)
293  {
294  BaseTreeItem* parentItem = item->getParent();
295  removeChildItem(item,parentItem);
296  }
297  }
298 
300  {
301  QList<ModuleItem*> trashcan; // access items to delete without map
302 
303  for (auto it = mGateMap.lowerBound(id); it != mGateMap.upperBound(id); ++it)
304  trashcan.append(it.value());
305 
306  for (ModuleItem* item : trashcan)
307  {
308  BaseTreeItem* parentItem = item->getParent();
309  removeChildItem(item,parentItem);
310  }
311  }
312 
314  {
315  QList<ModuleItem*> trashcan; // access items to delete without map
316 
317  for (auto it = mNetMap.lowerBound(id); it != mNetMap.upperBound(id); ++it)
318  trashcan.append(it.value());
319 
320  for (ModuleItem* item : trashcan)
321  {
322  BaseTreeItem* parentItem = item->getParent();
323  removeChildItem(item,parentItem);
324  }
325  }
326 
328  {
329  ModuleItem* retval = new ModuleItem(id, itemType, this);
330 
331  if (!parentItem) parentItem = mRootItem;
332  QModelIndex index = getIndexFromItem(parentItem);
333  int row = parentItem->getChildCount();
334  mIsModifying = true;
335  beginInsertRows(index, row, row);
336  parentItem->appendChild(retval);
337  endInsertRows();
338  mIsModifying = false;
339 
340  return retval;
341  }
342 
343  void ModuleModel::removeChildItem(ModuleItem *itemToRemove, BaseTreeItem *parentItem)
344  {
345  Q_ASSERT(itemToRemove);
346  Q_ASSERT(parentItem);
347 
348  while (itemToRemove->getChildCount())
349  {
350  ModuleItem* childItem = static_cast<ModuleItem*>(itemToRemove->getChildren().at(0));
351  removeChildItem(childItem,itemToRemove);
352  }
353 
354  QModelIndex index = getIndexFromItem(parentItem);
355 
356  int row = itemToRemove->getOwnRow();
357 
358  mIsModifying = true;
359  beginRemoveRows(index, row, row);
360  parentItem->removeChild(itemToRemove);
361  endRemoveRows();
362  mIsModifying = false;
363 
364  delete itemToRemove;
365  }
366 
367  void ModuleModel::handleModuleNameChanged(Module* mod)
368  {
369  updateModuleName(mod->get_id());
370  }
371 
372  void ModuleModel::handleModuleRemoved(Module* mod)
373  {
374  removeModule(mod->get_id());
375  }
376 
377  void ModuleModel::handleModuleCreated(Module* mod)
378  {
379  if (mod->get_parent_module() == nullptr) return;
380  addModule(mod->get_id(), mod->get_parent_module()->get_id());
381  }
382 
383  void ModuleModel::handleModuleGateAssigned(Module* mod, u32 gateId)
384  {
385  if (mTempGateAssignment.isAccumulate())
386  mTempGateAssignment.assignGateToModule(gateId,mod);
387  else
388  {
389  moduleAssignGate(mod->get_id(), gateId);
390  moduleAssignNets({gateId});
391  }
392  }
393 
394  void ModuleModel::handleModuleGateRemoved(Module* mod, u32 gateId)
395  {
396  QList<QPair<ModuleItem*,ModuleItem*> > trashcan; // item to delete, parent
397 
398  if (mTempGateAssignment.isAccumulate())
399  mTempGateAssignment.removeGateFromModule(gateId,mod);
400  else
401  {
402  for (auto it = mGateMap.lowerBound(gateId); it != mGateMap.upperBound(gateId); ++it)
403  {
404  ModuleItem* item = it.value();
405  if (item->isToplevelItem()) continue;;
406 
407  ModuleItem* parentItem = static_cast<ModuleItem*>(item->getParent());
408  if (parentItem->id() == mod->get_id())
409  trashcan.append(QPair<ModuleItem*,ModuleItem*>(item, parentItem));
410  }
411  }
412 
413  for (const QPair<ModuleItem*,ModuleItem*>& trash : trashcan)
414  removeChildItem(trash.first, trash.second);
415  }
416 
417  void ModuleModel::handleModuleGatesAssignBegin(Module* mod, u32 numberGates)
418  {
419  Q_UNUSED(mod);
420  Q_UNUSED(numberGates);
421  mTempGateAssignment.beginAccumulate();
422  }
423 
424  void ModuleModel::handleModuleGatesAssignEnd(Module* mod, u32 numberGates)
425  {
426  Q_UNUSED(mod);
427  Q_UNUSED(numberGates);
428  mTempGateAssignment.endAccumulate();
429  if (!mTempGateAssignment.isAccumulate())
430  {
431  for (auto it = mTempGateAssignment.mGateAssign.begin(); it != mTempGateAssignment.mGateAssign.end(); ++it)
432  {
433  moduleAssignGate(it.value()->get_id(), it.key()); // moduleId, gateId
434  }
435  moduleAssignNets(mTempGateAssignment.mGateAssign.keys());
436  mTempGateAssignment.mGateAssign.clear();
437  mTempGateAssignment.mGateRemove.clear();
438  }
439  }
440 
441  void ModuleModel::handleGateRemoved(Gate* gat)
442  {
443  removeGate(gat->get_id());
444  }
445 
446  void ModuleModel::handleGateCreated(Gate* gat)
447  {
448  Module* mod = gat->get_module();
449  if (mod) moduleAssignGate(mod->get_id(), gat->get_id());
450  }
451 
452  void ModuleModel::handleGateNameChanged(Gate* gat)
453  {
454  updateGateName(gat->get_id());
455  }
456 
457  void ModuleModel::handleNetCreated(Net* net)
458  {
459  addNet(net->get_id(), gNetlist->get_top_module()->get_id());
460  }
461 
462  void ModuleModel::handleNetRemoved(Net* net)
463  {
464  removeNet(net->get_id());
465  }
466 
467  void ModuleModel::handleNetNameChanged(Net* net)
468  {
469  updateNetName(net->get_id());
470  }
471 
472  void ModuleModel::handleNetUpdated(Net* net, u32 data)
473  {
474  Q_UNUSED(data);
476  }
477 
478  void ModuleModel::handleModuleParentChanged(const Module* mod)
479  {
480  Q_ASSERT(mod);
481  updateModuleParent(mod);
482 
483  QHash<const Net*,ModuleItem*> parentAssignment;
484  std::unordered_set<Net*> assignedNets;
485  findNetParentRecursion(mRootItem, parentAssignment, assignedNets);
486 
487  for(Net* net : mod->get_nets())
488  updateNetParent(net, &parentAssignment);
489  }
490 
491  void ModuleModel::handleModuleSubmoduleAdded(Module* mod, u32 submodId)
492  {
493  Q_UNUSED(mod);
494  Q_UNUSED(submodId);
495  }
496 
497  void ModuleModel::handleModuleSubmoduleRemoved(Module* mod, u32 submodId)
498  {
499  Q_UNUSED(mod);
500  Q_UNUSED(submodId);
501  }
502 
503  void ModuleModel::findNetParentRecursion(BaseTreeItem* parent, QHash<const Net *, ModuleItem *> &parentAssignment, std::unordered_set<Net*>& assignedNets) const
504  {
505  for (BaseTreeItem* bti : parent->getChildren())
506  {
507  ModuleItem* item = dynamic_cast<ModuleItem*>(bti);
508  if (!item || item->getType() != ModuleItem::TreeItemType::Module) continue;
509  findNetParentRecursion(item, parentAssignment, assignedNets);
510  Module* m = gNetlist->get_module_by_id(item->id());
511  Q_ASSERT(m);
512  std::unordered_set<Net*> internalNets = m->get_nets();
513  if (!internalNets.empty())
514  {
515  for (Net* n : assignedNets)
516  internalNets.erase(n);
517  for (Net* n : m->get_input_nets())
518  internalNets.erase(n);
519  for (Net* n : m->get_output_nets())
520  internalNets.erase(n);
521  }
522  for (Net* n : internalNets)
523  {
524  parentAssignment[n] = item;
525  assignedNets.insert(n);
526  }
527  }
528  }
529 
530  Module* ModuleModel::findNetParent(const Net *net) const
531  {
532  QHash<Module*,int> modHash;
533  if (net->is_global_input_net() || net->is_global_output_net()) return nullptr;
534  int maxDepth = 0;
535 
536  for (const Endpoint* ep : net->get_sources())
537  {
538  Module* m = ep->get_gate()->get_module();
539  Q_ASSERT(m);
540  int depth = m->get_submodule_depth();
541  if (depth > maxDepth) maxDepth = depth;
542  modHash.insert(m,depth);
543  }
544 
545  for (const Endpoint* ep : net->get_destinations())
546  {
547  Module* m = ep->get_gate()->get_module();
548  Q_ASSERT(m);
549  int depth = m->get_submodule_depth();
550  if (depth > maxDepth) maxDepth = depth;
551  modHash.insert(m,depth);
552  }
553 
554  while (modHash.size() > 1 && maxDepth > 0)
555  {
556  auto it = modHash.begin();
557  while (it != modHash.end())
558  {
559  if (it.value() == maxDepth)
560  {
561  Module* parentMod = it.key()->get_parent_module();
562  modHash.erase(it);
563  if (parentMod) modHash.insert(parentMod,maxDepth-1);
564  break;
565  }
566  ++it;
567  }
568  if (it == modHash.end())
569  --maxDepth;
570  }
571  if (modHash.empty()) return nullptr;
572  return modHash.begin().key();
573  }
574 
575  void ModuleModel::moduleAssignGate(const u32 moduleId, const u32 gateId)
576  {
577  // Don't need new function handleModuleGateRemoved(), because the GateAssinged event always follows GateRemoved
578  // or NetlistInternalManager updates Net connections when a gate is deleted.
579 
580  QSet<ModuleItem*> parentsHandled;
581  Q_ASSERT(gNetlist->get_gate_by_id(gateId));
582 
583  QList<QPair<ModuleItem*,ModuleItem*> > trashcan; // item to delete, parent
584  for (auto itGat = mGateMap.lowerBound(gateId); itGat != mGateMap.upperBound(gateId); ++itGat)
585  {
586  ModuleItem* gatItem = itGat.value();
587  if (gatItem->isToplevelItem()) continue;
588  ModuleItem* oldParentItem = static_cast<ModuleItem*>(gatItem->getParent());
589  Q_ASSERT(oldParentItem);
590 
591  if (oldParentItem->id() != moduleId)
592  {
593  trashcan.append(QPair<ModuleItem*,ModuleItem*>(gatItem,oldParentItem));
594  }
595  else
596  {
597  parentsHandled.insert(oldParentItem);
598  }
599  }
600  for (const QPair<ModuleItem*,ModuleItem*>& trash : trashcan)
601  removeChildItem(trash.first, trash.second);
602 
603  if (!moduleId) return;
604  for (auto itMod = mModuleMap.lowerBound(moduleId); itMod != mModuleMap.upperBound(moduleId); ++itMod)
605  {
606  ModuleItem* parentItem = itMod.value();
607  if (parentsHandled.contains(parentItem)) continue;
608  createChildItem(gateId, ModuleItem::TreeItemType::Gate, parentItem);
609  }
610 
611  }
612 
614  {
615  QHash<const Net*,ModuleItem*> parentAssignment;
616  std::unordered_set<Net*> assignedNets;
617  findNetParentRecursion(mRootItem, parentAssignment, assignedNets);
618 
619  QSet<const Net*> netsToAssign;
620  if (gateIds.isEmpty())
621  {
622 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
623  QList<const Net*> tempKeys = parentAssignment.keys();
624  netsToAssign = QSet(tempKeys.begin(),tempKeys.end());
625 #else
626  netsToAssign = parentAssignment.keys().toSet();
627 #endif
628  }
629  else
630  {
631  for (u32 id : gateIds)
632  {
633  Gate* gate = gNetlist->get_gate_by_id(id);
634  for(Net* in_net : gate->get_fan_in_nets())
635  netsToAssign.insert(in_net);
636  for(Net* out_net : gate->get_fan_out_nets())
637  netsToAssign.insert(out_net);
638  }
639  }
640 
641  for (const Net* n: netsToAssign)
642  updateNetParent(n, &parentAssignment);
643  }
644 
646  {
647  Q_ASSERT(net);
648  u32 netId = net->get_id();
649 
650  QSet<ModuleItem*> parentsHandled;
651  u32 newParentId = 0;
652  if (parentAssignment)
653  {
654  ModuleItem* modItem = parentAssignment->value(net);
655  if (modItem)
656  newParentId = modItem->id();
657  }
658  else
659  {
660  Module* newParentModule = findNetParent(net);
661  if (newParentModule)
662  newParentId = newParentModule->get_id();
663  }
664 
665  QList<QPair<ModuleItem*,ModuleItem*> > trashcan; // item to delete, parent
666 
667  for (auto itNet = mNetMap.lowerBound(netId); itNet != mNetMap.upperBound(netId); ++itNet)
668  {
669  if (itNet.value()->isToplevelItem()) continue;
670 
671  ModuleItem* netItem = itNet.value();
672  ModuleItem* oldParentItem = static_cast<ModuleItem*>(netItem->getParent());
673  Q_ASSERT(oldParentItem);
674 
675  if (newParentId == 0 || newParentId != oldParentItem->id())
676  {
677  trashcan.append(QPair<ModuleItem*,ModuleItem*>(netItem,oldParentItem));
678  break;
679  }
680  else
681  {
682  parentsHandled.insert(oldParentItem);
683  }
684  }
685 
686  for (const QPair<ModuleItem*,ModuleItem*>& trash : trashcan)
687  removeChildItem(trash.first, trash.second);
688 
689  if (!newParentId) return;
690  for (auto itMod = mModuleMap.lowerBound(newParentId); itMod != mModuleMap.upperBound(newParentId); ++itMod)
691  {
692  ModuleItem* parentItem = itMod.value();
693  if (parentsHandled.contains(parentItem)) continue;
694  createChildItem(net->get_id(), ModuleItem::TreeItemType::Net, parentItem);
695  }
696  }
697 
699  {
700  ModuleItem* moduleItemToBeMoved = nullptr;
701  bool moduleItemReassigned = false;
702 
703  Q_ASSERT(module);
704  u32 id = module->get_id();
705  Q_ASSERT(id != 1);
706 
707  QSet<ModuleItem*> parentsHandled;
708  u32 parentId = module->get_parent_module()->get_id();
709  Q_ASSERT(parentId > 0);
710 
711  QList<QPair<ModuleItem*,ModuleItem*> > trashcan; // item to delete, parent
712 
713  for (auto itSubm = mModuleMap.lowerBound(id); itSubm != mModuleMap.upperBound(id); ++itSubm)
714  {
715  ModuleItem* submItem = itSubm.value();
716  if (submItem->isToplevelItem()) continue;
717 
718  ModuleItem* oldParentItem = static_cast<ModuleItem*>(submItem->getParent());
719  Q_ASSERT(oldParentItem);
720 
721  if (oldParentItem->id() != parentId)
722  {
723  if (moduleItemToBeMoved)
724  {
725  // remove tree item recursively
726  trashcan.append(QPair<ModuleItem*,ModuleItem*>(submItem,oldParentItem));
727  }
728  else
729  {
730  // save tree item for reassignment
731  moduleItemToBeMoved = submItem;
732  QModelIndex index = getIndexFromItem(oldParentItem);
733 
734  int row = submItem->getOwnRow();
735 
736  mIsModifying = true;
737  beginRemoveRows(index, row, row);
738  oldParentItem->removeChild(submItem);
739  endRemoveRows();
740  mIsModifying = false;
741  }
742  }
743  else
744  {
745  parentsHandled.insert(oldParentItem);
746  }
747  }
748  for (const QPair<ModuleItem*,ModuleItem*>& trash : trashcan)
749  removeChildItem(trash.first, trash.second);
750 
751  if (!parentId) return;
752  for (auto itMod = mModuleMap.lowerBound(parentId); itMod != mModuleMap.upperBound(parentId); ++itMod)
753  {
754  ModuleItem* parentItem = itMod.value();
755  if (parentsHandled.contains(parentItem)) continue;
756  if (moduleItemToBeMoved && !moduleItemReassigned)
757  {
758  QModelIndex index = getIndexFromItem(parentItem);
759  int row = parentItem->getChildCount();
760  mIsModifying = true;
761  beginInsertRows(index, row, row);
762  parentItem->appendChild(moduleItemToBeMoved);
763  endInsertRows();
764  mIsModifying = false;
765  moduleItemReassigned = true;
766  }
767  else
768  {
769  addRecursively(module, parentItem);
770  }
771  }
772 
773  if (moduleItemToBeMoved && !moduleItemReassigned)
774  {
775  removeChildItem(moduleItemToBeMoved, moduleItemToBeMoved->getParent());
776  }
777 
778  }
779 
781  {
782  Q_ASSERT(gNetlist->get_module_by_id(id));
783 
784  for (auto it = mModuleMap.lowerBound(id); it != mModuleMap.upperBound(id); ++it)
785  {
786  ModuleItem* item = it.value();
787  Q_ASSERT(item);
788 
789  item->setName(QString::fromStdString(gNetlist->get_module_by_id(id)->get_name())); // REMOVE & ADD AGAIN
790 
793  }
794  }
795 
797  {
798  Q_ASSERT(gNetlist->get_gate_by_id(id));
799 
800  for (auto it = mGateMap.lowerBound(id); it != mGateMap.upperBound(id); ++it)
801  {
802  ModuleItem* item = it.value();
803  Q_ASSERT(item);
804 
805  item->setName(QString::fromStdString(gNetlist->get_gate_by_id(id)->get_name())); // REMOVE & ADD AGAIN
806 
809  }
810  }
811 
813  {
814  Q_ASSERT(gNetlist->get_net_by_id(id));
815 
816  // if net elment not in model loop will reject
817  for (auto it = mNetMap.lowerBound(id); it != mNetMap.upperBound(id); ++it)
818  {
819  ModuleItem* item = it.value();
820  Q_ASSERT(item);
821 
822  item->setName(QString::fromStdString(gNetlist->get_net_by_id(id)->get_name())); // REMOVE & ADD AGAIN
823 
826  }
827  }
828 
830  {
831  return mIsModifying;
832  }
833 
834  void ModuleModel::setIsModifying(bool pIsModifying)
835  {
836  mIsModifying = pIsModifying;
837  }
838 }
(Future) Base class for all tree models related to the details widget.
virtual QList< BaseTreeItem * > getChildren() const
virtual bool removeChild(BaseTreeItem *child)
virtual BaseTreeItem * getParent() const
virtual int getChildCount() const
virtual void appendChild(BaseTreeItem *child)
virtual int getOwnRow()
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()
void setHeaderLabels(const QStringList &label)
BaseTreeItem * getItemFromIndex(QModelIndex index) const
Definition: gate.h:58
const std::vector< Net * > & get_fan_in_nets() const
Definition: gate.cpp:591
const std::string & get_name() const
Definition: gate.cpp:105
const std::vector< Net * > & get_fan_out_nets() const
Definition: gate.cpp:735
Module * get_parent_module() const
Definition: module.cpp:125
const std::vector< Gate * > & get_gates() const
Definition: module.cpp:391
std::string get_name() const
Definition: module.cpp:87
std::vector< Module * > get_submodules(const std::function< bool(Module *)> &filter=nullptr, bool recursive=false) const
Definition: module.cpp:259
u32 get_id() const
Definition: module.cpp:82
An item in the ModuleModel.
Definition: module_item.h:48
QVariant getData(int column) const override
Definition: module_item.cpp:88
bool isToplevelItem() const
void setName(const QString &name)
u32 id() const
bool highlighted() const
TreeItemType getType() const
void updateModuleParent(const Module *module)
Qt::ItemFlags flags(const QModelIndex &index) const override
void updateNetName(const u32 id)
void addRecursively(const Module *module, BaseTreeItem *parentItem=nullptr)
void addNet(const u32 id, const u32 parentId)
void removeGate(const u32 id)
void moduleAssignNets(const QList< u32 > &gateIds=QList< u32 >())
void removeModule(const u32 id)
QList< ModuleItem * > getItems(const u32 id, ModuleItem::TreeItemType type=ModuleItem::TreeItemType::Module) const
void addGate(const u32 id, const u32 parentId)
ModuleItem * getItem(const QModelIndex &index) const
void populateFromGatelist(const std::vector< Gate * > &gates)
ModuleItem * createChildItem(u32 id, ModuleItem::TreeItemType itemType, BaseTreeItem *parentItem=nullptr)
void updateGateName(const u32 id)
void addModule(const u32 id, const u32 parentId)
QVariant data(const QModelIndex &index, int role) const override
void updateNetParent(const Net *net, const QHash< const Net *, ModuleItem * > *parentAssignment=nullptr)
void setIsModifying(bool pIsModifying)
ModuleModel(QObject *parent=nullptr)
void removeNet(const u32 id)
QMimeData * mimeData(const QModelIndexList &indexes) const override
void updateModuleName(const u32 id)
void clear() override
void removeChildItem(ModuleItem *itemToRemove, BaseTreeItem *parentItem)
void populateTree(const QVector< u32 > &modIds={}, const QVector< u32 > &gatIds={}, const QVector< u32 > &netIds={})
friend class ModuleItem
Definition: module_model.h:55
void moduleAssignGate(const u32 moduleId, const u32 gateId)
Definition: net.h:58
const std::string & get_name() const
Definition: net.cpp:98
Module * get_top_module() const
Definition: netlist.cpp:608
Gate * get_gate_by_id(const u32 gate_id) const
Definition: netlist.cpp:193
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
void netDestinationRemoved(Net *n, const u32 dst_gate_id) const
void moduleGatesAssignEnd(Module *m, u32 number_gates) const
void netCreated(Net *n) const
void netSourceAdded(Net *n, const u32 src_gate_id) const
void moduleGateRemoved(Module *m, const u32 removed_gate) const
void moduleGateAssigned(Module *m, const u32 assigned_gate) const
void netSourceRemoved(Net *n, const u32 src_gate_id) const
void netRemoved(Net *n) const
void netDestinationAdded(Net *n, const u32 dst_gate_id) const
void moduleSubmoduleRemoved(Module *m, const u32 removed_module) const
void moduleNameChanged(Module *m) const
void gateNameChanged(Gate *g) const
void moduleRemoved(Module *m) const
void moduleParentChanged(Module *m) const
void moduleSubmoduleAdded(Module *m, const u32 added_module) const
void moduleCreated(Module *m) const
void moduleGatesAssignBegin(Module *m, u32 number_gates) const
void netNameChanged(Net *n) const
static QString pyCodeModule(u32 moduleId)
static QString pyCodeNet(u32 netId)
static QString pyCodeGate(u32 gateId)
static SelectionDetailsIconProvider * instance()
const Module * module(const Gate *g, const NodeBoxes &boxes)
Netlist * gNetlist
Definition: plugin_gui.cpp:80
NetlistRelay * gNetlistRelay
Definition: plugin_gui.cpp:81
n
Definition: test.py:6
quint32 u32
PinType type
Net * net
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)
virtual Qt::ItemFlags flags(const QModelIndex &index) const const
const Key & key() const const
QHash::iterator begin()
bool empty() const const
QHash::iterator end()
QHash::iterator erase(QHash::iterator pos)
QHash::iterator insert(const Key &key, const T &value)
QList< Key > keys() const const
int size() const const
const T value(const Key &key) const const
void append(const T &value)
QList::iterator begin()
QList::iterator end()
bool isEmpty() const const
QMap::iterator insert(const Key &key, const T &value)
const T value(const Key &key, const T &defaultValue) const const
void setData(const QString &mimeType, const QByteArray &data)
void setText(const QString &text)
int column() const const
void * internalPointer() 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)
QString fromStdString(const std::string &str)
AlignRight
DecorationRole
typedef ItemFlags