Commit Graph

122 Commits

Author SHA1 Message Date
ispyisail 4278ef864e Add DXF export from the command line (--export-dxf)
qelectrotech --export-dxf <project.qet> <output_dir> [--show-terminals]
writes one DXF per folio, named <NN>_<title>.dxf like the PNG and SVG
exports. Discussion #1072.

The DXF code moves out of ExportDialog into DxfExport, unchanged except
that its options come from an ExportProperties argument instead of the
dialog. The dialog and the command line both call it, and the command
line uses the dialog's default options (the preferences' export
settings), so both write the same entities.

- Createdxf answers a file it cannot open with a message box and
  exit(0); the command line checks the file first and fails with a
  message and exit code 1 instead.
- A note is printed when pictures become outline boxes, as the dialog
  warns.
- Scripting: qet.exportDxf(outDir, showTerminals). MCP: format "dxf".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G2d2Zi8BfrYRPX88zhaoFG
2026-09-27 21:54:36 +13:00
ispyisail 7c4355338b Fix DXF export writing entities in a different order every time
Exporting the same folio to DXF twice gave files with the same entities
in a different order, so two exports never compared equal and a DXF could
not be diffed to spot a change. The export walked diagram->items(), whose
order follows memory addresses; saving had the same fault until
bugtracker #343.

Items are now taken in stacking order (z, then insertion order, which a
load makes the file's order), from the same rect query Diagram::toXml()
uses. Anything the query misses keeps its items() place after the rest.

Checked in the Export dialog on grafcet.qet, three folios, two exports
per build: master's differ every time, these are byte-identical, and both
contain exactly the same entities, only reordered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G2d2Zi8BfrYRPX88zhaoFG
2026-09-27 21:28:36 +13:00
Andre Rummler 6f80da66d5 Connected to previous image handling updates: images were not exported at all to dxf. In this
update instead of the image a placeholder box is drawn and a warning is given during export.

Current dxf version is extremely old and does not support any image embedding. Future possible
update is the introduction of a newer dxf version export option which would allow to embed a link to an external
image file.
2026-09-07 10:44:30 +02:00
ispyisail d988054aca Export the master-side cross-reference table to DXF
Follow-up to #740, which fixed the slave-side "(n-Xn)" cross-reference
label. The master-side item - the small table/cross drawn next to a
report or master element, listing where each of its slaves is used -
was still missing from DXF export. Measured against examples/
industrial.qet with the PDF export as an oracle (renders the whole
scene, so it shows what should be there):

                          before  after   PDF
  slave xrefs  "(n-Xn)"       41     41    41   (already fixed, #740)
  folio/position strings     358    403   403

DXF now matches the PDF exactly.

## Why this needed a different approach than #740

The slave label is a plain QGraphicsTextItem - one string, trivial to
walk and re-emit as a single DXF TEXT entity, which is what #740 did.

The master-side item (CrossRefItem) is not: it paints itself with
~600 lines of hand-written QPainter calls across three modes
(drawAsCross/drawAsContacts/drawAsPlcTable), including a header
table, contact symbols, and rules. Hand-porting that logic to emit
DXF primitives directly would mean maintaining two divergent
implementations of the same drawing that have to be kept in sync by
hand forever.

## Approach: a QPaintEngine that intercepts CrossRefItem's own paint()

DxfPaintEngine/DxfPaintDevice (sources/dxfpaintdevice.{h,cpp}) is a
QPaintEngine/QPaintDevice pair - the same mechanism QPrinter and
QSvgGenerator use to redirect QPainter output elsewhere. Constructing
a QPainter on a DxfPaintDevice and calling item->paint() on it produces
DXF entities instead of pixels, using the exact same drawing code that
already renders correctly on screen. CrossRefItem::paint() is
unmodified.

Scope is deliberately narrow - only the QPainter calls CrossRefItem's
paint() is observed to make: drawLines -> LINE, drawRects/drawPath's
fill case -> outline-only LWPOLYLINE (no HATCH support in v1 - DXF's
fill primitive is a separate, more involved entity type; documented as
a known limitation rather than attempted here), drawEllipse -> CIRCLE
or a flattened polygon for rotated ellipses, drawPath's arc case (from
drawArc/drawPie) -> chord-flattened LINE segments, drawPolygon ->
LWPOLYLINE, drawTextItem -> TEXT. drawPixmap is intentionally
unimplemented (qWarning + skip) since CrossRefItem never calls it -
this is not a general-purpose DXF paint engine, and isn't meant to be
in this PR.

CrossRefItem::paint() is protected, per the normal QGraphicsItem
contract - added a small paintForExport() wrapper rather than making
paint() itself public, or reaching around access control.

## Explicitly out of scope

QetShapeItem::toDXF() and QetGraphicsTableItem::toDXF() (both already
implemented and working) are untouched. Rewriting working exporters
onto this engine to prove an architectural point would be a large,
unrelated diff with no user-visible benefit - if that consolidation is
wanted later, it's a separate proposal once this engine has shipped
and proven out on the one item that currently has no DXF export at
all.

## Testing

Built clean on Qt5/Linux. Verified via the GUI export dialog
(Fichier > Exporter > DXF) against examples/industrial.qet, 50 folios:
export completes without error or crash, all 50 .dxf files are
structurally well-formed (balanced SECTION/ENDSEC, single EOF each),
and grepping the folio-position pattern gives the before/after/PDF
numbers above. Spot-checked several real label strings (e.g. "18-B18",
"20-A2") present as TEXT entity values in the output, not just an
artifact of the count matching.
2026-08-15 08:39:55 +12:00
Laurent Trinques f83ed508e3 Merge pull request #705 from arummler/master-update-more-signal-slot
Continued signal/slot migration
2026-08-13 21:40:30 +02:00
Andre Rummler 6d05bc2f21 Remove all Qt version checks and branches for <5.15.12 as such versions are no longer supported. 2026-08-13 16:20:30 +02:00
ispyisail 2e1ba46430 Export slave cross-reference labels to DXF
Cross-references were missing from DXF exports, as reported on the
forum: https://qelectrotech.org/forum/viewtopic.php?id=2481

generateDxf() walks the scene and collects items by cast. A slave
element's cross-reference label ("(6-G15)", pointing back to its master)
is a plain QGraphicsTextItem hung off a DynamicElementTextItem as a
child, so it matches neither the IndependentTextItem nor the
DynamicElementTextItem branch and was dropped on the floor. Nothing was
wrong with the label itself; it was simply never collected.

Collect it through the existing DynamicElementTextItem::slaveXrefItem()
accessor and draw it with the same placement, rotation and multi-line
handling as the other text items, using defaultTextColor() since a bare
QGraphicsTextItem has no DiagramTextItem::color().

Measured on examples/industrial.qet, comparing against the PDF export
(which renders the whole scene and so shows everything):

                          before   after   PDF
  slave xrefs "(n-Xn)"         0      41    41
  folio/position strings     317     358   403

The slave cross-references now match the PDF exactly.

Still missing, and not addressed here: the master-side cross-reference
table drawn by CrossRefItem, which accounts for the remaining 45
strings. CrossRefItem is a QGraphicsObject that renders itself with
custom QPainter code in three different modes (drawAsCross,
drawAsContacts, drawAsPlcTable) including contact symbols and rules, so
giving it a DXF representation is a larger piece of work than this.
2026-08-13 22:01:37 +12:00
Andre Rummler c25c400c93 Some of the newly guarded (Qt5 path) signal/slot connects could be still converted to method pointers. Mostly for completeness as they will go away anyhow soon.
Remaining: richtext editor.
2026-08-10 09:08:57 +02:00
Andre Rummler 201bd4c5f6 Migration of signal/slot to method pointer continued. Mostly simple cases. 2026-08-09 01:34:22 +02:00
Andre Rummler 90950075bf Three connects paired a zero-argument signal with a slot that has a default-valued parameter (e.g. void applyEnable(bool = true)).
Default arguments aren't part of a function's pointer-to-member type, so &Class::slot has a type requiring the argument regardless of its
default value -- incompatible with a signal providing none, and &Class::slot alone won't compile against these signals at all.
When migrating to the modern member pointer connect, replaced  with a lambda that calls the slot with no arguments, letting
the default apply exactly as before.

- SelectAutonumW::applyEnable(bool = true), connected to each  NumPartEditorW's changed() signal in both setContext() and
  on_add_button_clicked(). The corresponding disconnect() in on_remove_button_clicked() is removed rather than reimplemented: a
  lambda-based connection can't be matched and removed by a  separately-written disconnect() call, and the explicit disconnect
  was already redundant -- the very next line deletes the part object, which Qt automatically disconnects on destruction (the same
  guarantee setContext()'s own qDeleteAll() cleanup already relies  on).
- PartText::adjustItemPosition(int = 0), connected to QTextDocument::contentsChanged().
- ExportDialog::slot_changeFilesExtension(bool = false), connected to ExportPropertiesWidget::formatChanged().
2026-08-08 21:39:31 +02:00
Andre Rummler a668ccfa90 Migrating the remaining signal/slot connects with an ambigious activated(int) via qOverload<int>,
since QComboBox::activated(QString) still exists pre-Qt6 and makes &QComboBox::activated alone ambiguous:

- StyleEditor: outline_color/line_style/size_weight/filling_color,
  both connect (activeConnections(true)) and disconnect
  (activeConnections(false)) branches. antialiasing's stateChanged(int)
  connect modernized alongside them (single signal, no disambiguation
  needed).
- TitleBlockTemplateCellWidget: cell_type_input_ (two connects to
  different slots), horiz_align_input_, vert_align_input_, logo_input_.

Also modernises QETApp's system tray connect.

In two cases stateChanged already replaced with version guarded checkStateChanged for future proofing.
2026-08-08 21:29:17 +02:00
Andre Rummler 62ad49a6d3 Update old fashioned SIGNAL/SLOT to point-to-member. Only simple and clear cases. 2026-08-08 00:32:31 +02:00
Andre Rummler ab61e00cdf Fix QSignalMapper connects silently broken under Qt6 (using the old string based system). QSignalMapper::mapped(int/QWidget*) was deprecated in Qt 5.15 and
removed in Qt6, replaced by mappedInt/mappedWidget/mappedString.

What was broken:
* the logo-conflict rename dialog
* the system tray show/hide toggle
* the Window menu
* export dialog's per-diagram preview controls

Switched to the modern mappedInt/mappedWidget signals with pointer-to-member connect(), guarded for Qt < 5.15 until Qt5 can be dropped.
2026-08-05 10:29:31 +02:00
Shane Ringrose 8a837a11d4 Fix four memory leaks found by AddressSanitizer
- StyleEditor: QGridLayout(this) pre-empted the widget's layout slot,
  causing setLayout(main_layout) to silently fail and orphan main_layout.
  Fix: use QGridLayout() without a parent so setLayout() succeeds.

- ExportDialog: ~ExportDialog() was empty, leaving ExportDiagramLine
  heap objects in diagram_lines_ unfreed. Fix: qDeleteAll(diagram_lines_).

- GenericPanel::getItemForDiagram: when called without the bool* created
  arg, it created a parentless QTreeWidgetItem that callers immediately
  discarded. Fix: return nullptr when created==nullptr and item not found
  (all callers already guard with if (item)).

- ElementScene: m_paste_area (created in initPasteArea) was temporarily
  added/removed from the scene during XML loading but never freed in the
  destructor. Fix: delete it if not currently in the scene.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 01:45:07 +12:00
Laurent Trinques 416ec501fe GenerateSvg: Corrected view:
Auto-build doxygen docs / doxygen (push) Failing after 2m28s
Auto-build doxygen docs / deploy (push) Has been skipped
The contents of svg export is not correctly centered within the exported
area, thanks Tom
https://qelectrotech.org/forum/viewtopic.php?pid=22781#p22781
2026-04-23 09:49:42 +02:00
Laurent Trinques 4044d04cc5 One year
Auto-build doxygen docs / doxygen (push) Has been cancelled
Auto-build doxygen docs / deploy (push) Has been cancelled
2026-01-16 15:24:35 +01:00
plc-user ad29893842 use "%" for string-concatenation
Qt-Docs says it's less memory-usage...
2025-05-22 21:33:32 +02:00
Laurent Trinques 43f0107eb1 Revert "Try Clazy fix-its"
Segfault on old Qt versions!
This reverts commit dba7caed30.
2025-02-14 16:17:58 +01:00
Laurent Trinques dba7caed30 Try Clazy fix-its
clazy is a compiler plugin which allows clang to understand Qt
semantics. You get more than 50 Qt related compiler warnings, ranging
from unneeded memory allocations to misusage of API, including fix-its
for automatic refactoring.

https://invent.kde.org/sdk/clazy
2025-02-14 15:52:23 +01:00
plc-user bbbf77597a export: set maximum width / height according limitations in QPainter 2025-02-07 11:34:05 +01:00
plc-user 924d1c1b05 use "static const" - variables instead of multiple times values in source-code
use multiplication-sign "×" instead of asterisk "*" between widht and height
2025-02-06 15:16:19 +01:00
plc-user 33570ffceb export: set maximum width / height according specifications of export-type 2025-02-06 12:58:32 +01:00
Laurent Trinques c9ba7bee6c ExportDialog increase spinBox limit 10 000px to 100 000px
See: https://qelectrotech.org/forum/viewtopic.php?pid=21002#p21002
2025-02-06 07:12:56 +01:00
Laurent Trinques 77bfe84a4c One year 2025-01-04 13:37:40 +01:00
plc-user 4c52c8c9d0 correct indentations / whitespace 2024-04-10 10:28:58 +02:00
Laurent Trinques e73cf633ce 2023->2024 2024-03-29 10:09:48 +01:00
plc-user ec3952237f simplify setting of alpha-value for SVG-background 2024-03-28 09:32:55 +01:00
plc-user 2043fc2700 fix: add alpha-channel for SVG-background 2024-03-27 20:20:37 +01:00
plc-user 4de379d884 fix: no hardcoded colors for SVG-background 2024-03-27 20:13:35 +01:00
plc-user 2e379a3024 fix: specified colors for filled and transparent SVG 2024-03-27 19:23:19 +01:00
plc-user cc20c218d8 add option "transparent background" in SVG-export 2024-03-27 14:50:26 +01:00
plc-user 5df77291fe fix size of SVG-export 2024-03-14 08:51:53 +01:00
Laurent Trinques 9afef79629 Update Copyright date 2023-01-01 17:05:57 +01:00
David Varley af5d5e0aa3 Allow for open polygons (ie polylines) when saving as dxf 2022-08-13 11:57:29 +10:00
Laurent Trinques ef58f34c14 Update Copyright date 2021-02-20 12:13:46 +01:00
joshua 2513961cd6 Revert "Update Copyright date"
This reverts commit d04bccc384.
2021-02-06 19:00:48 +01:00
Laurent Trinques d04bccc384 Update Copyright date 2021-02-06 18:33:42 +01:00
Simon De Backer 10c4c3d528 Wip Fix preprocessor on Cmake 2020-12-08 19:57:35 +01:00
David Varley 2d6bef71ae DXF - Add some color 2020-09-22 19:41:47 +10:00
David Varley bcc5846662 DXF - Cleaning up scaling 2020-09-22 12:16:32 +10:00
David Varley 4d7ece07ab DXF - Simplifying, WIP 2020-09-17 21:45:14 +10:00
David Varley 6b1d51bab8 DXF - Add Polylines, use for conductors and rectangles 2020-09-11 11:22:08 +10:00
David Varley 046d7c6b59 DXF - Add terminals to plot (optional) 2020-09-10 18:35:22 +10:00
David Varley d5d8181332 DXF - fine tune text item locations 2020-09-10 00:12:45 +10:00
David Varley 713d467fe4 Merge branch 'master' of ssh://git.tuxfamily.org/gitroot/qet/qet 2020-09-08 22:10:31 +10:00
David Varley cc8d0da0ac DXF - Fix conductor number positioning, add junction dots 2020-09-08 21:44:58 +10:00
Simon De Backer 8ee38fab9e Fix Coding convention
Please download and use
https://qelectrotech.org/wiki_new/_media/doc/qtcreator-qet-style.xml
when you write code in Qt
2020-09-07 21:41:45 +02:00
David Varley babf3d2cf2 Merge branch 'master' of ssh://git.tuxfamily.org/gitroot/qet/qet 2020-09-07 22:14:07 +10:00
David Varley 68b4705630 Tidy up som comments 2020-09-07 16:27:59 +10:00
David Varley d062175da7 Add tables to dxf export 2020-09-07 16:16:33 +10:00