mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-07-30 07:44:13 +02:00
edz: name terminals terminalNr.designation (e.g. "XDI.2")
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>
This commit is contained in:
@@ -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<QString, int> 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<QString> used_names;
|
||||
QVector<QString> terminal_names(n);
|
||||
// Per-designation occurrence counter for the fallback suffix.
|
||||
QMap<QString, int> 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.
|
||||
|
||||
Reference in New Issue
Block a user