Commit Graph

4909 Commits

Author SHA1 Message Date
Laurent Trinques e335aa2e55 Merge branch 'test-1438' 2026-10-11 05:15:26 +02:00
ispyisail ee0593ce7d Merge pull request #1432 from bhangart/feature/image-crop-on-folio
Crop a picture directly on the folio
2026-10-11 16:12:14 +13:00
Laurent Trinques 78ac5222c0 Cable: use invalidateFilter() instead of begin/endFilterChange (Qt 6.8 compat) 2026-10-11 05:04:50 +02:00
Laurent Trinques 1cd8fadbc4 Reapply "Add cable management: drawing, cores, numbering, cross-references and cable list"
This reverts commit 2bb3343d2d.
2026-10-11 05:00:01 +02:00
Laurent Trinques 2bb3343d2d Revert "Add cable management: drawing, cores, numbering, cross-references and cable list" 2026-10-10 16:49:39 +02:00
Laurent Trinques 738ffbfc36 Merge pull request #1438 from Kellermorph/wiring-manager
Add cable management: drawing, cores, numbering, cross-references and cable list
2026-10-10 16:33:12 +02:00
Laurent Trinques 0fe88758aa Terminal strip: add resistor, varistor, test socket and reversed diode types
Add ElementData::TTResistor, TTVaristor, TTTestSocket and TTDiodeReversed
(xml values "resistor", "varistor", "test_socket", "diode_reversed"),
selectable in the element editor, the terminal strip editor and the free
terminal editor, and drawn in the terminal strip plan.
2026-10-10 16:03:47 +02:00
Laurent Trinques b089c5b245 Terminal strip: remove the circles at the end of connections and wires
Draw the top/bottom connections of the terminals and the wires under
the cable as plain lines, without the small circle at their end.
2026-10-10 15:46:14 +02:00
Kellermorph 9771ca96c9 Make the cable feature speak English like the rest of the interface
English has been the source language of the program for a while now
(upstream: "Make English the source language ..."), the cable feature
came in with French ones: about 200 translatable strings over 30 files,
the two settings pages built from .ui files, four comments and one test
which asserted the old wording (blocking review comment by ispyisail).

The wording follows what the code base already uses where it exists:
Plant (=) and Location (+) as qetinformation.cpp names those element
information, Designation for the field the cable form calls its BMK,
Length, Sheet for folio, Automatic numbering, Cross-reference, and Right
aligned / Centred / Left aligned the way cabletextformatdialog.cpp
already spells the three alignment entries.

Two things are more than a word-for-word swap:

- xrefpropertieswidget.cpp:291 wrote the label of the master field on
  every type change with a hardcoded tr("Maitre"), so the English
  "Master" coming from the .ui was overwritten for every type, cable or
  not: a real bug next to being French. The wording now comes back from
  the .ui and only a cable renames the field to "Text:", so the two
  cannot drift apart again.

- tst_cabletypelist kept asserting that a new catalogue is *labelled*
  in French. That label line is the translated header and reads English
  now. The test still reads files with French headers on purpose:
  headerAliasMap() keeps the five old French labels as aliases next to
  the English ones, so catalogues written by earlier builds, including
  the one the reviewer reads her own types from, keep loading.

The .ts files are deliberately not regenerated here. Upstream
regenerates them on master, as it did for the language change itself,
and a translation is keyed on the source string: while the sources were
French a German user saw French in the cable dialogs, and an English
source string with no translation yet shows as it is.

Build clean, ctest 92/93, the one failure being the pre-existing
headless tst_menubarkeyboard.
2026-10-10 13:48:45 +02:00
Beat Hangartner 446479e8d2 Fix a crop in progress outliving an undo or the picture's removal
While a picture was being cropped on the folio:

- Ctrl+Z or Ctrl+Y of an earlier crop of the same picture left the
  crop handles where they were, 10 px beside the frame for a crop
  that starts at (10, 10).
- undoing the picture's insertion dropped the crop but left the
  picture as the folio's keyboard item, also after a redo put it
  back.

setImageSource() and leaving the scene now end the crop without
applying it. Nothing is pushed on the undo stack from there, since
both can run inside an undo command. Delete and cut are unchanged:
they deselect the picture first, which applies the crop as its own
undo step before theirs.

No file-format change. Not covered by an automated test: crop mode
needs a folio and its view, which a test can only get from the
application object library of #1431. Checked with a throw-away test
on a local merge of both branches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 11:01:29 +02:00
Beat Hangartner 8261524208 Put the Escape comment back on m_drag_cancelled
The comment "Escape pressed: ignore the rest of this mouse gesture"
explains m_drag_cancelled. The crop commit moved it onto the
declaration of dragCropHandle(), added below it. No code changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 10:54:42 +02:00
ispyisail ada516d103 Merge remote-tracking branch 'upstream/master' into fix/report-arrow-without-terminal
# Conflicts:
#	tests/qttest/tst_resaveunchanged.cpp
2026-10-10 21:12:49 +13:00
ispyisail 420e211383 Merge pull request #1444 from ispyisail/fix/table-chain-deleted-folio
Fix a split table going blank and crashing after a folio is deleted
2026-10-10 21:12:06 +13:00
Laurent Trinques fb226d435e Terminal strip: add an anti-parallel diodes terminal type
Add ElementData::TTAntiParallelDiodes (xml value "antiparallel_diodes"),
selectable in the element editor, the terminal strip editor and the free
terminal editor, and drawn in the terminal strip plan as two diodes wired
in opposite directions between the top and the bottom of the terminal.
2026-10-10 10:01:12 +02:00
ispyisail 8d8a998f75 Merge pull request #1445 from ispyisail/fix/db-stale-after-edits
Fix the project database going stale after folio, symbol and wire edits
2026-10-10 20:54:01 +13:00
Laurent Trinques daa648099b Terminal strip: save the layout (font, cell sizes...) in the project
The default terminal strip layout was rebuilt at every project load,
so the font size set in the layout editor was reset to 15 px.
Add TerminalStripLayoutPattern::toXml/fromXml and
TerminalStripLayoutsHandler::toXml/fromXml, write a
<terminal_strip_layout> element in QETProject::toXml() and read it
before the diagrams are loaded. Projects without it keep the defaults.
2026-10-10 09:49:42 +02:00
Kellermorph 3f23e3dd2b Create the folder of the cable types file before writing into it
The catalogue is written with QSaveFile, which cannot write into a
folder that is not there. A fresh profile has no documents folder, and a
path typed into the settings may name a folder which was never created,
so the first write failed with "No such file or directory" and no way
for the user to see that the folder was the problem rather than the file
(non-blocking review comment by ispyisail).

writeFile() makes the folder first, which covers every writer: creating
the template, appending a type and editing one all go through it.

Covered by tst_cabletypelist::aMissingFolderIsCreated, writing into
<tmp>/not/there/yet/qet_cable_types.csv. Verified in both directions:
without the fix the test fails with 'createFile(path, &error) returned
FALSE. (No such file or directory)', with it the file is created and
reads back.
2026-10-10 09:42:59 +02:00
Kellermorph a2880ad79e Write the cable XML only where it has something to carry
Two pieces of cable XML went into every file the program saved, whether
the project had cables or not (non-blocking review comment by
ispyisail). Resaving one of the example projects added both of them.

- <cable_autonums> is now written only when it holds something: a named
  rule, an axis other than the default, the numbering question answered
  with no, or a rule of its own. When it is missing, the reader falls
  back to exactly the defaults a project which never touched cable
  numbering has, so nothing changes for those files.

  That is deliberately not "only when the project has cables", which
  would cost data: a rule configured before the first cable is drawn and
  an axis chosen before it are answers only this element can carry, and
  the question answered with no has to survive even if the cable which
  prompted it was cancelled again.

- the font attribute of <xref> is now written only when there is one.
  Only the cable cross-reference has a font of its own; writing it
  unconditionally put font="" on every cross-reference type of every
  project, and an absent attribute reads back as no font, which is what
  all the others are.

Verified by resaving examples/741.qet, examples/Projet_vierge.qet and
examples/affuteuse_250h.qet: before, cable_autonums=1 and font="" on
each; after, none of them. A cable project of the reviewer's own keeps
<cable_autonums axis_priority="y" current_autonum="Cable"> with its rule
and its real fonts, and only loses the four empty font attributes.
ctest 92/93, the one failure being the pre-existing headless
tst_menubarkeyboard.
2026-10-10 09:42:54 +02:00
Kellermorph 0743546542 Take the right button away from the cable tool only, not from every tool
The cable feature suppressed the quick command ring for every running
tool, so drawing a line or placing an element no longer got the ring a
right drag shows -- a far wider change than the feature needed, and one
nobody asked for (blocking review comment by ispyisail).

The condition is now the cable tool alone. Diagram::cableToolIsRunning()
says whether that is the running interface, and while it is, the right
click cancels the line being drawn and opens neither the ring nor a
context menu, neither QET's own nor the platform's -- which is the
behaviour the cable tool needs and the only part that was ever intended.

Everything else in mousePressEvent is upstream's original again: a
gesture is tracked whatever else is running, a running tool sets
m_gesture_over_tool so the press carries on to the scene and a drag ends
the tool before the ring appears, and only the click which neither draws
nor selects swallows the platform's menu. A structural diff of
mousePressEvent against the commit before the cable feature shows three
added conditions and nothing else.
2026-10-10 09:35:47 +02:00
ispyisail 8c6ac0aeec Fix the lupdate warning on the dropped-picture error texts
lupdate printed "Class 'ImageDrop' lacks Q_OBJECT macro" at
imagedrop.cpp:77 on every "update_translations" run (#1446).
ImageDrop is a namespace, not a class, and the file routed its texts
through a local tr() helper; lupdate reads tr() inside an ImageDrop::
function as a member of a class without Q_OBJECT.

Call QCoreApplication::translate("ImageDrop", ...) directly instead,
which lupdate reads without a class. The context and the four source
texts are unchanged, so the existing translations still apply.

Closes #1446

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 20:27:01 +13:00
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 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 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 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
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
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 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 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
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
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 7868dd13a4 Merge pull request #1414 from bhangart/fix/image-handle-escape
Cancel a picture's handle drag with Escape
2026-10-09 22:39:22 +13:00
ispyisail aeb97fcaaa Merge pull request #1410 from ispyisail/feature/settings-profile-parts
Add saving and loading only part of the settings
2026-10-09 22:35:37 +13:00
ispyisail 053ff0b6cf Fix wires moving to another symbol after saving an older project (#1408)
Symbols copied in old versions can share one uuid on a folio. Up to
0.100 that was harmless: a wire on a terminal without uuid was saved by
terminal number. Since #1118 every terminal has a uuid, so every wire was
saved by symbol uuid and terminal uuid, and on reopening findTerminal()
took the first symbol carrying it: all the copies' wires landed on it.

- Save: a wire end on a symbol whose uuid another symbol of the folio
  also carries is written by terminal number again.
- Load: when a wire's uuid names several symbols, pickEnds() takes the
  pair whose distance matches the wire's saved path, then the symbols
  whose labels match the ones saved with the wire, then two terminals no
  wire joins yet; otherwise the first, as before. This repairs a file a
  build with #1118 saved once.

tst_sharedsymboluuid gives the three lamps of
Habitat-Schemas_developpes.qet one uuid: master loses a net after a
save (8 of 9) and reopens the file it saved with 8; with this, 9 both
times. The 25 examples save the same as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:30:26 +13:00
ispyisail 50cbb3bcee Merge pull request #1404 from ispyisail/feature/1251-static-text-anchor
Add anchor="alignment" for static texts in element files (#1251)
2026-10-09 22:19:25 +13:00