Commit Graph

737 Commits

Author SHA1 Message Date
ispyisail e42ebdc861 Add a conductor colour button to the Schéma toolbar (#461)
An electrician on the forum draws 400 V and 24 V circuits in the same
folio and wants the colour to be one click away
(qelectrotech.org/forum, viewtopic pid=23296). Today the quickest route
is F2, which opens a colour dialog and refuses to act unless exactly one
conductor is selected, so colouring a run means one conductor, one
dialog, at a time.

This adds a swatch button beside the auto-conductor actions. Picking a
colour does two things:

  - recolours every conductor currently selected, as ONE undo step;
  - becomes the colour of the next conductor drawn, through the
    LastUsedStyle mechanism #888 already added and Conductor's
    constructor already reads.

Either half is useful alone: with nothing selected it just sets the pen
for what comes next.

The menu lists the colours the trade names -- the three phases, neutral,
earth, and the ones used for control and extra-low-voltage circuits --
then any custom colours picked this session, then the full colour
dialog. A colour already in the standard list is not repeated under
"recently used".

Nothing is written to the project or to QSettings. That is deliberate:
it is the same session-scoped "what did I just use" idea as
LastUsedStyle, so it adds no persisted state and no file-format change.
Named presets stored per project -- what #461 actually asks for -- are a
larger feature that needs a maintainer decision first; the question is
still open on that issue since 21 June.

Verified on a virtual display against examples/Habitat-Schemas_developpes.qet,
reading colours back from the saved project rather than the screen:

  select all on folio 1, pick Rouge
      21 conductors {none:1, #ff5500:2, #ff0000:6, #00aa00:5, #0000ff:7}
      -> all 21 #ff0000
  one Ctrl+Z
      -> back to the original five-colour mix, exactly
  pick Marron with nothing selected, then draw a conductor
      -> the new conductor is #7b3f00

ctest 12/12, Qt 6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CaKympWT3owLotCpEN2CFj
2026-09-19 09:02:58 +12:00
Jeff Patterson 8ef130a59d Add a "qet" icon theme and load icons by name
QET had no icon theme: the 446 entries of the icon table and the 116
iconsets in .ui files each named a resource path, so an icon could only
ever be one file, and a variant for another palette or a vector source
had nowhere to go (GitHub #466, #690, #870). This adds the theme layout
without changing a single pixel; a dark variant comes in a follow-up.

The theme "qet" follows the freedesktop layout Qt's icon loader
understands. misc/make_icon_themes.py generates ico/icon-themes.qrc,
which aliases the existing ico/<size>/<name>.png files into
themes/qet/<size>/<name>.png, and ico/themes/qet/index.theme. No file
moves. The four table entries that paired a 16 pixel file with a 22
pixel file of another name (ConductorSettings, DiagramAdd,
DiagramDelete, DialogInformation) get the 22 pixel file aliased under
the 16 pixel name.

QETApp::initIconTheme() registers the theme before initIcons() and makes
it current on every platform, so a desktop icon theme cannot replace
QET's icons. Icons are then looked up by name: QIcon::fromTheme() in
qeticons.cpp and in the few places that built a QIcon from a resource
path directly, and theme="..." on the iconsets in .ui files, with the
resource path kept as fallback. Flags, color swatches, application and
MIME icons stay on their paths.

One entry does not go through the theme. The elements panel draws the
project root with ProjectFileGP in the 50 pixel slot it reserves for
element previews, and the name "project" also carries the 128 pixel
file the configuration dialog uses. On a 2x display Qt's loader picks
that file for a 50 pixel request and fills the slot. ProjectFileGP
loads the 16 and 22 pixel files directly, as before.

tests/qttest/tst_qeticons: every name in the theme resolves, the four
aliases resolve at 22 pixels, a Fusion tool button shows its icon at
3:1 with disabled weaker than enabled, and the project root icon stays
at 22 pixels or less when asked for 50 at 2x while the configuration
dialog still gets its 128 pixel file. The rendering helpers shared
with tst_qetpalette moved to tests/qttest/inkcontrast.h.
2026-09-17 05:41:50 -05:00
Laurent Trinques c3b0e6725e Merge pull request #896 from ispyisail/feature/886-custom-sql-reports
Add read-only enforcement, preview and import/export to custom SQL reports
2026-09-17 12:38:17 +02:00
Laurent Trinques 3f8e6418d0 Merge pull request #881 from Kellermorph/checkbox-master-slave
Add Hide full masters checkbox to slave linking widget
2026-09-17 12:30:42 +02:00
ispyisail 12ecf6b28f Add read-only enforcement, preview, import/export to custom SQL reports
Refs discussion #886: a saved-report manager built on custom SQL and
nomenclature.json. Most of what was asked for already existed --
Projet > Exporter au format CSV already builds/saves/reuses named
SELECT queries via ElementQueryWidget and nomenclature.json, and
Projet > Ajouter une nomenclature already inserts one into a folio.
This fills the three real gaps.

- projectDataBase::isReadOnlySelect() rejects anything that isn't a
  single SELECT/WITH statement. Checked in newQuery() itself, the one
  choke point every query path already goes through -- including a
  query loaded from a saved nomenclature/summary table's <query>
  element on project open, not just the dialog's own custom-SQL box.
  ElementQueryWidget shows the same check live as you type, and
  BOMExportDialog surfaces it before running or exporting anything.
- BOMExportDialog gains a Preview button + table (QSqlQueryModel),
  so a report can be checked on screen before committing to a CSV file.
- ElementQueryWidget gains Importer.../Exporter... buttons that
  read/write nomenclature.json's saved reports as a JSON file, so a
  report can be handed to a colleague or another install. Import asks
  before overwriting a locally-saved report of the same name.

Verified: Qt 6.10.2, builds clean, ctest 8/8. Drove the real dialog
through Xvfb: typed "DROP TABLE element" into the custom-SQL box and
got the inline warning immediately, then confirmed Preview also
refuses it with a "Requête refusée" dialog rather than running it.
Preview against the real default query returned live column headers
and a row. Export opens a save dialog without crashing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-17 10:09:14 +12:00
Andre Rummler ce8884394a Remove all code switches for Qt<6 with one exception: caching in titlebordertemplate. Function for caching not called since Qt4; might profit from complete removal.
Another exception: one non-converted code path in projectprintwindow.cpp to be followed-up.

One issue found in the Qt6 code path of diagramview.cpp which has been fixed.
2026-09-17 00:07:46 +02:00
Laurent Trinques c71839a291 Merge pull request #869 from Kellermorph/fix-crossref-textfield
Clear stale xref data from PLC slave elementInformations on unlink and position change
2026-09-16 21:28:10 +02:00
Kellermorph a7f406cd44 Merge remote-tracking branch 'origin/master' into fix-crossref-textfield 2026-09-16 11:49:55 +02:00
Kellermorph dad6206386 Address review feedback: parentGroup guard, ELMT_XREF constant, indentation
- Add !parentGroup() guard to stale xref removal in updateXref()
  to prevent deleting xref data that ElementTextItemGroup::updateXref()
  just stored for a grouped text item.
- Replace QStringLiteral("xref") with QETInformation::ELMT_XREF
  in linkelementcommand.cpp and masterelement.cpp.
- Fix indentation in plclinkwidget.cpp.
2026-09-16 11:49:49 +02:00
Jeff Patterson b208a4f131 Show the text color as a swatch and keep the terminal plan preview on white
The Selection properties "texts" tab painted the color value's own text in
that color, so the default black was unreadable on a dark palette. Show a
swatch in the cell instead and leave the text in the palette's color.

The terminal plan preview draws black ink with a white brush, like the
printed page it previews, on whatever background the view inherits from
the palette. Give the view a white background.
2026-09-16 04:39:31 -05:00
Kellermorph e6ffc8b622 Address all review feedback 2026-09-16 11:37:27 +02:00
ispyisail 2eed3acd3d Merge pull request #723 from IBSYSLevi/feature/cabinet-layout
Added width/height/depth properties to elements
2026-09-16 18:51:34 +12:00
Kellermorph c2f405c32d Add Hide full masters checkbox to slave linking widget 2026-09-15 21:48:47 +02:00
Kellermorph 9bfe18807f Fix undo not restoring PLC slave fields and stale connections on position change
Two additional bugs found after the initial xref cleanup:

1. Undo after unlink did not restore PLC variables (PLC_TYPE,
   PLC_ADDRESS, etc.) because PlcLinkWidget::on_m_unlink_pb_clicked()
   never stored the current group index in the LinkElementCommand.
   makeLink() only populates PLC fields when group_idx >= 0, so
   the slave was re-linked but appeared empty. Fixed by reading the
   group index from the master via groupIndexForElement() and calling
   setGroupIndex() before unlinking.

2. m_update_slave_Xref_connection was only cleared inside the
   if(m_slave_Xref_item) block in the updateXref() cleanup path.
   For AlignHCenter (Text field) position, no m_slave_Xref_item
   is ever created — the connections are stored in
   m_update_slave_Xref_connection but never cleaned up on unlink.
   On re-link, the old stale entries prevented new connections from
   being established. Fixed by clearing the list unconditionally
   in the cleanup path.
2026-09-14 16:19:37 +02:00
Kellermorph 3c1c29f6c3 connect searchfield 2026-09-13 21:32:34 +02:00
Kellermorph cafc5bcf6d Add Hide linked elements checkbox to PLC link widget 2026-09-13 20:36:59 +02:00
ispyisail a6fd42ac5f Import automatic numbering rules from another project
Forum #3186 / issue #850: a user who has built up conductor and element
numbering rules in one project has no way to reuse them in the next one.
The only answer today is to open both .qet files in a text editor and copy
the XML across by hand.

Adds an "Import from another project..." button to the auto-numbering page
of the project properties dialog. It offers every numbering found in the
chosen file, per category, with names that already exist here unticked by
default and a "replace same-named numberings" option for when that is what
the user wants.

The source file is parsed as plain XML rather than opened as a QETProject.
Opening it would run the whole load path, including the modal dialog raised
for a file written by a different version of QElectroTech -- a dialog the
user has no reason to see, since nothing but the <newdiagrams> block is
being read.

Two supporting changes:

  - readValuesFromProject() clears the three combo boxes before filling
    them. It only ran once before; it now runs again after an import, and
    without the clear every name appeared twice.

  - FolioAutonumberingW::setContext() likewise replaces its list instead
    of appending to it. It has a single caller, the line above.

This deliberately does not attempt the project-template feature also raised
on the forum thread. That needs decisions about where templates live and
what else they carry, and is better settled in a discussion first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 09:56:25 +12:00
ispyisail f9d063bd38 Merge pull request #821 from enesgursoy6110/fix/shortcut-conflict-scope
Scope shortcut conflicts to overlapping editors
2026-09-13 00:00:54 +12:00
ispyisail a0acf878a2 Revert "Merge pull request #759 from ispyisail/fix-shortcut-conflict-scope"
This reverts merge commit 3d5799773, restoring shortcutsconfigpage.cpp to
its state before it.

#759 and #821 fix the same issue (#757). #821 was opened on 8 September and
is the better fix; #759 was merged on 12 September without checking whether a
PR for it already existed, and its merge is what left #821 conflicting with
master. Reverting is the way to let the right change land.

#759 keys conflict detection on the row's category, which is a tr() string.
#821 keys on the shortcut ID prefix, which is stable and untranslated, and
encodes the overlaps the category cannot express: main-window actions are
live while any editor is open, and the depth.* actions are installed into
both the diagram and the element editor.

Checked against the registry rather than by reading -- 94 registered actions
plus the four depth.* ones registered through QObject::tr. On the shipped
defaults the two behave identically: all 24 shared sequences are legitimate
cross-editor duplicates and neither flags them. They diverge on shortcuts a
user assigns, where #759 misses four classes of real conflict that #821
catches: a diagram or element editor action given the main window's F1, and
a diagram or element action given a depth.* sequence.

The reason #759 looked adequate is that the scope prefix currently maps
one-to-one onto the translated category for all seven scopes, so same-scope
detection comes out the same either way. It fails only where scopes overlap,
which is the case #821 exists to handle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 23:51:41 +12:00
ispyisail 9c3ab588a4 Merge branch 'master' into fix-shortcut-conflict-scope 2026-09-12 23:07:27 +12:00
ispyisail 52d5c7572c Merge branch 'master' into fix/projectconfigpage-virtual-cleanup 2026-09-12 22:49:42 +12:00
enesgursoy6110 77f8e26ffc Address smart device BOM review feedback 2026-09-11 20:12:09 +03:00
ispyisail b5722c3f2a Sort the wiring list by wire number as a number, not as text
Follows @scorpio810's review note on merging #630:

  ORDER BY diagram_position, wire_number sorts wire numbers as text,
  so "10" comes before "9".

Confirmed against the corpus: perceuse.qet put 111 before 12, and
affuteuse_250h.qet put 45 before 5. industrial.qet happened to look
correct only because its wire numbers are all the same width.

Wire numbers are free text and are not always numeric -- perceuse.qet
also carries an unresolved "%sequ_1" -- so the ordering has to cope with
both. Numeric values come first, ordered by value; anything else follows,
ordered as text. The trailing wire_number keeps ties stable.

Fixed in both places the query appears: the CLI exporter and the wiring
list dialog. They had the same ORDER BY, so fixing only one would have
made the dialog and --export-wiring disagree about the order of the same
data.

Verified on perceuse, affuteuse_250h, industrial and tremie_vibrante:
zero out-of-order numeric pairs afterwards, row counts unchanged, and
"%sequ_1" now sorts after the numbers rather than among them. Folio 3 of
perceuse.qet reads 0 1 2 3 4 4 5 5 6 6 7 7 12 12 where it previously
interleaved 111 before 12.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 12:43:07 +12:00
Laurent Trinques c7893c8229 Merge pull request #630 from ispyisail/feature-wiring-list-export
Wiring list dialog + excluded-conductor count (discussion #503, slice 4)
2026-09-10 22:45:22 +02:00
Laurent Trinques 6d09041dce Merge pull request #831 from ispyisail/feature/advisory-slave-limit
Make the slave limit advisory rather than a refusal
2026-09-10 14:50:56 +02:00
ispyisail 85f46f2b48 Use QLabel::pixmap()'s non-deprecated by-value form on Qt5
#824 read the pixmap through the pointer overload, which Qt 5.15
deprecates, so the fix it introduced compiled with two deprecation
warnings of its own. Qt 5.15 offers the by-value form behind
Qt::ReturnByValue, so both branches can take the same overload and the
difference reduces to the argument.

Equivalent: the pointer overload returns nullptr when no pixmap is set,
which the old expression turned into a null QPixmap; pixmap(
Qt::ReturnByValue) returns a null QPixmap directly. It also drops the
null check, so the Qt5 branch is now a single expression.

Verified both arms of the #if, since a preprocessor-branched change is
only half tested otherwise:

 - Qt 5.15.18: deprecation warnings for this file 2 -> 0, builds clean,
   binary runs
 - Qt 6.10.2: builds clean, 488/488, links
 - 22 example projects load and export with no crash or hang

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 16:50:49 +12:00
ispyisail ffd829bb69 Make the slave limit advisory rather than a refusal
max_slaves records how many contacts a part is expected to carry. It was
enforced as a rule the drawing had to obey, which obstructs the way both
@scorpio810 and @IBSYSLevi described working in #819: draw the schematic
first, choose the physical hardware afterwards. A limit that refuses the
link forces the hardware decision up front, which is exactly what they
said gets in the way.

Two changes, both in the UI rather than in isFull(), which stays the
query it always was:

 - MasterPropertiesWidget::on_link_button_clicked() now says the limit
   is reached and asks whether to link anyway, defaulting to yes,
   instead of refusing outright.

 - LinkSingleElementWidget no longer removes a full master from the
   candidate list. That was the worse half: a master at its limit simply
   was not there, indistinguishable from one that does not exist, with
   nothing to say why. It now stays selectable and the user decides.

PLC masters are deliberately left alone. Their limit is the number of
declared IO slots, which is structural rather than advisory -- a link
past it would have no IO index to map to -- and PlcLinkWidget already
tells the user when it hides one, via m_hidden_masters_label.

Only coils that opt into a limit are affected: max_slaves defaults to
-1, and no project in examples/ sets it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 11:54:52 +12:00
Laurent Trinques c1f9af8544 Merge pull request #822 from enesgursoy6110/fix/report-link-picker
Show folio identity first in report link picker
2026-09-09 07:49:42 +02:00
ispyisail f18eda845b Merge branch 'feature/general-tab-contact-count' into feature/per-type-contact-budget
# Conflicts:
#	sources/ui/elementpropertieswidget.cpp
2026-09-09 11:47:26 +12:00
ispyisail 73e9473db4 Keep the slave total in slots, and label the breakdown as contacts
Two units were being stacked in the same block. The line above reports
max_slaves, which is a number of slots, so reporting the line below in
contacts made a coil with one 4 pole slave read "maximum 4 / used 4"
while three slots were still free.

The total goes back to counting linked elements, matching the unit of
the line above it and restoring the original behaviour of that line.

The per-type breakdown keeps the pole multiplier, because that is the
question it answers -- how many contacts an auxiliary block must
provide -- and is now prefixed "Contacts :" so the two units are not
mistaken for each other.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 11:46:34 +12:00
ispyisail 6f2c66afef Show used against declared capacity where a master declares contact groups
Second half of #819: where a coil declares what contacts it provides, the
General tab now reports each type as used against declared rather than as
a bare count.

    NO : 3/4, NC : 1/2, inverseurs : 0/1, autres : 0/0

MasterElement::contactCapacity() sums contactCount over the element's
SlaveContactGroup list, per type, reusing the same ContactUsage tally the
used count is built on. The mapping from ElementData::SlaveState onto the
tally's own type is factored into one helper so the used count and the
declared capacity cannot classify a contact differently.

Falls back to the plain count from the previous commit when an element
declares no groups, which is every element in the standard collection
today -- nothing in the corpus declares slaveContactGroups, so this
changes no existing display.

A type used beyond what is declared reads as e.g. "1/0". That is
deliberate: it says this contact does not fit the part.

Display only. Whether a declared capacity should also feed
MasterElement::isFull() is the open question in #819 and is not touched
here.

Verified end to end against a purpose-built fixture, since no existing
element exercises this path: a coil declaring two NO groups of two, one
NC group of two and one changeover group of one parses and reports
NO=4 NC=2 SW=1 other=0 total=7, matching the declaration exactly.
tst_contactusage gains a case covering capacity summed across groups
(10 cases, all passing).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 10:49:16 +12:00
ispyisail c39c7414cf Show the NO/NC/SW contact breakdown in a master's General tab
Requested in #819: after drawing a schematic you need to know how many
NO, NC and changeover contacts a coil ended up using, so you can pick an
auxiliary block that satisfies it. Until now the General tab reported
only a single total, and counting the contacts by type meant counting
rows on the cross reference by hand.

Three changes to that block:

 - the used count now counts contacts rather than linked elements. The
   label already said "contacts" while the value was
   linkedElements().count(), so a slave standing for several contacts
   was under-reported. It reads MasterElement::contactUsage(), the
   same count isFull() uses.

 - a breakdown line is added below it, printed only when the master
   actually has contacts to break down.

 - a declared limit of -1 means "no limit set" rather than a real
   limit, so it is printed as such instead of showing "-1", which
   reads as a bad value.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 10:36:25 +12:00
ispyisail c265f0206c Fix Qt5 build: QLabel::pixmap() returns a pointer, not a value
ClickableImageLabel::mousePressEvent() calls pixmap().isNull() and
pixmap().width(). That is the Qt6 signature; in Qt5 QLabel::pixmap()
returns const QPixmap * and the code does not compile:

  error: request for member 'isNull' in '...QLabel::pixmap()',
  which is of pointer type 'const QPixmap*'

CMakeLists.txt defaults QT_VERSION_MAJOR to 5 when it is not specified,
so a default configuration of master has not built since 6b577ee75.

Read the pixmap once into a local, guarded the way the rest of the
codebase handles this split, which also drops four repeated pixmap()
calls in the same expression.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 09:52:06 +12:00
enesgursoy6110 cfa1e3ed27 Scope shortcut conflict detection by editor 2026-09-08 21:02:46 +03:00
enesgursoy6110 36dd1624d2 Show folio identity first in report link picker 2026-09-08 21:02:46 +03:00
Laurent Trinques 1738c3ad6c Merge pull request #771 from Kellermorph/spinbox-crossref
Add configurable distance between label and slave XRef
2026-09-08 08:20:33 +02:00
Andre Rummler a065867502 Fix issue that made it impossible to remove all transparency colours defined in a previously opened dialog. On the last color the OK button was greyed out. 2026-09-07 10:44:29 +02:00
Andre Rummler b395527915 Add transparency to each color for image transparency. 2026-09-05 20:54:19 +02:00
Andre Rummler 7741bb33b2 Use downscaled image for image transparency window to improve resposiveness. 2026-09-05 20:54:09 +02:00
Kellermorph a494a8fd6c Add 'Text field' option for slave cross-reference positioning 2026-09-05 18:55:14 +02:00
Andre Rummler 6b577ee757 Add editable resize/rotate/skew handles for shapes and images
Shapes and images can now be resized, rotated, and skewed directly
on the canvas, not just moved. Both share one small transform
struct (rotation, then skew, then scale, anchored on a movable
pivot) and one handle widget, so a corner drag, an edge skew, or
grabbing the rotate handle behaves the same way and runs through
the same matrix math everywhere, instead of every item type
reinventing its own.

Shapes also gained a proper pen tool (bezier paths, corner/smooth/
symmetric nodes), arc support, and mirroring. Images gained
non-destructive cropping and colour-keyed transparency, both
remember their own settings, so reopening the dialog picks up
where you left off instead of starting over.

Properties dialogs for both were extended to match (position,
size, angle, skew), with undo/redo wired through for every handle
drag.

Old XML files can read easily as the transformation is only added
if needed and the old syntax is still used and understood if it is
not needed.
2026-09-05 15:48:28 +02:00
ispyisail c69e5747a1 Add position-lock checkbox to element properties (issue #801)
Elements already inherited QetGraphicsItem::isMovable()/setMovable() --
the same mechanism images and drawn shapes use for their "lock position"
checkbox -- but nothing exposed it in the element properties panel, and
Element::toXml()/fromXml() never persisted it.

- ElementPropertiesWidget::generalWidget(): add a "Verrouiller la
  position" checkbox mirroring ShapeGraphicsItemPropertiesWidget's
  m_lock_pos_cb, toggling the element's inherited setMovable().
- Element::toXml()/fromXml(): persist is_movable, same attribute name
  and default-true behavior as DiagramImageItem/QetShapeItem.

Verified via headless --resave round-trip: is_movable="0" survives
load -> save unchanged, existing elements without the attribute default
to movable.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HdWpDp3TrPKbHnv7YUcNJj
2026-09-01 07:16:32 +12:00
ispyisail 6657b3de2b Make ProjectAutoNumConfigPage follow ProjectConfigPage's documented init() contract
ProjectConfigPage::init() is documented as "Typically, you should call this
function in your subclass constructor" -- it runs initWidgets(), initLayout(),
and (if a project is set) readValuesFromProject() and adjustReadOnly(), in
that order. ProjectMainConfigPage's constructor follows this. Until now,
ProjectAutoNumConfigPage's did not: it called initWidgets(), its own
buildConnections(), and readValuesFromProject() directly, skipping both
initLayout() and adjustReadOnly() entirely, and calling
readValuesFromProject() with no null-project guard.

In practice this was harmless today -- this subclass's initLayout() and
adjustReadOnly() overrides are both empty, and every construction site
happens to pass a real project -- but it is exactly the kind of latent
inconsistency Joshua's own refactor notes call out for this class ("remove
inconsistent virtual method usage... allow subclasses independent
implementation"). The day someone fills in adjustReadOnly() for this page
(e.g. to disable auto-numbering editing on a read-only project, which is
what the empty override's own doc comment says it is for), the constructor
path would silently never call it.

Fixed narrowly: the constructor now calls init() like its sibling does.
buildConnections() moves to the end of initWidgets(), the same relative
position it held in the constructor, so behaviour for the paths already
exercised is unchanged. This is the safe, no-redesign half of Joshua's
note; removing the init()/initWidgets()/initLayout()/readValuesFromProject()
scaffolding itself, so subclasses are free to sequence things however they
want, is a real redesign of the ConfigPage contract and needs his sign-off
on what should replace it -- not attempted here.

Verified with a GUI capture rather than by reading: opened Project
Properties on examples/industrial.qet, selected "Numérotation auto", and
confirmed the Management tab renders with its saved policy (Conductor/Element
"Both", "Apply to Entire Project") and the Conducteurs tab's combo box comes
up pre-populated with the project's saved context ("de la nouvelle
numérotation"), which on selection correctly fills the Type/Valeur/Formule
fields -- proving both readValuesFromProject() and the buildConnections()
signal wiring still work end-to-end through the new call sequence.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 23:09:12 +12:00
Laurent Trinques 03b552c601 Merge pull request #776 from ispyisail/remove/diagramselection-dead-code
Remove dead code: sources/ui/diagramselection.*
2026-08-23 13:50:00 +02:00
Laurent Trinques e44219778e Make QtPdf detection optional at configure time
QPdfDocument::pagePointSize() (used for PDF page import) requires
Qt >= 6.4, and the QtPdf module itself is missing entirely on some
Qt6 distributions (e.g. the Flatpak org.kde.Platform runtime), since
it ships from the qtwebengine source tree rather than Qt6 core.

CMake: probe Pdf with find_package(... QUIET) instead of REQUIRED,
mirroring the existing GuiPrivate pattern. Define QET_HAS_QTPDF
only when the module is found AND Qt >= 6.4.
Replace the ad-hoc QT_VERSION_CHECK(6, 0, 0) / (6, 4, 0) guards in
qetdiagrameditor.cpp, diagrameventaddpdf.{h,cpp} and
pdfpagesdialog.{h,cpp} with #ifdef QET_HAS_QTPDF, so version and
module-availability checks live in one place.
Fixes the Flatpak build (missing Qt6Pdf) and the Windows/Debian CI
failures (QPdfDocument::pagePointSize undeclared on Qt < 6.4). The
PDF import toolbar action is now silently unavailable wherever
QtPdf isn't usable, instead of breaking the whole build.
2026-08-23 12:05:52 +02:00
ispyisail 8d175754cd Remove dead code: sources/ui/diagramselection.*
Compiled into the binary but never instantiated -- searching the tree
for any reference outside its own three files finds nothing, and this
still holds on current master. Contains a latent bug that would be
user-visible if the widget were ever reachable
(on_tableDiagram_customContextMenuRequested compares QMenu::exec()'s
return value against one action but falls through to "select all" on
both the other action and on a plain dismiss, since exec() returns
nullptr on Escape/click-away and that's not equal to either QAction*),
which supports genuine disuse rather than temporary disconnection.

Removed the three files and their three explicit entries in
cmake/qet_compilation_vars.cmake (qelectrotech.pro globs sources/ui/*
so needs no change). Builds clean; no other file references
diagramselection.

Fixes #756.
2026-08-23 21:59:39 +12:00
ispyisail dab4c6c424 Scope shortcut conflict detection to the category
checkConflicts() compared key sequences across the whole registry, but
QElectroTech deliberately registers one key per editor window: Undo,
Redo, New, Open, Save and Ctrl+Shift+S each exist three times, once for
the diagram, element and titleblock editors. Those are not collisions --
they act on different windows.

The result was that 60 of the 95 shipped default bindings displayed as
conflicts, so the indicator carried no information and the page looked
broken on first open.

Conflicts are now keyed on (category, sequence). The category is the
registry's existing per-window grouping, so no new concept and no
ShortcutManager API change is needed.

Fixes #757
2026-08-23 21:50:42 +12:00
Laurent Trinques e542724953 Merge pull request #774 from Kellermorph/fix-plc-warnings
Fix PLC table dangling reference warning and row deletion
2026-08-23 11:05:26 +02:00
Laurent Trinques 45afc7e6aa Merge pull request #772 from Kellermorph/pdf-import
Add PDF page import as image
2026-08-22 19:30:33 +02:00
Kellermorph ff25a77159 Improve PDF import: DPI selection, page preview, Qt5 compat, custom icon
- Add DPI selection (150/300/600) to the page selection dialog
- Add live page preview in the selection dialog
- Conditionally compile PDF import only for Qt6 (#if QT_VERSION)
- Add custom pdf-import icon (PDF document with + symbol)
- Register new icon in qelectrotech.qrc
- Qt5 builds: PDF import action is hidden, everything else works as before
2026-08-22 18:53:36 +02:00