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