diff --git a/application.cpp b/application.cpp index 7a47e19..374163f 100644 --- a/application.cpp +++ b/application.cpp @@ -288,6 +288,30 @@ bool Application::removeComponent(std::string componentName) { return true; } +void Application::removeConnection(domain::ConnectionInstance *connectionInstance) { + if(auto directConnection = dynamic_cast(connectionInstance)) { + schema->busInstances.erase( + std::remove_if( + schema->busInstances.begin(), + schema->busInstances.end(), + [directConnection](const std::shared_ptr &bus) { + return directConnection->bus == bus.get(); + }), + schema->busInstances.end() + ); + } + schema->connections.erase( + std::remove_if( + schema->connections.begin(), + schema->connections.end(), + [connectionInstance](const std::shared_ptr &conn) { + return connectionInstance == conn.get(); + }), + schema->connections.end() + ); + +} + bool Application::removeBus(std::string busName) { auto bus = findBusByName(busName); if (bus == nullptr) { @@ -367,4 +391,4 @@ void Application::renameBus(std::string currentName, std::string newName) { if(bus) { bus->name = newName; } -} +} \ No newline at end of file diff --git a/application.h b/application.h index 1d0432e..838d592 100644 --- a/application.h +++ b/application.h @@ -52,6 +52,8 @@ public: void renameComponent(std::string currentName, std::string newName); void renameBus(std::string currentName, std::string newName); + + void removeConnection(domain::ConnectionInstance *pInstance); }; diff --git a/comdel/display/component_display.cpp b/comdel/display/component_display.cpp index 190dbc9..2ef59b0 100644 --- a/comdel/display/component_display.cpp +++ b/comdel/display/component_display.cpp @@ -16,6 +16,12 @@ namespace display { QPen connectionPen(QColor::fromRgb(150, 150, 250)); + Component::Component(const std::shared_ptr &instance): instance(instance) { + setFlag(ItemSendsGeometryChanges, true); + setToolTip(QString::fromStdString(instance->name + "::" + instance->component.getName())); + instance->component.getDisplay().render(this); + } + void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QMenu menu; menu.addAction("Izmjeni ime", [this]() { @@ -30,6 +36,7 @@ namespace display { auto newName = dialog->getName(); Application::instance()->renameComponent(currentName, newName); + setToolTip(QString::fromStdString(instance->name + "::" + instance->component.getName())); }); menu.addSeparator(); for (int i = 0; i < this->instance->attributes.size(); i++) { @@ -61,14 +68,57 @@ namespace display { menu.exec(event->screenPos()); } - Component::Component(const std::shared_ptr &instance): instance(instance) { - setFlag(ItemSendsGeometryChanges, true); - instance->component.getDisplay().render(this); - } - void Pin::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QMenu menu; - menu.addAction("Poveži pin", [&]() {}); + + auto pinConnections = Application::instance()->getSchema()->getConnections(componentInstance->name, pin.getName()); + + if(isSingleAutomatic(pinConnections)) { + auto *update = menu.addMenu("Izmjeni"); + auto *remove = menu.addMenu("Ukloni"); + for (auto pinConnection: pinConnections) { + // this always must be true as only directConnections can be connected multiple times + if (auto directConnection = dynamic_cast(pinConnection)) { + if (directConnection->bus->bus.getType() == domain::Bus::SINGLE_AUTOMATIC) { + auto connectionName = directConnection->attributes[0].value.stringify() + "-" + + directConnection->attributes[1].value.stringify(); + update->addAction(QString::fromStdString("Izmjeni " + connectionName), [directConnection]() { + auto dialog = new SingleAutomaticDialog(directConnection->attributes); + dialog->exec(); + }); + remove->addAction(QString::fromStdString("Ukloni " + connectionName), + [this, directConnection]() { + Application::instance()->removeConnection(directConnection); + auto view = dynamic_cast(this->scene()->views()[0]); + view->refreshContent(); + }); + } + } + } + } else { + auto pinConnection = pinConnections[0]; + if(auto busConnection = dynamic_cast(pinConnection)) { + menu.addSection(QString::fromStdString(busConnection->bus->name)); + } else if(auto directConnection = dynamic_cast(pinConnection)) { + if(directConnection->instance == componentInstance.get()) { + menu.addSection(QString::fromStdString(directConnection->secondInstance->name + "." + directConnection->connection.getSecondComponent()->pin)); + } else { + menu.addSection(QString::fromStdString(directConnection->instance->name + "." + directConnection->connection.getComponent().pin)); + } + } + for (int i = 0; i < pinConnection->attributes.size(); i++) { + auto *attr = &pinConnection->attributes[i]; + menu.addAction(QString::fromStdString("Izmjeni '" + attr->name + "'"),[attr]() { + auto dialog = new AttributeDialog(attr); + dialog->exec(); + }); + } + menu.addAction("Ukloni poveznicu", [this, pinConnection]() { + Application::instance()->removeConnection(pinConnection); + auto view = dynamic_cast(this->scene()->views()[0]); + view->refreshContent(); + }); + } menu.exec(event->screenPos()); } @@ -116,6 +166,23 @@ namespace display { return componentInstance.get(); } + bool Pin::isSingleAutomatic(std::vector pinConnections) { + if(pinConnections.empty()) { + return false; + } + auto pinConnection = pinConnections[0]; + if(auto directConnection = dynamic_cast(pinConnection)) { + return directConnection->bus->bus.getType() == domain::Bus::SINGLE_AUTOMATIC; + } else { + return false; + } + } + + Bus::Bus(const std::shared_ptr &instance): busInstance(instance) { + instance->bus.getDisplayBus()->render(this, instance->size); + setToolTip(QString::fromStdString(busInstance->name + "::" + busInstance->bus.getName())); + } + void Bus::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QMenu menu; menu.addAction("Izmjeni ime", [this]() { @@ -130,6 +197,7 @@ namespace display { auto newName = dialog->getName(); Application::instance()->renameBus(currentName, newName); + setToolTip(QString::fromStdString(busInstance->name + "::" + busInstance->bus.getName())); }); menu.addSeparator(); menu.addAction(QString::fromStdString("Ukloni " + this->busInstance->name), [this]() { @@ -140,14 +208,6 @@ namespace display { menu.exec(event->screenPos()); } - Bus::Bus(const std::shared_ptr &instance): busInstance(instance) { - instance->bus.getDisplayBus()->render(this, instance->size); - } - - domain::BusInstance *Bus::getBusInstance() { - { return busInstance.get(); } - } - QVariant BusGroup::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionChange && scene()) { // value is the new position. diff --git a/comdel/display/component_display.h b/comdel/display/component_display.h index 17a095c..fb92aed 100644 --- a/comdel/display/component_display.h +++ b/comdel/display/component_display.h @@ -17,9 +17,7 @@ namespace display { std::shared_ptr componentInstance; public: - Pin(domain::Pin pin, std::shared_ptr componentInstance) : pin(pin), - componentInstance(std::move( - componentInstance)) { + Pin(domain::Pin pin, std::shared_ptr componentInstance) : pin(pin), componentInstance(std::move(componentInstance)) { pin.getDisplayPin().render(this); this->setToolTip(QString::fromStdString(pin.getTooltip())); } @@ -35,6 +33,8 @@ namespace display { domain::Pin &getPin(); domain::ComponentInstance *getComponentInstance(); + + bool isSingleAutomatic(std::vector pinConnections); }; class Component : public QGraphicsItemGroup { @@ -52,8 +52,6 @@ namespace display { public: explicit Bus(const std::shared_ptr &instance); - domain::BusInstance *getBusInstance(); - void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; }; diff --git a/comdel/domain/schema.cpp b/comdel/domain/schema.cpp index 2bdf9a8..365ecb4 100644 --- a/comdel/domain/schema.cpp +++ b/comdel/domain/schema.cpp @@ -7,18 +7,28 @@ namespace domain { } ConnectionInstance *Schema::getConnection(string &component, string &pin) { + auto pinConnections = getConnections(component, pin); + if(pinConnections.empty()) { + return nullptr; + } else { + return pinConnections[0]; + } + } + + std::vector Schema::getConnections(string &component, string &pin) { + std::vector pinConnections; for (auto &conn: connections) { if (conn->instance->name == component && conn->connection.getComponent().pin == pin) { - return conn.get(); + pinConnections.push_back(conn.get()); } auto dirConn = dynamic_cast(conn.get()); if (dirConn != nullptr) { if (dirConn->secondInstance->name == component && conn->connection.getSecondComponent()->pin == pin) { - return dirConn; + pinConnections.push_back(conn.get()); } } } - return nullptr; + return pinConnections; } BusInstance *Schema::getBusInstance(string &name) { diff --git a/comdel/domain/schema.h b/comdel/domain/schema.h index ef2d9f3..91991e6 100644 --- a/comdel/domain/schema.h +++ b/comdel/domain/schema.h @@ -42,6 +42,8 @@ namespace domain { ConnectionInstance *getConnection(string &component, string &pin); std::vector availableConnections(std::string instance, std::string pin, bool onlyConnectable); + + vector getConnections(string &component, string &pin); }; } // namespace domain