Commit Graph

219 Commits

Author SHA1 Message Date
Laurent Trinques 89bf07f5c7 Terminal block manager: say that it is opening
Opening the terminal block manager reads every terminal of the project,
and builds the folios not built yet (lazy folios): on a big project it can
take a while, and the user could think that nothing happens.

TerminalStripEditorWindow::instance(), used by the menu action and by a
double click on a terminal strip of a folio, now shows a busy message
("Opening the terminal block manager...") and a wait cursor while the
window is built or switched to another project. Moved from the header to
the .cpp file.
2026-10-18 17:01:59 +02:00
Laurent Trinques ff18467117 Terminal strip item: also redraw an item just added to a folio
The redraw on change was connected in setTerminalStrip() only, used when
an item is read from the project. An item added with the "Add terminal
strip" dialog is built with TerminalStripItem(strip), which did not
connect: it was not redrawn after the terminal strip editor was applied,
until the project was reopened.

Both constructors now go through connectStrip().
2026-10-18 16:53:31 +02:00
Laurent Trinques 015811d243 Terminal strip editor: add spare terminals, numbered, counted in the nomenclature
A spare (reserved) terminal is a terminal of a strip which is drawn on no
folio. RealTerminal already foresaw it ("a terminal set by user but not
present on any folio") but every terminal needed an element.

- RealTerminal::createSpare(): a terminal without element, with its own
  data (label, type, function, led, informations: section, width, catalog
  terminal, color, manufacturer...). Saved in the strip:
  <real_terminal spare_uuid="..." type="..." function="..."><informations>
  Older versions ignore these terminals.
- TerminalStrip::insertSpareTerminals() / insertTerminals(): insert at a
  position of the strip. Undoable commands AddSpareTerminalsCommand and
  ChangeSpareTerminalDataCommand.
- Terminal strip editor: "Add spare terminals..." button. The terminals
  are inserted after the selected terminal (at the end if none), numbered
  from its label ("X1:12" -> "X1:13", "X1:14", leading zeros kept), with
  its properties if asked. The labels can be changed or removed in the
  table, like the other cells; the Xref column shows "Spare". Moving a
  spare terminal to the independent terminals removes it (undoable).
- Nomenclature: the spare terminals are in the new spare_terminal table,
  added to element_nomenclature_view (UNION ALL, same columns), after the
  folios, in the order of their strip. exclude_from_bom is honoured.
- The modified cells of the editor model are kept by real terminal, not by
  element, since a spare terminal has none.
2026-10-18 16:34:41 +02:00
Laurent Trinques ddc71553e2 Terminal strip item: redraw the strip as soon as it changes
TerminalStripItem was connected to nothing: after applying the terminal
strip editor (width, catalog terminal, color, type...), undo or redo, the
strip drawn on the folio kept its old drawing until something else made
the scene repaint, and its bounding rect was not updated when the width of
the terminals changed.

- TerminalStrip::dataChanged() is emitted when the data of the strip is
  set, and when the data of the element of one of its terminals changes
  (Element::setElementData(), Element::setElementInformations()).
- TerminalStripItem connects to dataChanged(), orderChanged(),
  bridgeChanged() and bridgeColorChanged() of its strip, and updates its
  geometry and redraws itself.
2026-10-18 16:06:59 +02:00
Laurent Trinques ea2acfcaeb Realistic terminal strip: draw the clamp of the terminal chosen in the catalog
The realistic styles drew every terminal of a strip with the clamp of the
layout (RealisticScrew or RealisticPushIn), whatever terminal was chosen:
a Phoenix Contact ST (spring) was drawn with screws in a screw layout.

Each entry of the terminal catalog now has its clamp: screw (Phoenix
Contact UT, Weidmüller WDU, ABB Entrelec M, Legrand Viking 3), spring
(Phoenix Contact ST) or push-in (WAGO TOPJOB S). A terminal chosen in the
catalog is drawn with its own clamp, the spring-cage ones like the push-in
ones; the clamp of the layout is kept for the other terminals, so a strip
mixing screw and spring terminals is drawn as it is.
2026-10-18 15:48:00 +02:00
Laurent Trinques f7196c48e1 Terminal strip editor: remember the manufacturer filter of each strip
The manufacturer chosen to filter the terminals of the Width column is
stored in the data of the terminal strip (information "manufacturer" of
terminal_strip_data, written only when set), and selected again when the
strip is shown in the editor. Each strip keeps its own manufacturer.
Older versions ignore this information.

TerminalStripEditor::apply() now starts from the current data of the strip
instead of a new TerminalStripData: the uuid of the strip was replaced by
a new one at each apply, and the new information would have been lost.
2026-10-18 15:48:00 +02:00
Laurent Trinques 851ddfad16 Terminal catalog: remember the chosen terminal, not only its width
Several terminals of the catalog have the same width (6.2 mm: Phoenix
Contact UT 4 and ST 4; 5.2 mm: WAGO 2002 and Phoenix Contact ST 2,5...).
Only the width was stored, so on reopening the first entry with that
width was shown instead of the terminal that was chosen.

- New element information terminal_catalog_entry: the label of the
  terminal chosen in the catalog (e.g. "Phoenix Contact ST 4").
- Choosing a terminal also fills the manufacturer and manufacturer
  reference informations (bill of materials, %{manufacturer_reference}),
  only when they are empty or still hold what the previous catalog entry
  wrote: a value typed by the user is never overwritten.
- Element editor: the manufacturer and the exact terminal are restored on
  reopening. A width typed by hand, or stored before this change, stays a
  plain width instead of taking the first terminal with the same width.
- Terminal strip editor: new "Manufacturer" combo filtering the terminals
  proposed in the Width column (with the section filter); the column shows
  "6,2 - Phoenix Contact ST 4", and copy/paste keeps the terminal.

Existing projects are unchanged: without the new information, only the
width is used, as before.
2026-10-18 15:48:00 +02:00
DaTweety 83607c0b76 Terminal catalog: add the Phoenix Contact ST spring-cage terminals
ST 1,5 (4.2 mm, 1.5 mm²), ST 2,5 and ST 2,5-QUATTRO (5.2 mm, 2.5 mm²)
and ST 4 (6.2 mm, 4 mm²), next to the UT screw terminals already listed.
Widths from the Phoenix Contact catalog and data sheets (ST 2,5-QUATTRO
3031306, ST 4 3037151, ST 1,5 3031076).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 11:47:49 +02:00
Laurent Trinques 3d2da9ed4e Terminal strip: specific drawings of fuse, disconnect and test terminals
In the realistic styles, some types of terminal get the parts seen on
the real products:
- fuse terminal: black hinged fuse holder on the middle of the terminal,
  with its hinge pin, a window on the fuse, a ribbed grip and, for a
  fuse terminal with led, a red led
- sectional (disconnect) terminal: orange knife with its hinge and grip
- test terminal: two brass test sockets between the wire entries and
  the middle band (in the middle band for a terminal with levels)

The marker tag and the type symbol are drawn on the lever. The lever is
shorter with screw clamps and stays on the middle band for a terminal
with levels.
2026-10-17 20:56:23 +02:00
Laurent Trinques fed204eb78 Terminal strip: clickable terminals in the realistic styles
The realistic styles don't write the xrefs, so each terminal becomes a
clickable zone, like the xref text of the schematic style:
- double-click on a terminal goes to its element on the folio
- the terminal under the mouse is outlined in blue, and a tool tip
  shows its label and its xref
- the zones are exported as clickable links in the PDF

A terminal with one level is clickable on its whole body; a terminal
with levels is clickable on the rows of wire entries of each level.
Only the terminals with an xref (element placed on a folio) are
clickable. The zones use the same physical / real indexes as the
schematic style, so the double-click and the PDF export need no
other change.
2026-10-17 20:41:25 +02:00
Laurent Trinques 34557928d1 Terminal strip: realistic drawing styles and separator plates
Add two realistic drawing styles for the terminal strip plan, besides
the existing schematic one:
- Realistic (push-in) and Realistic (screw): the strip seen from above,
  at scale (real width of each terminal), like a cabinet mounting
  drawing: end stops, group marker carrier with the strip name, one row
  of wire entries per level, bridge channels with red bridges, marker
  tags with the terminal number, type symbol (fuse, LED, diode,
  sectional, ground...), green/yellow PE and terminal color.

The style is chosen for each plan in the "Add terminal strip plan"
dialog and saved with the item (attribute draw_style of
terminal_strip_item). Items saved before keep the schematic style.
Several plans of the same strip can use different styles.

The values used by the realistic styles are in the layout (scale in
px/mm, terminal length in mm, end stops, group marker) and can be set
in the layout editor, whose style combo box only changes the preview.

Separator plates: a new "Separator plate after" check box column in
the terminal strip editor, stored in the terminal element informations
(key terminal_separator). Drawn as a plate at scale in the realistic
styles and as a thick line in the schematic style.

New files: realisticterminalstripdrawer.{h,cpp} (realistic drawing) and
terminalstripdrawerhelpers.h (helpers shared with the schematic drawer).
2026-10-17 20:21:35 +02:00
Laurent Trinques b1cd3a8a6e Terminal strip: marker tags calibrated on the longest number of the strip
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 1m39s
Every marker tag of a strip has the length of its longest terminal
number (at least two digits), so three-digit numbers are no longer
reduced. The font is still reduced if a number doesn't fit the text
zone of the layout.
2026-10-16 16:42:26 +02:00
Laurent Trinques 5a60dac2aa Terminal strip: xref as plain text, same size for every marker tag
- The xref is drawn as plain text, without marker tag.
- Every marker tag of the terminal numbers has the same length
  (two digits), the font is reduced when the number is longer.
- The body of every terminal reserves the zone of the longest xref
  of the strip, so all terminals of a strip are drawn the same way.
2026-10-16 16:36:12 +02:00
Laurent Trinques d2c2a09dae Terminal strip drawer: draw terminals like a real terminal block
- Draw only the terminal number (part after the last ':'), the strip
  name is already in the header; the manager and the tree still show
  the full label.
- Clip texts to the width of their terminal and shrink the font in
  narrow terminals so they no longer overlap.
- New housing: body with narrower wire entry caps and a slope between
  them, grey by default (terminals with a color or a ground type keep
  theirs); stripes are clipped to this shape.
- White marker tags behind the number and the cross reference, fitted
  to the text and its alignment; black ribbed tags for isolating
  (sectional) terminals.
- Clamping parts (screw in a window, castle tab, big center circle, tab,
  screw) drawn in the free zone between the two tags, whatever the
  layout; fewer parts if the zone is small.
- Remove the wire entry mark that overlapped the cross reference text.
2026-10-16 13:31:56 +02:00
Laurent Trinques 7d87c0e789 Terminal strip drawer: show only the terminal number, fit texts to cells
- Draw only the terminal number (the part after the last ':') instead of
  the full label (e.g. "1" instead of "XAUZ1:1"); the terminal manager
  and tree still show the full label.
- Clip each text to the width of its terminal and shrink the font in
  narrow terminals so that texts no longer overlap their neighbours.
- Remove the wire entry mark in the lower part of the terminal body,
  which overlapped the cross reference text.
2026-10-16 12:43:16 +02:00
Laurent Trinques 3365817cf1 Terminal catalog: more manufacturer widths and manufacturer filter
Extend the terminal catalog (terminalcatalog.h) with the widths of
more terminal blocks, from the catalogs of Phoenix Contact (UT),
Weidmuller (WDU), WAGO (TOPJOB S 2002/2006), ABB Entrelec (M series)
and Legrand (Viking 3). For Legrand and ABB Entrelec the value is the
pitch given by the catalog.

Each entry now carries its manufacturer, and the element properties
dialog gets a "Manufacturer" combo box before the width one. The list
of widths is filtered by manufacturer and by the selected section; if
the manufacturer has nothing for that section, all its terminals are
listed. The combo box is created by the code, no change in the .ui.
2026-10-16 12:10:30 +02:00
Laurent Trinques 5e28ec4246 Terminal sections: show the AWG equivalent in the section lists
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 1m42s
The section combo boxes of the terminal strip editor and of the
element editor now show the nearest AWG / kcmil size next to the
section in mm2, for example "2.5 mm² (AWG 14)".

The correspondence is approximate (the two systems don't have the
same steps) and is stored in TerminalCatalog::awgForSection().
The stored value is unchanged (terminal_section, in mm2).
2026-10-16 07:57:00 +02:00
Laurent Trinques 5cbc1c4b8d Element editor: add section, width and color to terminal elements
Terminal block elements can now define, in the element properties
dialog (Terminal block element group):
- the section in mm2 (combo box with the usual sections, editable)
- the width / manufacturer reference (Weidmuller, Phoenix Contact,
  WAGO, ABB Entrelec), filtered by the selected section
- the color, using the palette of the terminal strip (editable,
  accepts a name, #rrggbb or #rrggbb/#rrggbb)

Values are stored in the element informations (terminal_section,
terminal_width, terminal_color) with the dot as decimal separator,
the keys already read by RealTerminal. An empty value removes the key.

The sections and the manufacturer widths move from
terminalstripmodel.cpp to the new header-only terminalcatalog.h,
shared by the terminal strip editor and the element editor.
2026-10-16 07:50:34 +02:00
Laurent Trinques 8d59d25796 Improve terminal_strip
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 1m45s
2026-10-15 16:26:45 +02:00
Laurent Trinques e883d2c3bf Improve terminal_strip 2026-10-15 14:38:11 +02:00
ispyisail e398f65f0a Warn when a terminal strip lists a terminal no symbol has
A terminal strip saved with a terminal whose symbol is gone left that
terminal out without a word. It still does, and says so in the log.
The same happens with every folio built: the database is filled from
the document, so a symbol in the file is never missing from it.

Review of #1472 (scorpio810, point 8).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 06:20:57 +13:00
ispyisail 5c4fa8fadf Build folios only when needed, by default (stage D6)
Every project now opens without building its folios; a folio is built
when it is shown or something needs its items (QETProject::lazyFolios()).
QET_LAZY_FOLIOS is gone; QET_EAGER_FOLIOS=1 builds every folio on
opening, as before, for comparisons and troubleshooting. Comments that
named the old variable now say "lazy folios"; the tests switch modes
with the new one.

The first save of a .qet as .qetz still builds every folio: a .qet does
not say which program wrote it, so its folios are written again rather
than copied. A .qetz opens and saves without building.

ctest 96/96 by default and with QET_EAGER_FOLIOS=1; 342 corpus projects
save the same in all four arms and export the same. In the GUI
(qet-gui-dialog): a 136-folio .qetz opens with no folio built, shows
folios 1 to 4, saves building none, the save = the original but the time
spent in it; a .qet opens lazily, saves as a .qetz beside it after the
notice, the .qet unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 23:03:51 +13:00
ispyisail e89ccf2a40 Open a .qetz from its database, each folio read when built (stage D2)
A .qetz now carries index.sqlite: the project database as QElectroTech
keeps it -- every table but the drawing items, which exist for built
folios only -- with each folio's own data (Diagram::headerXml()) and a
stamp of the schema it was written with (projectDataBase::indexFile(),
QETProject::writeContainerFile(): Save, --resave, --set-titleblock, a
script's and live mode's save). Written when every folio, symbol and wire
has a uuid of its own; a reader that does not know the entry skips it.

With QET_LAZY_FOLIOS=1, a .qetz with an index opens from it: the project
document is joined without its folios (QetContainer::join() with
folio_files), the database and the stores of symbol information and wire
properties are filled from the index (fillFromIndex()), each folio is made
from its own data and keeps the name of its part, read when the folio is
built (Diagram::deferredXml(), QETProject::readFolioPart(),
QetContainer::readFolio() -- pictures and engineering data back from
project.sqlite, QetContainerDb::restoreFolio()). A terminal strip finds its
terminals' folios in the database. Any other .qetz, or one whose index
cannot be used, is read whole as before.

The index is untrusted: refused unless written with this database's
schema, every table read a plain table (not a view), nothing in its schema
run (trusted_schema off); refused, the project is read whole. Checked: an
index of garbage, a wrong stamp, a table made a view -- each refused and
the project saved as a plain save.

The 136-folio f2099 as .qetz opens in 1.8 s (3.65 s read whole, 29 s
building every folio); what is left is mostly its 7 MB of symbol
definitions (0.8 s). The file grows from 2.6 to 5.2 MB, the index
overlapping project.sqlite until D3.

tst_lazyfolios: a .qetz opened from its index builds only the terminal
strip's folios, numbering read as when built, every folio shown in turn
draws and links as when built, the save as when built; fails when a folio
part's engineering data is not put back. Corpus, 342 projects: 340 .qetz
carry an index and open from it (2 have symbols sharing a uuid); saved
back as .qet = eager = master on all 342. Probe on industrial and f2099
.qetz: every folio as eager but the 3 render-noise folios of f2099. In a
real window the .qetz opens and pages building only shown folios and
partners. ctest 96/96 with and without QET_LAZY_FOLIOS=1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 23:03:43 +13:00
Laurent Trinques 77e2a9bfc5 Speed up opening big projects with lazy folios 2026-10-13 11:01:21 +02:00
Laurent Trinques b8dd03923a TerminalStripItem add pdfRefs
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 1m53s
2026-10-12 16:02:26 +02:00
Laurent Trinques 9f5406bd8c Terminal strip: add a label filter to the free terminals table 2026-10-11 13:31:30 +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
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
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
Laurent Trinques e89c69719a Improve terminal_strip 2026-10-09 09:18:40 +02:00
Laurent Trinques 36cfa938e9 Improve terminal_strip 2026-10-08 23:32:29 +02:00
ispyisail 80c8e297ec Regenerate the English source conversion on master 8b5a09f3fc
Generated by tools/qet-en-source/regenerate.sh, not edited by hand. The
tree is the fresh conversion; this commit only joins it to the PR's
history so the branch is never force-pushed.
2026-10-09 05:05:49 +13:00
Laurent Trinques b719502060 Terminal strip: natural sort for automatic ordering and terminal lists
"Position automatique" sorted labels as plain strings, so XAUZ1:10
came before XAUZ1:2. Add QETUtils::naturalLessThan (digit runs compared
by value, case insensitive; QCollator numeric mode is ignored by some
Qt backends) and use it in SortTerminalStripCommand, FreeTerminalModel
and the terminal strip tree dock.
2026-10-08 16:19:44 +02:00
ispyisail f5962ecd06 Make English the source language of the interface text
Every tr() source string in the code and the forms is now the English
text, and French is a translation (qet_fr.ts) like the other languages.
Generated, not hand-edited: master ef795a21e5 converted by
qet-en-source (harness 4c4ddc9).

3144 messages get an English source, 665 already had one, 0 left French; 8 shared-wording pairs disambiguated.
C++: 2904 literals in 233 files. Forms: 809 strings in 65 files. All 34 .ts files re-keyed; qet_fr.ts filled.
lupdate check: PASS. What each of 38 languages shows, old vs new: same 118266, English instead of French 38433, comment fallback 51, differences 0.
2026-10-08 12:50:13 +13:00
ispyisail 57c650e6e0 Fix 9 messages always shown in French; add missing English
Nine messages were never passed through tr(), so every user saw them in
French: the undo entries for grouping and ungrouping terminals, for
editing an arc (3), an ellipse, a rectangle and a PLC table in the
element editor, and the error box when integrating a title block
template fails. They are now wrapped, text unchanged.

qet_en.ts also lacked English for 63 messages added since the last
translations update (Customize dialog, mouse gestures, toolbar contents,
mirror, element scale, paste element information, paper format).
update_translations was run on qet_en.ts with lupdate's guessing
heuristics off, then the 72 new entries were translated. Most of the
diff is lupdate refreshing line numbers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit d0657f36db)
2026-10-08 12:49:39 +13:00
ispyisail d0657f36db Fix 9 messages always shown in French; add missing English
Nine messages were never passed through tr(), so every user saw them in
French: the undo entries for grouping and ungrouping terminals, for
editing an arc (3), an ellipse, a rectangle and a PLC table in the
element editor, and the error box when integrating a title block
template fails. They are now wrapped, text unchanged.

qet_en.ts also lacked English for 63 messages added since the last
translations update (Customize dialog, mouse gestures, toolbar contents,
mirror, element scale, paste element information, paper format).
update_translations was run on qet_en.ts with lupdate's guessing
heuristics off, then the 72 new entries were translated. Most of the
diff is lupdate refreshing line numbers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 12:29:08 +13:00
ispyisail 306c682112 Fix the free terminal table staying empty after a move (#1306)
In the terminal strip manager, after a free terminal was moved into a
strip, clicking another free terminal showed nothing on the right. It
only came back after selecting a strip first.

The tree remembers whether a free terminal is selected and only tells
the window to update when that, or the selected strip, changes. Moving
a terminal rebuilds the tree, which clears the selection and shows the
empty page, but the "free terminal selected" flag stayed true. The next
click on a free terminal then looked like no change and was ignored.

The flag is now reset when the selection is cleared, and updated on
every change it takes part in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 22:02:11 +13:00
Jeff Patterson 6753aa3ce7 Loaded icons by theme name and removed the PNGs nothing uses 2026-10-02 05:47:40 -05:00
Laurent Trinques d777b8d44d Merge pull request #1199 from ispyisail/feature/terminal-strip-drag-drop
Add drag and drop of free terminals onto a terminal strip (#409)
2026-10-01 08:14:25 +02:00
ispyisail 66ad129c20 Add drag and drop of free terminals onto a terminal strip (#409)
In the terminal strip manager, free terminals could only be moved into a
strip with the "move to" list and its button. Dragging one onto a strip,
which is what users try first (#409), did nothing.

Free terminals can now be dragged onto a strip in the tree on the left,
from either place they are listed:
- the free terminal table: every selected row is moved;
- the tree itself: the dragged free terminal is moved.

Dropping on a strip, or on a terminal already in that strip, moves them
with the same undo command as the button, so one undo puts them back.
The strip is then selected, showing the terminals just added. A drop
anywhere else is refused.

A drop is also refused while the free terminal table has edits that are
not applied yet: moving reloads that table and would lose them. The
button is disabled in the same case.

The drag carries the uuids of the terminal elements under its own mime
type, and the tree only moves terminals that are still free in the
project when the drop happens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 18:33:50 +13:00
ispyisail 97239657c7 Fix the terminal strip's move button saying the wrong thing (#409)
The button that moves free terminals into a strip is disabled when there
is nothing it can do, but its tooltip always gave the same reason: apply
or cancel the pending edits. With no row selected, which is what the
screenshot on #409 shows, that sends the user looking for edits they
never made.

It also stayed enabled when the project had no terminal strip at all.
The "move to" list is then empty and a click did nothing.

The button is now disabled in all three cases and the tooltip names the
one that applies, the most basic first: no strip yet (create one with
the + button), edits pending, or nothing selected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 18:11:45 +13:00
ispyisail a70e27b4c4 Merge pull request #1165 from ispyisail/revive/691-dialog-geometry
Remember dialog sizes, and drop a light-grey box in dark themes
2026-09-30 11:35:25 +13:00
ispyisail a28e834185 Remember dialog size and position across sessions
QETElementEditor, QETDiagramEditor and QETTemplateEditor already
persist their geometry via QSettings; none of the modal QDialog
subclasses did, so any dialog resized to see more of its content
(Search and Replace, Diagram properties, Export, ...) is back to its
default size the next time it's opened.

Adds QET::trackDialogGeometry(), one call at the end of each dialog
constructor (after any default resize()), following the same
restoreGeometry()/saveGeometry() pattern as the three editors above,
stored under [dialoggeometry] and keyed by class name by default. An
explicit key is used for PropertiesEditorDialog, a single class
templated over several unrelated wrapped editors, so they don't all
fight over one saved size.

Covers the 36 dialogs of the original change (#691) plus seven added
since: RenumberElementsDialog, MaterialEntryDialog, AiAssistantDialog,
DuplicateOffsetDialog, ImageTransparentColorDialog, PdfPagesDialog and
WiringListDialog.

Deliberately not touched: BackupDialog and ImageCropDialog, which
setFixedSize() themselves, and MaterialSelectionDialog, which already
restores its own size.

A size saved while the dialog sat partly off-screen is restored on
screen: restoreGeometry() moves it back inside the available screen
(checked: saved at 1502,972 on a 1600x1000 screen, reopened at 600,317).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:31:12 +13:00
ispyisail fbb59ee1e7 Fix a crash when closing a project after its terminal strip window is gone
The terminal strip window's tree dock connects to its project's
destroyed() signal with a lambda capturing `this`, but without `this`
as the connection's context, and never disconnects it. When the dock is
deleted before the project, closing the project runs the lambda on
freed memory.

The terminal strip window is a single instance, parented to the editor
window it was first opened from. With two editor windows:

1. open the terminal strip manager from window 1 (project A);
2. open it from window 2 (project B): the same window switches to B,
   still a child of window 1;
3. close window 1: the terminal strip window and its dock are deleted,
   the connection to B stays;
4. close window 2, or project B: heap-use-after-free in the lambda
   (terminalstriptreedockwidget.cpp:66), reported by AddressSanitizer
   3 times out of 3. Freed by ~TerminalStripEditorWindow from
   ~QETDiagramEditor.

Passing `this` as the context removes the connection with the dock, as
FreeTerminalEditor, FreeTerminalModel and TerminalStripEditor already
do for the same signal. With the fix: no error, 3 times out of 3.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 09:22:05 +13:00
Andre Rummler 574d6dcd56 Fix captor operator [=] which needs to be written explciitly [this] in C++20. 2026-09-28 23:01:42 +02:00
ispyisail 2266497b0b Write the move button tooltips in French, the tr() source language
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:20:43 +12:00
Shane Ringrose dcb79b6553 fix(terminal-strip): free-terminal move button disabled and unresponsive
Three bugs stacked to produce the symptom in issue #409 (move button does
nothing):

1. selectionChanged() was declared in freeterminaleditor.h but had no body
   and was never connected to the selection model, so the move button had no
   awareness of whether a terminal was selected. The button could appear
   enabled with nothing selected, then silently return early in
   on_m_move_pb_clicked() at the real_t_vector.isEmpty() guard.

2. The dataChanged→setDisabledMove(true) connection was a one-way trap: any
   cell edit (including accidentally opening and closing a type/function
   combo, or toggling LED back to its current value) permanently disabled the
   move button until reload() was called. There was no tooltip explaining why
   the button was greyed out, so the user had no way to recover.

3. FreeTerminalModel::setData() for LED_CELL had no change guard, unlike
   LABEL_CELL which checks label != value. Clicking the LED combo while it
   was already at the same value still emitted dataChanged and triggered the
   disable.

Fix:
- Implement selectionChanged() to enable the move controls only when at
  least one row is selected AND there are no pending (yellow) edits.
- Connect it to both selectionModel::selectionChanged and model::dataChanged
  so the button state is always consistent with actual UI state.
- Route reload()'s re-enable through selectionChanged() instead of calling
  setDisabledMove(false) directly, so the selection state is respected
  immediately after a move.
- Add a tooltip to m_move_pb explaining the disabled state.
- Add the missing change guard to LED_CELL in setData().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-24 22:20:43 +12:00
Andre Rummler 3202c145e8 Fix French origin strings (language improvement). 2026-09-22 08:03:07 +02:00
Andre Rummler 7e3420b1a5 Avoid constructing sentences. 2026-09-19 10:39:54 +02:00