The previous sort used QString::toInt() to order terminal names,
which returns 0 for any string containing a non-numeric prefix
(e.g. "R1", "R2", "L1", "L2"...). This caused undefined sort order
and incorrect pole pairing in the Xref contact mirror.
Example: a 4-pole NC power contact with terminals R1..R8 was
displaying R1/R3, R5/R7, R2/R4, R6/R8 instead of the correct
R1/R2, R3/R4, R5/R6, R7/R8.
Fix: extract the trailing numeric part of each terminal name and
compare prefixes separately. If both names share the same prefix
and both have a trailing number, sort numerically on that number;
otherwise fall back to full string comparison.
This covers all naming conventions: "1"/"2"/"3", "R1"/"R2"/"R3",
"L1"/"L2"/"L3", etc.
Applied in both drawContact() and setUpCrossBoundingRect().
Three bugs were causing a crash (SIGSEGV in QRegion::begin) when
a power NC slave element was placed on a folio, even before linking
it to a master element.
1. m_drawing (QPicture) was never reset between updateLabel() calls.
QPicture accumulates paint commands — calling qp.begin() on an
existing QPicture appends to it rather than replacing its content.
After several updates (load, move, hover...) the picture became
corrupted and crashed on play().
Fix: reset m_drawing = QPicture() at the start of updateLabel().
2. m_drawed_contacts was only initialized to 0 in drawAsContacts(),
but not in drawAsCross(). When drawing in Cross mode, fillCrossRef()
called drawContact() with an uninitialized m_drawed_contacts value,
producing a garbage offset. The NC contact symbol uses drawPolyline()
with a sub-pixel Y coordinate (offset+2.5); with a random offset Qt
generated an invalid QRegion and crashed.
This explains why NC contacts crashed but NO contacts did not: the
NO symbol only uses drawLine() which is more tolerant of bad coords.
Fix: add m_drawed_contacts = 0 at the start of drawAsCross().
3. setUpCrossBoundingRect() used QRectF() (null rect) as the reference
rect for painter.boundingRect(), which can return invalid dimensions.
Additionally, height was accumulated incorrectly: united() + setHeight()
doubled the height at each iteration, causing an exponentially growing
bounding rect with multiple contacts.
Fix: use QRectF(0, 0, 500, 20) as reference rect and accumulate
height and width independently.
Extend TerminalData::Type enum with three new semantic values:
- No : Normally Open terminal of a switch (SW) contact
- Nc : Normally Closed terminal of a switch (SW) contact
- Common : Common terminal of a switch (SW) contact
Update typeToString() and typeFromString() accordingly.
Fully backward compatible: existing Generic/Inner/Outer types
are unchanged. Elements without typed terminals fall back
to the previous behavior (first 2 named terminals).
terminal: expose terminalType() as public accessor
Add Terminal::terminalType() returning the TerminalData::Type
of this terminal. This allows crossrefitem and other consumers
to filter terminals by semantic role (No, Nc, Common) without
accessing TerminalData internals directly.
terminaleditor: add No, Nc, Common entries to type combobox
Expose the three new TerminalData types (No, Nc, Common) in
the element editor UI so users can assign a semantic role to
each terminal of a SW contact element.
Also fix a pre-existing bug in updateForm() where m_type_cb
was incorrectly using m_orientation_cb->findData() instead
of m_type_cb->findData(), preventing the type from being
restored correctly when selecting a terminal.
terminaleditor: add No, Nc, Common entries to type combobox
Expose the three new TerminalData types (No, Nc, Common) in
the element editor UI so users can assign a semantic role to
each terminal of a SW contact element.
Also fix a pre-existing bug in updateForm() where m_type_cb
was incorrectly using m_orientation_cb->findData() instead
of m_type_cb->findData(), preventing the type from being
restored correctly when selecting a terminal.
When a slave element has named terminals in its element definition
(.elmt), the terminal names (e.g. 13/14 for NO, 11/12 for NC,
12/13/14 for SW) are now displayed on each side of the contact
symbol in the cross-reference view.
- NO/NC contacts: name[0] on the left, name[1] on the right
- SW contacts: name[0] (NO) top-left, name[1] (common) top-right,
name[2] (NC) bottom-left
Terminal names are read from Terminal::name() which is populated
from TerminalData::m_name during element parsing. If terminals are
not named, nothing is displayed (fully backward compatible).
Users are expected to name their own terminals in the element
editor to avoid duplicating elements in the official collection.
Due to the changes made in the commit "Add highlight current page in
ProjectView", there is a problem when moving diagrams in the ProjectView
using the keyboard. The diagrams lose focus after being moved.
The cause is: The DiagramItem loses its selection before the move
function is executed.
The code has been adjusted.
Disable the QTabWidget internal scroll buttons and add own buttons for
scroll 'one page left' and scroll 'one page right'. The scrolled
diagrams will be activated.
corresponding to operation of project and diagram tabs
- click on the item activates the corresponding diagram or project.
- double click opens the corresponding properties editor.
- selecting with the up and down arrow keys has the same effect.