The six user-facing error strings in EdzArchive::extract() were hard-coded
QStringLiteral, so they could not be translated (reported by plc-user in
PR #513).
Wrap them in tr() via Q_DECLARE_TR_FUNCTIONS — EdzArchive is not a QObject,
so this gives it its own translation context without pulling in a moc
dependency. The *.part.xml glob stays a QStringLiteral: it is a filename
pattern, not user-facing text.
Adds German and French translations for all six. German wording for
"Cannot read %1" is plc-user's ("Kann %1 nicht lesen.").
Note for review: the rest of QET uses French source strings translated to
en/de in the .ts files, whereas these strings are English in the source
(as merged in PR #513). This commit keeps them English rather than
rewriting strings already reviewed; happy to flip them to French sources
for consistency if preferred.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Resolve cmake/qet_compilation_vars.cmake conflict: keep both upstream's
cli_export.cpp/h and pdf_links.cpp/h and the EDZ source additions.
- 10-position grid alignment: pin_y values are multiples of 10 so terminals
snap cleanly to QET's default grid. group_gap raised to 10 (one full slot).
- Named connector groups get a header label (group name) placed in the gap
above the first pin, so the electrician sees block names (XDI, XPOW, …)
without reading individual terminal designations.
- Device-tag dynamic_text now uses 9pt LABEL_FONT and y = min_y - 9 so it
clears the element body and is legible at normal zoom.
- Add EPLAN Data Portal Terms of Use disclaimer to sources/import/edz/README.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previous logic resolved duplicate connectionDesignation values by
appending sanitised description text or numeric suffixes, which was
fragile and produced names an electrician could not easily map back to
the physical wiring.
New scheme:
• terminalNr present → "XDI.2", "XRO1.3", "XPOW.1" …
• terminalNr absent → designation as-is ("L1/U1", "UDC+", "PE") —
these are busbar / power connections and are already globally unique
• collision (malformed data) → numeric suffix as safety net
The description (connectiondescription) remains as the human-readable
label beside the terminal symbol, exactly as suggested by plc-user.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
EdzPin gained a third field (group) but the fallback initializer at
line 70 still listed only two fields, triggering -Wmissing-field-initializers.
Added the explicit QString() for group.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
EPLAN 2022-style part.xml files (e.g. IFM AL1122) use a numeric
functiondefgroup attribute and do not carry the text functiondefinition
block name that the previous grouping logic relied on. Those parts
fell back to grouping by pin designation, producing symbols with all
pin "1"s stacked together, then all "2"s, etc. — the bug reported in
PR #513.
Fix: read terminalNr first (the physical M12/connector socket identifier,
e.g. "X01", "X31") as the primary group key; fall back to functiondefinition
text for older EPLAN formats that omit terminalNr. Pins within each
connector group are still sorted by designation using natural sort.
Also remove the dashed inter-group separator lines; the existing 5 px
gap between groups provides sufficient visual separation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous grouping compared `connectionDesignation` values (e.g. "1",
"2", "3") to detect group boundaries. Those values are pin position
numbers within a terminal block, not functional group identifiers, so
devices like the ABB ACS880 produced 11+ tiny single-pin "groups" instead
of the ~8 functional blocks (AC-IN, Motor-OUT, DC-Bus, Brake-Resistor,
Analog-I/O, Digital-I/O, ...) the reviewer identified.
Fix:
- Add `group` field to EdzPin, populated from the `functiondefinition`
attribute on <functiontemplate> (newer EPLAN) or its parent <function>
element (older EPLAN).
- Sort pins by group first (preserving XML appearance order per group),
then by designation within each group using natural sort.
- Use `groupKey()` — group when present, designation as fallback — for
the group-break detection that drives separator lines and Y-gaps.
Parts without any functiondefinition data retain the previous
designation-based behaviour unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pins are already sorted by designation (see EdzPart::parse natural sort).
This change makes same-designation groups visually obvious in the element
symbol by:
- Inserting a 5 px gap between consecutive terminals whose designation
differs, so each group reads as a distinct block.
- Drawing a thin dashed horizontal line through each gap, mirroring
the grouped-I/O style shown in typical manufacturer datasheets.
The body rectangle and bounding box grow automatically to accommodate the
extra gaps, so no fixed sizes change. Unique terminal names (added in the
previous commit) are unaffected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two issues raised in PR review:
1. Copyright year: new files carried "2006" (the project's founding year).
Updated to "2006-2026" to reflect the actual authorship period.
2. Duplicate terminal names: EPLAN parts can have multiple connection
templates sharing the same connectionDesignation (e.g. a drive where
both wire entries of terminal "1" are labelled "1"). QET requires
unique terminal names for wiring and terminal-diagram generation.
Resolution order in EdzElementBuilder::build():
- Unique designation → used as-is.
- Duplicated designation with distinct sanitised description →
"designation_description" (e.g. "1_L_P").
- Otherwise → numeric suffix: "1", "1_2", "1_3", …
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- EdzArchive checks the archive magic up front: gives a clear message for
zip-format .edz (not yet supported) and unrecognised data, instead of an
opaque 7z decode error.
- Trim the vendored LZMA SDK headers to the decode closure actually used
(removes 21 unused encoder/multithread/Xz/Aes headers; 18 .c + 18 .h remain).
- Add sources/import/edz/README.md documenting the feature, the data mapping
and the bundled SDK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replaces the QProcess->7z shim with the public-domain LZMA SDK (23.01) 7-Zip
reader, vendored under sources/import/edz/lzma/ (decode-only subset). New
edzsevenzip.cpp wraps SzArEx_Open/SzArEx_Extract and writes entries via Qt, so
EdzArchive no longer needs an external 7-Zip at runtime. Enables the C language
in CMake for the vendored sources.
Verified: the bundled decoder extracts all three ifm sample .edz and the
generated elements still match the Python oracle exactly (byte-correct decode),
with no 7z on the path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wires EPLAN .edz import into the elements panel. EdzImporter orchestrates
EdzArchive -> EdzPart -> EdzElementBuilder and writes the generated .elmt into a
destination collection folder (named by order number). A right-click
"Importer une piece EPLAN (.edz)..." action on a writable collection directory
opens a file picker, runs the importer into that folder's fileSystemPath() and
reloads the panel; errors surface via QetMessageBox. Modeled on newElement().
EdzImporter verified headless against the Python oracle for KG6000/MFH200/
R1D200; the panel wiring is built/tested via the WSL Qt5+KF5 build.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Port of the edz2qet.py prototype's mapping to C++. EdzPart parses an EPLAN
part.xml into a portable model (identity/metadata, localized names, connection
list); EdzElementBuilder turns that into a QET element (generic symbol: body
rectangle + one west-facing terminal per pin, per-pin labels, localized <name>s,
and elementInformations for the BOM).
Pins are natural-sorted by designation so they stack 1,2,3,4 regardless of the
order EPLAN lists them (MFH200 lists 1,3,4,2). Output verified structurally
identical (uuids aside) to the Python oracle for three ifm samples — KG6000
(4-pin), MFH200 (4-pin, reordered) and R1D200 (5-pin, incl. Dutch name) — and
the generated element loads in the QET editor with correct UTF-8.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
First piece of native EPLAN Data Portal (.edz) import. A .edz is a 7-Zip
archive; QET previously had no archive handling. EdzArchive unpacks one to a
temporary directory and locates the contained part.xml.
The extraction backend is isolated behind extractWithSevenZipCli() so it can be
replaced with a bundled decompressor later without touching callers; this M0
step shells out to a 7-Zip CLI via QProcess. Verified on three ifm sample
parts (KG6000, MFH200, R1D200 — all 7z), plus the corrupt/missing-file paths.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>