Basic refactor

This commit is contained in:
Borna Rajković committed 2022-05-27 08:18:17 +02:00
1 parent aac972c6ca
commit 0c4afe87d9
89 files changed
+7106 -6768

No files matched your search

+236 -39
View File
@@ -7,55 +7,159 @@
namespace display {
void AttributeDialog::onUpdate() {
auto oldValue = attributeValue->value;
void AttributeDialog::onUpdate() {
auto oldValue = attributeValue->value;
attributeValue->value = value;
domain::ComdelValidator validator(domain::getSupportedValidators());
attributeValue->value = value;
domain::ComdelValidator validator(domain::getSupportedValidators());
domain::ValidationContext context;
domain::ValidationContext context;
for (auto &addressSpace: MainWindow::getLibrary()->getAddressSpaces()) {
context.addressSpaces.insert(std::make_pair(addressSpace.getName(), addressSpace));
}
auto validationErrors = validator.validateAttribute(attributeValue, context);
if(validationErrors.empty()) {
accept();
} else {
bool canAccept = true;
std::vector<domain::ValidationError> errors;
std::vector<domain::ValidationError> warnings;
for(auto& err: validationErrors) {
if(err.type == domain::Action::ERROR) {
errors.push_back(err);
} else {
warnings.push_back(err);
}
}
if(!errors.empty()) {
canAccept = false;
auto errorDialog = new ErrorDialog(errors);
errorDialog->exec();
for (auto &addressSpace: MainWindow::getLibrary()->getAddressSpaces()) {
context.addressSpaces.insert(std::make_pair(addressSpace.getName(), addressSpace));
}
for(auto& warning: warnings) {
auto warningDialog = new WarningDialog(warning);
int response = warningDialog->exec();
if(response == QDialog::Rejected) {
canAccept = false;
}
}
if(canAccept) {
auto validationErrors = validator.validateAttribute(attributeValue, context);
if (validationErrors.empty()) {
accept();
} else {
attributeValue->value = oldValue;
bool canAccept = true;
std::vector<domain::ValidationError> errors;
std::vector<domain::ValidationError> warnings;
for (auto &err: validationErrors) {
if (err.type == domain::Action::ERROR) {
errors.push_back(err);
} else {
warnings.push_back(err);
}
}
if (!errors.empty()) {
canAccept = false;
auto errorDialog = new ErrorDialog(errors);
errorDialog->exec();
}
for (auto &warning: warnings) {
auto warningDialog = new WarningDialog(warning);
int response = warningDialog->exec();
if (response == QDialog::Rejected) {
canAccept = false;
}
}
if (canAccept) {
accept();
} else {
attributeValue->value = oldValue;
}
}
}
AttributeDialog::AttributeDialog(domain::InstanceAttribute *attribute) {
setAttribute(Qt::WA_DeleteOnClose);
attributeValue = attribute;
this->setWindowTitle(QString::fromStdString("Izmjeni " + attribute->attribute.getName()));
auto layout = new QVBoxLayout(this);
this->setLayout(layout);
auto popup = *attribute->attribute.getPopup();
layout->addWidget(new QLabel(popup.getTitle().c_str()));
layout->addWidget(new QLabel(popup.getText().c_str()));
auto type = attribute->attribute.getDefault().getType();
value = attribute->value;
if (attribute->attribute.getPopup()->isEnumerated()) {
auto *combo = new QComboBox(this);
auto enumeration = attribute->attribute.getPopup()->getEnumeration();
for (auto entry: enumeration) {
combo->addItem(QString::fromStdString(entry.getName()));
}
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&AttributeDialog::onEnumerationChanged);
layout->addWidget(combo);
for (int i = 0; i < enumeration.size(); i++) {
if (attributeValue->value.equals(enumeration[i].getValue())) {
combo->setCurrentIndex(i);
break;
}
}
} else if (!(type == domain::Value::ValueType::WIRE_REFERENCE || type == domain::Value::ValueType::BOOL)) {
auto edit = new QLineEdit(this);
connect(edit, &QLineEdit::textChanged, this, &AttributeDialog::onTextChanged);
layout->addWidget(edit);
switch (attribute->attribute.getDefault().getType()) {
case domain::Value::ValueType::INT:
edit->setValidator(new QIntValidator(-10000000, 10000000, edit));
edit->insert(std::to_string(attribute->value.asInt()).c_str());
break;
case domain::Value::ValueType::STRING:
edit->insert(attribute->value.asString().c_str());
break;
default:
throw std::exception();
}
} else if (type == domain::Value::ValueType::BOOL) {
auto *group = new QGroupBox(this);
auto *radioLayout = new QHBoxLayout(group);
group->setLayout(radioLayout);
auto isTrue = new QRadioButton("true", group);
connect(isTrue, &QRadioButton::clicked, [this]() {
this->value = domain::Value::fromBool(true);
});
auto isFalse = new QRadioButton("false", group);
connect(isFalse, &QRadioButton::clicked, [this]() {
this->value = domain::Value::fromBool(false);
});
if (attribute->value.asBool()) {
isTrue->setChecked(true);
} else {
isFalse->setChecked(true);
}
radioLayout->addWidget(isTrue);
radioLayout->addWidget(isFalse);
layout->addWidget(group);
}
auto button = new QPushButton("Ažuriraj");
connect(button, &QPushButton::clicked, this, &AttributeDialog::onUpdate);
layout->addWidget(button);
}
void AttributeDialog::onTextChanged(const QString &string) {
switch (value.getType()) {
case domain::Value::STRING:
value.setString(string.toStdString());
break;
case domain::Value::INT:
value = domain::Value::fromInt(parseInt(string.toStdString()));
break;
default:
throw std::exception();
}
}
}
void AttributeDialog::onEnumerationChanged(int index) {
value = attributeValue->attribute.getPopup()->getEnumeration()[index].getValue();
}
void MemoryDialog::onUpdate() {
@@ -63,4 +167,97 @@ void AttributeDialog::onUpdate() {
accept();
}
MemoryDialog::MemoryDialog(domain::InstanceAttribute *attribute,
std::vector<std::shared_ptr<domain::ComponentInstance>> instances) {
memoryInstances = std::vector<std::string>();
setAttribute(Qt::WA_DeleteOnClose);
attributeValue = attribute;
this->setWindowTitle(QString::fromStdString("Izmjeni " + attribute->attribute.getName()));
for (auto &instance: instances) {
if (instance->component.getType() == domain::Component::MEMORY) {
memoryInstances.push_back(instance->name);
}
}
auto layout = new QVBoxLayout(this);
this->setLayout(layout);
auto popup = *attribute->attribute.getPopup();
layout->addWidget(new QLabel(popup.getTitle().c_str()));
layout->addWidget(new QLabel(popup.getText().c_str()));
value = attribute->value;
auto *combo = new QComboBox(this);
for (auto &entry: memoryInstances) {
combo->addItem(QString::fromStdString(entry));
}
combo->addItem("null");
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MemoryDialog::onMemoryChanged);
layout->addWidget(combo);
combo->setCurrentIndex(memoryInstances.size());
for (int i = 0; i < memoryInstances.size(); i++) {
if (attributeValue->value.asMemoryReference().has_value() &&
attributeValue->value.asMemoryReference() == memoryInstances[i]) {
combo->setCurrentIndex(i);
break;
}
}
auto button = new QPushButton("Ažuriraj");
connect(button, &QPushButton::clicked, this, &MemoryDialog::onUpdate);
layout->addWidget(button);
}
void MemoryDialog::onMemoryChanged(int index) {
if (index == memoryInstances.size()) {
value = domain::Value::fromMemoryReference(std::nullopt);
} else {
value = domain::Value::fromMemoryReference(memoryInstances[index]);
}
}
ErrorDialog::ErrorDialog(std::vector<domain::ValidationError> errors) {
setAttribute(Qt::WA_DeleteOnClose);
this->setWindowTitle("Greške");
auto layout = new QVBoxLayout(this);
this->setLayout(layout);
for (auto &err: errors) {
layout->addWidget(new QLabel(QString::fromStdString(err.message), this));
}
}
WarningDialog::WarningDialog(domain::ValidationError error) {
setAttribute(Qt::WA_DeleteOnClose);
this->setWindowTitle("Upozorenje");
auto layout = new QVBoxLayout(this);
this->setLayout(layout);
layout->addWidget(new QLabel(QString::fromStdString(error.message), this));
auto buttonLayout = new QHBoxLayout(this);
auto okButton = new QPushButton("U redu", this);
auto cancelButton = new QPushButton("Odustani", this);
connect(okButton, &QPushButton::clicked, [this]() { accept(); });
connect(cancelButton, &QPushButton::clicked, [this]() { reject(); });
buttonLayout->addWidget(okButton);
buttonLayout->addWidget(cancelButton);
layout->addItem(buttonLayout);
}
}
+42 -221
View File
@@ -11,257 +11,78 @@
#include <QLabel>
#include <QVBoxLayout>
#include <utility>
#include <comdel/domain/instanceattribute.h>
#include <comdel/domain/instance_attribute.h>
#include <comdel/domain/value.h>
#include "comdel/domain/comdelvalidator.h"
#include "comdel/domain/comdel_validator.h"
namespace display {
class AttributeDialog: public QDialog {
domain::Value value;
long long int parseInt(std::string expression) {
try {
if (expression.size() > 2) {
if (expression.substr(0, 2) == "0x") {
return std::stoll(expression, 0, 16);
} else if (expression.substr(0, 2) == "0b") {
return std::stoll(expression, 0, 2);
} else {
return std::stoll(expression, 0, 10);
}
} else {
return std::stoll(expression, 0, 10);
}
} catch (std::exception &e) {
return 0;
}
}
domain::InstanceAttribute* attributeValue;
public:
AttributeDialog(domain::InstanceAttribute *attribute) {
setAttribute(Qt::WA_DeleteOnClose);
attributeValue = attribute;
this->setWindowTitle(QString::fromStdString("Izmjeni " + attribute->attribute.getName()));
auto layout = new QVBoxLayout(this);
this->setLayout(layout);
auto popup = *attribute->attribute.getPopup();
layout->addWidget(new QLabel(popup.getTitle().c_str()));
layout->addWidget(new QLabel(popup.getText().c_str()));
auto type = attribute->attribute.getDefault().getType();
value = attribute->value;
if(attribute->attribute.getPopup()->isEnumerated()) {
auto* combo = new QComboBox(this);
auto enumeration = attribute->attribute.getPopup()->getEnumeration();
for(auto entry: enumeration) {
combo->addItem(QString::fromStdString(entry.getName()));
}
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AttributeDialog::onEnumerationChanged);
layout->addWidget(combo);
for(int i=0; i<enumeration.size(); i++) {
if(attributeValue->value.equals(enumeration[i].getValue())) {
combo->setCurrentIndex(i);
break;
}
}
} else if(!(type == domain::Value::ValueType::WIRE_REFERENCE || type == domain::Value::ValueType::BOOL)) {
auto edit = new QLineEdit(this);
connect(edit, &QLineEdit::textChanged, this, &AttributeDialog::onTextChanged);
layout->addWidget(edit);
switch (attribute->attribute.getDefault().getType()) {
case domain::Value::ValueType::INT:
edit->setValidator(new QIntValidator(-10000000, 10000000, edit));
edit->insert(std::to_string(attribute->value.asInt()).c_str());
break;
case domain::Value::ValueType::STRING:
edit->insert(attribute->value.asString().c_str());
break;
}
} else if(type == domain::Value::ValueType::BOOL) {
auto *group = new QGroupBox(this);
auto *radioLayout = new QHBoxLayout(group);
group->setLayout(radioLayout);
auto isTrue = new QRadioButton("true", group);
connect(isTrue, &QRadioButton::clicked, [this]() {
this->value = domain::Value::fromBool(true);
});
auto isFalse = new QRadioButton("false", group);
connect(isFalse, &QRadioButton::clicked, [this]() {
this->value = domain::Value::fromBool(false);
});
if(attribute->value.asBool()) {
isTrue->setChecked(true);
} else {
isFalse->setChecked(true);
}
radioLayout->addWidget(isTrue);
radioLayout->addWidget(isFalse);
layout->addWidget(group);
}
auto button = new QPushButton("Ažuriraj");
connect(button, &QPushButton::clicked, this, &AttributeDialog::onUpdate);
layout->addWidget(button);
}
public slots:
void onTextChanged(const QString& string) {
switch (value.getType()) {
case domain::Value::STRING:
value.setString(string.toStdString());
break;
case domain::Value::INT:
value = domain::Value::fromInt(parseInt(string.toStdString()));
}
};
void onEnumerationChanged(int index) {
value = attributeValue->attribute.getPopup()->getEnumeration()[index].getValue();
}
void onUpdate();
};
class MemoryDialog: public QDialog {
class AttributeDialog : public QDialog {
domain::Value value;
domain::InstanceAttribute* attributeValue;
std::vector<std::string> memoryInstances;
long long int parseInt(std::string expression) {
try {
if (expression.size() > 2) {
if (expression.substr(0, 2) == "0x") {
return std::stoll(expression, nullptr, 16);
} else if (expression.substr(0, 2) == "0b") {
return std::stoll(expression, nullptr, 2);
} else {
return std::stoll(expression, nullptr, 10);
}
} else {
return std::stoll(expression, nullptr, 10);
}
} catch (std::exception &e) {
return 0;
}
}
domain::InstanceAttribute *attributeValue;
public:
MemoryDialog(domain::InstanceAttribute *attribute, std::vector<std::shared_ptr<domain::ComponentInstance>> instances) {
memoryInstances = std::vector<std::string>();
setAttribute(Qt::WA_DeleteOnClose);
attributeValue = attribute;
this->setWindowTitle(QString::fromStdString("Izmjeni " + attribute->attribute.getName()));
for(auto& instance: instances) {
if(instance->component.getType() == domain::Component::MEMORY) {
memoryInstances.push_back(instance->name);
}
}
auto layout = new QVBoxLayout(this);
this->setLayout(layout);
auto popup = *attribute->attribute.getPopup();
layout->addWidget(new QLabel(popup.getTitle().c_str()));
layout->addWidget(new QLabel(popup.getText().c_str()));
value = attribute->value;
auto* combo = new QComboBox(this);
for(auto& entry: memoryInstances) {
combo->addItem(QString::fromStdString(entry));
}
combo->addItem("null");
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MemoryDialog::onMemoryChanged);
layout->addWidget(combo);
combo->setCurrentIndex(memoryInstances.size());
for(int i=0; i<memoryInstances.size(); i++) {
if(attributeValue->value.asMemoryReference().has_value() && attributeValue->value.asMemoryReference() == memoryInstances[i]) {
combo->setCurrentIndex(i);
break;
}
}
auto button = new QPushButton("Ažuriraj");
connect(button, &QPushButton::clicked, this, &MemoryDialog::onUpdate);
layout->addWidget(button);
}
AttributeDialog(domain::InstanceAttribute *attribute);
public slots:
void onMemoryChanged(int index) {
if(index == memoryInstances.size()) {
value = domain::Value::fromMemoryReference(std::nullopt);
} else {
value = domain::Value::fromMemoryReference(memoryInstances[index]);
}
}
void onTextChanged(const QString &string);
void onEnumerationChanged(int index);
void onUpdate();
};
class ErrorDialog: public QDialog {
class MemoryDialog : public QDialog {
domain::Value value;
domain::InstanceAttribute *attributeValue;
std::vector<std::string> memoryInstances;
public:
ErrorDialog(std::vector<domain::ValidationError> errors) {
MemoryDialog(domain::InstanceAttribute *attribute,
std::vector<std::shared_ptr<domain::ComponentInstance>> instances);
setAttribute(Qt::WA_DeleteOnClose);
public slots:
this->setWindowTitle("Greške");
void onMemoryChanged(int index);
auto layout = new QVBoxLayout(this);
this->setLayout(layout);
void onUpdate();
for(auto& err: errors) {
layout->addWidget(new QLabel(QString::fromStdString(err.message), this));
}
}
};
class WarningDialog: public QDialog {
class ErrorDialog : public QDialog {
public:
WarningDialog(domain::ValidationError error) {
setAttribute(Qt::WA_DeleteOnClose);
this->setWindowTitle("Upozorenje");
auto layout = new QVBoxLayout(this);
this->setLayout(layout);
layout->addWidget(new QLabel(QString::fromStdString(error.message), this));
auto buttonLayout = new QHBoxLayout(this);
auto okButton = new QPushButton("U redu", this);
auto cancelButton = new QPushButton("Odustani", this);
connect(okButton, &QPushButton::clicked, [this]() { accept(); });
connect(cancelButton, &QPushButton::clicked, [this]() { reject(); });
buttonLayout->addWidget(okButton);
buttonLayout->addWidget(cancelButton);
layout->addItem(buttonLayout);
}
ErrorDialog(std::vector<domain::ValidationError> errors);
};
class WarningDialog : public QDialog {
public:
WarningDialog(domain::ValidationError error);
};
}
+157 -61
View File
@@ -9,31 +9,37 @@
namespace display {
void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
QMenu menu;
menu.addAction("Izmjeni ime", [this](){
auto dialog = new NameDialog(this->instance.get());
dialog->exec();
});
menu.addSeparator();
for(int i=0; i<this->instance->attributes.size(); i++) {
auto* attr = &this->instance->attributes[i];
bool enabled = attr->attribute.getPopup().has_value();
auto action = menu.addAction(QString::fromStdString("Izmjeni " + attr->name),
[attr]() {
if(attr->value.getType() == domain::Value::MEMORY_REFERENCE) {
auto dialog = new MemoryDialog(attr, MainWindow::getSchema()->componentInstances);
dialog->exec();
} else {
auto dialog = new AttributeDialog(attr);
dialog->exec();
}
void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
QMenu menu;
menu.addAction("Izmjeni ime", [this]() {
auto dialog = new NameDialog(this->instance.get());
dialog->exec();
});
action->setEnabled(enabled);
menu.addSeparator();
for (int i = 0; i < this->instance->attributes.size(); i++) {
auto *attr = &this->instance->attributes[i];
bool enabled = attr->attribute.getPopup().has_value();
auto action = menu.addAction(QString::fromStdString("Izmjeni " + attr->name),
[attr]() {
if (attr->value.getType() == domain::Value::MEMORY_REFERENCE) {
auto dialog = new MemoryDialog(attr,
MainWindow::getSchema()->componentInstances);
dialog->exec();
} else {
auto dialog = new AttributeDialog(attr);
dialog->exec();
}
});
action->setEnabled(enabled);
}
menu.exec(event->screenPos());
}
Component::Component(const std::shared_ptr<domain::ComponentInstance> &instance): instance(instance) {
setFlag(ItemSendsGeometryChanges, true);
instance->component.getDisplay().render(this);
}
menu.exec(event->screenPos());
}
void Pin::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
QMenu menu;
@@ -42,11 +48,13 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
}
void Pin::mousePressEvent(QGraphicsSceneMouseEvent *event) {
if(event->button() == Qt::MouseButton::LeftButton) {
auto view = dynamic_cast<Schema*>(this->scene()->views()[0]);
if (event->button() == Qt::MouseButton::LeftButton) {
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
view->state = Schema::CREATING_CONNECTION;
view->context.pin = this;
view->context.startingPoint = dynamic_cast<ComponentGroup*>(this->parentItem())->pos() + QPointF(pin.getDisplayPin().getConnectionX(), pin.getDisplayPin().getConnectionY());
view->context.startingPoint = dynamic_cast<ComponentGroup *>(this->parentItem())->pos() +
QPointF(pin.getDisplayPin().getConnectionX(),
pin.getDisplayPin().getConnectionY());
view->context.line = new QGraphicsLineItem(QLineF(view->context.startingPoint, event->scenePos()));
this->scene()->addItem(view->context.line);
@@ -55,8 +63,8 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
}
void Pin::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
auto view = dynamic_cast<Schema*>(this->scene()->views()[0]);
if(view->state == Schema::CREATING_CONNECTION) {
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
if (view->state == Schema::CREATING_CONNECTION) {
auto line = view->context.line->line();
line.setP2(event->scenePos());
view->context.line->setLine(line);
@@ -64,8 +72,8 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
}
void Pin::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
if(event->button() == Qt::MouseButton::LeftButton) {
auto view = dynamic_cast<Schema*>(this->scene()->views()[0]);
if (event->button() == Qt::MouseButton::LeftButton) {
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
view->state = Schema::DEFAULT;
this->scene()->removeItem(view->context.line);
delete view->context.line;
@@ -73,14 +81,30 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
}
}
domain::Pin &Pin::getPin() {
return pin;
}
domain::ComponentInstance *Pin::getComponentInstance() {
return componentInstance.get();
}
void Bus::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
QMenu menu;
menu.addAction("Izmjeni ime", [this](){
auto dialog = new NameDialog(this->busInstance.get());
dialog->exec();
});
menu.exec(event->screenPos());
}
QMenu menu;
menu.addAction("Izmjeni ime", [this]() {
auto dialog = new NameDialog(this->busInstance.get());
dialog->exec();
});
menu.exec(event->screenPos());
}
Bus::Bus(const std::shared_ptr<domain::BusInstance> &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()) {
@@ -89,13 +113,13 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
busInstance->position.first = newPos.x();
busInstance->position.second = newPos.y();
auto view = dynamic_cast<Schema*>(scene()->views()[0]);
auto view = dynamic_cast<Schema *>(scene()->views()[0]);
view->updateConnections();
}
return QGraphicsItem::itemChange(change, value);
}
BusGroup::BusGroup(const std::shared_ptr<domain::BusInstance> &instance): busInstance(instance) {
BusGroup::BusGroup(const std::shared_ptr<domain::BusInstance> &instance) : busInstance(instance) {
setFlag(ItemIsMovable, true);
setFlag(ItemSendsGeometryChanges, true);
@@ -105,7 +129,7 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
addToGroup(bus);
setPos(instance->position.first, instance->position.second);
}
}
QVariant ComponentGroup::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) {
@@ -115,36 +139,43 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
componentInstance->position.first = newPos.x();
componentInstance->position.second = newPos.y();
auto view = dynamic_cast<Schema*>(scene()->views()[0]);
auto view = dynamic_cast<Schema *>(scene()->views()[0]);
view->updateConnections();
}
return QGraphicsItem::itemChange(change, value);
}
void BusConnection::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
QMenu menu;
menu.addAction("Ukloni poveznicu", [this](){});
menu.addSeparator();
for(int i=0; i<this->connection->attributes.size(); i++) {
auto* attr = &this->connection->attributes[i];
bool enabled = attr->attribute.getPopup().has_value();
auto action = menu.addAction(QString::fromStdString("Izmjeni " + attr->name),
[attr]() {
auto dialog = new AttributeDialog(attr);
dialog->exec();
});
action->setEnabled(enabled);
}
menu.exec(event->screenPos());
std::shared_ptr<domain::ComponentInstance> ComponentGroup::getComponentInstance() {
return componentInstance;
}
void DirectConnection::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
std::vector<display::Pin *> &ComponentGroup::getPins() {
return pins;
}
ComponentGroup::ComponentGroup(const std::shared_ptr<domain::ComponentInstance> &instance): componentInstance(
instance) {
setFlag(ItemIsMovable, true);
setFlag(ItemSendsGeometryChanges, true);
setHandlesChildEvents(false);
addToGroup(new display::Component(instance));
for (auto &pin: instance->component.getPins()) {
pins.push_back(new display::Pin(pin, componentInstance));
addToGroup(pins.back());
}
setPos(instance->position.first, instance->position.second);
}
void BusConnection::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
QMenu menu;
menu.addAction("Ukloni poveznicu", [this](){});
menu.addAction("Ukloni poveznicu", [this]() {});
menu.addSeparator();
for(int i=0; i<this->connection->attributes.size(); i++) {
auto* attr = &this->connection->attributes[i];
for (int i = 0; i < this->connection->attributes.size(); i++) {
auto *attr = &this->connection->attributes[i];
bool enabled = attr->attribute.getPopup().has_value();
auto action = menu.addAction(QString::fromStdString("Izmjeni " + attr->name),
@@ -157,4 +188,69 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
menu.exec(event->screenPos());
}
BusConnection::BusConnection(domain::BusConnectionInstance *connection, ComponentGroup *component, BusGroup *bus): connection(
connection), component(component), bus(bus) {
updateConnection();
setHandlesChildEvents(false);
}
void BusConnection::updateConnection() {
auto busPosition = bus->boundingRect();
auto pin = connection->instance->component.getPin(
connection->connection.getComponent().pin).getDisplayPin();
setLine(connection->instance->position.first + pin.getConnectionX(),
connection->instance->position.second + pin.getConnectionY(),
connection->bus->position.first + busPosition.width() / 2,
connection->bus->position.second + busPosition.height() / 2);
connection->start.first = connection->instance->position.first + pin.getConnectionX();
connection->start.second = connection->instance->position.second + pin.getConnectionY();
connection->end.first = connection->bus->position.first + busPosition.width() / 2;
connection->end.second = connection->bus->position.second + busPosition.height() / 2;
}
void DirectConnection::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
QMenu menu;
menu.addAction("Ukloni poveznicu", [this]() {});
menu.addSeparator();
for (int i = 0; i < this->connection->attributes.size(); i++) {
auto *attr = &this->connection->attributes[i];
bool enabled = attr->attribute.getPopup().has_value();
auto action = menu.addAction(QString::fromStdString("Izmjeni " + attr->name),
[attr]() {
auto dialog = new AttributeDialog(attr);
dialog->exec();
});
action->setEnabled(enabled);
}
menu.exec(event->screenPos());
}
DirectConnection::DirectConnection(domain::DirectConnectionInstance *connection, ComponentGroup *first,
ComponentGroup *second): connection(connection), first(first), second(second) {
updateConnection();
setHandlesChildEvents(false);
}
void DirectConnection::updateConnection() {
auto pin1 = connection->instance->component.getPin(
connection->connection.getComponent().pin).getDisplayPin();
auto pin2 = connection->secondInstance->component.getPin(
connection->connection.getSecondComponent()->pin).getDisplayPin();
setLine(connection->instance->position.first + pin1.getConnectionX(),
connection->instance->position.second + pin1.getConnectionY(),
connection->secondInstance->position.first + pin2.getConnectionX(),
connection->secondInstance->position.second + pin2.getConnectionY());
connection->start.first = connection->instance->position.first + pin1.getConnectionX();
connection->start.second = connection->instance->position.second + pin1.getConnectionY();
connection->end.first = connection->secondInstance->position.first + pin2.getConnectionX();
connection->end.second = connection->secondInstance->position.second + pin2.getConnectionY();
}
} // namespace display
+95 -148
View File
@@ -2,169 +2,116 @@
#define DISPLAY_COMPONENT_H
#include <comdel/domain/instance.h>
#include <comdel/domain/wireinstance.h>
#include <QGraphicsItemGroup>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsSceneMouseEvent>
#include "comdel/domain/connectioninstance.h"
#include <utility>
#include "comdel/domain/connection_instance.h"
namespace display {
class Pin: public QGraphicsItemGroup
{
private:
domain::Pin pin;
std::shared_ptr<domain::ComponentInstance> componentInstance;
public:
Pin(domain::Pin pin, std::shared_ptr<domain::ComponentInstance> componentInstance): pin(pin), componentInstance(componentInstance) {
pin.getDisplayPin().render(this);
}
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
domain::Pin& getPin() {
return pin;
}
domain::ComponentInstance* getComponentInstance() {
return componentInstance.get();
}
};
class Component: public QGraphicsItemGroup
{
private:
std::shared_ptr<domain::ComponentInstance> instance;
public:
Component(const std::shared_ptr<domain::ComponentInstance>& instance): instance(instance) {
setFlag(ItemSendsGeometryChanges, true);
instance->component.getDisplay().render(this);
}
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
};
class Bus: public QGraphicsItemGroup
{
std::shared_ptr<domain::BusInstance> busInstance;
public:
Bus(const std::shared_ptr<domain::BusInstance>& instance): busInstance(instance) {
instance->bus.getDisplayBus()->render(this, instance->size);
}
domain::BusInstance *getBusInstance() { return busInstance.get(); }
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
};
class ComponentGroup: public QGraphicsItemGroup
{
private:
std::shared_ptr<domain::ComponentInstance> componentInstance;
std::vector<display::Pin*> pins;
public:
std::shared_ptr<domain::ComponentInstance> getComponentInstance() { return componentInstance; }
std::vector<display::Pin*>& getPins() { return pins; }
explicit ComponentGroup(const std::shared_ptr<domain::ComponentInstance>& instance): componentInstance(instance) {
setFlag(ItemIsMovable, true);
setFlag(ItemSendsGeometryChanges, true);
setHandlesChildEvents(false);
addToGroup(new display::Component(instance));
for(auto &pin: instance->component.getPins()) {
pins.push_back(new display::Pin(pin, componentInstance));
addToGroup(pins.back());
}
setPos(instance->position.first, instance->position.second);
}
protected:
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
};
class BusGroup: public QGraphicsItemGroup
{
private:
std::shared_ptr<domain::BusInstance> busInstance;
display::Bus* bus;
public:
explicit BusGroup(const std::shared_ptr<domain::BusInstance>& instance);
display::Bus* getBus() { return bus; }
protected:
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
};
class BusConnection: public QGraphicsLineItem
{
private:
domain::BusConnectionInstance* connection;
ComponentGroup* component;
BusGroup* bus;
public:
BusConnection(domain::BusConnectionInstance* connection, ComponentGroup *component, BusGroup *bus): connection(connection), component(component), bus(bus) {
updateConnection();
setHandlesChildEvents(false);
}
void updateConnection() {
auto busPosition = bus->boundingRect();
auto pin = connection->instance->component.getPin(connection->connection.getComponent().pin).getDisplayPin();
setLine(connection->instance->position.first + pin.getConnectionX(), connection->instance->position.second + pin.getConnectionY(), connection->bus->position.first + busPosition.width()/2, connection->bus->position.second + busPosition.height()/2);
connection->start.first = connection->instance->position.first + pin.getConnectionX();
connection->start.second = connection->instance->position.second + pin.getConnectionY();
connection->end.first = connection->bus->position.first + busPosition.width()/2;
connection->end.second = connection->bus->position.second + busPosition.height()/2;
}
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
};
class DirectConnection: public QGraphicsLineItem
{
class Pin : public QGraphicsItemGroup {
private:
domain::DirectConnectionInstance* connection;
ComponentGroup* first;
ComponentGroup* second;
domain::Pin pin;
std::shared_ptr<domain::ComponentInstance> componentInstance;
public:
DirectConnection(domain::DirectConnectionInstance* connection, ComponentGroup *first, ComponentGroup *second): connection(connection), first(first), second(second) {
updateConnection();
setHandlesChildEvents(false);
Pin(domain::Pin pin, std::shared_ptr<domain::ComponentInstance> componentInstance) : pin(pin),
componentInstance(std::move(
componentInstance)) {
pin.getDisplayPin().render(this);
this->setToolTip(QString::fromStdString(pin.getTooltip()));
}
void updateConnection() {
auto pin1 = connection->instance->component.getPin(connection->connection.getComponent().pin).getDisplayPin();
auto pin2 = connection->secondInstance->component.getPin(connection->connection.getSecondComponent()->pin).getDisplayPin();
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
setLine(connection->instance->position.first + pin1.getConnectionX(), connection->instance->position.second + pin1.getConnectionY(),
connection->secondInstance->position.first + pin2.getConnectionX(), connection->secondInstance->position.second + pin2.getConnectionY());
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
connection->start.first = connection->instance->position.first + pin1.getConnectionX();
connection->start.second = connection->instance->position.second + pin1.getConnectionY();
connection->end.first = connection->secondInstance->position.first + pin2.getConnectionX();
connection->end.second = connection->secondInstance->position.second + pin2.getConnectionY();
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
}
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
domain::Pin &getPin();
domain::ComponentInstance *getComponentInstance();
};
class Component : public QGraphicsItemGroup {
private:
std::shared_ptr<domain::ComponentInstance> instance;
public:
explicit Component(const std::shared_ptr<domain::ComponentInstance> &instance);
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
};
class Bus : public QGraphicsItemGroup {
std::shared_ptr<domain::BusInstance> busInstance;
public:
explicit Bus(const std::shared_ptr<domain::BusInstance> &instance);
domain::BusInstance *getBusInstance();
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
};
class ComponentGroup : public QGraphicsItemGroup {
private:
std::shared_ptr<domain::ComponentInstance> componentInstance;
std::vector<display::Pin *> pins;
public:
std::shared_ptr<domain::ComponentInstance> getComponentInstance();
std::vector<display::Pin *> &getPins();
explicit ComponentGroup(const std::shared_ptr<domain::ComponentInstance> &instance);
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
};
class BusGroup : public QGraphicsItemGroup {
private:
std::shared_ptr<domain::BusInstance> busInstance;
display::Bus *bus;
public:
explicit BusGroup(const std::shared_ptr<domain::BusInstance> &instance);
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
};
class BusConnection : public QGraphicsLineItem {
private:
domain::BusConnectionInstance *connection;
ComponentGroup *component;
BusGroup *bus;
public:
BusConnection(domain::BusConnectionInstance *connection, ComponentGroup *component, BusGroup *bus);
void updateConnection();
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
};
class DirectConnection : public QGraphicsLineItem {
private:
domain::DirectConnectionInstance *connection;
ComponentGroup *first;
ComponentGroup *second;
public:
DirectConnection(domain::DirectConnectionInstance *connection, ComponentGroup *first, ComponentGroup *second);
void updateConnection();
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
};
+34 -34
View File
@@ -6,47 +6,47 @@
namespace display {
Library::Library()
{
auto layout = new QVBoxLayout();
this->setLayout(layout);
Library::Library() {
auto layout = new QVBoxLayout();
this->setLayout(layout);
componentList = new LibraryList(this);
busList = new LibraryList(this);
componentList = new LibraryList(this);
busList = new LibraryList(this);
layout->setMargin(4);
layout->addWidget(new QLabel("Components:"));
layout->addWidget(componentList, 1);
layout->addSpacing(8);
layout->addWidget(new QLabel("Buses:"));
layout->addWidget(busList, 1);
layout->setMargin(4);
layout->addWidget(new QLabel("Components:"));
layout->addWidget(componentList, 1);
layout->addSpacing(8);
layout->addWidget(new QLabel("Buses:"));
layout->addWidget(busList, 1);
setLibrary(library);
}
void Library::setLibrary(std::optional<domain::Library> library) {
componentList->clear();
busList->clear();
if(!library) {
return;
setLibrary(library);
}
for(auto& component: library->getComponents()) {
auto item = new LibraryListItem{component.getName(), "comdel/component", component.getName(), componentList};
item->setToolTip(QString::fromStdString(component.getTooltip()));
componentList->addItem(item);
}
void Library::setLibrary(std::optional<domain::Library> library) {
for(auto& bus: library->getBuses()) {
if(bus.getType() == domain::Bus::REGULAR) {
auto item = new LibraryListItem{bus.getName(), "comdel/bus", bus.getName(), busList};
item->setToolTip(QString::fromStdString(bus.getTooltip()));
busList->addItem(item);
componentList->clear();
busList->clear();
if (!library) {
return;
}
}
}
for (auto &component: library->getComponents()) {
auto item = new LibraryListItem{component.getName(), "comdel/component", component.getName(),
componentList};
item->setToolTip(QString::fromStdString(component.getTooltip()));
componentList->addItem(item);
}
for (auto &bus: library->getBuses()) {
if (bus.getType() == domain::Bus::REGULAR) {
auto item = new LibraryListItem{bus.getName(), "comdel/bus", bus.getName(), busList};
item->setToolTip(QString::fromStdString(bus.getTooltip()));
busList->addItem(item);
}
}
}
} // namespace display
+9 -10
View File
@@ -9,20 +9,19 @@
namespace display {
class Library: public QWidget
{
public:
Library();
class Library : public QWidget {
public:
Library();
void setLibrary(std::optional<domain::Library> library);
void setLibrary(std::optional<domain::Library> library);
private:
std::optional<domain::Library> library;
private:
std::optional<domain::Library> library;
LibraryList *componentList;
LibraryList *busList;
LibraryList *componentList;
LibraryList *busList;
};
};
} // namespace display
+6 -5
View File
@@ -10,22 +10,23 @@
namespace display {
LibraryList::LibraryList(QWidget *parent): QListWidget(parent) {
LibraryList::LibraryList(QWidget *parent) : QListWidget(parent) {
setDragDropMode(DragOnly);
}
QMimeData *LibraryList::mimeData(const QList<QListWidgetItem *> items) const {
for(auto qItem: items) {
for (auto qItem: items) {
// we only allow one item to be dragged at a time
auto item = dynamic_cast<LibraryListItem*>(qItem);
auto* md = new QMimeData();
auto item = dynamic_cast<LibraryListItem *>(qItem);
auto *md = new QMimeData();
md->setData(QString::fromStdString(item->mimeType), QByteArray::fromStdString(item->value));
return md;
}
return nullptr;
}
LibraryListItem::LibraryListItem(std::string title, std::string mimeType, std::string value, QListWidget *parent): QListWidgetItem(parent), mimeType(mimeType), value(value) {
LibraryListItem::LibraryListItem(std::string title, std::string mimeType, std::string value, QListWidget *parent)
: QListWidgetItem(parent), mimeType(mimeType), value(value) {
setText(QString::fromStdString(title));
}
} // display
+4 -4
View File
@@ -11,16 +11,16 @@
namespace display {
class LibraryList: public QListWidget {
Q_OBJECT
class LibraryList : public QListWidget {
Q_OBJECT
public:
LibraryList(QWidget *parent);
protected:
QMimeData *mimeData(const QList<QListWidgetItem*> items) const override;
QMimeData *mimeData(const QList<QListWidgetItem *> items) const override;
};
class LibraryListItem: public QListWidgetItem {
class LibraryListItem : public QListWidgetItem {
public:
std::string mimeType;
+37
View File
@@ -3,3 +3,40 @@
//
#include "name_dialog.h"
display::NameDialog::NameDialog(domain::ComponentInstance *instance) : componentInstance(instance) {
auto *layout = new QVBoxLayout(this);
layout->addWidget(new QLabel("Izmjeni ime", this));
edit = new QLineEdit(this);
edit->insert(instance->name.c_str());
layout->addWidget(edit);
this->setWindowTitle("Izmjeni ime");
auto *button = new QPushButton("Ažuriraj", this);
connect(button, &QPushButton::clicked, this, &NameDialog::onNameChange);
layout->addWidget(button);
this->setLayout(layout);
}
display::NameDialog::NameDialog(domain::BusInstance *instance): busInstance(instance) {
auto *layout = new QVBoxLayout(this);
layout->addWidget(new QLabel("Izmjeni ime", this));
edit = new QLineEdit(this);
edit->insert(instance->name.c_str());
layout->addWidget(edit);
this->setWindowTitle("Izmjeni ime");
auto *button = new QPushButton("Ažuriraj", this);
connect(button, &QPushButton::clicked, this, &NameDialog::onNameChange);
layout->addWidget(button);
this->setLayout(layout);
}
void display::NameDialog::onNameChange() {
if (componentInstance != nullptr) {
componentInstance->name = this->edit->text().toStdString();
} else if (busInstance != nullptr) {
busInstance->name = this->edit->text().toStdString();
}
this->close();
}
+10 -40
View File
@@ -11,52 +11,22 @@
namespace display {
class NameDialog: public QDialog {
class NameDialog : public QDialog {
QLineEdit *edit = nullptr;
domain::ComponentInstance *componentInstance = nullptr;
domain::BusInstance *busInstance = nullptr;
QLineEdit *edit = nullptr;
domain::ComponentInstance *componentInstance = nullptr;
domain::BusInstance *busInstance = nullptr;
public:
public:
NameDialog(domain::ComponentInstance *instance): componentInstance(instance) {
auto *layout = new QVBoxLayout(this);
layout->addWidget(new QLabel("Izmjeni ime", this));
NameDialog(domain::ComponentInstance *instance);
edit = new QLineEdit(this);
edit->insert(instance->name.c_str());
layout->addWidget(edit);
this->setWindowTitle("Izmjeni ime");
auto *button = new QPushButton("Ažuriraj", this);
connect(button, &QPushButton::clicked, this, &NameDialog::onNameChange);
layout->addWidget(button);
this->setLayout(layout);
}
NameDialog(domain::BusInstance *instance);
NameDialog(domain::BusInstance *instance): busInstance(instance) {
auto *layout = new QVBoxLayout(this);
layout->addWidget(new QLabel("Izmjeni ime", this));
public slots:
edit = new QLineEdit(this);
edit->insert(instance->name.c_str());
layout->addWidget(edit);
this->setWindowTitle("Izmjeni ime");
auto *button = new QPushButton("Ažuriraj", this);
connect(button, &QPushButton::clicked, this, &NameDialog::onNameChange);
layout->addWidget(button);
this->setLayout(layout);
}
public slots:
void onNameChange() {
if(componentInstance != nullptr) {
componentInstance->name = this->edit->text().toStdString();
} else if(busInstance != nullptr) {
busInstance->name = this->edit->text().toStdString();
}
this->close();
}
};
void onNameChange();
};
}
+100 -87
View File
@@ -7,96 +7,98 @@
namespace display {
Schema::Schema()
{
this->selectedBrush.setColor(QColor::fromRgb(20,20,125));
this->selectedPen.setColor(QColor::fromRgb(20, 20, 125));
Schema::Schema() {
this->selectedBrush.setColor(QColor::fromRgb(20, 20, 125));
this->selectedPen.setColor(QColor::fromRgb(20, 20, 125));
this->setScene(&scene);
this->setAcceptDrops(true);
}
this->setScene(&scene);
this->setAcceptDrops(true);
}
void Schema::setSchema(domain::Schema* _schema, domain::Library* _library)
{
components.clear();
buses.clear();
void Schema::setSchema(domain::Schema *_schema, domain::Library *_library) {
components.clear();
buses.clear();
scene.clear();
busConnections.clear();
this->schema = _schema;
this->library = _library;
if(schema != nullptr) {
for(auto &instance: schema->componentInstances) {
auto group = new display::ComponentGroup(instance);
for(auto pin: group->getPins()) {
display::Pin* p = pin;
domain::ConnectionComponent connection{instance->name, p->getPin().getName()};
pins.insert(std::make_pair(connection, p));
}
components.insert(std::make_pair(instance->name, group));
scene.addItem(group);
}
for(auto &instance: schema->busInstances) {
if(instance->bus.getDisplayBus().has_value()) {
auto group = new display::BusGroup(instance);
buses.insert(std::make_pair(instance->name, group));
scene.clear();
busConnections.clear();
this->schema = _schema;
this->library = _library;
if (schema != nullptr) {
for (auto &instance: schema->componentInstances) {
auto group = new display::ComponentGroup(instance);
for (auto pin: group->getPins()) {
display::Pin *p = pin;
domain::ConnectionComponent connection{instance->name, p->getPin().getName()};
pins.insert(std::make_pair(connection, p));
}
components.insert(std::make_pair(instance->name, group));
scene.addItem(group);
}
}
for(auto &connection: schema->connections) {
auto busInstance = dynamic_cast<domain::BusConnectionInstance*>(connection.get());
if(busInstance != nullptr) {
auto con = new display::BusConnection(busInstance, components[busInstance->instance->name], buses[busInstance->bus->name]);
busConnections.push_back(con);
scene.addItem(con);
for (auto &instance: schema->busInstances) {
if (instance->bus.getDisplayBus().has_value()) {
auto group = new display::BusGroup(instance);
buses.insert(std::make_pair(instance->name, group));
scene.addItem(group);
}
}
auto directInstance = dynamic_cast<domain::DirectConnectionInstance*>(connection.get());
if(directInstance != nullptr) {
auto con = new display::DirectConnection(directInstance, components[directInstance->instance->name], components[directInstance->secondInstance->name]);
directConnections.push_back(con);
scene.addItem(con);
for (auto &connection: schema->connections) {
auto busInstance = dynamic_cast<domain::BusConnectionInstance *>(connection.get());
if (busInstance != nullptr) {
auto con = new display::BusConnection(busInstance, components[busInstance->instance->name],
buses[busInstance->bus->name]);
busConnections.push_back(con);
scene.addItem(con);
}
auto directInstance = dynamic_cast<domain::DirectConnectionInstance *>(connection.get());
if (directInstance != nullptr) {
auto con = new display::DirectConnection(directInstance, components[directInstance->instance->name],
components[directInstance->secondInstance->name]);
directConnections.push_back(con);
scene.addItem(con);
}
}
}
}
}
void Schema::updateConnections() {
if(schema != nullptr) {
for(auto conn: busConnections) {
conn->updateConnection();
}
for(auto conn: directConnections) {
conn->updateConnection();
void Schema::updateConnections() {
if (schema != nullptr) {
for (auto conn: busConnections) {
conn->updateConnection();
}
for (auto conn: directConnections) {
conn->updateConnection();
}
}
}
}
void Schema::dragEnterEvent(QDragEnterEvent *event) {
if(event->mimeData()->hasFormat("comdel/component") ||
event->mimeData()->hasFormat("comdel/bus")) {
if (event->mimeData()->hasFormat("comdel/component") ||
event->mimeData()->hasFormat("comdel/bus")) {
event->acceptProposedAction();
}
}
void Schema::dropEvent(QDropEvent *event) {
if(event->mimeData()->hasFormat("comdel/component")) {
if (event->mimeData()->hasFormat("comdel/component")) {
auto component = library->getComponent(event->mimeData()->data("comdel/component").toStdString());
auto attributes = std::vector<domain::InstanceAttribute>();
for(auto attr: component.getAttributes()) {
for (auto attr: component.getAttributes()) {
attributes.emplace_back(attr.getName(), attr.getDefault(), attr);
}
auto currentPos = this->mapToScene(event->pos());
auto instance = std::make_shared<domain::ComponentInstance>(component.getInstanceName(), attributes, std::make_pair(currentPos.x(), currentPos.y()), component);
auto instance = std::make_shared<domain::ComponentInstance>(component.getInstanceName(), attributes,
std::make_pair(currentPos.x(), currentPos.y()),
component);
schema->componentInstances.push_back(instance);
auto group = new display::ComponentGroup(instance);
scene.addItem(group);
for(auto pin: group->getPins()) {
display::Pin* p = pin;
for (auto pin: group->getPins()) {
display::Pin *p = pin;
domain::ConnectionComponent connection{instance->name, p->getPin().getName()};
pins.insert(std::make_pair(connection, p));
}
@@ -105,12 +107,13 @@ void Schema::updateConnections() {
event->acceptProposedAction();
}
if(event->mimeData()->hasFormat("comdel/bus")) {
if (event->mimeData()->hasFormat("comdel/bus")) {
auto bus = library->getBus(event->mimeData()->data("comdel/bus").toStdString());
auto currentPos = this->mapToScene(event->pos());
auto instance = std::make_shared<domain::BusInstance>(bus.getName(), std::make_pair(currentPos.x(), currentPos.y()), bus);
auto instance = std::make_shared<domain::BusInstance>(bus.getName(),
std::make_pair(currentPos.x(), currentPos.y()), bus);
schema->busInstances.push_back(instance);
auto group = new display::BusGroup(instance);
@@ -127,19 +130,19 @@ void Schema::updateConnections() {
void Schema::removeConnectable(QPointF endPoint) {
auto instance = context.pin->getComponentInstance();
auto& pin = context.pin->getPin();
auto &pin = context.pin->getPin();
auto busInstances = getAvailableConnectionBusses(instance, pin);
for(auto &bus: busInstances) {
for (auto &bus: busInstances) {
auto rect = buses[bus->name]->boundingRect();
rect = QRectF(buses[bus->name]->x(), buses[bus->name]->y(), rect.width(), rect.height());
if(rect.contains(endPoint)) {
if (rect.contains(endPoint)) {
auto con = library->getConnection({instance->component.getName(), pin.getName()}, bus->bus.getName());
if(con.has_value()) {
if (con.has_value()) {
std::vector<domain::InstanceAttribute> attributes;
for(auto attr: con->getAttributes()) {
for (auto attr: con->getAttributes()) {
attributes.emplace_back(attr.getName(), attr.getDefault(), attr);
}
@@ -148,7 +151,7 @@ void Schema::updateConnections() {
if (conInstance != nullptr) {
auto c = new display::BusConnection(conInstance.get(), components[conInstance->instance->name],
buses[conInstance->bus->name]);
buses[conInstance->bus->name]);
busConnections.push_back(c);
scene.addItem(c);
}
@@ -159,29 +162,35 @@ void Schema::updateConnections() {
auto pinInstances = getAvailableConnectionPins(instance, pin);
for(auto &pinInstance: pinInstances) {
for (auto &pinInstance: pinInstances) {
auto rect = pins[pinInstance]->boundingRect();
rect.setX(pins[pinInstance]->scenePos().x());
rect.setY(pins[pinInstance]->scenePos().y());
if(rect.contains(endPoint)) {
if (rect.contains(endPoint)) {
auto name = components[pinInstance.component]->getComponentInstance()->component.getName();
auto con = library->getConnection({instance->component.getName(), pin.getName()}, {name, pinInstance.pin});
if(con.has_value()) {
auto con = library->getConnection({instance->component.getName(), pin.getName()},
{name, pinInstance.pin});
if (con.has_value()) {
auto bus = library->getBus(con->getBus());
auto busInstance = std::make_shared<domain::BusInstance>(bus.getName(), bus);
schema->busInstances.push_back(busInstance);
std::vector<domain::InstanceAttribute> attributes;
for(auto attr: con->getAttributes()) {
for (auto attr: con->getAttributes()) {
attributes.emplace_back(attr.getName(), attr.getDefault(), attr);
}
auto conInstance = std::make_shared<domain::DirectConnectionInstance>(instance, components[pinInstance.component]->getComponentInstance().get(), attributes, busInstance.get(), *con);
auto conInstance = std::make_shared<domain::DirectConnectionInstance>(instance,
components[pinInstance.component]->getComponentInstance().get(),
attributes, busInstance.get(),
*con);
schema->connections.push_back(conInstance);
if (conInstance != nullptr) {
auto c = new display::DirectConnection(conInstance.get(), components[conInstance->instance->name], components[conInstance->secondInstance->name]);
auto c = new display::DirectConnection(conInstance.get(),
components[conInstance->instance->name],
components[conInstance->secondInstance->name]);
directConnections.push_back(c);
scene.addItem(c);
}
@@ -193,7 +202,7 @@ void Schema::updateConnections() {
updateConnections();
for(auto& item: this->context.selectable) {
for (auto &item: this->context.selectable) {
this->scene.removeItem(item);
delete item;
}
@@ -201,12 +210,12 @@ void Schema::updateConnections() {
}
void Schema::showConnectable(Pin *domainPin) {
auto& pin = domainPin->getPin();
auto &pin = domainPin->getPin();
auto busInstances = getAvailableConnectionBusses(domainPin->getComponentInstance(), domainPin->getPin());
for(auto bus: busInstances) {
auto& group = buses[bus->name];
for (auto bus: busInstances) {
auto &group = buses[bus->name];
auto rect = new QGraphicsRectItem(group->boundingRect());
rect->setPen(selectedPen);
rect->setPos(group->scenePos());
@@ -220,10 +229,11 @@ void Schema::updateConnections() {
scene.addItem(rect);
}
std::vector<domain::ConnectionComponent> pinInstances = getAvailableConnectionPins(domainPin->getComponentInstance(), domainPin->getPin());
std::vector<domain::ConnectionComponent> pinInstances = getAvailableConnectionPins(
domainPin->getComponentInstance(), domainPin->getPin());
for(auto& pinInstance: pinInstances) {
auto& instance = pins[pinInstance];
for (auto &pinInstance: pinInstances) {
auto &instance = pins[pinInstance];
auto rect = new QGraphicsRectItem(instance->boundingRect());
rect->setPen(selectedPen);
rect->setPos(instance->scenePos());
@@ -239,22 +249,25 @@ void Schema::updateConnections() {
}
std::vector<domain::BusInstance*> Schema::getAvailableConnectionBusses(domain::ComponentInstance *instance, domain::Pin &pin) {
std::vector<domain::BusInstance*> instances;
for(const auto& bus: schema->busInstances) {
if(library->hasConnection(domain::ConnectionComponent{instance->component.getName(), pin.getName()}, bus->bus.getName())) {
std::vector<domain::BusInstance *>
Schema::getAvailableConnectionBusses(domain::ComponentInstance *instance, domain::Pin &pin) {
std::vector<domain::BusInstance *> instances;
for (const auto &bus: schema->busInstances) {
if (library->hasConnection(domain::ConnectionComponent{instance->component.getName(), pin.getName()},
bus->bus.getName())) {
instances.push_back(bus.get());
}
}
return instances;
}
std::vector<domain::ConnectionComponent> Schema::getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin) {
std::vector<domain::ConnectionComponent>
Schema::getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin) {
std::vector<domain::ConnectionComponent> instances;
domain::ConnectionComponent source{instance->component.getName(), pin.getName()};
for(const auto& entry: pins) {
for (const auto &entry: pins) {
std::string name = components[entry.first.component]->getComponentInstance()->component.getName();
if(library->hasConnection(source, domain::ConnectionComponent{name, entry.first.pin})) {
if (library->hasConnection(source, domain::ConnectionComponent{name, entry.first.pin})) {
instances.push_back(entry.first);
}
}
+55 -52
View File
@@ -14,64 +14,67 @@ namespace display {
class BusConnection;
class Schema: public QGraphicsView
{
class Schema : public QGraphicsView {
Q_OBJECT
public:
public:
QBrush selectedBrush;
QPen selectedPen;
QBrush selectedBrush;
QPen selectedPen;
enum State {
DEFAULT,
CREATING_CONNECTION
enum State {
DEFAULT,
CREATING_CONNECTION
};
struct Context {
display::Pin *pin = nullptr;
QPointF startingPoint;
QGraphicsLineItem *line = nullptr;
std::vector<QGraphicsRectItem *> selectable;
};
std::map<std::string, display::ComponentGroup *> components;
std::map<std::string, display::BusGroup *> buses;
std::map<domain::ConnectionComponent, display::Pin *> pins;
State state = DEFAULT;
Context context;
Schema();
std::vector<BusConnection *> busConnections;
std::vector<DirectConnection *> directConnections;
void setSchema(domain::Schema *schema, domain::Library *library);
void updateConnections();
void removeConnectable(QPointF f);
void showConnectable(Pin *pin);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dropEvent(QDropEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
private:
QGraphicsScene scene;
domain::Schema *schema;
domain::Library *library;
std::vector<domain::BusInstance *>
getAvailableConnectionBusses(domain::ComponentInstance *instance, domain::Pin &pin);
std::vector<domain::ConnectionComponent>
getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin);
};
struct Context {
display::Pin *pin = nullptr;
QPointF startingPoint;
QGraphicsLineItem *line = nullptr;
std::vector<QGraphicsRectItem*> selectable;
};
std::map<std::string, display::ComponentGroup*> components;
std::map<std::string, display::BusGroup*> buses;
std::map<domain::ConnectionComponent, display::Pin*> pins;
State state = DEFAULT;
Context context;
Schema();
std::vector<BusConnection*> busConnections;
std::vector<DirectConnection*> directConnections;
void setSchema(domain::Schema* schema, domain::Library* library);
void updateConnections();
void removeConnectable(QPointF f);
void showConnectable(Pin *pin);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dropEvent(QDropEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
private:
QGraphicsScene scene;
domain::Schema* schema;
domain::Library* library;
std::vector<domain::BusInstance*> getAvailableConnectionBusses(domain::ComponentInstance *instance, domain::Pin &pin);
std::vector<domain::ConnectionComponent> getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin);
};
} // namespace display
#endif // DISPLAY_SCHEMA_H