изменено: CMakeLists.txt
новый файл: cmake/Info.plist.in новый файл: default.nix новый файл: desktop.nix новый файл: packaging/linux/idef0-editor.desktop новый файл: packaging/linux/idef0.xml новый файл: packaging/windows/idef0-file-association.reg.in изменено: src/MainWindow.cpp изменено: src/MainWindow.h изменено: src/items/ArrowItem.cpp изменено: src/items/ArrowItem.h изменено: src/items/BlockItem.cpp изменено: src/items/BlockItem.h изменено: src/items/DiagramScene.cpp изменено: src/items/DiagramScene.h новый файл: src/plugins/Manual.md новый файл: src/plugins/PluginApi.h новый файл: src/plugins/PluginManager.cpp новый файл: src/plugins/PluginManager.h новый файл: src/plugins/color/ColorsPlugin.cpp новый файл: src/plugins/color/ColorsPlugin.h новый файл: src/plugins/color/translations/colors_en.ts новый файл: src/plugins/color/translations/colors_fr.ts новый файл: src/plugins/color/translations/colors_ru.ts новый файл: translations/README.txt новый файл: translations/idef0_en.ts новый файл: translations/idef0_fr.ts новый файл: translations/idef0_ru.ts
This commit is contained in:
parent
f6f0598ff2
commit
630c952382
28 changed files with 2720 additions and 90 deletions
|
|
@ -12,6 +12,7 @@
|
|||
#include <QLineEdit>
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
#include <QCoreApplication>
|
||||
#include "DiagramScene.h"
|
||||
#include <algorithm>
|
||||
#include <QSet>
|
||||
|
|
@ -35,6 +36,8 @@ QColor ArrowItem::s_textColor = QColor(10, 10, 10);
|
|||
ArrowItem::ArrowItem(QGraphicsItem* parent)
|
||||
: QGraphicsPathItem(parent)
|
||||
{
|
||||
static int s_nextId = 1;
|
||||
m_internalId = s_nextId++;
|
||||
QPen pen(s_lineColor);
|
||||
pen.setWidthF(1.4);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
|
|
@ -101,6 +104,18 @@ void ArrowItem::setLabelSource(ArrowItem* src) {
|
|||
m_labelSource = src;
|
||||
}
|
||||
|
||||
void ArrowItem::setCustomColor(const QColor& color) {
|
||||
if (!color.isValid()) return;
|
||||
m_customColor = color;
|
||||
updatePath();
|
||||
}
|
||||
|
||||
void ArrowItem::clearCustomColor() {
|
||||
if (!m_customColor) return;
|
||||
m_customColor.reset();
|
||||
updatePath();
|
||||
}
|
||||
|
||||
ArrowItem* ArrowItem::labelSourceRoot() const {
|
||||
const ArrowItem* cur = this;
|
||||
QSet<const ArrowItem*> visited;
|
||||
|
|
@ -674,10 +689,13 @@ void ArrowItem::updateLabelItem(const QVector<QPointF>& pts) {
|
|||
// Обновляем маршрут ортогонально, добавляя/схлопывая сегменты при необходимости.
|
||||
void ArrowItem::updatePath() {
|
||||
QPen themedPen = pen();
|
||||
themedPen.setColor(s_lineColor);
|
||||
themedPen.setColor(m_customColor.value_or(s_lineColor));
|
||||
if (m_isCallMechanism) {
|
||||
themedPen.setStyle(Qt::DashLine);
|
||||
}
|
||||
setPen(themedPen);
|
||||
if (m_labelItem) {
|
||||
m_labelItem->setBrush(s_textColor);
|
||||
m_labelItem->setBrush(m_customColor.value_or(s_textColor));
|
||||
}
|
||||
|
||||
const QRectF oldSceneRect = mapRectToScene(boundingRect());
|
||||
|
|
@ -912,7 +930,13 @@ void ArrowItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* e) {
|
|||
void ArrowItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* e) {
|
||||
if (e->button() == Qt::LeftButton && !m_labelLocked) {
|
||||
bool ok = false;
|
||||
const QString text = QInputDialog::getText(nullptr, QObject::tr("Arrow label"), QObject::tr("Label:"), QLineEdit::Normal, m_label, &ok);
|
||||
const QString text = QInputDialog::getText(
|
||||
nullptr,
|
||||
QCoreApplication::translate("ArrowItem", "Arrow label"),
|
||||
QCoreApplication::translate("ArrowItem", "Label:"),
|
||||
QLineEdit::Normal,
|
||||
m_label,
|
||||
&ok);
|
||||
if (ok) {
|
||||
setLabel(text);
|
||||
setLabelHidden(false);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public:
|
|||
qreal topOffset() const { return m_topOffset; }
|
||||
qreal bottomOffset() const { return m_bottomOffset; }
|
||||
int type() const override { return Type; }
|
||||
int internalId() const { return m_internalId; }
|
||||
bool isInterface() const { return m_isInterface; }
|
||||
bool isInterfaceStub() const { return m_isInterface && m_interfaceStubOnly; }
|
||||
bool isLabelLocked() const { return m_labelLocked; }
|
||||
|
|
@ -58,6 +59,13 @@ public:
|
|||
void resetInterfaceStub();
|
||||
void setLabelLocked(bool locked);
|
||||
static void setVisualTheme(const QColor& lineColor, const QColor& textColor);
|
||||
void setCustomColor(const QColor& color);
|
||||
void clearCustomColor();
|
||||
std::optional<QColor> customColor() const { return m_customColor; }
|
||||
void setCallMechanism(bool v) { m_isCallMechanism = v; }
|
||||
bool isCallMechanism() const { return m_isCallMechanism; }
|
||||
void setCallRefId(int id) { m_callRefId = id; }
|
||||
int callRefId() const { return m_callRefId; }
|
||||
|
||||
void updatePath();
|
||||
std::optional<QPointF> hitTest(const QPointF& scenePos, qreal radius) const;
|
||||
|
|
@ -87,6 +95,10 @@ private:
|
|||
ArrowItem* m_labelSource = nullptr;
|
||||
static QColor s_lineColor;
|
||||
static QColor s_textColor;
|
||||
std::optional<QColor> m_customColor;
|
||||
int m_internalId = -1;
|
||||
bool m_isCallMechanism = false;
|
||||
int m_callRefId = -1;
|
||||
|
||||
DragPart m_dragPart = DragPart::None;
|
||||
QPointF m_lastDragScenePos;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ BlockItem::BlockItem(QString title, QGraphicsItem* parent, int id)
|
|||
m_rect(0, 0, 200, 100),
|
||||
m_id(id)
|
||||
{
|
||||
if (m_title.isEmpty()) {
|
||||
m_title = tr("Function");
|
||||
}
|
||||
setFlags(ItemIsMovable | ItemIsSelectable | ItemSendsGeometryChanges);
|
||||
}
|
||||
|
||||
|
|
@ -45,11 +48,15 @@ void BlockItem::paint(QPainter* p, const QStyleOptionGraphicsItem*, QWidget*) {
|
|||
|
||||
// фон
|
||||
p->setPen(Qt::NoPen);
|
||||
p->setBrush(isSelected() ? s_selectedBackgroundColor : s_backgroundColor);
|
||||
const QColor borderColor = m_customColor.value_or(s_borderColor);
|
||||
const QColor fontColor = m_customColor.value_or(s_fontColor);
|
||||
const QColor foregroundColor = m_customColor.value_or(s_foregroundColor);
|
||||
const QColor selectedBg = m_customColor ? m_customColor->lighter(160) : s_selectedBackgroundColor;
|
||||
p->setBrush(isSelected() ? selectedBg : s_backgroundColor);
|
||||
p->drawRoundedRect(m_rect, 6, 6);
|
||||
|
||||
// рамка
|
||||
QPen pen(s_borderColor);
|
||||
QPen pen(borderColor);
|
||||
pen.setWidthF(1.5);
|
||||
p->setPen(pen);
|
||||
p->setBrush(Qt::NoBrush);
|
||||
|
|
@ -65,22 +72,22 @@ void BlockItem::paint(QPainter* p, const QStyleOptionGraphicsItem*, QWidget*) {
|
|||
fold.closeSubpath();
|
||||
p->setBrush(s_backgroundColor.darker(108));
|
||||
p->drawPath(fold);
|
||||
p->setPen(QPen(s_borderColor.lighter(130), 1.0));
|
||||
p->setPen(QPen(borderColor.lighter(130), 1.0));
|
||||
p->drawLine(m_rect.topLeft() + QPointF(ear, 0), m_rect.topLeft() + QPointF(0, ear));
|
||||
}
|
||||
|
||||
// заголовок
|
||||
p->setPen(s_fontColor);
|
||||
p->setPen(fontColor);
|
||||
p->drawText(m_rect.adjusted(10, 8, -10, -8), Qt::AlignLeft | Qt::AlignTop, m_title);
|
||||
if (!m_number.isEmpty()) {
|
||||
QFont f = p->font();
|
||||
f.setBold(true);
|
||||
p->setFont(f);
|
||||
p->setPen(s_foregroundColor);
|
||||
p->setPen(foregroundColor);
|
||||
p->drawText(m_rect.adjusted(8, 4, -8, -8), Qt::AlignRight | Qt::AlignBottom, m_number);
|
||||
}
|
||||
if (m_price.has_value()) {
|
||||
p->setPen(s_foregroundColor);
|
||||
p->setPen(foregroundColor);
|
||||
p->drawText(m_rect.adjusted(8, 4, -8, -8), Qt::AlignLeft | Qt::AlignBottom, formattedPrice());
|
||||
}
|
||||
}
|
||||
|
|
@ -89,12 +96,14 @@ void BlockItem::setTitle(const QString& t) {
|
|||
if (t == m_title) return;
|
||||
m_title = t;
|
||||
update();
|
||||
emit titleChanged(m_title);
|
||||
}
|
||||
|
||||
void BlockItem::setNumber(const QString& n) {
|
||||
if (n == m_number) return;
|
||||
m_number = n;
|
||||
update();
|
||||
emit numberChanged(m_number);
|
||||
}
|
||||
|
||||
void BlockItem::setPrice(std::optional<qreal> price) {
|
||||
|
|
@ -103,6 +112,18 @@ void BlockItem::setPrice(std::optional<qreal> price) {
|
|||
update();
|
||||
}
|
||||
|
||||
void BlockItem::setCustomColor(const QColor& color) {
|
||||
if (!color.isValid()) return;
|
||||
m_customColor = color;
|
||||
update();
|
||||
}
|
||||
|
||||
void BlockItem::clearCustomColor() {
|
||||
if (!m_customColor) return;
|
||||
m_customColor.reset();
|
||||
update();
|
||||
}
|
||||
|
||||
void BlockItem::setCurrencyFormat(const QString& symbol, const QString& placement) {
|
||||
QString effectiveSymbol = symbol;
|
||||
if (effectiveSymbol.isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public:
|
|||
enum class Port { Input, Control, Output, Mechanism };
|
||||
enum { Type = UserType + 1 };
|
||||
|
||||
explicit BlockItem(QString title = "Function", QGraphicsItem* parent = nullptr, int id = -1);
|
||||
explicit BlockItem(QString title = QString(), QGraphicsItem* parent = nullptr, int id = -1);
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
void paint(QPainter* p, const QStyleOptionGraphicsItem*, QWidget*) override;
|
||||
|
|
@ -43,9 +43,14 @@ public:
|
|||
const QColor& border,
|
||||
const QColor& font,
|
||||
const QColor& selectedBackground);
|
||||
void setCustomColor(const QColor& color);
|
||||
void clearCustomColor();
|
||||
std::optional<QColor> customColor() const { return m_customColor; }
|
||||
|
||||
signals:
|
||||
void geometryChanged();
|
||||
void titleChanged(const QString& title);
|
||||
void numberChanged(const QString& number);
|
||||
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant& value) override;
|
||||
|
|
@ -62,6 +67,7 @@ private:
|
|||
bool m_hasDecomposition = false;
|
||||
QSet<ArrowItem*> m_arrows;
|
||||
std::optional<qreal> m_price;
|
||||
std::optional<QColor> m_customColor;
|
||||
|
||||
static QString s_currencySymbol;
|
||||
static QString s_currencyPlacement;
|
||||
|
|
|
|||
|
|
@ -37,9 +37,10 @@ DiagramScene::DiagramScene(QObject* parent)
|
|||
}
|
||||
|
||||
BlockItem* DiagramScene::createBlockAt(const QPointF& scenePos) {
|
||||
auto* b = new BlockItem("Function", nullptr, m_nextBlockId++);
|
||||
auto* b = new BlockItem(QString(), nullptr, m_nextBlockId++);
|
||||
addItem(b);
|
||||
b->setNumber(assignNumber(b));
|
||||
connectBlockSignals(b);
|
||||
const QRectF r = m_contentRect.isNull() ? sceneRect() : m_contentRect;
|
||||
const QPointF desired = scenePos - QPointF(100, 50); // центрируем
|
||||
const QRectF br = b->boundingRect().translated(desired);
|
||||
|
|
@ -59,6 +60,7 @@ BlockItem* DiagramScene::createBlockWithId(const QPointF& scenePos, int id, cons
|
|||
addItem(b);
|
||||
b->setPos(scenePos);
|
||||
if (b->number().isEmpty()) b->setNumber(assignNumber(b));
|
||||
connectBlockSignals(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
|
|
@ -155,9 +157,9 @@ void DiagramScene::updateMeta(const QVariantMap& patch) {
|
|||
}
|
||||
|
||||
QString DiagramScene::currentNodeLabel() const {
|
||||
if (m_currentBlockId < 0) return QStringLiteral("TOP");
|
||||
if (m_currentBlockId < 0) return tr("TOP");
|
||||
if (!m_currentPrefix.isEmpty()) return m_currentPrefix;
|
||||
return QStringLiteral("A0");
|
||||
return tr("A0");
|
||||
}
|
||||
|
||||
QString DiagramScene::currentDiagramTitle() const {
|
||||
|
|
@ -594,6 +596,9 @@ DiagramScene::Snapshot DiagramScene::captureSnapshot() const {
|
|||
blk.hasDecomp = hasDecomp;
|
||||
blk.number = b->number();
|
||||
blk.price = b->price();
|
||||
if (auto col = b->customColor()) {
|
||||
blk.color = col->name();
|
||||
}
|
||||
s.blocks.push_back(blk);
|
||||
}
|
||||
}
|
||||
|
|
@ -621,9 +626,14 @@ DiagramScene::Snapshot DiagramScene::captureSnapshot() const {
|
|||
ar.isInterface = a->isInterface();
|
||||
ar.isInterfaceStub = a->isInterfaceStub();
|
||||
ar.labelLocked = a->isLabelLocked();
|
||||
ar.callMechanism = a->isCallMechanism();
|
||||
ar.callRefId = a->callRefId();
|
||||
if (a->interfaceEdge()) {
|
||||
ar.interfaceEdge = encodeEp(*a->interfaceEdge());
|
||||
}
|
||||
if (auto col = a->customColor()) {
|
||||
ar.color = col->name();
|
||||
}
|
||||
s.arrows.push_back(std::move(ar));
|
||||
}
|
||||
}
|
||||
|
|
@ -655,6 +665,10 @@ void DiagramScene::restoreSnapshot(const Snapshot& snap, bool resetHistoryState)
|
|||
if (b.price.has_value()) {
|
||||
blk->setPrice(b.price);
|
||||
}
|
||||
if (b.color.has_value()) {
|
||||
const QColor col(*b.color);
|
||||
if (col.isValid()) blk->setCustomColor(col);
|
||||
}
|
||||
blockMap.insert(b.id, blk);
|
||||
m_nextBlockId = std::max(m_nextBlockId, b.id + 1);
|
||||
}
|
||||
|
|
@ -710,10 +724,17 @@ for (const auto& j : snap.junctions) {
|
|||
ar->setLabelHidden(a.labelHidden);
|
||||
ar->setLabelInherited(a.labelInherited);
|
||||
ar->setLabelLocked(a.labelLocked);
|
||||
ar->setCallMechanism(a.callMechanism);
|
||||
ar->setCallRefId(a.callRefId);
|
||||
if (a.color.has_value()) {
|
||||
const QColor col(*a.color);
|
||||
if (col.isValid()) ar->setCustomColor(col);
|
||||
}
|
||||
ar->finalize();
|
||||
}
|
||||
|
||||
m_restoringSnapshot = false;
|
||||
updateCallMechanismLabels();
|
||||
if (resetHistoryState) {
|
||||
resetHistory(captureSnapshot());
|
||||
}
|
||||
|
|
@ -742,9 +763,59 @@ void DiagramScene::scheduleSnapshot() {
|
|||
QTimer::singleShot(0, this, [this]{
|
||||
m_snapshotScheduled = false;
|
||||
pushSnapshot();
|
||||
updateCallMechanismLabels();
|
||||
});
|
||||
}
|
||||
|
||||
void DiagramScene::connectBlockSignals(BlockItem* b) {
|
||||
if (!b) return;
|
||||
connect(b, &BlockItem::titleChanged, this, [this]{ updateCallMechanismLabels(); });
|
||||
connect(b, &BlockItem::numberChanged, this, [this]{ updateCallMechanismLabels(); });
|
||||
}
|
||||
|
||||
void DiagramScene::updateCallMechanismLabels() {
|
||||
QHash<int, BlockItem*> blockById;
|
||||
for (QGraphicsItem* it : items()) {
|
||||
if (auto* b = qgraphicsitem_cast<BlockItem*>(it)) {
|
||||
blockById.insert(b->id(), b);
|
||||
}
|
||||
}
|
||||
for (QGraphicsItem* it : items()) {
|
||||
auto* a = qgraphicsitem_cast<ArrowItem*>(it);
|
||||
if (!a || !a->isCallMechanism()) continue;
|
||||
BlockItem* ref = blockById.value(a->callRefId(), nullptr);
|
||||
if (!ref) continue;
|
||||
const QString num = ref->number();
|
||||
const QString title = ref->title();
|
||||
const QString label = num.isEmpty() ? title : QStringLiteral("%1 %2").arg(num, title);
|
||||
a->setLabel(label);
|
||||
a->setLabelHidden(false);
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramScene::purgeBrokenCallMechanisms() {
|
||||
QSet<BlockItem*> blocks;
|
||||
for (QGraphicsItem* it : items()) {
|
||||
if (auto* b = qgraphicsitem_cast<BlockItem*>(it)) blocks.insert(b);
|
||||
}
|
||||
QVector<ArrowItem*> toRemove;
|
||||
for (QGraphicsItem* it : items()) {
|
||||
if (auto* a = qgraphicsitem_cast<ArrowItem*>(it)) {
|
||||
if (!a->isCallMechanism()) continue;
|
||||
auto from = a->from();
|
||||
auto to = a->to();
|
||||
bool ok = true;
|
||||
if (from.block && !blocks.contains(from.block)) ok = false;
|
||||
if (to.block && !blocks.contains(to.block)) ok = false;
|
||||
if (!ok) toRemove.push_back(a);
|
||||
}
|
||||
}
|
||||
for (ArrowItem* a : toRemove) {
|
||||
removeItem(a);
|
||||
delete a;
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramScene::undo() {
|
||||
if (m_historyIndex <= 0) return;
|
||||
m_historyIndex -= 1;
|
||||
|
|
@ -1022,6 +1093,7 @@ void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* e) {
|
|||
maybeSnapshotMovedItems();
|
||||
m_itemDragActive = false;
|
||||
}
|
||||
purgeBrokenCallMechanisms();
|
||||
QGraphicsScene::mouseReleaseEvent(e);
|
||||
}
|
||||
|
||||
|
|
@ -1056,6 +1128,47 @@ void DiagramScene::keyPressEvent(QKeyEvent* e) {
|
|||
QGraphicsScene::keyPressEvent(e);
|
||||
}
|
||||
|
||||
bool DiagramScene::hasCallMechanism(const BlockItem* target) const {
|
||||
if (!target) return false;
|
||||
const auto all = items();
|
||||
for (QGraphicsItem* it : all) {
|
||||
if (auto* a = qgraphicsitem_cast<ArrowItem*>(it)) {
|
||||
if (!a->isCallMechanism()) continue;
|
||||
const auto from = a->from();
|
||||
if (from.block && from.block == target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DiagramScene::startCallMechanism(BlockItem* origin, BlockItem* refBlock, const QString& label) {
|
||||
if (!origin || !refBlock) return false;
|
||||
if (origin == refBlock) return false;
|
||||
if (hasCallMechanism(origin)) return false;
|
||||
cancelCurrentDrag();
|
||||
auto* a = new ArrowItem();
|
||||
addItem(a);
|
||||
ArrowItem::Endpoint from;
|
||||
from.scenePos = origin->portScenePos(BlockItem::Port::Mechanism) + QPointF(0, 40);
|
||||
from.port = BlockItem::Port::Mechanism;
|
||||
ArrowItem::Endpoint to;
|
||||
to.block = origin;
|
||||
to.port = BlockItem::Port::Mechanism;
|
||||
a->setFrom(from);
|
||||
a->setTo(to);
|
||||
a->setCallMechanism(true);
|
||||
a->setCallRefId(refBlock->id());
|
||||
a->setLabel(label);
|
||||
a->setLabelHidden(false);
|
||||
a->setLabelLocked(true);
|
||||
a->setLabelInherited(false);
|
||||
a->finalize();
|
||||
pushSnapshot();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DiagramScene::cancelCurrentDrag() {
|
||||
if (m_dragArrow) {
|
||||
if (m_dragArrow->isInterface()) {
|
||||
|
|
@ -1119,7 +1232,10 @@ void DiagramScene::deleteSelection() {
|
|||
delete it;
|
||||
}
|
||||
|
||||
if (!toDelete.isEmpty()) pushSnapshot();
|
||||
if (!toDelete.isEmpty()) {
|
||||
purgeBrokenCallMechanisms();
|
||||
pushSnapshot();
|
||||
}
|
||||
}
|
||||
|
||||
void DiagramScene::requestSnapshot() {
|
||||
|
|
@ -1278,6 +1394,7 @@ QVariantMap DiagramScene::exportToVariant() {
|
|||
o["hasDecomp"] = b.hasDecomp;
|
||||
o["number"] = b.number;
|
||||
if (b.price.has_value()) o["price"] = *b.price;
|
||||
if (b.color.has_value()) o["color"] = *b.color;
|
||||
blocks.append(o);
|
||||
}
|
||||
root["blocks"] = blocks;
|
||||
|
|
@ -1307,6 +1424,9 @@ QVariantMap DiagramScene::exportToVariant() {
|
|||
o["isInterfaceStub"] = a.isInterfaceStub;
|
||||
o["labelLocked"] = a.labelLocked;
|
||||
o["interfaceEdge"] = endpointToJson(a.interfaceEdge);
|
||||
o["callMechanism"] = a.callMechanism;
|
||||
o["callRefId"] = a.callRefId;
|
||||
if (a.color.has_value()) o["color"] = *a.color;
|
||||
arrows.append(o);
|
||||
}
|
||||
root["arrows"] = arrows;
|
||||
|
|
@ -1340,7 +1460,7 @@ bool DiagramScene::importFromVariant(const QVariantMap& map) {
|
|||
Snapshot snap;
|
||||
for (const auto& vb : root.value("blocks").toArray()) {
|
||||
const auto o = vb.toObject();
|
||||
const auto posArr = o.value("pos").toArray();
|
||||
const auto posArr = o.value("pos").toArray();
|
||||
if (posArr.size() != 2) continue;
|
||||
DiagramScene::Snapshot::Block blk;
|
||||
blk.id = o.value("id").toInt();
|
||||
|
|
@ -1351,6 +1471,8 @@ bool DiagramScene::importFromVariant(const QVariantMap& map) {
|
|||
if (o.contains("price") && !o.value("price").isNull()) {
|
||||
blk.price = o.value("price").toDouble();
|
||||
}
|
||||
const QString blkColor = o.value("color").toString();
|
||||
if (!blkColor.isEmpty()) blk.color = blkColor;
|
||||
snap.blocks.push_back(blk);
|
||||
}
|
||||
for (const auto& vj : root.value("junctions").toArray()) {
|
||||
|
|
@ -1376,6 +1498,10 @@ bool DiagramScene::importFromVariant(const QVariantMap& map) {
|
|||
ar.isInterfaceStub = o.value("isInterfaceStub").toBool(false);
|
||||
ar.labelLocked = o.value("labelLocked").toBool(false);
|
||||
ar.interfaceEdge = endpointFromJson(o.value("interfaceEdge").toObject());
|
||||
ar.callMechanism = o.value("callMechanism").toBool(false);
|
||||
ar.callRefId = o.value("callRefId").toInt(-1);
|
||||
const QString arrowColor = o.value("color").toString();
|
||||
if (!arrowColor.isEmpty()) ar.color = arrowColor;
|
||||
snap.arrows.push_back(ar);
|
||||
}
|
||||
return snap;
|
||||
|
|
|
|||
|
|
@ -23,12 +23,16 @@ public:
|
|||
QRectF contentRect() const { return m_contentRect; }
|
||||
QString currentNodeLabel() const;
|
||||
QString currentDiagramTitle() const;
|
||||
int currentBlockId() const { return m_currentBlockId; }
|
||||
bool goDownIntoSelected();
|
||||
bool goDownIntoBlock(BlockItem* b);
|
||||
bool goUp();
|
||||
void propagateLabelFrom(ArrowItem* root);
|
||||
QVariantMap exportToVariant();
|
||||
bool importFromVariant(const QVariantMap& map);
|
||||
bool startCallMechanism(BlockItem* origin, BlockItem* refBlock, const QString& label);
|
||||
bool hasCallMechanism(const BlockItem* origin) const;
|
||||
void updateCallMechanismLabels();
|
||||
signals:
|
||||
void changed();
|
||||
void metaChanged(const QVariantMap& meta);
|
||||
|
|
@ -48,7 +52,7 @@ private:
|
|||
std::optional<QPointF> localPos;
|
||||
std::optional<QPointF> scenePos;
|
||||
};
|
||||
struct Block { int id; QString title; QPointF pos; bool hasDecomp = false; QString number; std::optional<qreal> price; };
|
||||
struct Block { int id; QString title; QPointF pos; bool hasDecomp = false; QString number; std::optional<qreal> price; std::optional<QString> color; };
|
||||
struct Junction { int id; QPointF pos; };
|
||||
struct Arrow {
|
||||
Endpoint from;
|
||||
|
|
@ -64,6 +68,9 @@ private:
|
|||
bool isInterfaceStub = false;
|
||||
bool labelLocked = false;
|
||||
Endpoint interfaceEdge;
|
||||
std::optional<QString> color;
|
||||
bool callMechanism = false;
|
||||
int callRefId = -1;
|
||||
};
|
||||
QVector<Block> blocks;
|
||||
QVector<Junction> junctions;
|
||||
|
|
@ -113,6 +120,8 @@ private:
|
|||
QString currentPathKey() const;
|
||||
QString childKeyFor(int blockId) const;
|
||||
QString assignNumber(BlockItem* b);
|
||||
void connectBlockSignals(BlockItem* b);
|
||||
void purgeBrokenCallMechanisms();
|
||||
|
||||
enum class Edge { None, Left, Right, Top, Bottom };
|
||||
Edge hitTestEdge(const QPointF& scenePos, QPointF* outScenePoint = nullptr) const;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue