diff --git a/sources/import/edz/edzelementbuilder.cpp b/sources/import/edz/edzelementbuilder.cpp index 8df885efd..c9161ab50 100644 --- a/sources/import/edz/edzelementbuilder.cpp +++ b/sources/import/edz/edzelementbuilder.cpp @@ -238,63 +238,31 @@ QDomDocument EdzElementBuilder::build(const EdzPart &part) dyn.appendChild(info_name); desc.appendChild(dyn); - // Build unique terminal names. QET requires every terminal in an element - // to have a distinct name for wiring and terminal-diagram generation to - // work. EPLAN parts sometimes repeat the same connectionDesignation across - // multiple function templates (e.g. a drive with several connections named - // "1", "2", "3"). Resolve duplicates: - // 1. If a designation is unique, keep it as-is. - // 2. If duplicated, append "_" + sanitised description when that yields - // a unique result (e.g. "1_L+_P" -> "1_L_P"). - // 3. Fall back to appending "_2", "_3", … when descriptions are missing - // or still collide. - auto sanitise = [](const QString &s) -> QString { - QString out; - for (const QChar c : s) { - out += (c.isLetterOrNumber() || c == QLatin1Char('-')) ? c - : QLatin1Char('_'); - } - // Collapse consecutive underscores and strip trailing ones. - while (out.contains(QStringLiteral("__"))) - out.replace(QStringLiteral("__"), QStringLiteral("_")); - while (out.endsWith(QLatin1Char('_'))) - out.chop(1); - return out; - }; - - // Count occurrences of each raw designation. - QMap desig_count; - for (const EdzPin &p : pins) - desig_count[p.designation]++; - + // Build unique terminal names that an electrician can read directly on + // a wiring list. When a terminalNr connector label is present, prefix it: + // "XDI.2" (terminal block XDI, position 2) + // "XRO1.3" (relay output block XRO1, position 3) + // Power/busbar connections that carry no terminalNr use their designation + // as-is — these are already globally unique ("L1/U1", "UDC+", "PE", …). + // A numeric suffix is appended only if a collision still occurs, which + // should not happen with well-formed EPLAN data. QSet used_names; QVector terminal_names(n); - // Per-designation occurrence counter for the fallback suffix. - QMap desig_seen; for (int i = 0; i < n; ++i) { const EdzPin &pin = pins.at(i); - desig_seen[pin.designation]++; - - if (desig_count[pin.designation] == 1) { - // Unique designation — use directly. - terminal_names[i] = pin.designation; - } else { - // Try designation + sanitised description first. - const QString candidate = pin.description.isEmpty() - ? QString() - : pin.designation + QLatin1Char('_') + sanitise(pin.description); - if (!candidate.isEmpty() && !used_names.contains(candidate)) { - terminal_names[i] = candidate; - } else { - // Numeric suffix fallback: "1", "1_2", "1_3", … - const int occ = desig_seen[pin.designation]; - terminal_names[i] = (occ == 1) - ? pin.designation - : pin.designation + QLatin1Char('_') + QString::number(occ); - } + QString name = pin.group.isEmpty() + ? pin.designation + : pin.group + QLatin1Char('.') + pin.designation; + // Collision guard (malformed data safety net). + if (used_names.contains(name)) { + int suffix = 2; + while (used_names.contains(name + QLatin1Char('_') + QString::number(suffix))) + ++suffix; + name += QLatin1Char('_') + QString::number(suffix); } - used_names.insert(terminal_names[i]); + terminal_names[i] = name; + used_names.insert(name); } // Terminals.