Commit Graph

253 Commits

Author SHA1 Message Date
ispyisail bd5cff4211 Add a unit test locking in Diagram::toXml()'s coordinate sort order
Follow-up to the positionKey() fix merged directly in #779
(b2f4ef5d2): per review request, add a small regression test so this
class of bug (fixed-precision "%.4f" formatting compares out of
numeric order once the integer part's digit count differs) can't
silently reappear.

positionKey()/coordinateKey() move out of diagram.cpp's anonymous
namespace into a small header-only diagramsortkeys.h so the test can
link against the exact same code Diagram::toXml() uses, instead of
duplicating the algorithm. Behavior is unchanged.

tst_diagramsortkeys covers: single- vs double-digit, double- vs
triple-digit, negative-vs-negative, negative-vs-positive, and
negative-vs-zero coordinate pairs, plus sub-precision deltas.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-07 20:54:18 +12:00
ispyisail b2f4ef5d25 Fix: positionKey() didn't sort coordinates numerically
Plain fixed-precision formatting ("%.4f") produces strings that don't
compare in numeric order once the integer part has a different digit
count -- e.g. "15.0000" sorts before "5.0000" as text, even though
15 > 5. That silently broke the determinism goal of this branch for
any diagram with coordinates spanning more than one digit width.

Shift into a non-negative range and zero-pad to a fixed width instead,
so the formatted string sorts the same way the number does, including
negative values.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-07 20:13:05 +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
Laurent Trinques 7f7185172f Merge pull request #628 from ispyisail/feature-wiring-db-tables
Add terminal and conductor tables to projectDataBase (discussion #503, slice 2)
2026-08-21 14:03:02 +02:00
ispyisail 43da912aad Add terminal and conductor tables to projectDataBase
Slice 2 of discussion #503 (from-to wiring list built on projectDataBase),
building on the conductor uuid from slice 1 (#625). Pure plumbing: two
new additive tables plus their populate/add/remove hooks. No view, no UI,
no visible behavior change yet -- the wiring-list view is slice 3.

Follows the existing shape of the class throughout: same table/column
naming, same prepared-statement idiom in prepareQuery(), same
bind/exec/qDebug-lastError error handling, same DELETE-then-loop
populate pattern.

- `terminal (uuid, element_uuid, name)` and
  `conductor (uuid, diagram_uuid, terminal1_uuid, terminal1_element_uuid,
   terminal2_uuid, terminal2_element_uuid, text)` created alongside the
  existing tables in createDataBase().
- populateConductorTable() added as a fifth populate* call in updateDB().
  Terminal population is folded into it, since a terminal only matters
  here in the context of a conductor referencing it.
- addConductor()/removeConductor() hooked into the already-existing
  Conductor::Type branch of Diagram::addItem()/removeItem(), mirroring
  the Element::Type branch directly above.

Two things the original schema sketch in the discussion got wrong, found
by testing rather than inspection:

1. Terminal::uuid() is NOT unique per placed terminal. It is the
   terminal-position id baked into the catalog .elmt definition ("the
   top terminal"), so every placed instance of the same catalog element
   shares it. A terminal instance is only uniquely identified by
   (uuid, element_uuid) together, so that pair is the terminal table's
   primary key and the conductor table carries both halves for each
   endpoint. With uuid alone as PK, the second placed instance of any
   element silently lost its terminals to the INSERT OR IGNORE.
2. Conductors whose terminals predate terminal uuids are omitted rather
   than given a fabricated identity, as agreed in the discussion. This
   turns out to matter far more than expected in practice -- see below.

Testing (all live, in the running app):

- Incremental add: fresh project, two vertically aligned contacts placed
  so autoconnect creates a conductor -> 2 terminals, 1 conductor.
- Incremental remove: deleting that conductor -> conductor count 1 -> 0.
- Undo: ctrl+Z after the delete -> back to 1, no duplicate-primary-key
  error (the same Conductor object keeps its uuid).
- Bulk populate: examples/weneedpolonez-Polonez_MR89_wiring_diagram.qet
  (366 conductors) -> 478 terminals, 280 conductors; the 86 conductors
  touching legacy terminals correctly omitted.
- Join correctness: conductor -> terminal (composite key) -> element_info
  resolves real from-to rows with real element labels.
- Legacy-only project: examples/industrial.qet has 1794 terminals and
  *zero* terminal uuids, so all 671 of its conductors are omitted. Loads
  and renders fine, no crash, no spurious rows -- but worth stating
  plainly that a from-to wiring list for that project would be empty
  today. This is a property of the element catalog definitions, not of
  the project file, and is the strongest argument for surfacing an
  "N conductors excluded" count to the user when the view lands.
- No SQL errors logged in any of the above.

Known limitation, consistent with existing behavior: removeDiagram()
does not cascade-delete the conductor rows of that diagram, exactly as
it already does not cascade to element/element_info. A full updateDB()
rebuild clears them, and the future wiring-list view INNER JOINs from
conductor, so orphan terminal rows never surface.
2026-08-21 19:07:49 +12:00
Andre Rummler 7ba295a339 Remove all Qt version checks and branches for <5.14.0 as such versions are no longer supported. 2026-08-13 15:45:15 +02:00
Kellermorph b3a4a41ad9 new Checkbox 2026-08-06 21:37:40 +02:00
Kellermorph 979df376d1 show terminalnames in export 2026-08-06 12:48:11 +02:00
Dieter Mayer 1265e51ebe Replace deprecated qAsConst with std::as_const
qAsConst was deprecated in Qt 6.6; std::as_const (C++17, already the
project standard) is the drop-in replacement. Clears 46 -Wdeprecated-
declarations warnings across 18 files. No behavioural change.
2026-07-14 19:27:16 +02:00
Kellermorph 0555cd9045 Address review feedback: double spinboxes, tabs, and fix export bug 2026-06-18 13:37:24 +02:00
Kellermorph 4e0c075575 Fix grid and guide startup behavior and update german translation 2026-06-16 17:41:03 +02: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
achim 73ce3ae9fe Correct compositeText alignment on copying
After the commit 'Correcting dynamicElementTextItem alignment on
copying', not all composite text was displayed correctly. As soon as the
composite text contained multiple variables in a line or user text, the
alignment was no longer correct. Furthermore, the text value was not
correctly written to the clipboard, so it was no longer present when
pasting. I have corrected these errors here.
2025-08-19 20:16:31 +02:00
achim 96d84bf852 Better handling of conductors when creating from XML
The position of a conductor is determined by the two terminals the
conductor connects. Therefore, it makes no sense to set the position
with 'setPos()'.

It is better to first load all elements (but not the conductors),
position them if necessary, and only then load the conductors and assign
them to the elements (terminals).
2025-08-03 01:04:37 +02:00
achim 0a6efa466e Correcting dynamicElementTextItem alignment on copying
When copying and pasting selected areas, right-aligned dynamic text in
report and slave elements was not displayed correctly. The text
insertion point was always shifted to the left by the text width.

To correct this, the insertion point of dynamicElementTextItems is reset
to its origin insertion point before writing to clipboard.
2025-08-02 23:27:09 +02:00
plc-user c7ed744481 Include some fonts to QElectroTech
- include Liberation-Fonts and osifont
  (thanks elevatormind!)
- use "Liberation Sans" as default-font
- adjust License-Tab in About-Form
- Bugfix: When selecting a font, the current
  font is highlighted in dialog
- adjust some whitespace and English comments
2025-05-18 14:15:20 +02:00
plc-user eeb453f120 only calculate grid-point-size, when min != max 2025-03-13 20:46:04 +01:00
plc-user 0804d3524a improvement: ajust size of grid-dots with zoom-factor
Introduced additional spinboxes in config-page for
setting min- and max-size of grid-dots separately for
diagram- and element-editor.
That assures maximal flexibility for setting the grids.
Don't want the grid-dots to change over zooming-levels?
Set min- and max-values to the same number.
Preset-values for all min-/max-values is "1".
If the adjustable range of 1 to 5 is not sufficient, it
can be easily adjusted. Only need feedback for this.
2025-03-07 20:16:21 +01:00
plc-user a36de7de74 implement variable point-size of grid 2025-02-28 16:33:24 +01:00
plc-user 15ae8b0058 fix typo of variable 2025-02-28 16:02:58 +01:00
Laurent Trinques 43f0107eb1 Revert "Try Clazy fix-its"
Segfault on old Qt versions!
This reverts commit dba7caed30.
2025-02-14 16:17:58 +01:00
Laurent Trinques dba7caed30 Try Clazy fix-its
clazy is a compiler plugin which allows clang to understand Qt
semantics. You get more than 50 Qt related compiler warnings, ranging
from unneeded memory allocations to misusage of API, including fix-its
for automatic refactoring.

https://invent.kde.org/sdk/clazy
2025-02-14 15:52:23 +01:00
Laurent Trinques 77bfe84a4c One year 2025-01-04 13:37:40 +01:00
plc-user 4c52c8c9d0 correct indentations / whitespace 2024-04-10 10:28:58 +02:00
Laurent Trinques e73cf633ce 2023->2024 2024-03-29 10:09:48 +01:00
joshua 27dcd5ef00 Improve last commit
Remove setter function : void BorderTitleBlock::setTitle(const QString
&title)
Remove singal diagramTitleChanged from BorderTitleBlock and use instead
the signal informationChanged.
2023-10-17 22:46:04 +02:00
joshua 8955ca2c82 Improve commit 73c0848fcd 2023-10-17 21:50:37 +02:00
joshua 107c59d680 diagram.cpp : remove unused #include 2023-10-16 22:31:47 +02:00
joshua 73c0848fcd Fix : conductor don't display well user defined variable as conductor text
see : https://qelectrotech.org/forum/viewtopic.php?pid=18835#p18835
2023-10-16 22:24:18 +02:00
Laurent 5cbb444c0a macOS fix: add Move diagram item with the keyboard arrow 2023-03-29 13:10:50 +02:00
joshua b1f6b1823a Fix crash 2023-01-08 16:20:13 +01:00
joshua 539e0a7a49 Merge branch 'terminal_strip'
* terminal_strip:
  Terminal strip item can saved / loaded to .qet file
  See previous commit...
  Move terminal strip drawer class in is own file
  Fix wrong use of QStringLiteral and QLatin1String
  Double click a TerminalStripItem open the editor
  Minor change about checkable QAction of QetDiagramEditor
  Minor : corrects a minor aesthetic defect when unbridge terminals
  Revamp code
  Add and move terminal strip item are now managed by undo command
  TerminalStripItem : Draw terminal bridge
  Terminal strip item can be added to diagram
  Minor : add QGIUtility namespace
2023-01-02 19:40:08 +01:00
Laurent Trinques 9afef79629 Update Copyright date 2023-01-01 17:05:57 +01:00
joshua f54bea713e Terminal strip item can saved / loaded to .qet file 2022-12-21 19:18:49 +01:00
luz paz a76e5446aa Fix various typos in source documentation and comments
Found via `codespell`
2022-12-04 13:30:01 +01:00
joshua ce21a812c0 Fix bug 244
I was thinking that the commit 5a51f6bace
fix the bug 244, but not they only fix this bug :
https://qelectrotech.org/forum/viewtopic.php?pid=16022#p16022

This commit really fix the bug 244
2022-04-01 20:04:17 +02:00
joshua 5912a99c16 Minor fix : master XRef is not updated when variable %F is used 2021-06-28 21:24:28 +02:00
joshua 8960981f09 Use QStringLiteral and QLatin1String. 2021-03-30 20:48:56 +02: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 6e17996d37 fix problem that default conductor is not found 2021-03-08 20:48:23 +01:00
Martin Marmsoler 058824f29a move all static xml functions to qetxml 2021-03-06 20:01:31 +01:00
Martin Marmsoler 221773ea8a fix some issues 2021-03-04 21:25:04 +01:00
Martin Marmsoler 9d4b90da1a Add userProperties 2021-03-04 19:18:28 +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 c592b7a7fd Fix crash
When use the function "invert selection" qet crash when a selected
conductor is being deselected.
2021-02-09 21:05:32 +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
Claveau Joshua b514c39883 Improve update of the project database 2020-11-01 21:27:40 +01:00