diff --git a/cmake/qet_compilation_vars.cmake b/cmake/qet_compilation_vars.cmake index 4593d5d56..38e698ea2 100644 --- a/cmake/qet_compilation_vars.cmake +++ b/cmake/qet_compilation_vars.cmake @@ -352,6 +352,8 @@ set(QET_SRC_FILES ${QET_DIR}/sources/diagramevent/diagrameventaddimage.h ${QET_DIR}/sources/diagramevent/diagrameventaddshape.cpp ${QET_DIR}/sources/diagramevent/diagrameventaddshape.h + ${QET_DIR}/sources/diagramevent/diagrameventfillet.cpp + ${QET_DIR}/sources/diagramevent/diagrameventfillet.h ${QET_DIR}/sources/diagramevent/diagrameventaddpath.cpp ${QET_DIR}/sources/diagramevent/diagrameventaddpath.h ${QET_DIR}/sources/diagramevent/diagrameventaddtext.cpp diff --git a/ico/generated/scalable-22/draw-fillet.svg b/ico/generated/scalable-22/draw-fillet.svg new file mode 100644 index 000000000..d73a6778a --- /dev/null +++ b/ico/generated/scalable-22/draw-fillet.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/ico/icon-themes.qrc b/ico/icon-themes.qrc index 12b084713..45d6454ca 100644 --- a/ico/icon-themes.qrc +++ b/ico/icon-themes.qrc @@ -29,6 +29,7 @@ 128x128/settings.png scalable/align-horizontal-center.svg scalable/align-horizontal-left.svg + scalable/draw-fillet.svg scalable/align-horizontal-right.svg scalable/align-vertical-bottom.svg scalable/align-vertical-center.svg @@ -61,17 +62,29 @@ scalable/16/align-horizontal-center.svg scalable/16/align-horizontal-center.svg scalable/16/align-horizontal-left.svg + scalable/16/draw-fillet.svg generated/scalable-22/align-horizontal-left.svg + generated/scalable-22/draw-fillet.svg scalable/16/align-horizontal-left.svg + scalable/16/draw-fillet.svg scalable/align-horizontal-left.svg + scalable/draw-fillet.svg scalable/16/align-horizontal-left.svg + scalable/16/draw-fillet.svg scalable/16/align-horizontal-left.svg + scalable/16/draw-fillet.svg scalable/16/align-horizontal-left.svg + scalable/16/draw-fillet.svg generated/scalable-22/align-horizontal-left.svg + generated/scalable-22/draw-fillet.svg scalable/16/align-horizontal-left.svg + scalable/16/draw-fillet.svg scalable/align-horizontal-left.svg + scalable/draw-fillet.svg scalable/16/align-horizontal-left.svg + scalable/16/draw-fillet.svg scalable/16/align-horizontal-left.svg + scalable/16/draw-fillet.svg scalable/16/align-horizontal-right.svg generated/scalable-22/align-horizontal-right.svg scalable/16/align-horizontal-right.svg @@ -2372,6 +2385,7 @@ themes/qet-dark/128x128/settings.png themes/qet-dark/scalable/align-horizontal-center.svg themes/qet-dark/scalable/align-horizontal-left.svg + themes/qet-dark/scalable/draw-fillet.svg themes/qet-dark/scalable/align-horizontal-right.svg themes/qet-dark/scalable/align-vertical-bottom.svg themes/qet-dark/scalable/align-vertical-center.svg @@ -2394,7 +2408,9 @@ themes/qet-dark/scalable-16/align-horizontal-center.svg themes/qet-dark/scalable-22/align-horizontal-center.svg themes/qet-dark/scalable-16/align-horizontal-left.svg + themes/qet-dark/scalable-16/draw-fillet.svg themes/qet-dark/scalable-22/align-horizontal-left.svg + themes/qet-dark/scalable-22/draw-fillet.svg themes/qet-dark/scalable-16/align-horizontal-right.svg themes/qet-dark/scalable-22/align-horizontal-right.svg themes/qet-dark/scalable-16/align-vertical-bottom.svg @@ -2990,17 +3006,29 @@ themes/qet-dark/scalable-16/align-horizontal-center.svg themes/qet-dark/scalable-16/align-horizontal-center.svg themes/qet-dark/scalable-16/align-horizontal-left.svg + themes/qet-dark/scalable-16/draw-fillet.svg themes/qet-dark/scalable-22/align-horizontal-left.svg + themes/qet-dark/scalable-22/draw-fillet.svg themes/qet-dark/scalable-16/align-horizontal-left.svg + themes/qet-dark/scalable-16/draw-fillet.svg themes/qet-dark/scalable/align-horizontal-left.svg + themes/qet-dark/scalable/draw-fillet.svg themes/qet-dark/scalable-16/align-horizontal-left.svg + themes/qet-dark/scalable-16/draw-fillet.svg themes/qet-dark/scalable-16/align-horizontal-left.svg + themes/qet-dark/scalable-16/draw-fillet.svg themes/qet-dark/scalable-16/align-horizontal-left.svg + themes/qet-dark/scalable-16/draw-fillet.svg themes/qet-dark/scalable-22/align-horizontal-left.svg + themes/qet-dark/scalable-22/draw-fillet.svg themes/qet-dark/scalable-16/align-horizontal-left.svg + themes/qet-dark/scalable-16/draw-fillet.svg themes/qet-dark/scalable/align-horizontal-left.svg + themes/qet-dark/scalable/draw-fillet.svg themes/qet-dark/scalable-16/align-horizontal-left.svg + themes/qet-dark/scalable-16/draw-fillet.svg themes/qet-dark/scalable-16/align-horizontal-left.svg + themes/qet-dark/scalable-16/draw-fillet.svg themes/qet-dark/scalable-16/align-horizontal-right.svg themes/qet-dark/scalable-22/align-horizontal-right.svg themes/qet-dark/scalable-16/align-horizontal-right.svg diff --git a/ico/scalable/16/draw-fillet.svg b/ico/scalable/16/draw-fillet.svg new file mode 100644 index 000000000..d152e7f4e --- /dev/null +++ b/ico/scalable/16/draw-fillet.svg @@ -0,0 +1,11 @@ + + + + + + + diff --git a/ico/scalable/draw-fillet.svg b/ico/scalable/draw-fillet.svg new file mode 100644 index 000000000..01c5a994a --- /dev/null +++ b/ico/scalable/draw-fillet.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/ico/themes/qet-dark/scalable-16/draw-fillet.svg b/ico/themes/qet-dark/scalable-16/draw-fillet.svg new file mode 100644 index 000000000..f1c06dbae --- /dev/null +++ b/ico/themes/qet-dark/scalable-16/draw-fillet.svg @@ -0,0 +1,11 @@ + + + + + + + diff --git a/ico/themes/qet-dark/scalable-22/draw-fillet.svg b/ico/themes/qet-dark/scalable-22/draw-fillet.svg new file mode 100644 index 000000000..c0585e5e1 --- /dev/null +++ b/ico/themes/qet-dark/scalable-22/draw-fillet.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/ico/themes/qet-dark/scalable/draw-fillet.svg b/ico/themes/qet-dark/scalable/draw-fillet.svg new file mode 100644 index 000000000..8fea23abe --- /dev/null +++ b/ico/themes/qet-dark/scalable/draw-fillet.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/sources/diagramevent/diagrameventfillet.cpp b/sources/diagramevent/diagrameventfillet.cpp new file mode 100644 index 000000000..e5ffe8c82 --- /dev/null +++ b/sources/diagramevent/diagrameventfillet.cpp @@ -0,0 +1,343 @@ +/* + Copyright 2006-2026 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "diagrameventfillet.h" + +#include "../QPropertyUndoCommand/qpropertyundocommand.h" +#include "../diagram.h" +#include "../qetapp.h" +#include "../qetdiagrameditor.h" +#include "../qetgraphicsitem/qetshapeitem.h" +#include "../qgimanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace { + +const char *radiusSettingKey = "diagrameditor/fillet_radius"; + +/** + Adds the fillet's arc to the diagram exactly where it was computed. + AddGraphicsObjectCommand is not used: its redo() calls setPos(), + and QetShapeItem::setPos() snaps the outline's corner to the grid, + which would pull the arc off the two lines it has to touch. +*/ +class AddFilletArcCommand : public QUndoCommand +{ + public: + AddFilletArcCommand(QetShapeItem *arc, Diagram *diagram, QUndoCommand *parent) : + QUndoCommand(parent), m_arc(arc), m_diagram(diagram) + { m_diagram->qgiManager().manage(m_arc); } + ~AddFilletArcCommand() override + { m_diagram->qgiManager().release(m_arc); } + void redo() override { m_diagram->addItem(m_arc); } + void undo() override { m_diagram->removeItem(m_arc); } + + private: + QetShapeItem *m_arc; + Diagram *m_diagram; +}; + +qreal length(const QPointF &v) { return std::hypot(v.x(), v.y()); } +qreal dot(const QPointF &a, const QPointF &b) { return a.x() * b.x() + a.y() * b.y(); } + +qreal distanceToSegment(const QPointF &p, const QLineF &segment) +{ + const QPointF d = segment.p2() - segment.p1(); + const qreal len2 = dot(d, d); + if (len2 <= 0) + return length(p - segment.p1()); + const qreal t = qBound(qreal(0), dot(p - segment.p1(), d) / len2, qreal(1)); + return length(p - (segment.p1() + t * d)); +} + +QLineF sceneLine(const QetShapeItem *line) +{ + return QLineF(line->mapToScene(line->line().p1()), line->mapToScene(line->line().p2())); +} + + //Angle of a point on a circle, in the convention QPainterPath::arcTo() + //and QetShapeItem use: degrees, anticlockwise from three o'clock. +qreal arcAngle(const QPointF ¢re, const QPointF &p) +{ + return qRadiansToDegrees(std::atan2(-(p.y() - centre.y()), p.x() - centre.x())); +} + + //Same test as QetShapeItem::setStartAngle()/setEndAngle() use to snap + //an arc back to a full ellipse. +bool nearlyFullTurn(qreal span) +{ + qreal wrapped = std::fmod(span, 360.0); + if (wrapped < 0) wrapped += 360.0; + return wrapped < 5.0 || wrapped > 355.0; +} + +} // namespace + +DiagramEventFillet::DiagramEventFillet(Diagram *diagram) : + DiagramEventInterface(diagram) +{ + m_running = true; + //Deferred for the same reason as DiagramEventAddShape's hint: + //the previous tool's destructor clears the status bar after + //this constructor returns. + QTimer::singleShot(0, this, [this]() { showDefaultHint(); }); +} + +DiagramEventFillet::~DiagramEventFillet() +{ + clearFirstPick(); + if (m_diagram && !m_diagram->views().isEmpty()) + { + if (auto *editor = QETApp::diagramEditorAncestorOf(m_diagram->views().constFirst())) + editor->statusBar()->clearMessage(); + } +} + +void DiagramEventFillet::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->setAccepted(true); + if (Q_UNLIKELY(m_diagram->isReadOnly())) + return; + + if (event->button() == Qt::RightButton) + { + if (m_first_line) { + clearFirstPick(); + showDefaultHint(); + } else { + m_running = false; + emit finish(); + } + return; + } + if (event->button() != Qt::LeftButton) + return; + + const QPointF pos = event->scenePos(); + const QList lines = linesNear(pos); + if (lines.isEmpty()) { + showHint(tr("Aucune ligne ici : cliquez sur une ligne dessinée sur le folio")); + return; + } + + if (!m_first_line) + { + //One click where two lines meet picks both of them + if (lines.size() >= 2) { + filletLines({lines.at(0), pos}, {lines.at(1), pos}); + return; + } + m_first = {lines.first(), pos}; + m_first_line = lines.first(); + m_diagram->clearSelection(); + m_first_line->setSelected(true); + showHint(tr("Cliquez sur la deuxième ligne ; clic droit : annuler")); + return; + } + + const auto other = std::find_if(lines.cbegin(), lines.cend(), + [this](QetShapeItem *line) { return line != m_first_line; }); + if (other == lines.cend()) { + showHint(tr("Cliquez sur une autre ligne ; clic droit : annuler")); + return; + } + const Pick first = m_first; + clearFirstPick(); + filletLines(first, {*other, pos}); +} + +/** + @brief DiagramEventFillet::linesNear + @return the Line shapes passing within a few screen pixels of + scenePos, nearest first. Only the items under the cursor are looked + at; the diagram is not walked. +*/ +QList DiagramEventFillet::linesNear(const QPointF &scenePos) const +{ + qreal scale = 1; + if (!m_diagram->views().isEmpty()) + scale = m_diagram->views().constFirst()->transform().m11(); + const qreal tolerance = 6.0 / qMax(scale, qreal(0.01)); + + QList> found; + const QRectF area(scenePos - QPointF(tolerance, tolerance), QSizeF(2 * tolerance, 2 * tolerance)); + for (QGraphicsItem *item : m_diagram->items(area)) + { + if (item->type() != QetShapeItem::Type) + continue; + auto *shape = static_cast(item); + if (shape->shapeType() != QetShapeItem::Line) + continue; + const qreal distance = distanceToSegment(scenePos, sceneLine(shape)); + if (distance <= tolerance) + found.append({distance, shape}); + } + std::sort(found.begin(), found.end(), + [](const auto &a, const auto &b) { return a.first < b.first; }); + + QList lines; + for (const auto &f : found) + lines.append(f.second); + return lines; +} + +/** + @brief DiagramEventFillet::filletLines + Rounds the corner between the two picked lines. For each line, the + part kept is the one on the side of the corner where it was clicked; + a click on the corner itself keeps the longer part. The other end of + each line moves to the point where the arc touches it -- shortening + the line, or lengthening it when the two lines did not reach each + other. One undo step undoes the whole fillet. +*/ +void DiagramEventFillet::filletLines(const Pick &a, const Pick &b) +{ + const QLineF s1 = sceneLine(a.line); + const QLineF s2 = sceneLine(b.line); + + QPointF corner; + if (s1.intersects(s2, &corner) == QLineF::NoIntersection) { + showHint(tr("Ces deux lignes sont parallèles : pas de congé possible")); + return; + } + + qreal scale = 1; + if (!m_diagram->views().isEmpty()) + scale = m_diagram->views().constFirst()->transform().m11(); + const qreal cornerTolerance = 6.0 / qMax(scale, qreal(0.01)); + + auto keptEnd = [&](const QLineF &segment, const QPointF &pick) -> int { + const QPointF ends[2] = {segment.p1(), segment.p2()}; + const QPointF towardPick = pick - corner; + const bool onCorner = length(towardPick) < cornerTolerance; + int best = -1; + for (int pass = 0; pass < 2 && best < 0; ++pass) { + qreal bestLength = -1; + for (int i = 0; i < 2; ++i) { + const QPointF v = ends[i] - corner; + if (pass == 0 && !onCorner && dot(v, towardPick) <= 0) + continue; + if (length(v) > bestLength) { best = i; bestLength = length(v); } + } + } + return best; + }; + const int keep1 = keptEnd(s1, a.pos); + const int keep2 = keptEnd(s2, b.pos); + const QPointF e1 = keep1 == 0 ? s1.p1() : s1.p2(); + const QPointF e2 = keep2 == 0 ? s2.p1() : s2.p2(); + const qreal len1 = length(e1 - corner); + const qreal len2 = length(e2 - corner); + if (len1 < 1e-6 || len2 < 1e-6) { + showHint(tr("Une des lignes s'arrête au coin : rien à arrondir de ce côté")); + return; + } + + const QPointF u1 = (e1 - corner) / len1; + const QPointF u2 = (e2 - corner) / len2; + const qreal theta = std::acos(qBound(qreal(-1), dot(u1, u2), qreal(1))); + if (qRadiansToDegrees(theta) > 174.0) { + showHint(tr("Ces deux lignes sont presque alignées : pas de congé possible")); + return; + } + + QSettings settings; + bool ok = false; + QWidget *parent = m_diagram->views().isEmpty() ? nullptr : m_diagram->views().constFirst(); + const qreal radius = QInputDialog::getDouble(parent, tr("Congé"), tr("Rayon :"), + settings.value(radiusSettingKey, 20.0).toDouble(), 0.1, 100000.0, 1, &ok); + if (!ok || !m_diagram) + return; + settings.setValue(radiusSettingKey, radius); + + const qreal tangentDistance = radius / std::tan(theta / 2); + if (tangentDistance > len1 + 1e-6 || tangentDistance > len2 + 1e-6) { + showHint(tr("Rayon trop grand pour ces lignes (%1 au plus)") + .arg(std::min(len1, len2) * std::tan(theta / 2), 0, 'f', 1)); + return; + } + + const QPointF t1 = corner + u1 * tangentDistance; + const QPointF t2 = corner + u2 * tangentDistance; + const QPointF bisector = (u1 + u2) / length(u1 + u2); + const QPointF centre = corner + bisector * (radius / std::sin(theta / 2)); + + //Each line keeps its picked end and moves its other end to the + //tangent point; p1/p2 keep their roles, mapped back into the + //line's own coordinates (it may be rotated or skewed). + auto newLine = [](QetShapeItem *line, int keep, const QPointF &kept, const QPointF &tangent) { + const QPointF p1 = keep == 0 ? kept : tangent; + const QPointF p2 = keep == 0 ? tangent : kept; + return QLineF(line->mapFromScene(p1), line->mapFromScene(p2)); + }; + + auto *arc = new QetShapeItem(centre - QPointF(radius, radius), + centre + QPointF(radius, radius), QetShapeItem::Ellipse); + arc->setPen(a.line->pen()); + qreal start = std::fmod(arcAngle(centre, t1), 360.0); + if (start < 0) start += 360.0; + const qreal span = std::fmod(arcAngle(centre, t2) - start + 540.0, 360.0) - 180.0; + //Set the two angles in an order whose intermediate state is not + //close to a full turn, which the setters would snap to an ellipse. + if (!nearlyFullTurn(360.0 - start)) { + arc->setStartAngle(start); + arc->setEndAngle(start + span); + } else { + arc->setEndAngle(start + span); + arc->setStartAngle(start); + } + + auto *undo = new QUndoCommand(tr("Ajouter un congé")); + new QPropertyUndoCommand(a.line, "line", a.line->line(), newLine(a.line, keep1, e1, t1), undo); + new QPropertyUndoCommand(b.line, "line", b.line->line(), newLine(b.line, keep2, e2, t2), undo); + new AddFilletArcCommand(arc, m_diagram, undo); + m_diagram->undoStack().push(undo); + showDefaultHint(); +} + +void DiagramEventFillet::clearFirstPick() +{ + if (m_first_line) + m_first_line->setSelected(false); + m_first_line.clear(); + m_first = Pick(); +} + +void DiagramEventFillet::showHint(const QString &text) const +{ + if (!m_diagram || m_diagram->views().isEmpty()) + return; + if (auto *editor = QETApp::diagramEditorAncestorOf(m_diagram->views().constFirst())) + editor->statusBar()->showMessage(text); +} + +void DiagramEventFillet::showDefaultHint() const +{ + showHint(tr("Congé : cliquez sur deux lignes, ou une fois là où elles se rejoignent ; " + "Échap ou clic droit : terminer")); +} diff --git a/sources/diagramevent/diagrameventfillet.h b/sources/diagramevent/diagrameventfillet.h new file mode 100644 index 000000000..c12664f10 --- /dev/null +++ b/sources/diagramevent/diagrameventfillet.h @@ -0,0 +1,62 @@ +/* + Copyright 2006-2026 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#ifndef DIAGRAMEVENTFILLET_H +#define DIAGRAMEVENTFILLET_H + +#include "diagrameventinterface.h" + +#include +#include + +class QetShapeItem; + +/** + @brief The DiagramEventFillet class + The "add a fillet" tool: rounds the corner between two drawn lines, + the way a sketch fillet does in a CAD program. Click the two lines + one after the other, or once where they meet; a dialog asks for the + radius. The lines are trimmed (or extended) to the points where the + arc touches them, and an arc is added between them -- an ordinary + Ellipse shape with a start and end angle, so nothing new is saved. +*/ +class DiagramEventFillet : public DiagramEventInterface +{ + Q_OBJECT + + public: + DiagramEventFillet(Diagram *diagram); + ~DiagramEventFillet() override; + void mousePressEvent (QGraphicsSceneMouseEvent *event) override; + + private: + struct Pick { + QetShapeItem *line = nullptr; + QPointF pos; // where the line was clicked, in scene coordinates + }; + + QList linesNear(const QPointF &scenePos) const; + void filletLines(const Pick &a, const Pick &b); + void clearFirstPick(); + void showHint(const QString &text) const; + void showDefaultHint() const; + + Pick m_first; + QPointer m_first_line; // m_first.line, guarded: the line can be deleted between the two clicks +}; + +#endif // DIAGRAMEVENTFILLET_H diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index 0218f7cf8..7add56cc7 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -38,6 +38,7 @@ #endif #include "diagramevent/diagrameventaddshape.h" #include "diagramevent/diagrameventaddpath.h" +#include "diagramevent/diagrameventfillet.h" #include "diagramevent/diagrameventaddtext.h" #include "diagramevent/diagrameventaddpaste.h" #include "diagramview.h" @@ -1063,6 +1064,7 @@ void QETDiagramEditor::setUpActions() QAction *add_arc = m_add_item_actions_group.addAction(QET::Icons::PartArc, tr("Ajouter un arc")); QAction *add_polyline = m_add_item_actions_group.addAction(QET::Icons::PartPolygon, tr("Ajouter une polyligne")); QAction *add_path = m_add_item_actions_group.addAction(QET::Icons::PartBezier, tr("Ajouter une courbe")); + QAction *add_fillet = m_add_item_actions_group.addAction(QET::Icons::DrawFillet, tr("Ajouter un congé")); QAction *add_terminal_strip = m_add_item_actions_group.addAction(QET::Icons::TerminalStrip, tr("Ajouter un plan de bornes")); add_text ->setStatusTip(tr("Ajoute un champ de texte sur le folio actuel")); @@ -1076,6 +1078,7 @@ void QETDiagramEditor::setUpActions() add_arc ->setStatusTip(tr("Ajoute un arc sur le folio actuel")); add_polyline ->setStatusTip(tr("Ajoute une polyligne sur le folio actuel")); add_path ->setStatusTip(tr("Ajoute une courbe de Bézier sur le folio actuel")); + add_fillet ->setStatusTip(tr("Arrondit le coin entre deux lignes du folio actuel")); add_terminal_strip->setStatusTip(tr("Ajoute un plan de bornier sur le folio actuel")); add_text ->setData(QStringLiteral("text")); @@ -1089,6 +1092,7 @@ void QETDiagramEditor::setUpActions() add_arc ->setData(QStringLiteral("arc")); add_polyline ->setData(QStringLiteral("polyline")); add_path ->setData(QStringLiteral("path")); + add_fillet ->setData(QStringLiteral("fillet")); add_terminal_strip->setData(QStringLiteral("terminal_strip")); add_text->setCheckable(true); @@ -1098,6 +1102,7 @@ void QETDiagramEditor::setUpActions() add_arc->setCheckable(true); add_polyline->setCheckable(true); add_path->setCheckable(true); + add_fillet->setCheckable(true); connect(&m_add_item_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::addItemGroupTriggered); //No default key, but an id: they can then be found by the command @@ -2049,6 +2054,8 @@ void QETDiagramEditor::addItemGroupTriggered(QAction *action) { diagram_event = new DiagramEventAddPath (d); } + else if (value == "fillet") + diagram_event = new DiagramEventFillet (d); else if (value == "image") { DiagramEventAddImage *deai = new DiagramEventAddImage(d); diff --git a/sources/qeticons.cpp b/sources/qeticons.cpp index 244de3a98..ae3c9ff4f 100644 --- a/sources/qeticons.cpp +++ b/sources/qeticons.cpp @@ -140,6 +140,7 @@ namespace QET { QIcon Orientations; QIcon PartArc; QIcon PartBezier; + QIcon DrawFillet; QIcon PartCircle; QIcon PartEllipse; QIcon PartLine; @@ -540,6 +541,7 @@ void QET::Icons::initIcons() Orientations = QIcon::fromTheme("orientations"); PartArc = QIcon::fromTheme("arc"); PartBezier = QIcon::fromTheme("draw-bezier-curves"); + DrawFillet = QIcon::fromTheme("draw-fillet"); PartCircle = QIcon::fromTheme("circle"); PartEllipse = QIcon::fromTheme("ellipse"); PartLine = QIcon::fromTheme("line"); diff --git a/sources/qeticons.h b/sources/qeticons.h index 31a4d0aa8..345e6ceda 100644 --- a/sources/qeticons.h +++ b/sources/qeticons.h @@ -148,6 +148,7 @@ namespace QET { extern QIcon Orientations; extern QIcon PartArc; extern QIcon PartBezier; + extern QIcon DrawFillet; extern QIcon PartCircle; extern QIcon PartEllipse; extern QIcon PartLine;