Commit Graph

246 Commits

Author SHA1 Message Date
ispyisail 15c893de89 Merge pull request #765 from IBSYSLevi/feature/Add-existing-editor-properties-to-element
Editable auto_num_locked/potential_isolating/exclude_from_bom in the element editor
2026-09-13 00:36:02 +12:00
ispyisail 061f07ef9e Merge branch 'master' into fix-informations-tab-visibility
# Conflicts:
#	sources/editor/ui/elementpropertieseditorwidget.cpp
2026-09-13 00:30:27 +12:00
ispyisail 88f5af08d7 Merge branch 'master' into fix/bugtracker-243-copy-from-readonly 2026-09-12 23:06:47 +12:00
ispyisail 18477c22b5 Merge branch 'master' into fix/element-editor-info-tab-slave-terminal-663 2026-09-12 22:32:39 +12:00
Laurent Trinques a583b3c43c Merge pull request #688 from IBSYSLevi/fix/saving-coil-master
Fix: saving coil master
2026-09-08 08:35:00 +02: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
Laurent Trinques 1793dcb9a8 Revert "Feature: Terminal potential grouping" 2026-09-07 15:44:12 +02:00
Kellermorph a494a8fd6c Add 'Text field' option for slave cross-reference positioning 2026-09-05 18:55:14 +02:00
Levi Jetzer 1e1039dd32 Address review
1. Drop dead prepareGeometryChange()/update() calls in
setPotential(), split unrelated terminaleditor.h re-indent into its
own change

2. Removed: setPotential() had prepareGeometryChange()/update() left over from
the label-display mechanism that was dropped before this PR
2026-09-04 13:12:21 +02:00
ispyisail 95d7b74e9e Merge remote-tracking branch 'upstream/master' into pr721-merge
# Conflicts:
#	sources/editor/ui/elementpropertieseditorwidget.cpp
2026-09-04 22:05:13 +12:00
Levi Jetzer 10bf0411bb Add "Potentiel" field to the terminal editor (element editor)
New QLineEdit (m_potential_le) between Type and Nom: an optional,
symbol-author-chosen grouping identifier shared by terminals that
belong to the same physical terminal within a multi-terminal block.

Stored as TerminalData::m_potential (new field, persisted as the
"potential" XML attribute, empty by default).
Used by relatedPotentialTerminal() in terminal.cpp: when
potential_isolating is enabled on a Terminal-type element, terminals
sharing a non-empty, matching potential value now stay electrically
linked to each other instead of every terminal in the block being
isolated from every other one.

Tooltip on the field for explanation
2026-09-02 19:30:26 +02:00
Laurent Trinques 487b22f483 Merge pull request #769 from Kellermorph/layout-fix
Fix dock widget size/position not being restored on Qt6
2026-08-28 09:25:00 +02:00
Kellermorph 8f6f41ed19 Clean up readSettingsState() in all three editors
- Remove dead #if QT_VERSION conditionals (both branches were identical)
- Add settings.remove() guard on restoreState() failure consistently
  across all three editors (now safe since all run after show())
2026-08-23 18:25:23 +02:00
Kellermorph 61a160fa62 Fix restoreState() for QETElementEditor and QETTitleBlockTemplateEditor on Qt6
Apply the same split readSettings()/readSettingsState() pattern from
QETDiagramEditor to the other two main windows:
- QETElementEditor: split in constructor, call readSettingsState() after show()
- QETTitleBlockTemplateEditor: split readSettings(), callers call
  readSettingsState() after show() (newTemplate + 2x openTitleBlockTemplate)
- Remove destructive settings.remove() guards that would delete saved
  state on every Qt6 launch when restoreState() fails before show()

Co-authored-by: ispyisail
2026-08-23 10:37:52 +02:00
Kellermorph 4edd4932bb Fix PLC table dangling reference warning and row deletion 2026-08-22 16:42:13 +02:00
Kellermorph f6afd87522 Fix dock widget size/position not being restored on Qt6 2026-08-22 11:08:02 +02:00
Levi Jetzer 31feb7b7b0 Show the element editor's Informations tab for Terminal and Thumbnail
setTabVisible(1, ...) only allowed Simple and Master, but the tree
(updateTree()) and the actual write path (ElementScene::toXml()) both
already support elementInformations for Terminal and Thumbnail too --
three independent "is this type allowed" checks that were never
reconciled, leaving already-working support unreachable through the
UI for those two types. Slave stays excluded here, consistent with
having no elementInformations support at either of the other two
points either (separate, larger gap, not addressed here).
2026-08-21 16:23:41 +02:00
Levi Jetzer 622791f994 Remove auto_num_locked/potential_isolating/exclude_from_bom checkboxes'
"false" writes, delete key instead

Unchecking a checkbox previously wrote the key with value "false"
rather than omitting it -- behaviorally identical to every consumer
(all three do a case-sensitive == "true" comparison), but left dead
entries cluttering the .elmt file, inconsistent with how other
elementInformation fields (manufacturer, designation) are only present
when actually set. Now removes the key entirely when unchecked.
2026-08-21 15:59:06 +02:00
Levi Jetzer 884ec4bbb9 Add editable "auto_num_locked"/"potential_isolating"/"exclude_from_bom"
checkboxes to the element editor

These elementInformation keys were previously only editable on an
already-placed instance (via ElementInfoWidget on the diagram side).
Since elementInformation values are seeded from the .elmt file's own
<elementInformations> block at placement time, a symbol author had no
proper way to set these as the *default* for every future placement --
only a workaround via the generic, unvalidated key/value tree.

Adds dedicated checkboxes to ElementPropertiesEditorWidget, mirroring
ElementInfoWidget's own labels/behavior: auto_num_locked and
potential_isolating inside the existing terminal-only group
(m_terminal_gb, shown only for ElementData::Terminal), exclude_from_bom
always visible regardless of type. Written after the generic tree loop
so they take precedence over any stale raw entry for the same key.
No new storage or file format change -- purely a missing editor UI for
an already-existing mechanism.
2026-08-19 17:58:16 +02:00
ChuckNr11 9d81a9788f move position of element editor coord display to center of statusbar
for better visibility only
2026-08-19 12:00:43 +02:00
Levi Jetzer fb0649ceee Fixed incorrect OR and AND checks 2026-08-14 22:23:25 +02:00
Kellermorph fe6191f26d Fix slave contact groups being trimmed to one when reopening element properties 2026-08-14 10:31:15 +02:00
Andre Rummler 6d05bc2f21 Remove all Qt version checks and branches for <5.15.12 as such versions are no longer supported. 2026-08-13 16:20:30 +02:00
Laurent Trinques 2186d2733f Merge pull request #709 from arummler/master-continue-qt6-migration
Qt6 migration beyond signal/slot
2026-08-13 10:55:47 +02:00
ispyisail 6f9f5f84c2 Fix bugtracker #243: allow copying out of a read-only element
Opening an element you cannot write -- anything from the QET collection,
for instance -- disabled Copy along with everything else, so there was no
way to reuse a primitive from it. The workaround was to save the whole
element into your own collection first, just to take one shape out of it.

Two actions stood in the way, and neither of them modifies anything:

- Select All and Invert Selection were in the list disabled outright when
  read only, so nothing could be selected in the first place;
- Copy was enabled only when "!m_read_only && selectedItems().count()", so
  even a mouse selection left it greyed out.

Both now work on a read-only element. Copy is safe there:
ElementScene::copy() serialises the current selection to the clipboard and
touches neither the element nor the file.

Cut, Paste, Paste-in-area, Delete, Rotate, Flip, Mirror, the depth actions
and the add-primitive tools stay disabled exactly as before, so the element
is still protected -- this only stops the editor from refusing to read out
what it is already displaying.

Verified with a chmod 444 element: Select All then Copy now work, the
clipboard receives the expected <definition> with all three primitives,
Cut/Paste/Delete remain greyed out, Save stays disabled, and the file is
untouched (same permissions, same checksum).
2026-08-13 11:28:51 +12:00
Andre Rummler c14d6a6dd6 In order to migrate to Qt6 all options for KF6 were added:
a) using a system provided KF6
b) downloading and compiling KF6
c) using the vendored-in re-creation of the functionality

The behaviour for both Qt5 and Qt6 is steered with the same two variables which were renamed to become version agnostic:
a) BUILD_WITH_KF=ON BUILD_KF=OFF
b) BUILD_WITH_KF=ON BUILD_KF=ON
c) BUILD_WITH_KF=OFF

The version is automatically derived from the chosen Qt major version.
2026-08-12 12:29:56 +02:00
ispyisail 762bd7febf Fix bugtracker #333: selecting several dynamic texts overwrites their colours
Selecting more than one dynamic text field in the element editor silently
replaced every selected field's colour with the colour of the first one.
Nothing was clicked -- merely extending the selection destroyed the others'
colours, and the change went onto the undo stack as if the user had asked
for it.

Cause: updateForm() loads the current part's colour into the colour button
with m_color_kpb->setColor(). KColorButton::changed is emitted for a
programmatic setColor() just as it is for user interaction, and it is
connected to m_color_kpb_changed(), which applies the new colour to *every*
part in m_parts. So simply displaying the first part's colour wrote that
colour to all the others.

Every other widget in updateForm() is immune because it is wired to a
user-only signal -- on_m_x_sb_editingFinished(), on_m_frame_cb_clicked() --
which setValue() and setChecked() do not emit. The colour button is the one
control whose signal cannot distinguish the two, so block it while loading.

This also explains why the reporter saw it only when rubber-band selecting
bottom-to-top: the write happens only when the first part's colour differs
from what the button already shows, which depends on selection order.

Verified in the element editor with two dynamic texts, one red and one blue:
select the red one, then ctrl-click the blue one. Before: the blue text
turned red. After: both keep their colours. Changing the colour deliberately
with the button still applies to all selected texts, as intended.
2026-08-12 15:53:30 +12:00
ispyisail 7afc1eb56b Enable Information tab in element editor for Slave and Terminal basetypes
GitHub issue #663: the "Informations" tab in the element editor's
properties dialog was only made visible for Simple and Master basetypes
(setTabVisible gate in on_m_base_type_cb_currentIndexChanged), hiding it
entirely for Slave and Terminal Block elements.

This wasn't a data-model limitation: ElementData::m_informations is read
and written identically for every basetype (elementdata.cpp), and
updateTree() already special-cased Terminal as enabled and injected
PLC-specific info rows for PLC Slave elements - that logic was simply
unreachable because the tab itself was hidden for both types. Also
flipped updateTree()'s Slave case from setDisabled to setEnabled so the
tree is actually editable once visible, matching Terminal's existing
behavior.

This lets users attach manufacturer/part-number/reference metadata
directly to Terminal Block and Slave (e.g. multi-part contactor)
elements, as requested in the issue - useful when a Slave's part number
differs from its Master's (e.g. a contactor's auxiliary contact block
vs. its coil).

Not verified: interactive element-editor GUI testing wasn't performed
in this sandbox; verified via clean incremental build only.
2026-08-11 18:00:43 +12:00
Laurent Trinques 7f75500023 Merge pull request #694 from IBSYSLevi/feature/center-rotation-option-for-textfields
Feature added: Rotation point center property for dynamic text fields
2026-08-09 21:09:19 +02:00
Laurent Trinques cdf5cad1e5 Merge pull request #698 from arummler/master-modernize-signal-slot
Migrate string based signal/slot to method pointer
2026-08-09 21:08:28 +02:00
Kellermorph 5e02111600 Fix-PLC-Warnings 2026-08-09 18:27:20 +02:00
Andre Rummler c7ed3229d0 Migrating more SLOT() macros. 2026-08-09 12:30:15 +02:00
Andre Rummler 5adf61936b Merge branch 'master' into master-modernize-signal-slot 2026-08-08 23:13:42 +02:00
Levi Jetzer 615e40dee2 Feature added: Rotation point center property for dynamic text fields
Now a new checkbox in the dynamictextfieldeditor is available (by default set to false for legacy) to make it possible to turn dynamic text fields around its own center.
This resolves an undesirable behaviour that occurs when the text alignment is retained

Including translation to english and german
2026-08-08 11:10:36 +02:00
Levi Jetzer d7c75ea5a5 Fixed saving coil master -> correction +
Added space for a better style ;)
2026-08-08 09:07:22 +02:00
Levi Jetzer b9153269a4 Fixed saving coil master -> correction
Added check to the type of master so that types which are not using "max slave elements" are saved with the value -1 (infinity).
2026-08-08 09:05:27 +02:00
Andre Rummler 62ad49a6d3 Update old fashioned SIGNAL/SLOT to point-to-member. Only simple and clear cases. 2026-08-08 00:32:31 +02:00
Levi Jetzer eab9603d8a Fixed saving coil master
Removed "isVisible" check on max_slave_checkbox before saving because isVisible is maybe not true, when the ok button is pressed
Then the value -1 is written and so on not saved to the elements xml
2026-08-07 21:52:40 +02:00
Kellermorph 4f9474a05f PLC Fix scroll sync, data persistence, font defaults, copy/paste, and layout fixes 2026-08-06 07:33:39 +02:00
ispyisail eb520ac3f8 Pre-fill SVG export filename with the element's own name
Suggests the element's filename (without its .elmt extension) as the
default save name when exporting to SVG, instead of only defaulting to
the customElementsDir with no filename. Addresses plc-user's review
suggestion on PR #637.
2026-08-03 08:31:17 +12:00
ispyisail 8a72230916 Add "Export to SVG" to the element editor
Implements discussion #605. The diagram editor can already export a folio
to SVG; the element editor, where a single .elmt symbol is drawn, had no
export capability at all -- confirmed by grepping its header for "export"
before starting: nothing.

## Renders the live scene, not ElementPictureFactory's cache

The discussion proposed sourcing this from ElementPictureFactory's cached
per-element QPicture (m_pictures_H), the one used for the elements-panel
preview icons. Checked that cache's actual invalidation before building on
it: nothing in the editor ever tells it to drop an entry on edit, and it is
keyed by the element's on-disk uuid. So for any element already previewed
once in the panel, exporting from the cache would silently produce stale
content after any edit; for a brand-new, never-saved element, no entry
would exist at all. Neither is acceptable for a File > Export action a
user expects to reflect what's on screen right now.

Renders ElementScene directly instead, the same way
ExportDialog::generateSvg() already renders the live Diagram for the
diagram editor's own SVG export: no new drawing logic, only a new playback
target (QSvgGenerator instead of the screen), sized to the element's own
content bounds via the existing elementSceneGeometricRect() helper.

## Hotspot cross excluded from the export

ElementScene::drawForeground() draws the red origin/hotspot cross on every
render() call, unconditionally -- it's an editing aid, not part of the
element being drawn, and diagram editor's SVG export has no equivalent
problem since Diagram doesn't draw one. Added a settable
hotspotVisible flag, defaulting to true (the existing editing view is
completely unaffected) and turned off only for the duration of the export
render() call.

## Verified end-to-end via a real Xvfb session, not just a build

Opened a real shipped element (en_60617_05_06_04.elmt, "Phototransistor"),
exported it, and rendered the resulting SVG back to a bitmap with a small
QSvgRenderer-based harness -- pixel-identical in shape to the element as
shown in the editor. Confirmed the file is valid XML and contains no
red/#ff0000 stroke (the hotspot cross did not leak in).

Then the case the whole "render live, not cached" decision was about:
opened the same element, drew a new line with the line tool, and exported
again *without saving*. The new line is present in the exported SVG.
git status on the source .elmt file after both exports shows it completely
untouched -- the export is read-only and reflects live, unsaved editor
state, exactly the property a cache-based implementation would have gotten
wrong.

Built clean, no new warnings.
2026-08-02 23:06:12 +12:00
Laurent Trinques 2d99ba67f1 Merge pull request #588 from Kellermorph/Fix-PLC-Manager
Fix-PLC-Manager
2026-08-01 15:30:10 +02:00
Kellermorph e91bab14fe Update 2026-08-01 14:26:39 +02:00
Laurent Trinques 6cdf60e2e7 Merge pull request #587 from ispyisail/feature-configurable-shortcuts
Add configurable shortcuts: Shortcuts preferences page + app-wide registry
2026-08-01 07:23:56 +02:00
ispyisail 9637f0ff9e Add live cursor-coordinate readout to the element editor status bar (#580)
Displays the cursor's scene position (same grid units as the parts'
X/Y property spinboxes) in a permanent status bar label, updated on
every mouse move. Addresses the overlapping-node mis-click case from
the originating forum report: with a live readout, precise pointing
no longer requires guessing against nearby z-ordered points.

ElementScene::mouseMoveEvent already computed the (optionally
grid-snapped) scene position on every move; it now also emits it via
a new mouseMoved(QPointF) signal, which QETElementEditor's status bar
label subscribes to.
2026-08-01 15:12:44 +12:00
Kellermorph 4c1f82f814 Fix-PLC-Manager 2026-07-31 21:02:07 +02:00
ispyisail 5275fb44fe Add configurable shortcuts: ShortcutManager registry + Shortcuts config page (#574)
Implements the first pillar of #574: a "Shortcuts" preferences page letting
users rebind, search and reset every keyboard shortcut in the app.

What it does
- New ShortcutManager singleton: every one of the ~95 setShortcut()/
  setShortcuts() call sites across qet.cpp, qetmainwindow.cpp,
  elementspanelwidget.cpp, autonumberingdockwidget.cpp, richtexteditor.cpp,
  qetdiagrameditor.cpp, qettemplateeditor.cpp and qetelementeditor.cpp now
  calls registerAction(target, id, category, default_sequence) instead,
  which applies the user's saved override (or the default) and remembers
  the target for later editing.
- New ShortcutsConfigPage, added to the existing "Configurer QElectroTech"
  dialog: a filterable table of every registered shortcut, grouped by
  category, each with a QKeySequenceEdit and a per-row reset button, plus a
  "reset all" button. Bindings are only persisted (via
  ShortcutManager::setSequence()) when the dialog is accepted.
- Conflict detection: rows whose currently-edited sequence collides with
  another row are highlighted with a tooltip naming the conflicting action.
- Overrides are stored under a "shortcuts/" QSettings group, one key per
  id, keyed to match the id (not persisted at all when equal to the
  hardcoded default), so a future QET version can safely raise a default
  for anyone who never customized it.

Design notes
- Targets are handled generically via QObject rather than QAction, since one
  call site (autonumberingdockwidget's "Configurer" button) is a
  QPushButton, not a QAction. Both declare an identical "shortcut"
  QKeySequence Q_PROPERTY, so registerAction() reads/writes it through the
  property system instead of needing a separate code path.
- Several live targets can share one id at once -- QET allows multiple
  windows of the same kind (diagram editor, element editor...) open
  simultaneously, each constructing its own QAction with the same id.
  setSequence() updates every live target for that id in one call, so a
  rebind takes effect in all open windows immediately, without restart.
- A shortcut's description is captured from its target's text() the first
  time that id is registered, then cached -- so the config page stays
  correct even after the owning window is closed. One consequence: a
  shortcut belonging to an on-demand window (element editor, title block
  editor, rich text editor) only appears in the list once that window has
  been opened at least once in the current session, since nothing has
  registered its id yet otherwise.

Testing
Full CMake build (qmake CONFIG+=no_kf5, Qt 5.15) compiles clean with zero
errors and zero new warnings. Verified end-to-end in a real running session
(Xvfb + xdotool):
- The Shortcuts page appears in Configure QElectroTech with the right icon,
  lists every always-registered shortcut with correct category/action name/
  current binding.
- The filter box correctly narrows the list, and correctly returns nothing
  for an action whose owning window hasn't been constructed yet this
  session (confirming the on-demand-registration behavior above is working
  as designed, not silently broken).
- Conflict detection correctly flagged a real pre-existing same-key overlap
  between "Supprimer" (delete selection, Del) and "Supprimer ce folio"
  (delete diagram from panel, Del) -- both highlighted with explanatory
  tooltips.
- Rebound "Manuel en ligne" to Ctrl+Shift+M, clicked OK: persisted under
  [shortcuts] in QElectroTech.conf, and the Aide menu's entry showed the new
  binding immediately, no restart needed.
- Reopened the dialog: the rebind was still shown. Clicked its per-row
  reset button, then OK: the settings key was removed entirely (not stored
  as "F1"), correctly falling back to the hardcoded default.

Retrofitting the Tab/Shift+Tab, select-all (#585) and Ctrl+G jump-to-element
(#586) shortcuts through this registry is left for a follow-up once those
PRs land, to avoid re-merging still-open branches into this one.

Developed with assistance from Claude (Anthropic).
2026-08-01 01:35:51 +12:00
Laurent Trinques 717c89fa66 Merge pull request #562 from Kellermorph/PLC-Manager
PLC Manager
2026-07-31 09:05:30 +02:00
ispyisail b60e73d93b Fix #487: drag-selecting dynamic text fields silently converts their text source
updateForm() called on_m_text_from_cb_activated() directly, intending
only to enable the sibling widget matching the combo box's current
index ("For enable the good widget"). But that slot also loops over
every currently selected part and pushes an undo command overwriting
textFrom on any part that doesn't match, since it's normally only
reached via the combo box's own activated(int) signal (real user
interaction, never fired by programmatic setCurrentIndex()).

updateForm() runs on every selection change, so during a rubber-band
drag over dynamic text fields with different sources, each time a new
field enters the selection, the representative part's textFrom gets
force-applied to every other selected part - converting e.g. a
UserText field to ElementInfo mid-drag, before the user has released
the mouse or interacted with the combo box at all.

Split the cosmetic widget-enable logic into updateTextFromWidgetsEnabled(),
called from updateForm(). on_m_text_from_cb_activated() keeps the
part-mutating loop, now only reached from real user activation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-30 19:11:25 +12:00
Laurent Trinques 88962570a8 Merge pull request #569 from DieterMayerOSS/pr/parttext-alignment
Element editor: optional alignment for static texts
2026-07-28 17:45:43 +02:00