directly to the related component on its folio, framing the target element.
When a project is exported to PDF, every cross-reference becomes an internal
link. Four kinds are covered:
- **Master → contact**: the contact list on a coil/relay (`CrossRefItem`)
- **Folio report → report**: report element labels (`DynamicElementTextItem`)
- **Slave → master**: the `(folio-position)` reference shown on a slave
(both standalone `DynamicElementTextItem` and grouped `ElementTextItemGroup`)
Clicking a link navigates **inside** the open document (no new viewer
instance) and zooms to frame the target element.
1. **Injection** (`printDiagram`, only when the paint engine is a `QPdfEngine`):
link rectangles are added with `QPdfEngine::drawHyperlink()`. The scene→page
mapping is rebuilt to match exactly what `QGraphicsScene::render()` does
(top-left anchored, `KeepAspectRatio`, **no centering**), and rectangles are
passed in device pixels — `pageMatrix()` already applies the 72/resolution
scale and Y-flip internally.
2. Each link URL encodes the target page and the target element's rectangle, in
PDF points on its own page: `#page=N&fitr=L_B_R_T`.
3. **Post-processing** (`pdfConvertUriToGoTo`, run after the painter is closed):
the `/S /URI` annotations are rewritten to native `/S /GoTo` actions with a
`/D [pageObj 0 R /FitR L B R T]` destination, and the xref table is rebuilt.
Pages are enumerated from the `/Pages /Kids` tree (reliable), not by scanning
for `/Type /Page` in raw bytes.
- `sources/print/projectprintwindow.{cpp,h}` — injection + post-processing
- `sources/qetgraphicsitem/crossrefitem.{cpp,h}` — `hoveredContactsMap()` accessor; store text rect for hit area
- `sources/qetgraphicsitem/dynamicelementtextitem.h` — `slaveXrefItem()` / `masterElement()` accessors
- `sources/qetgraphicsitem/elementtextitemgroup.h` — `slaveXrefItem()` accessor
- `qelectrotech.pro`, `cmake/qet_compilation_vars.cmake` — enable Qt gui-private headers (`<private/qpdf_p.h>`)
- **Fit-to-page mode only.** Links are not injected in tiled mode (multiple
pages per folio), which would require a per-tile transform.
- Uses Qt private API (`QPdfEngine::drawHyperlink`), stable since Qt 4 but not
part of the public API; the build links against `gui-private`.
- Page-tree enumeration assumes the flat `/Kids` array Qt produces (no nested
page trees).
- The frame zoom is controlled by two constants in `destRectPdf` (`pad`,
`minSide`) and can be tuned.
- Tested on Qt5; the `/Kids` parsing and `pageMatrix` behaviour are identical on
Qt6.
Fix a use-after-free crash (SIGSEGV in QRegion::begin, Qt5Gui+0x49af60)
confirmed by analysis of 19 coredumps. The crash was triggered when the
scene viewport clip region was freed during zoom/resize events while
QPicture::play() replayed drawPolyline commands through the scene painter.
Qt's raster engine then dereferenced a stale QRegionData pointer.
Root cause: CrossRefItem used three nested QPicture objects (m_drawing,
m_hdr_no_ctc, m_hdr_nc_ctc). The nested drawPicture() calls amplified
the use-after-free risk on any repaint event.
Fix: remove all QPicture from CrossRefItem entirely.
- updateLabel() now uses a QImage-backed dummy painter to compute
m_bounding_rect, m_shape_path and m_hovered_contacts_map geometry.
A bool m_update_map flag prevents the map from being overwritten
during paint().
- paint() calls drawAsCross()/drawAsContacts() directly on the scene
painter — no QPicture::play() anywhere in the class.
- buildHeaderContact() now draws NO/NC symbols directly onto the painter
instead of recording them into QPicture members.
Also fix mouseDoubleClickEvent: the element under the click is now found
directly from m_hovered_contacts_map using the event position, rather
than relying on m_hovered_contact which could be reset by hoverMoveEvent
between the two clicks of a double-click.
Also remove setBold(true) on terminal name labels: the Qt PDF/SVG/print
engine rendered bold at 4pt as extremely thick glyphs, making exports
unreadable. Normal weight at 4pt is correct and legible on all backends.
Fixes: SIGSEGV in CrossRefItem::paint() on zoom/resize
Fixes: double-click navigation unreliable on Xref contact symbols
Fixes: terminal name labels unreadable in PDF/SVG/print export
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.
This option alows for displaying XRef without contact drawing.
This is useful for spliting one physical part into multiple
logical elements when the slave element is not a switch.
From now, the class ElementTextItem is not anymore use in qet. Every texts in a diagram are DynamicElementTextItem.
the Xref item was adapted to dynamic text.
Previously, the comment and location, displayed as a "static text" below the "old text" tagged "label" are now automaticaly converted to DynamicElementTextItem, so visually, these texts stay unchanged
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5216 bfdf4180-ca20-0410-9c96-a3a8aa849046
Some variable was not assigned.
Improve the bounding rect to be more accurate
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4783 bfdf4180-ca20-0410-9c96-a3a8aa849046
Master element : minor change related to the change of cross ref item
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@3539 bfdf4180-ca20-0410-9c96-a3a8aa849046
They don't work now with official collection, because we must to update the information of element (type coil or protection).
You can test it by creating new master element (dont forget to define the master type, coil or protection).
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@3185 bfdf4180-ca20-0410-9c96-a3a8aa849046
Double clic in xref open the properties dialog of master.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@3183 bfdf4180-ca20-0410-9c96-a3a8aa849046
Minor improvemnt: the table update is size according to his content
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@3060 bfdf4180-ca20-0410-9c96-a3a8aa849046
Option is found in config dialog under the tab Cross ref.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@3033 bfdf4180-ca20-0410-9c96-a3a8aa849046
Change properties in project is applied immediately to cross ref
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@2985 bfdf4180-ca20-0410-9c96-a3a8aa849046
element : improve the function to sort an element list
qet graphics item : add a bool to disable the snap to grid (used for cross ref item, to be exactly at the bottom of element)
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@2948 bfdf4180-ca20-0410-9c96-a3a8aa849046