Commit Graph

81 Commits

Author SHA1 Message Date
ispyisail bec0f1c7b4 Fix #1280: junction dot missing where a wire's corner meets a wire it is not wired to
A conductor draws a junction dot at each of its bends that lies on
another conductor. It only looked at the conductors on its own two
terminals, so a bend lying on a conductor of the same potential that
shares no terminal with it got no dot. Dragging the horizontal parts of
a chain of conductors onto one line, as in the report, does exactly that.

Look at every conductor of the potential on the folio instead
(relatedPotentialConductors(false)). The folio scene uses NoIndex, so a
scene lookup at each bend scans every item and made export of the
366-conductor Polonez example 60% slower; walking the potential costs
nothing measurable there (2.08 s vs 2.11 s) or on a 153-conductor
potential (0.97 s both).

The test for one other conductor moves into bendMakesJunction(). It
also stops a point being appended once per matching segment: master drew
the dot above K2 in the fixture ten times.

Across the 23 examples (133 folios) exported to SVG, 6 dots are added,
all at T-joints that had none, and none removed.

tst_junctiondots exports fixtures/junction_dot_shared_potential.qet and
checks for both dots; it fails on master with the dot above K3 missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 10:57:27 +13:00
ispyisail 649f06b3b8 Add View > Show to hide texts, shapes, pictures by kind (bugtracker #301)
A submenu under View (Affichage > Afficher) with one tick per kind:
symbol texts, wire texts, free texts, shapes, pictures, tables and
cross-references. Unticking one hides it on every folio of every open
project; the status bar says how many kinds are hidden. Session only,
not saved in the project.

Each item is tagged with its kind by its constructor (ShownKinds::tag),
so an item created while its kind is hidden starts hidden whatever
created it. A tag rather than type(): the cross-reference under a
contact's label is a plain QGraphicsTextItem.

Items that already hide themselves (wire text switched off, one text per
potential, a cross-reference snapped elsewhere) now go through
ShownKinds::setVisible(): the kind state can only veto a show, and
apply() re-shows only what it hid itself (hidden_key), never what an
item hid. Conductor::updateTextVisibility() replaces the same visibility
rule pasted in diagrampropertiesdialog.cpp and qetscriptapi.cpp.

Hidden items are not selectable (Qt), so Select All, copy and delete
skip them. Print, PDF and image export render the scene and leave them
out; the DXF export walks items itself and skips them through
ShownKinds::isHidden(). CrossRefItem::linkedChanged() keeps following
its slaves while hidden only by kind, so its label is right when shown.

Known limitation: QGraphicsScene::itemsBoundingRect() still counts hidden
items, so Zoom to fit and borderless image export keep their space.

Verified: tst_shownkinds (12 cases, two mutation checks) and ctest 55/55;
GUI hide/show of symbol texts, wire texts (incl. one text per potential),
free texts, shapes and cross-references returns pixel-identical folios;
with nothing hidden, --export-dxf of the 24 examples is byte-identical to
master (133 files) and --export-pdf renders identically (133 pages).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015FPuYPS4T7QuEwjNu22rXD
2026-10-03 19:44:12 +13:00
ispyisail 5e28e015e0 Scripting API and MCP: route a conductor around the symbols in its way
A new conductor gets the default two or three straight segments, which
run through whatever symbol or wire lies between its terminals; scripts
then fix it segment by segment with moveConductorSegment().

ConductorRouter finds an orthogonal path on the folio grid that leaves
and enters each terminal in its own direction, keeps clear of every
element's rectangle, stays inside the border, and charges for bends and
for running along or crossing other wires. qet.routeConductor() and
qet.routeConductorBetween() apply it through Conductor::setPathPoints(),
which pushes the same ChangeConductorCommand a handle drag does, so the
path is saved, survives a reload, and one undo restores the default.
Where no route exists the wire keeps its path and the call says so.

qet-mcp: add_conductor takes "route": "avoid", and a route_conductor op
reroutes an existing conductor (by terminal or by uuid). The router
methods are required only by an edit that routes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 22:28:11 +13:00
ispyisail 79a8637251 Add optional hops where wires cross (#436)
Where two wires cross without being connected, a project can now draw a
small arc (a hop) on one of them, instead of the user inserting a jump
symbol and splitting the wire. It is a project setting, off by default:
Project properties > Général > "Croisements de conducteurs", with no
hops, hops on horizontal wires, or hops on vertical wires. Choosing the
orientation rather than following drawing order keeps a project
consistent.

Only the drawing changes: no element is added and no wire is split. A
wire that ends or bends on another one is a junction and never hops,
and a crossing too close to the end of a segment for the arc to fit is
drawn plainly. PDF, SVG and image export and printing show the hops,
since they paint through Conductor::paint(); DXF export, which writes
the segments itself, does not.

The setting is saved as <wire_crossings hop="..."/> under the project
root, next to <usage>, and only when hops are on, so a project that
never used them saves exactly as before.

The geometry is in wirehops.cpp, free of any graphics item, and tested
on its own. Conductor::paintedPath() feeds it the conductors of the
folio from a snapshot of their scene points, rebuilt only when a
conductor changes shape, moves, or enters or leaves a folio; each hop
path is cached the same way. Asking the scene for the conductors in a
rect instead strokes every candidate's shape, which made a 366-wire
folio render 0.6 s slower; with the snapshot the difference is within
measurement noise.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:18:12 +13:00
ispyisail b3a4e30010 Give wires saved without a uuid a lasting one, from what they connect
A wire saved without a uuid got a random one on every load, never saved
(#754): it had no identity from one session to the next, so a script
could only name it as "the wire on terminal N of symbol X", and a
comparison of two versions could not tell a moved wire from a new one.

When a folio is loaded, such a wire now gets a UUID v5 derived from its
two ends -- the symbol and terminal at each, sorted so the direction it
was drawn in does not matter -- and it is written on save. Never its
place in the file or its folio's index: inserting or moving a folio, or
saving the wires in another order, does not change it. Once saved the
uuid no longer depends on the ends, so re-connecting the wire keeps it;
QETProject::derivedItemUuid() never hands out a uuid the file already
carries, so a wire later drawn on the ends it left gets another one.
Wires that have a uuid keep it; a paste still renews them.

The 24 example projects: 3,189 wires, none with a uuid before, all 3,189
after one save, none lost, no uuid used twice in any project; two saves
of the same file are identical, and a second save keeps every wire's
uuid. Discussion #1103 has the measurements behind the recipe.

tst_derivedwireuuid runs --resave on a fixture naming ends by uuid and on
examples/tremie_vibrante.qet (ends by terminal number): every wire gets a
distinct uuid, the same on every load, read back after a save, kept per
wire when a folio is inserted, the wires are reordered or a wire is drawn
the other way, and a newcomer on a re-connected wire's old ends gets
another uuid. Without this change 14 of the 18 fail; with the uuid taken
from folio index and file order instead, the folio-insert and reorder
tests fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 21:13:02 +13:00
ispyisail ea1f65107e Add manual conductor routing to the scripting API
Conductor::moveSegment(index, dx, dy) is the same primitive
handlerMouseMoveEvent()/handlerMouseReleaseEvent() apply on a drag --
move both axes on the target segment (each of ConductorSegment's
moveX()/moveY() silently no-ops on the wrong axis or a static,
terminal-anchored segment), recompute the path, and push one
ChangeConductorCommand undo step via the existing saveProfile().

Caught while writing the first test for it: moveSegment() never set
modified_path, so Conductor::toXml() skipped writing <segment> children
and a manually rerouted conductor silently reverted to auto-routing on
the very next save -- the change took effect in the running scene but
never reached disk. Fixed by setting the flag, the same as every other
path-modifying call site already does.

qet.conductorSegments() lists a conductor's segments (endpoints in
scene coordinates, orientation, static/movable) so a script can find
the index it wants; qet.moveConductorSegment() applies the move and
refuses a static segment or an out-of-range index.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 21:56:31 +12:00
ispyisail 0d08a4e265 Make Diagram::toXml() serialize elements and conductors deterministically
Saving an unmodified project produced a different byte stream on
every run: QGraphicsScene::items() returns items in stacking order,
and ties between same-Z items follow the scene's internal index --
not any content-derived order -- so it isn't reproducible across
process runs. The legacy terminal-id table inherits the same
instability, since ids are assigned sequentially in element order.

Sort list_elements and list_conductors into a deterministic order
before serializing, using a key built from data that's actually
stable across loads (position), not Element::uuid()/Conductor::uuid():
for an item with no persisted uuid attribute, fromXml() invents a
fresh random one on every load, so sorting by uuid would still be
non-deterministic across process runs for any legacy file -- which
this corpus has plenty of.

Also fixes a second, related source of byte-level non-determinism
found while verifying the above: Conductor::toXml() unconditionally
wrote m_uuid back out, including the synthetic value fromXml() just
invented for a conductor with no uuid attribute in the file. Every
conductor in every example project checked has no persisted uuid at
all, so this alone meant no project with conductors could ever
resave identically, regardless of ordering. Conductor gets a
m_persist_uuid flag, false only when the uuid it's holding was
synthesized rather than loaded, so toXml() stops writing a value
that was never meant to be permanent.

Deliberately NOT applying the same uuid-persistence fix to Element:
element uuids are cross-referenced by other elements' <links_uuids>
blocks for master/slave/report linking (element.cpp, tmp_uuids_link,
matched by elmt->uuid() == stored uuid on load). Making an element's
own uuid non-persistent would silently break that match for any
linked element without one already -- a real regression, not a
theoretical one. Left as a smaller, separate residual: 1-6 elements
per project across the corpus (a few tenths of a percent) still get
a fresh uuid on each load, same class of bug, needs the link-aware
version of this fix instead of this one.

Verified against 8 example projects (the ones with conductors, plus
the two zero-conductor control cases from FINDINGS.md F002), 5
resaves each in isolated HOME/XDG environments:
- Element and conductor ORDER: 0 churning sections across the whole
  corpus (previously the majority of diagrams in industrial.qet,
  m_000.qet and tremie_vibrante.qet churned on every run).
- Conductor uuid VALUES: 0 churn (previously every conductor in
  every project, since none have a persisted uuid).
- 6 of 8 projects are now byte-for-byte identical (md5) across all 5
  runs. The remaining 2 (industrial.qet, m_000.qet) differ only in
  the handful of element uuids covered by the known Element residual
  above -- confirmed by checking those uuids specifically, not
  inferred.
- Element/conductor counts before and after resave match exactly on
  every project (no data loss from the sort).

Fixes #754.
2026-08-24 20:41:01 +12:00
ispyisail a3511e8694 Give Conductor its own persisted uuid
Slice 1 of discussion #503 (from-to wiring list built on projectDataBase).

Conductor is the one item type on a diagram without a stable identity
of its own -- Element and Diagram both have a uuid, Conductor didn't.
This is the prerequisite the wiring-list tables need: a conductor
table keyed by uuid, the same way the existing element table is keyed
by Element::uuid().

- Conductor gets a QUuid m_uuid, generated in the constructor, with
  uuid()/newUuid() accessors mirroring Element's exact pattern.
- toXml()/fromXml() read/write a "uuid" attribute the same way
  Element already does, including the same generate-on-missing
  fallback (QUuid(e.attribute("uuid", QUuid::createUuid().toString())))
  for projects saved before this change.
- PasteDiagramCommand::redo() calls newUuid() on every pasted
  conductor (content.conductors(), all three categories), mirroring
  the existing per-element newUuid() call right above it -- otherwise
  copy-paste would duplicate a conductor's uuid.

Backward compatibility: Conductor::valideXml() doesn't require the
"uuid" attribute, so old files parse unchanged. Verified by opening a
genuinely pre-uuid project (examples/industrial.qet, 150 folios, 671
conductors, legacy integer terminal1/terminal2 references with no
uuid attribute at all) -- loads and renders correctly, gets uuids
assigned on load, and those uuids are stable across a second
load/save cycle (byte-identical uuid values). Verified paste
separately: copying a selection with conductors and pasting produces
distinct new uuids for every pasted conductor, none colliding with
the originals or each other.
2026-08-02 08:12:22 +12:00
Laurent Trinques 4044d04cc5 One year
Auto-build doxygen docs / doxygen (push) Has been cancelled
Auto-build doxygen docs / deploy (push) Has been cancelled
2026-01-16 15:24:35 +01:00
plc-user e987d8c271 fix typo in variable-name 2025-02-28 20:25:31 +01:00
plc-user 3471140b64 fix typo in fuction-name (looked like a mixture of French and English) 2025-02-14 16:47:39 +01:00
Laurent Trinques 77bfe84a4c One year 2025-01-04 13:37:40 +01:00
plc-user fa68d545d0 correct more indentations / whitespace 2024-04-24 14:14:40 +02:00
Laurent Trinques e73cf633ce 2023->2024 2024-03-29 10:09:48 +01:00
joshua ec5cda10db Minor : improve first and last segment position of conducteur 2023-01-31 23:13:05 +01:00
Laurent Trinques 9afef79629 Update Copyright date 2023-01-01 17:05:57 +01:00
luz paz 1994235bc5 Fix various typos in source documentation and comments (cont.)
Found via `codespell`
2022-12-04 20:46:32 +01:00
joshua 11b8ef927b Revert "Merge branch 'XMLPropertiesNew'"
**Break a lot of thing.**

This reverts commit 1db1800572, reversing
changes made to 4c563821e8.
2021-03-11 19:52:50 +01:00
Martin Marmsoler 5d3710c4b2 copy all toXML() from master commit 4b82c3a0c4 into the current branch, because the new concept will be used only for user properties 2021-03-07 10:09:45 +01:00
Martin Marmsoler 9d4b90da1a Add userProperties 2021-03-04 19:18:28 +01:00
Martin 02b7ead041 fix compile issues 2021-02-24 18:48:59 +01:00
Martin ea364f9c4e merge 2021-02-23 17:35:55 +01:00
Laurent Trinques ef58f34c14 Update Copyright date 2021-02-20 12:13:46 +01:00
joshua 2513961cd6 Revert "Update Copyright date"
This reverts commit d04bccc384.
2021-02-06 19:00:48 +01:00
Laurent Trinques d04bccc384 Update Copyright date 2021-02-06 18:33:42 +01:00
Simon De Backer 10c4c3d528 Wip Fix preprocessor on Cmake 2020-12-08 19:57:35 +01:00
Martin Marmsoler 9658a88c18 fix compile issues 2020-10-20 08:54:56 +02:00
Martin Marmsoler 12e301b887 replace 4 spaces by a tab 2020-10-20 08:54:56 +02:00
Martin Marmsoler f3097fc537 rebase XMLProperties_New (c0d9bf9) to master 2020-10-20 08:54:14 +02:00
Martin Marmsoler 73b394527d replace tabs by 4 spaces 2020-10-20 08:53:43 +02:00
David Varley 713d467fe4 Merge branch 'master' of ssh://git.tuxfamily.org/gitroot/qet/qet 2020-09-08 22:10:31 +10:00
David Varley cc8d0da0ac DXF - Fix conductor number positioning, add junction dots 2020-09-08 21:44:58 +10:00
Simon De Backer 5d92393ee7 Wrap code for better readability 2020-09-07 22:03:40 +02:00
Simon De Backer 566747eb2b Improve code style, Wrap code for better readability 2020-08-18 21:29:12 +02:00
Simon De Backer 5e3e3aa4bd Improve code style, Wrap code for better readability, Mod doc 2020-08-16 14:24:51 +02:00
Simon De Backer d4ee161c07 Mod doc set style de same 2020-08-16 11:19:36 +02:00
Laurent Trinques e10ae8ce2e Update Copyright date 2020-06-15 17:42:53 +02:00
scorpio810 3ed7a4e63b Minor : update Copyright date
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5705 bfdf4180-ca20-0410-9c96-a3a8aa849046
2019-01-13 16:56:12 +00:00
scorpio810 e4b1ba9797 Apply clang-tidy's performance-unnecessary-value-param, performance-for-
range-copy


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5448 bfdf4180-ca20-0410-9c96-a3a8aa849046
2018-07-19 14:14:31 +00:00
blacksun bca58fa555 Conductor is an herited class of QGraphicsObject, instead of QObject and QGraphicsPathItem
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5371 bfdf4180-ca20-0410-9c96-a3a8aa849046
2018-05-18 19:36:27 +00:00
scorpio810 31f36b8625 Modernize-use-override refactors code
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5009 bfdf4180-ca20-0410-9c96-a3a8aa849046
2017-08-05 02:10:01 +00:00
scorpio810 9f9b127c04 Modernize-use-nullptr refactors code
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5008 bfdf4180-ca20-0410-9c96-a3a8aa849046
2017-08-05 02:06:59 +00:00
blacksun 618683d962 Toatly revamp of the handlers use to modify primitves, shapes and conductors.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5001 bfdf4180-ca20-0410-9c96-a3a8aa849046
2017-08-02 15:26:14 +00:00
scorpio810 54c85db29c Minor update Copyright year
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4860 bfdf4180-ca20-0410-9c96-a3a8aa849046
2017-01-20 10:55:49 +00:00
blacksun 7bad2f1b50 Text of conductor is updated when folio position change, if formula contain the variable %id.
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4845 bfdf4180-ca20-0410-9c96-a3a8aa849046
2017-01-14 15:01:49 +00:00
blacksun 14f02d4ed1 revert and merge rev 4823.
Fix : in old projects without the conductors formula, the conductors texts aren't loaded and displayed
Fix it in method void Conductor::refreshText()


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4825 bfdf4180-ca20-0410-9c96-a3a8aa849046
2016-12-28 10:03:47 +00:00
scorpio810 52f911887d Revert rev 4814 and 4820 momentarily
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4823 bfdf4180-ca20-0410-9c96-a3a8aa849046
2016-12-24 12:48:44 +00:00
blacksun d8a374629b Modifie the text item of a conductor directly on a diagram also change the value of formula and label of the conductor property.
The change is apply for every conductors in the same potential


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4814 bfdf4180-ca20-0410-9c96-a3a8aa849046
2016-12-19 15:57:20 +00:00
blacksun 543578c3dc Conductor :
Use method toXml and fromXml of sequentialNumbers.
Use m_freeze_label instead of m_frozen_label to save the frozen status of the text item.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4807 bfdf4180-ca20-0410-9c96-a3a8aa849046
2016-12-12 10:52:44 +00:00
blacksun 9f014d55af Revamp struct sequenceStruct to class sequentialNumbers.
Element now use methods (toXml and fromXml) of sequentialNumbers to store and load sequential.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@4803 bfdf4180-ca20-0410-9c96-a3a8aa849046
2016-12-08 15:06:46 +00:00