25 #include <QJsonDocument>
26 #include <QJsonObject>
27 #include <QTextStream>
33 "graph_view/net_grp_pin",
35 "Appearance:Graph View",
36 "If set net grouping colors are also applied to input and output pins of gates");
39 "graph_view/pan_middle_button",
42 "If enabled middle mouse button will pan the graphics.\n"
43 "If disabled middle mouse button can be used for rubber band selection.");
52 "eXpert Settings:Debug",
53 "Specifies whether the debug grid is displayed in the Graph View. The gird represents the scene as the layouter interprets it.");
58 "eXpert Settings:Debug",
59 "Dump input data from junction router to file 'junction_data.txt' for external debugging.");
61 mSettingParseLayout =
new SettingsItemCheckbox(
"Apply Parsed Position",
"graph_view/layout_parse",
true,
"Graph View",
"Use parsed verilog coordinates if available.");
63 mSettingLayoutBoxes =
new SettingsItemCheckbox(
"Optimize Box Layout",
"graph_view/layout_boxes",
true,
"Graph View",
"If disabled faster randomized placement.");
84 if (!parentItem || !itemToMove)
return false;
86 return mContextTreeModel->
moveItem(itemToMove, parentItem, row);
97 if (parentItem)
return parentItem->
getId();
101 if (!context)
return 0;
107 if (parentItem)
return parentItem->
getId();
129 if (!ctx || ctx->
id() == ctxId)
134 if (ctxId > mMaxContextId)
135 mMaxContextId = ctxId;
184 PlacementHint plc(PlacementHint::PlacementModeType::GridPosition);
185 int currentY = -(int)(
net->get_num_of_sources()/2);
186 for(
auto endpoint :
net->get_sources()) {
187 u32 id = endpoint->get_gate()->get_id();
191 currentY = -(int)(
net->get_num_of_destinations()/2);
192 for(
auto endpoint :
net->get_destinations()) {
193 u32 id = endpoint->get_gate()->get_id();
211 ctx->mName = newName;
243 return mContextTreeModel->
list();
262 if (directory)
return directory;
272 if (ctx->name() ==
name && !ctx->isDirty())
282 if (ctx->getExclusiveModuleId() == module_id)
303 if (ctx->name() ==
name)
314 if (context->getSpecialUpdate())
316 context->add({m->
get_id()}, {});
317 context->setSpecialUpdate(
false);
325 if (context->getExclusiveModuleId() == m->
get_id())
327 context->setExclusiveModuleId(0,
false);
330 else if (context->modules().contains(m->
get_id()))
332 context->remove({m->
get_id()}, {});
334 if (context->empty() || context->willBeEmptied())
343 if (context->modules().contains(m->
get_id()))
344 context->scheduleSceneUpdate();
350 if (context->modules().contains(m->
get_id()))
351 context->scheduleSceneUpdate();
361 if (context->modules().contains(m->
get_id())
362 || context->gates().intersects(gateIDs))
363 context->scheduleSceneUpdate();
373 Module* current_module = m;
379 }
while (current_module);
383 if (context->isShowingFoldedTopModule())
continue;
384 if (context->isShowingModule(m->
get_id(), {added_module}, {}, {}, {}) && !context->isShowingModule(added_module, {}, {}, {}, {}))
385 context->add({added_module}, {});
387 context->testIfAffected(m->
get_id(), &added_module,
nullptr);
391 if (context->isShowingModule(added_module, {}, {}, {}, {}))
394 modules.
remove(added_module);
400 for (
u32 id : module_ids)
403 context->removeModuleContents(added_module);
418 if (context->isShowingFoldedTopModule())
continue;
420 context->isShowingModule(m->
get_id(), {}, {}, {removed_module}, {}))
421 context->remove({removed_module}, {});
423 context->testIfAffected(m->
get_id(), &removed_module,
nullptr);
425 if (context->empty() || context->willBeEmptied())
435 Module* current_module = m;
441 }
while (current_module);
445 if (context->isShowingFoldedTopModule())
continue;
446 if (context->isShowingModule(m->
get_id(), {}, {inserted_gate}, {}, {}))
447 context->add({}, {inserted_gate});
449 context->testIfAffected(m->
get_id(),
nullptr, &inserted_gate);
451 if (context->gates().contains(inserted_gate))
455 for (
u32 id : module_ids)
458 context->
remove({}, {inserted_gate});
470 if (context->isShowingFoldedTopModule())
continue;
472 context->isShowingModule(m->
get_id(), {}, {}, {}, {removed_gate}))
474 context->remove({}, {removed_gate});
475 if (context->empty() || context->willBeEmptied())
482 context->add({m->
get_id()}, {});
489 context->testIfAffected(m->
get_id(),
nullptr, &removed_gate);
497 void GraphContextManager::dump(
const QString& title,
u32 mid,
u32 xid)
const
500 xout <<
"===" << title <<
"===" << mid <<
"===" << xid <<
"===\n";
503 xout <<
"M" << m->get_id() <<
" SM:";
505 xout <<
" " << sm->get_id();
507 for (
Gate*
g : m->get_gates())
508 xout <<
" " <<
g->get_id();
513 xout <<
" " <<
g->get_id();
516 for (GraphContext* ctx : mContextTreeModel->
list())
518 xout <<
"ctx " << ctx->id() <<
":";
519 for (
hal::Node nd : ctx->getLayouter()->positionToNodeMap().values())
521 xout <<
" " << (nd.type() ==
Node::Module ?
'm' :
'g') << nd.id();
533 if (context->modules().contains(m->
get_id()))
535 context->updateNets();
536 context->scheduleSceneUpdate();
543 if (context->gates().contains(
g->get_id()))
544 context->remove({}, {
g->get_id()});
550 if (context->gates().contains(
g->get_id()))
551 context->scheduleSceneUpdate();
565 if (context->nets().contains(
n->get_id()))
566 context->scheduleSceneUpdate();
572 if (context->nets().contains(
n->get_id()))
573 context->scheduleSceneUpdate();
580 if (context->nets().contains(
n->get_id()) || context->gates().contains(src_gate_id))
583 context->applyChanges();
584 context->scheduleSceneUpdate();
595 if (context->nets().contains(
n->get_id()))
598 context->applyChanges();
599 context->scheduleSceneUpdate();
608 if (context->nets().contains(
n->get_id()) || context->gates().contains(dst_gate_id))
611 context->applyChanges();
612 context->scheduleSceneUpdate();
623 if (context->nets().contains(
n->get_id()))
626 context->applyChanges();
627 context->scheduleSceneUpdate();
636 if (context->nets().contains(mNetId) || context->isShowingNetDestination(mNetId))
638 context->applyChanges();
639 context->scheduleSceneUpdate();
648 if (context->nets().contains(mNetId) || context->isShowingNetSource(mNetId))
650 context->applyChanges();
651 context->scheduleSceneUpdate();
659 if (context->nets().contains(mNetId))
661 context->applyChanges();
662 context->scheduleSceneUpdate();
669 if (context->nets().contains(mNetId))
671 context->applyChanges();
672 context->scheduleSceneUpdate();
697 return mContextTreeModel;
705 mContextTreeModel->
clear();
710 QFile jsFile(filename);
718 if (json.
contains(
"directories") && json[
"directories"].isArray())
720 QJsonArray jsonDirectories = json[
"directories"].toArray();
721 int ndir = jsonDirectories.
size();
722 for (
int idir = 0; idir < ndir; idir++)
725 if (!jsondir.
contains(
"id") || !jsondir[
"id"].isDouble())
727 u32 dirId = jsondir[
"id"].toInt();
728 if (!jsondir.
contains(
"name") || !jsondir[
"name"].isString())
730 QString dirName = jsondir[
"name"].toString();
733 u32 dirParentId = jsondir[
"parentId"].toInt();
737 if (dirParentId != 0)
738 dirParent = mContextTreeModel->
getDirectory(dirParentId);
740 if (dirId < 0 || dirId > 0x7FFFFFFF)
741 dirId = ++mMaxContextId;
743 mContextTreeModel->
addDirectory(dirName, dirParent, dirId);
746 if (json.
contains(
"views") && json[
"views"].isArray())
748 QJsonArray jsonViews = json[
"views"].toArray();
749 int nviews = jsonViews.
size();
750 for (
int iview = 0; iview < nviews; iview++)
753 if (!jsonView.
contains(
"id") || !jsonView[
"id"].isDouble())
755 u32 viewId = jsonView[
"id"].toInt();
756 if (!jsonView.
contains(
"name") || !jsonView[
"name"].isString())
758 QString viewName = jsonView[
"name"].toString();
759 if (viewId > mMaxContextId)
760 mMaxContextId = viewId;
763 visibleFlag = jsonView[
"visible"].toInt();
765 u32 viewParentId = 0;
767 viewParentId = jsonView[
"parentId"].toInt();
771 if (viewParentId != 0) {
772 viewParent = mContextTreeModel->
getDirectory(viewParentId);
781 if (viewName != context->mName)
785 log_warning(
"gui",
"failed to set up existing context ID={} from view file {}.", context->
id(), filename.
toStdString());
806 mContextTreeModel->
addContext(context, viewParent);
811 if (jsonView.
contains(
"exclusiveModuleId"))
814 selectedContext = context;
816 selectedContext = context;
818 firstContext = context;
822 if (selectedContext)
return selectedContext;
828 QFile jsFile(filename);
842 context->writeToFile(jsonView, parentId);
843 jsonViews.
append(jsonView);
845 json[
"views"] = jsonViews;
851 directory->writeToFile(jsonDirectory);
852 jsonDirectories.
append(jsonDirectory);
854 json[
"directories"] = jsonDirectories;
Adds an item to a module or grouping.
void setPlacementHint(PlacementHint hint)
(Future) Base class for all tree models related to the details widget.
virtual BaseTreeItem * getParent() const
BaseTreeItem * getRootItem() const
BaseTreeItem * getItemFromIndex(QModelIndex index) const
ContextManagerWidget * getContextManagerWidget()
void setName(QString name_)
void selectViewContext(GraphContext *context)
void handleOpenContextClicked()
Base model for the ContextManagerWidget to manage GraphContexts.
bool moveItem(ContextTreeItem *itemToMove, BaseTreeItem *newParent, int row=-1)
void removeDirectory(ContextDirectory *directory)
const QVector< GraphContext * > & list()
QModelIndex getIndexFromContext(GraphContext *context) const
BaseTreeItem * getDirectory(u32 directoryId) const
void removeContext(GraphContext *context)
ContextDirectory * addDirectory(QString name, BaseTreeItem *parentItem, u32 id)
void addContext(GraphContext *context, BaseTreeItem *parent=nullptr)
const QVector< ContextDirectory * > & directoryList()
BaseTreeItem * getContext(u32 contextId) const
Logical container for modules, gates, and nets.
bool readFromFile(const QJsonObject &json)
void setExclusiveModuleId(u32 id, bool emitSignal=true)
void setShader(GraphShader *shader)
void setLayouter(GraphLayouter *layouter)
void contextRenamed(GraphContext *context)
void handleModuleNameChanged(Module *m) const
void renameContextDirectoryAction(ContextDirectory *ctxDir, const QString &newName)
void openGateInView(u32 gateId)
QString nextViewName(const QString &prefix) const
GraphContext * createNewContext(const QString &name, u32 parentId=0)
void handleMarkedGlobalOutput(u32 mNetId)
void renameGraphContextAction(GraphContext *ctx, const QString &newName)
void deleteContextDirectory(ContextDirectory *ctxDir)
void handleNetCreated(Net *n) const
void setContextId(GraphContext *ctx, u32 ctxId)
void handleNetNameChanged(Net *n) const
void handleModuleTypeChanged(Module *m) const
void handleNetRemoved(Net *n) const
GraphContext * getContextById(u32 id) const
bool handleSaveTriggered(const QString &filename)
ContextTreeModel * getContextTreeModel() const
GraphContext * getContextByExclusiveModuleId(u32 module_id) const
void handleMarkedGlobalInput(u32 mNetId)
u32 getParentId(u32 childId, bool isDirectory) const
void handleNetDestinationRemoved(Net *n, const u32 dst_gate_id) const
GraphContext * getCleanContext(const QString &name) const
void handleGateRemoved(Gate *g) const
void handleModuleGateAssigned(Module *m, const u32 inserted_gate) const
bool contextWithNameExists(const QString &name) const
void handleNetSourceRemoved(Net *n, const u32 src_gate_id) const
void handleUnmarkedGlobalOutput(u32 mNetId)
GraphLayouter * getDefaultLayouter(GraphContext *const context) const
void handleUnmarkedGlobalInput(u32 mNetId)
void handleNetDestinationAdded(Net *n, const u32 dst_gate_id) const
void contextCreated(GraphContext *context)
void deleteGraphContext(GraphContext *ctx)
static SettingsItemCheckbox * sSettingPanOnMiddleButton
static SettingsItemCheckbox * sSettingNetGroupingToPins
ContextDirectory * createNewDirectory(const QString &name, u32 parentId=0)
void handleModuleCreated(Module *m) const
void handleModuleSubmoduleAdded(Module *m, const u32 added_module) const
void handleModulePortsChanged(Module *m, PinEvent pev, u32 pgid)
void handleModuleGateRemoved(Module *m, const u32 removed_gate)
bool moveItem(u32 itemId, bool isDirectory, u32 parentId, int row=-1)
void handleModuleColorChanged(Module *m) const
GraphShader * getDefaultShader(GraphContext *const context) const
void directoryRenamed(ContextDirectory *directory)
GraphContext * restoreFromFile(const QString &filename)
void openModuleInView(u32 moduleId, bool unfold)
void handleModuleSubmoduleRemoved(Module *m, const u32 removed_module)
void deletingDirectory(ContextDirectory *directory)
void handleNetSourceAdded(Net *n, const u32 src_gate_id) const
ContextDirectory * getDirectoryById(u32 id) const
void handleGateNameChanged(Gate *g) const
void openNetEndpointsInView(u32 netId)
void handleModuleRemoved(Module *m)
QVector< GraphContext * > getContexts() const
void deletingContext(GraphContext *context)
Base class for all specific layouters.
void setDumpJunctionEnabled(bool enabled)
Base class to store and update visual information about the graph.
Module * get_parent_module() const
const std::vector< Gate * > & get_gates() const
std::string get_name() const
std::vector< Module * > get_submodules(const std::function< bool(Module *)> &filter=nullptr, bool recursive=false) const
Specifically stores/updates visual information about a module and its items.
const std::vector< Gate * > & get_gates() const
const std::vector< Module * > & get_modules() const
Module * get_module_by_id(u32 module_id) const
Net * get_net_by_id(u32 net_id) const
The Node class object represents a module or a gate.
The PlacementHint class object provides hints for the layouter how new box objects are placed on a vi...
void addGridPosition(const Node &nd, const QPoint &p)
A SettingsItem representing a Checkbox.
virtual QVariant value() const override
The standard layouter used to layout netlists.
void setParseLayoutEnabled(bool enabled)
void setLayoutBoxesEnabled(bool enabled)
void addAction(UserAction *act)
void setUseCreatedObject()
virtual UserActionObject object() const
#define log_warning(channel,...)
const Module * module(const Gate *g, const NodeBoxes &boxes)
ContentManager * gContentManager
GraphContextManager * gGraphContextManager
virtual bool open(QIODevice::OpenMode mode) override
qint64 write(const char *data, qint64 maxSize)
void append(const QJsonValue &value)
QJsonValue at(int i) const const
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QJsonObject object() const const
bool contains(const QString &key) const const
QJsonObject toObject() const const
void append(const T &value)
bool isValid() const const
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)
bool remove(const T &value)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromStdString(const std::string &str)
QString number(int n, int base)
std::string toStdString() const const
bool toBool() const const