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.");
46 "graph_view/layout_on_chage",
49 "If enabled every change will invoke layout() routine,\n"
50 "which will not happen upon rename and recolor otherwise.");
59 "eXpert Settings:Debug",
60 "Specifies whether the debug grid is displayed in the Graph View. The gird represents the scene as the layouter interprets it.");
65 "eXpert Settings:Debug",
66 "Dump input data from junction router to file 'junction_data.txt' for external debugging.");
68 mSettingParseLayout =
new SettingsItemCheckbox(
"Apply Parsed Position",
"graph_view/layout_parse",
true,
"Graph View",
"Use parsed verilog coordinates if available.");
70 mSettingLayoutBoxes =
new SettingsItemCheckbox(
"Optimize Box Layout",
"graph_view/layout_boxes",
true,
"Graph View",
"If disabled faster randomized placement.");
91 if (!parentItem || !itemToMove)
return false;
93 return mContextTreeModel->
moveItem(itemToMove, parentItem, row);
104 if (parentItem)
return parentItem->
getId();
108 if (!context)
return 0;
114 if (parentItem)
return parentItem->
getId();
136 if (!ctx || ctx->
id() == ctxId)
141 if (ctxId > mMaxContextId)
142 mMaxContextId = ctxId;
191 PlacementHint plc(PlacementHint::PlacementModeType::GridPosition);
192 int currentY = -(int)(
net->get_num_of_sources()/2);
193 for(
auto endpoint :
net->get_sources()) {
194 u32 id = endpoint->get_gate()->get_id();
198 currentY = -(int)(
net->get_num_of_destinations()/2);
199 for(
auto endpoint :
net->get_destinations()) {
200 u32 id = endpoint->get_gate()->get_id();
218 ctx->mName = newName;
250 return mContextTreeModel->
list();
269 if (directory)
return directory;
279 if (ctx->name() ==
name && !ctx->isDirty())
289 if (ctx->getExclusiveModuleId() == module_id)
310 if (ctx->name() ==
name)
321 if (context->getSpecialUpdate())
323 context->add({m->
get_id()}, {});
324 context->setSpecialUpdate(
false);
332 if (context->getExclusiveModuleId() == m->
get_id())
334 context->setExclusiveModuleId(0,
false);
337 else if (context->modules().contains(m->
get_id()))
339 context->remove({m->
get_id()}, {});
341 if (context->empty() || context->willBeEmptied())
350 if (context->modules().contains(m->
get_id()))
352 context->scheduleSceneUpdate();
354 context->refreshModule(m->
get_id());
360 if (context->modules().contains(m->
get_id()))
362 context->scheduleSceneUpdate();
364 context->refreshModule(m->
get_id());
372 gateIDs.
insert(g->get_id());
374 if (context->modules().contains(m->
get_id())
375 || context->gates().intersects(gateIDs))
377 context->scheduleSceneUpdate();
380 context->handleLayouterFinished();
381 context->refreshModule(m->
get_id());
392 Module* current_module = m;
398 }
while (current_module);
402 if (context->isShowingFoldedTopModule())
continue;
404 if (context->getExclusiveModuleId() && context->isShowingModule(m->
get_id(), {added_module}, {}, {}, {}) && !context->isShowingModule(added_module, {}, {}, {}, {}))
405 context->add({added_module}, {});
407 context->testIfAffected(m->
get_id(), &added_module,
nullptr);
411 if (context->isShowingModule(added_module, {}, {}, {}, {}))
414 modules.
remove(added_module);
420 for (
u32 id : module_ids)
423 context->removeModuleContents(added_module);
438 if (context->isShowingFoldedTopModule())
continue;
441 (context->getExclusiveModuleId() && context->isShowingModule(m->
get_id(), {}, {}, {removed_module}, {})))
442 context->remove({removed_module}, {});
444 context->testIfAffected(m->
get_id(), &removed_module,
nullptr);
446 if (context->empty() || context->willBeEmptied())
456 Module* current_module = m;
462 }
while (current_module);
466 if (context->isShowingFoldedTopModule())
continue;
468 if (context->getExclusiveModuleId() && context->isShowingModule(m->
get_id(), {}, {inserted_gate}, {}, {}))
469 context->add({}, {inserted_gate});
471 context->testIfAffected(m->
get_id(),
nullptr, &inserted_gate);
473 if (context->gates().contains(inserted_gate))
477 for (
u32 id : module_ids)
480 context->
remove({}, {inserted_gate});
492 if (context->isShowingFoldedTopModule())
continue;
495 (context->getExclusiveModuleId() && context->isShowingModule(m->
get_id(), {}, {}, {}, {removed_gate})))
497 context->remove({}, {removed_gate});
498 if (context->empty() || context->willBeEmptied())
505 context->add({m->
get_id()}, {});
512 context->testIfAffected(m->
get_id(),
nullptr, &removed_gate);
520 void GraphContextManager::dump(
const QString& title,
u32 mid,
u32 xid)
const
523 xout <<
"===" << title <<
"===" << mid <<
"===" << xid <<
"===\n";
526 xout <<
"M" << m->get_id() <<
" SM:";
528 xout <<
" " << sm->get_id();
530 for (
Gate* g : m->get_gates())
531 xout <<
" " << g->get_id();
536 xout <<
" " << g->get_id();
539 for (GraphContext* ctx : mContextTreeModel->
list())
541 xout <<
"ctx " << ctx->id() <<
":";
542 for (
hal::Node nd : ctx->getLayouter()->positionToNodeMap().values())
544 xout <<
" " << (nd.type() ==
Node::Module ?
'm' :
'g') << nd.id();
556 if (context->modules().contains(m->
get_id()))
558 context->updateNets();
559 context->scheduleSceneUpdate();
566 if (context->gates().contains(g->
get_id()))
567 context->remove({}, {g->
get_id()});
573 if (context->gates().contains(g->
get_id()))
574 context->scheduleSceneUpdate();
588 if (context->nets().contains(n->
get_id()))
589 context->scheduleSceneUpdate();
595 if (context->nets().contains(n->
get_id()))
596 context->scheduleSceneUpdate();
603 if (context->nets().contains(n->
get_id()) || context->gates().contains(src_gate_id))
606 context->applyChanges();
607 context->scheduleSceneUpdate();
618 if (context->nets().contains(n->
get_id()))
621 context->applyChanges();
622 context->scheduleSceneUpdate();
631 if (context->nets().contains(n->
get_id()) || context->gates().contains(dst_gate_id))
634 context->applyChanges();
635 context->scheduleSceneUpdate();
646 if (context->nets().contains(n->
get_id()))
649 context->applyChanges();
650 context->scheduleSceneUpdate();
659 if (context->nets().contains(mNetId) || context->isShowingNetDestination(mNetId))
661 context->applyChanges();
662 context->scheduleSceneUpdate();
671 if (context->nets().contains(mNetId) || context->isShowingNetSource(mNetId))
673 context->applyChanges();
674 context->scheduleSceneUpdate();
682 if (context->nets().contains(mNetId))
684 context->applyChanges();
685 context->scheduleSceneUpdate();
692 if (context->nets().contains(mNetId))
694 context->applyChanges();
695 context->scheduleSceneUpdate();
720 return mContextTreeModel;
728 mContextTreeModel->
clear();
733 QFile jsFile(filename);
741 if (json.
contains(
"directories") && json[
"directories"].isArray())
743 QJsonArray jsonDirectories = json[
"directories"].toArray();
744 int ndir = jsonDirectories.
size();
745 for (
int idir = 0; idir < ndir; idir++)
748 if (!jsondir.
contains(
"id") || !jsondir[
"id"].isDouble())
750 u32 dirId = jsondir[
"id"].toInt();
751 if (!jsondir.
contains(
"name") || !jsondir[
"name"].isString())
753 QString dirName = jsondir[
"name"].toString();
756 u32 dirParentId = jsondir[
"parentId"].toInt();
760 if (dirParentId != 0)
761 dirParent = mContextTreeModel->
getDirectory(dirParentId);
763 if (dirId < 0 || dirId > 0x7FFFFFFF)
764 dirId = ++mMaxContextId;
766 mContextTreeModel->
addDirectory(dirName, dirParent, dirId);
769 if (json.
contains(
"views") && json[
"views"].isArray())
771 QJsonArray jsonViews = json[
"views"].toArray();
772 int nviews = jsonViews.
size();
773 for (
int iview = 0; iview < nviews; iview++)
776 if (!jsonView.
contains(
"id") || !jsonView[
"id"].isDouble())
778 u32 viewId = jsonView[
"id"].toInt();
779 if (!jsonView.
contains(
"name") || !jsonView[
"name"].isString())
781 QString viewName = jsonView[
"name"].toString();
782 if (viewId > mMaxContextId)
783 mMaxContextId = viewId;
786 visibleFlag = jsonView[
"visible"].toInt();
788 u32 viewParentId = 0;
790 viewParentId = jsonView[
"parentId"].toInt();
794 if (viewParentId != 0) {
795 viewParent = mContextTreeModel->
getDirectory(viewParentId);
804 if (viewName != context->mName)
808 log_warning(
"gui",
"failed to set up existing context ID={} from view file {}.", context->
id(), filename.
toStdString());
829 mContextTreeModel->
addContext(context, viewParent);
834 if (jsonView.
contains(
"exclusiveModuleId"))
837 selectedContext = context;
839 selectedContext = context;
841 firstContext = context;
845 if (selectedContext)
return selectedContext;
851 QFile jsFile(filename);
865 context->writeToFile(jsonView, parentId);
866 jsonViews.
append(jsonView);
868 json[
"views"] = jsonViews;
874 directory->writeToFile(jsonDirectory);
875 jsonDirectories.
append(jsonDirectory);
877 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
static SettingsItemCheckbox * sSettingLayoutOnEveryChange
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