Commit Graph

10455 Commits

Author SHA1 Message Date
Kellermorph a16964c055 Fix the double free when a deleted cable is undone and edited again
Deleting a cable and pressing Ctrl+Z twice leaves the cable out of the
project while AddCableCommand still stands and still thinks it has to
clean that cable up. The next edit of any kind makes the stack throw the
undone commands away: ~RemoveCableCommand frees the cable, and
~AddCableCommand frees the same memory again. A plain build hides it,
AddressSanitizer reports it as a heap-use-after-free in
addcablecommand.cpp (blocking review comment by ispyisail).

AddCableCommand now holds the cable as a QPointer, which is what
RemoveCableCommand already did: whoever of the two runs first frees it,
the other one sees a null pointer and has nothing left to do, in either
order of destruction. The destructor also stopped dereferencing
project() without checking it, which it did on that very line.

Covered by tst_cableundointegration, a probe linked against the
application's objects the way the other integration probes are. It draws
a cable, deletes it, undoes twice and pushes a further edit -- the
sequence which used to crash. Verified in both directions: with the raw
pointer the probe dies with SIGSEGV inside ~AddCableCommand called from
QUndoStack::push, with the QPointer it prints its PASS line.
2026-10-10 09:24:15 +02:00
ispyisail 9a4a303503 Merge remote-tracking branch 'upstream/master' into fix/table-chain-deleted-folio 2026-10-10 20:08:03 +13:00
ispyisail 36024aecac Merge remote-tracking branch 'upstream/master' into fix/db-stale-after-edits 2026-10-10 20:08:03 +13:00
ispyisail 44b2129d5a Fix a crash opening a project whose folio report arrow has no terminal
A folio report arrow's text looks for a wire to show: on the arrow
itself, else on the arrow it is linked to, through that arrow's first
terminal. Some report symbols have no terminal -- ref_voyant_2_h.elmt in
the collection, and older collections' arrows -- so a project linking an
arrow with no wire to one of them crashed QElectroTech as it opened.
The other arrow's terminals are now checked first, as the arrow's own
already were.

Found on a project attached to the forum (saved by 0.70), which crashed
on opening.

Test: tst_resaveunchanged::reportArrowWithoutTerminalOpens builds the
case from Projet_vierge.qet's own symbols; it crashes without the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Wga9B92BNurDEtxxtCDxf
2026-10-10 20:05:58 +13:00
ispyisail d4352b72c1 Merge pull request #1443 from ispyisail/fix/linked-elements-sorted-copy
Fix master's failing link order test (#1441 + #1442)
2026-10-10 20:02:01 +13:00
ispyisail 727188f564 Fix master's failing link order test: sort a copy in linkedElements()
Element::linkedElements() sorted the element's own list of linked
elements by position before returning it, so any caller reordered what
is saved. #1441 restores the file's order after linking; #1442 fills the
link table through linkedElements(), which sorted it again, so on master
a coil's contacts are saved in position order and
tst_resaveunchanged::savedLinkOrderKept fails.

linkedElements() now returns a sorted copy. Callers still get the list
by position; the saved order is left alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Wga9B92BNurDEtxxtCDxf
2026-10-10 19:33:06 +13:00
ispyisail 5e6677ebec Keep the project database current when folios, symbols and wires change
The project database is kept up to date edit by edit, and a script's
qet.query() and the folio tables read it without a full rebuild. Three
edits left it out of date until the next rebuild:

- adding or removing a folio: the folios after it kept their old
  position and folio number, and a removed folio's diagram_info row
  stayed;
- moving a symbol: its folio cell (element.pos) stayed where the symbol
  was added;
- deleting a wire: its two ends stayed in the terminal table, which
  lists the terminals a wire ends on.

Positions and folio numbers are now written again after a folio is
added, removed or moved (one function for the three), the removed
folio's diagram_info row goes, a moved symbol's cell is written when
the database is next read (as drawing items are), and a deleted wire's
ends go unless another wire ends there.

Found by comparing the tables after random scripted edits with those
a fresh open of the saved project gives. Left alone: labels and wire
numbers made from a folio formula, which the drawing itself keeps until
the project is reopened.

Tests (tst_databasefromdocument): folioAddedAndRemoved,
movedElementCell, deletedWireTerminals; each fails without its part of
the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Wga9B92BNurDEtxxtCDxf
2026-10-10 19:07:03 +13:00
ispyisail ee164f1bf1 Fix a split table losing its data and crashing after a folio is deleted
A summary or parts-list table split over several folios saves its data
with its first part only; each later part names the part before it.
Deleting a folio keeps its tables in memory for undo, still in the
chain, so saving then named the deleted part as the previous table of
the next one. On reopening, every part after the gap had no data, and
closing the project crashed: the first orphaned part, destroyed, handed
its missing data on to the next part through a null model.

toXml() now names the nearest previous part still in the project, or
saves the data if there is none. setPreviousTable() no longer copies a
null model, so files already saved this way open and close.

Tests (tst_resaveunchanged): missingPreviousTableOpens,
deletedFolioKeepsTableChain; both fail without the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Wga9B92BNurDEtxxtCDxf
2026-10-10 19:03:50 +13:00
ispyisail 13dbacef1e Merge pull request #1442 from ispyisail/feat/db-link-table
Add a link table to the project database
2026-10-10 18:19:57 +13:00
ispyisail e2363eb9e4 Merge pull request #1441 from ispyisail/fix/f101-link-order
Fix a coil's contacts being saved in a different order each time
2026-10-10 18:19:42 +13:00
ispyisail 3089408b19 Add a link table to the project database
One row per element and element it is linked to -- a coil and its
contacts, a pair of folio reports -- from each side, with the contact
group the element saved for it. Nothing reads it yet: cross-references
are the main thing one folio needs from another, and this is what lets
them be answered without building every folio.

Filled like the other tables: from the document when it can be read
exactly (a link only one side lists, between kinds that cannot link, or
giving a contact a second coil is left to the folios), from the folios
otherwise. A link made or undone afterwards rewrites that element's rows
when the database is next read, as drawing items are, since the contact
group is set after the link is made.

Test: tst_databasefromdocument compares the link table both ways on
every example; linksAreListed checks a coil and contact (with a group)
in m_000.qet, oneSidedLinkFallsBack the refusal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Wga9B92BNurDEtxxtCDxf
2026-10-10 17:22:56 +13:00
ispyisail 5441e2ae76 Keep a coil's contacts in the order the file saved them
On opening a project, a coil and its contacts are linked in the order
the folios' items are visited. When contacts are on an earlier folio
than the coil they link first, so the coil's list followed the folio
order instead of the file's, and contacts on one folio swapped places
from run to run. Saving the same project twice could then give two
different files.

After linking, Element::initLink() now puts the linked elements back in
the order the file listed them. Elements linked but not in that list
keep their place after it.

Test: tst_resaveunchanged::savedLinkOrderKept reverses a coil's two
contacts in m_000.qet and checks a resave keeps that order; it fails
without the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Wga9B92BNurDEtxxtCDxf
2026-10-10 16:54:26 +13:00
ispyisail 613f05a05e Merge pull request #1433 from bhangart/i18n/fr-image-drop-texts
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 1m39s
Translate the texts of dropping pictures on a folio
2026-10-10 07:52:12 +13:00
ispyisail 82b3232d59 Merge pull request #1430 from bhangart/fix/refused-files-colon
Write the list of refused dropped files with an English colon
2026-10-10 07:52:08 +13:00
ispyisail 4c7ea90c51 Merge pull request #1429 from bhangart/fix/image-missing-size
Load a picture without a usable size at size 1, not 0
2026-10-10 07:52:03 +13:00
ispyisail 4b99c73c03 Merge pull request #1428 from bhangart/fix/free-text-nonfinite-position
Load a free text's non-finite position or rotation as 0
2026-10-10 07:51:59 +13:00
ispyisail 82716f6291 Merge pull request #1427 from bhangart/test/menubar-wait-active
Wait for the window to be active in the menu bar keyboard tests
2026-10-10 07:51:55 +13:00
ispyisail ce3a4d82ea Merge pull request #1437 from ispyisail/fix/genericdevice-test-font-height
Fix tst_genericdevice failing in the Linux CI
2026-10-10 07:50:08 +13:00
Kellermorph 69eb071f45 Merge upstream/master: translation wave plus generic device
Upstream moved 56 commits ahead of the last merge. Six files conflicted,
all of them files where upstream's French -> English tr() translation wave
touched lines we had also touched with the cable feature. Resolution rule
applied everywhere: take upstream's English source strings, keep our cable
additions.

Resolved:

- sources/ui/xrefpropertieswidget.ui : kept our structure (m_labels_gb
  pulled out of the display group, m_slave_row, the m_font_pb "Police..."
  button of the cable cross-reference) and mechanically applied upstream's
  20 English string replacements on top of it.

- sources/ui/xrefpropertieswidget.cpp : our version plus upstream's 7
  translated combo entries; the tr("Cable") item we add for the cable
  cross-reference type stays.

- sources/autoNum/ui/numparteditorw.cpp : upstream's English part names
  ("number format 1", "Sheet no.", "Plant", "Location", ...) for the
  number-format list, with our comment explaining why type 3 (cable) takes
  the conductor kinds of variable.

- sources/ui/configpage/configpages.cpp : upstream's English tab titles
  (Conductors / Elements / Sheets) plus our Cables tab.

- sources/ui/configpage/projectconfigpages.cpp : upstream's "Sheets" tab
  title plus our Cables tab block (single-rule SelectAutonumW(3)).

- sources/qetdiagrameditor.cpp : union of both sides - upstream's new
  "Add a generic device" action (icon, status tip, data id) and its
  English menu names ("File"/"Edit"/"Project"/"Display"), together with our
  cable action, the Numbering and Lists menus, the cable list actions and
  the CSV export in the Project menu.

Kept French: our own cable tr() source strings stay French for now. That
is the smaller change and the translation pass can follow separately.

Verified: full build 1065/1065, ctest 91/92 (only the pre-existing
headless tst_menubarkeyboard fails: no window manager, so Alt+F and F10
cannot open a menu bar), smoke start exit 124, no conflict marker left in
the tree.
2026-10-09 20:44:58 +02:00
ispyisail 2d5a249039 Fix tst_genericdevice failing on machines without Liberation Sans
edgeCases() expected an empty device to be exactly MinHeight (30) tall.
The sizing rule is max(MinHeight, 2 x label height) rounded up to the
grid, so with a taller fallback font the body is 40 and the test fails.
The Linux CI image has no Liberation Sans; fontconfig substitutes Nimbus
Sans (fonts-urw-base35), whose line height gives 40.

Compute the expected height from the label font's metrics, as the
layout does.

Reproduced locally with a fontconfig file listing only the urw-base35
fonts: the old test fails with the CI's exact message (40 vs 30), the
new one passes. Doubling the label factor to 3 in genericdevice.cpp
still makes the new check fail, with Liberation and with Nimbus.

Reported by bhangart on #1418.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 07:28:03 +13:00
Kellermorph d55a3c7881 Fix cable numbering rule questions: per project, and a first rule counts
Two defects found while re-testing the cable management after the
upstream merge, plus one change of intent for the numbering question.

The question "define a cable numbering rule now?" kept its answer in
the program settings, so saying no once silenced every project of the
program -- the exact opposite of what it should do. The answer now
travels with the project itself, stored on the <cable_autonums>
element as ask_numbering_rule="false"; a file which does not hold the
answer asks again, and taking the rule away in the project properties
or in the numbering window brings the question back for that project
alone. Read-only projects are no longer asked at all, since there is
nowhere in them to define a rule.

The numbering window could not hand out the first rule of a project:
it drew the rule, worked the numbers out with it, and only wrote the
rule into the project together with those numbers -- while the
planning refused to run on a project which had no rule saved yet.
The counters of a cable rule are kept under its fixed name anyway, so
planning now falls back to that name when the project holds no rule
yet: a rule which is being drawn in the window counts from the moment
it is complete, and the first renumbering of a project works.
2026-10-09 20:22:45 +02:00
Beat Hangartner e1cb6006c6 Load a picture without a usable size at size 1, not 0
DiagramImageItem::fromXml() read the size attribute with a plain
toDouble(). A picture whose size was missing or not a number got size
0, so it was invisible on the folio, left out of the SVG export, and
a resave wrote size="0" back, which then stayed 0 on every load. "nan"
was kept and written back as such. The <transform> child, which newer
files carry, already defaults its scale to 1.

Read the size with an ok flag and use 1, the size a picture is added
with, when it is missing, not a number, not finite, or 0.

No file-format change for usable sizes. A picture that an earlier save
left at size="0" shows again, at size 1, after this change.

Tests: tst_imagemissingsize runs the binary's --resave and --export-svg
on a fixture with six small pictures: size missing, "0", "nan", "big",
"0.5" and "2". The first four fail on master (saved as 0, 0, nan, 0)
and the export draws only 3 of the 6 pictures there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Beat Hangartner <beat@hangartners.ch>
2026-10-09 15:58:49 +02:00
Beat Hangartner 9136c605f4 Load a free text's non-finite position or rotation as 0
"nan", "inf" and "-inf" parse as numbers, and IndependentTextItem::
fromXml() used them as they came for x, y and rotation. A project with
such a value kept it: --resave wrote x="nan" back, and the SVG export
drew the text at matrix(1,0,0,1,nan,95), which is not valid SVG.
Conductors and element texts already load a non-finite position as 0.

Load a non-finite x, y or rotation of a free text as 0, the same way.

No file-format change: finite values load and save as before.

Tests: tst_freetextnonfinite runs the binary's --resave and --export-svg
on a fixture with x="nan", y="inf", x="-inf", rotation="nan" and a
finite text (61.7, 61.3, 37 degrees, kept as they are). The four
non-finite cases and the export check fail on master.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Beat Hangartner <beat@hangartners.ch>
2026-10-09 15:58:44 +02:00
Beat Hangartner c52cd3b2fc Keep a line's pivot at its centre when one of its ends is dragged
A shape's pivot follows its centre when it is resized, unless it was
placed by hand: setLine() and setRect() do that, and so did dragging a
rectangle's or an ellipse's handles, which goes through setRect().
Dragging an end of a line moved the end directly and left the pivot
where it was, so the next rotation turned the line around a point
beside it. Undo and redo already re-centred it, through setLine().

The line's handle drag now applies the same rule.

New tst_linepivotresize, on a real folio with scene mouse events: the
pivot is at the new centre after an end is dragged (fails without the
change: it stays at the old centre), and after undo and redo; a pivot
placed by hand stays; a rectangle's pivot follows as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:47:53 +02:00
Beat Hangartner 448a82fae6 Test Escape during a picture's handle drag
tst_imagehandleescape covers #1414 through the real editor: a picture's
resize, rotate and pivot handle are pressed and dragged with scene mouse
events, Escape goes to the DiagramView, then the rest of the gesture.
Each time the picture is back as it was at the press, still selected,
and no undo step is recorded; without a drag, Escape still clears the
selection. The three drag cases fail with #1414 reversed (Escape cleared
the selection under the drag).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:47:52 +02:00
Beat Hangartner eab557d9af Test that Space on a picture turns the rotation its file saves
The first test that runs a real QETApp, offscreen (qetapptest.h): it
links qelectrotech_objects, keeps its settings, configuration and data
in a temporary folder, and triggers the editor's own actions.

tst_rotateselectionimage covers #1413: Space ("rotate_selection") turns
a picture's rotationAngle, not QGraphicsItem's rotation, in place, and a
picture read back from its XML has the angle; undo and redo, twice; and
a group turn ("rotate_group_selection") moves each picture's pivot a
quarter turn around the group's centre. All three fail with the code
from before #1413.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:47:52 +02:00
Beat Hangartner 3dd977a040 Build the application's code once as an object library
The executable compiled every source file itself, so a test could only
reach the application's classes by listing their .cpp files one by one,
which stops working as soon as a class needs a folio, its view or the
editor window -- that pulls in nearly everything.

The sources (except main.cpp) and the two .qrc files now build once as
qelectrotech_objects, an OBJECT library; the executable is main.cpp
linked with it. Its link libraries and include folders are PUBLIC, and
it passes on this directory's compile definitions, so a target in
tests/ that links it compiles and links like the application.
lupdate's targets scan the library (main.cpp has no tr() text).

The executable, its compile flags and what it saves do not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:47:52 +02:00
Beat Hangartner d996426e8a Translate the texts of cropping a picture on the folio
The French of the six new texts (the crop mode's name and hints, "Crop on
the folio", "Reset crop", "Properties..."), as lupdate's own entries,
inserted where lupdate places them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:46:46 +02:00
Beat Hangartner 05131d1238 Show crop bars instead of handle points while cropping
Black bars on a white outline, an L at each corner and a short bar in
the middle of each side, at the same size on screen at any zoom, with
the matching resize cursor over each. The handles underneath still
take the drags but are no longer drawn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:46:46 +02:00
Beat Hangartner d86f2d5461 Crop a picture directly on the folio
Double-clicking a picture, or "Crop on the folio" in its context
menu, crops it in place: the whole original is shown, dimmed outside
the region kept, and eight handles move the crop's edges; a drag inside
the frame moves the crop window over the original. Enter, a double-click
or a click elsewhere applies the crop as one undo step, keeping the
kept region where it is on the folio; Escape drops it. Rotated and
scaled pictures are cropped along their own sides.

While cropping, the picture is the folio's keyboardItem (see the
Escape commit before this one), so the view hands it Enter and Escape
before its own shortcuts: Enter does not repeat the last placing
command, and Escape does not clear the selection, which would apply
the crop.

The context menu gains "Reset crop", which shows the
whole original again, and "Properties...", since double-click no
longer opens them. The crop dialog stays available.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:46:46 +02:00
Beat Hangartner 95fe56527d Translate the texts of dropping pictures on a folio
The texts added with dropping picture files on a folio (#1416) had no
entry in the translation files yet, so the French interface showed them
in English, and the English one wrote "Add 1 image(s)".

- qet_fr.ts: the French of all nine texts (the eight of #1416 and the
  "%1: %2" of the list of refused files), "%1 : %2" with the French
  space before the colon.
- qet_en.ts: the singular and plural of "Add %n image(s)".

The entries are lupdate's own, inserted where lupdate places them, so a
later refresh of the .ts files moves nothing; lupdate run over sources/
finds them all as existing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:46:45 +02:00
Beat Hangartner 0fc5963793 Write the list of refused dropped files with an English colon
The message listing the files a drop could not add wrote each line as
"name : reason", with the space French puts before a colon, and as a
fixed string that no translation could change. It is now a tr() text,
"name: reason", so each language can write it its own way.

Suggested in the review of #1416.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:46:45 +02:00
Laurent Trinques 5f6e74918e Merge pull request #1418 from ispyisail/feature/generic-device
Add a generic device: a box symbol with terminals on any side
2026-10-09 14:35:21 +02:00
Laurent Trinques 88f8c260ab Merge pull request #1425 from bhangart/ci/windows-tests-on
CI: build and run the unit tests in the Windows job again
2026-10-09 14:34:29 +02:00
Beat Hangartner 7866a37f14 Wait for the window to be active in the menu bar keyboard tests
tst_menubarkeyboard sends Alt+F and F10 right after the test window is
exposed, then sleeps 300 ms and checks. Menu mnemonics and the F10
shortcut (a Qt::WindowShortcut) only fire in the active window, and
being exposed does not mean being active: on a loaded Xvfb, or on macOS
with another application in front, activation arrives later and the key
is dropped. The sleep comes after the key and cannot help. This made
shortcutOpensMenuBar fail on #1420's Linux CI ("F10 did not activate the
menu bar") while the same base passed on #1421 and #1422, and made the
Alt+F control fail in 1 of about 33 local runs with the cocoa platform.

Every test now waits for the window to be active before pressing a key
(qWaitForWindowActive, with its own failure message), and the two tests
that expect a menu poll for it with QTRY_VERIFY2 instead of a fixed
sleep. plainF10DoesNothingInQt keeps its 300 ms: it checks that nothing
happens, which cannot be polled for; with the window now active first,
that check can no longer pass merely because the key went nowhere.

Test-only change. Checked: with a second window active, F10 sent to the
exposed but inactive window does not activate its menu bar (offscreen
and cocoa); once it is active, it does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:30:27 +02:00
Laurent Trinques cbcdcf88ba Merge pull request #1422 from bhangart/fix/lang-pl-update
Update qet_pl.ts: 61 new strings and term corrections
2026-10-09 14:29:39 +02:00
Laurent Trinques bdd623ea47 Merge pull request #1421 from bhangart/fix/lang-de-update
Update qet_de.ts: 61 new strings and the SPS wording
2026-10-09 14:29:23 +02:00
Laurent Trinques fb847c8fc5 Merge pull request #1420 from bhangart/fix/lang-fr-plurals
Give the French plural messages real singular and plural forms
2026-10-09 14:28:45 +02:00
Kellermorph 955dfb3a73 Merge remote-tracking branch 'upstream/master' into wiring-manager
Conflicts resolved in 24 files. Notable decisions:

- ico/icon-themes.qrc: upstream's icon folder restructure kept; the 36
  cable icon entries re-added under the new qet/qet-dark path scheme
  (XML valid, every referenced file exists).
- Toolbar system: upstream's DiagramToolbarSettings now owns the
  toolbar filling. The cable tool is registered as
  diagrameditor.add_cable (generic group loop) and listed on the
  "diagram" toolbar right after the auto-break conductor action,
  separated by a divider, exactly like before the merge.
- Paste: the cable lines of a copy are handed to
  PasteNumberingImport::push() as extra commands, so paste + cable
  lines + the numbering question stay ONE undo step on both paste
  paths (DiagramView::paste and DiagramEventAddPaste::commit).
- PDF links: upstream's deterministic link sorting kept together with
  the cable cross-reference injector (injectLinkTo -> links list).
- Element renumbering: upstream's ElementAutoNumSchemeCommand::renumber
  replaces the old formula-based body of
  QETProject::renumberElementsBySchemeTitle; the cable numbering rule
  API (cableAutoNum, axis priority, rule name) is kept in full.
- Auto-numbering pages: upstream's scheme management kept, the Câbles
  tab added as index 4 (changeToCableTab), both entry points
  changeToCable() and changeToElement() kept side by side.
- SelectAutonumW: dirty tracking and the contextEdited signal moved
  into upstream's insertPartRow() row API, so single-rule mode, the
  rule-removable button and "confirm without change leaves the project
  alone" keep working.
- xrefpropertieswidget: upstream's offset clamping kept; the cable
  branch (Texte field, Police button, hidden display options) kept;
  the stack-overlapping checkbox is hidden for cables.

Verified after the merge: build green (515/515, no errors), ctest
85/86 (only the pre-existing headless tst_menubarkeyboard failure),
offscreen smoke exit 124.
2026-10-09 14:09:08 +02:00
Beat Hangartner a9274cff2a Update qet_pl.ts: 61 new strings and term corrections
lupdate over sources/ adds the 32 strings merged since the conversion to
English (#1390); with the entries already empty on master, 59 had
no Polish text and 2 only a lupdate guess. All 61 are translated with the
file's terms; "cable" is
"przewód" and its wires "żyły".

Corrections to existing entries:
- "master" (master element) is "główny", not "nadrzędny", in the 11
  entries that still used it (properties, cross-references, search and
  replace, terminal editor); "nadrzędny" stays where it means a parent
  folder or collection.
- the help text for %folio in two widgets still had a French sentence
  ("Les variables suivantes sont utilisables :") inside the Polish text.
- "Komentaż PLC" typo, now "Komentarz PLC".
- 6 colons with a French space before them ("Marginesy :").

Most of the diff is lupdate moving line numbers. Checked with lrelease
(3847 translations, no warning) and the placeholder check for every
changed entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:32:01 +02:00
Beat Hangartner ff9348aed8 Update qet_de.ts: 61 new strings and the SPS wording
lupdate over sources/ adds the 32 strings merged since the conversion to
English (#1390), among them picture drop, element scaling, paste element
information, the terminal strip cable fields and the settings-loading
dialog. With the 29 entries that were already empty on master, 61
entries had no German text, so the German UI showed
English there. All 61 are translated with the terms the file already
uses (Bauteil, Anschluss, Klemme, Raster, Kabel/Adern, Spiegeln).

As arummler noted in #1381, "Programmable Logic Controller (PLC)" read
"SPS (PLC)"; it is now "Speicherprogrammierbare Steuerung (SPS)" in both
places, and "PLC-Querverweis" becomes "SPS-Querverweis" like every other
PLC string in the file.

Most of the diff is lupdate moving line numbers. Checked with lrelease
(3847 translations, no warning) and the placeholder check for every
changed entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:31:45 +02:00
Beat Hangartner d4da4e1fd5 Give the French plural messages real singular and plural forms
25 of the 79 plural messages in qet_fr.ts used the old "(s)" marker in
both forms, e.g. "Ce document PDF contient %n page(s)" for one page and
for many. They come from the time French was the source language: the
French source text had "(s)", and when French became a translation in
#1379 and #1390 that text was copied into both forms. Reported by
arummler in #1381.

Each of them now has a singular form (also used for 0, as Qt's French
rule does) and a plural form, with the agreements that follow ("%n
borne de cet élément n'est pas sur la grille" / "%n bornes ... ne sont
pas"). Only <numerusform> lines change; no other message is touched.

Checked with lrelease (3815 finished, no warning); placeholders checked
for every form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:31:30 +02:00
Beat Hangartner faf2fc9ab2 CI: build and run the unit tests in the Windows job again
7c6a0411d set PACKAGE_TESTS=OFF in windows-build.yml to make the job
green again. The job had turned red because three tests merged on
2026-10-07 (tst_toolbarsettings, tst_diagramtoolbarsettings,
tst_gesturesettings) set no settings scope, so QSettings on Windows had
no registry key and they failed. #1411 gives them their scope. With
PACKAGE_TESTS=OFF the "Run the unit tests" step finds no tests and
still succeeds, so the job checks nothing.

Set PACKAGE_TESTS back to ON.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Beat Hangartner <beat@hangartners.ch>
2026-10-09 13:20:14 +02:00
ispyisail a3594c6633 Add a generic device: a box symbol with terminals on any side
Edit > Add > Generic device (also on the Add toolbar, and found by the
command search as diagrameditor.add_generic_device) opens a three-page
wizard for devices used too rarely to draw a symbol for, such as a VSD
or a power supply:

1. Layout: terminals per side (0 for none), a gap every N terminals,
   divider marks on gaps, groups lined up across opposite sides, pitch
   and extra size.
2. Terminals: a table per side and the same list as one line, where
   In{4} is In1..In4, Q{z4} is Q0..Q3, X{3-6} is X3..X6 and an empty
   entry is a gap; number pins 1..n counter-clockwise; paste rows of
   side, name, function from a spreadsheet or a CSV file.
3. Information: name, label, manufacturer, reference, description.

A preview beside every page shows the box as it will be placed. Finish,
available from the first page, writes an ordinary symbol to the folder
"Generic devices" of the project's collection and puts it on the cursor.
The box sizes itself to its terminals and their names; every terminal
lands on the grid and gets a uuid. No new XML: any QElectroTech reads it.

The layout is pure (sources/genericdevice/genericdevice.cpp) and tested
by tst_genericdevice. ElementPictureFactory gains pictureFromDefinition()
to draw the preview with the same code as a placed element.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:31:26 +13:00
ispyisail ff35d0dc69 Merge pull request #1416 from bhangart/feature/drop-images-on-folio
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 1m40s
Drop picture files on a folio to add them
2026-10-09 22:59:20 +13:00
ispyisail d02f6c1c12 Merge pull request #1417 from ispyisail/fix/1408-shared-symbol-uuid
Fix wires moving to another symbol after saving an older project (#1408)
2026-10-09 22:54:57 +13:00
ispyisail f5c643da06 Merge pull request #1415 from bhangart/fix/shape-pivot-flag-undo
Undo restores whether a shape's pivot was placed by hand
2026-10-09 22:50:30 +13:00
ispyisail e18bd1c182 Merge pull request #1412 from bhangart/fix/mirror-twice-keeps-position
Mirror a symbol twice and it comes back where it was
2026-10-09 22:45:58 +13:00
ispyisail b769fa1213 Merge pull request #1413 from bhangart/fix/image-rotation-saved
Save the rotation of a picture turned with Space
2026-10-09 22:44:40 +13:00
ispyisail af978ab907 Merge pull request #1411 from bhangart/fix/settings-tests-windows
Give the toolbar and gesture settings tests their own settings scope
2026-10-09 22:39:37 +13:00