Commit Graph

9310 Commits

Author SHA1 Message Date
ispyisail 61a509e5d8 Fix nameless "false" row in the element Informations panel
"exclude_from_bom" is listed in QETInformation::elementInfoKeys() so the
project database can build the element_info table column for it, but it
is not a free-text property: ElementInfoWidget already gives it its own
"Exclure de la nomenclature" check box.

Because buildInterface() creates one ElementInfoPartWidget per key in
that list, the key also got a second, generic edit row. And since
translatedInfoKey() has no case for it and falls through to
"return QString()", that row carries no label at all - an anonymous edit
line at the bottom of the panel. currentInfo() then writes
exclude_from_bom unconditionally, so as soon as the user edits anything
the nameless row fills with "true"/"false".

Drop the key from the list buildInterface() iterates. The check box
remains the only way to set it, currentInfo() still writes it exactly as
before, elementInfoKeys() is untouched so the database schema and
elementquerywidget are unaffected, and predefinedKeys() already excluded
it from the custom-property rows.

Reported by plc-user on #642.
2026-08-13 21:24:50 +12: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
plc-user b7efbdc323 Merge pull request #726 from ispyisail/fix/bugtracker-333-multiselect-text-color
Fix bugtracker #333: selecting several dynamic texts overwrites their colours
2026-08-13 09:39:36 +02:00
plc-user b00e053dab Merge pull request #725 from ispyisail/fix/pdf-export-filename-multiple-dots-forum3005
Fix PDF export truncating project filenames at the first dot
2026-08-13 09:22:48 +02:00
子墨庄 b0172f4dd7 Change comment style for title block edge method
Updated comment to use Doxygen style for documentation.
2026-08-13 08:50:24 +08: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 1de9f7eaf0 The Qt6 CMake signatures for translation handling changed multiple times with minor versions. 2026-08-12 22:37:46 +02:00
philippeagray b72794bea1 CLI export: document --show-terminals in cli_export.h 2026-08-12 10:33:45 -06:00
philippeagray 11357eb504 CLI export: add --show-terminals instead of hardcoding markers off 2026-08-12 10:33:37 -06:00
philippeagray 85346305e5 CLI export: hide terminal markers and names in rendered output
Terminal::paint() draws the red terminal stroke, the blue docking dot
and the terminal name whenever the diagram's drawTerminals() /
drawTerminalNames() flags are set, and both default to true. The GUI
export dialog clears them through Diagram::applyProperties(), but the
headless CLI export (--export-pdf/--export-png/--export-svg) never
did, so every terminal shipped as coloured editor UI in otherwise
finished drawings.

Toggle both flags off around the render in renderDiagram(), exactly
like the existing grid/guides handling, and restore them afterwards.
2026-08-12 10:22:51 -06:00
Andre Rummler d2a921ea80 Fixing MacOS only GUI adjustment relying on QWheelEvent->delta() which was removed in Qt6. Some simplification was possible but no test due to lack of OS.
Discovered due to new CI.
2026-08-12 12:29:56 +02:00
Andre Rummler a4d23fe312 QUuid and QHash no longer transititve. Adding includes explicitly. 2026-08-12 12:29:56 +02:00
Andre Rummler 8cfb777fe1 Fixing the translation installation for Qt5. Messed up the order of two lines. 2026-08-12 12:29:56 +02:00
Andre Rummler 8d08c3fd56 Replacing depreciated qAsConst with std::as_const 2026-08-12 12:29:56 +02:00
Andre Rummler 766a6b981d QUuid not transitively included in Qt6; added explicit includes. 2026-08-12 12:29:56 +02:00
Andre Rummler 8b40134a47 sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp
QVector<int>(Qt::DisplayRole) creates a vector of size 0 (since  Qt::DisplayRole == 0), not a vector containing DisplayRole. Fixed
to {Qt::DisplayRole}.

The sam applies to QVector<int>(role) which gets changed to {role}.
2026-08-12 12:29:56 +02:00
Andre Rummler cc032c9c76 Fixing comment removing the long dash that AIs tend to use. 2026-08-12 12:29:56 +02:00
Andre Rummler 92b2608bfb Comments in CMake with # and not //... always remember the language you are currently using. 2026-08-12 12:29:56 +02:00
Andre Rummler af87d28e33 Fix several parameters after Qt6 migration. 2026-08-12 12:29:56 +02:00
Andre Rummler c5d714089f Replacing KF5 missed in shell print out. 2026-08-12 12:29:56 +02:00
Shane Ringrose 206c37f620 cmake(qt6): verify Qt6::GuiPrivate at configure time, drop #warning
<private/qpdf_p.h> (QPdfEngine::drawHyperlink) needs Qt's private GUI
module, previously flagged only by a #warning at compile time.

Qt >= 6.7 ships GuiPrivate as a proper find_package component, but some
distro packages (e.g. Ubuntu's qt6-base-private-dev, Qt 6.8.3) do not
install Qt6GuiPrivateConfig.cmake and only provide the implicit
Qt6::GuiPrivate target created alongside Qt6::Gui. Requesting the
component unconditionally would therefore break distro-Qt builds.

Instead: try the component quietly, then hard-verify the Qt6::GuiPrivate
target exists after the main find_package, failing at configure time
with an actionable message if the private headers are missing. The
compile-time #warning in pdf_links.cpp and projectprintwindow.cpp is
now redundant and removed.

Verified: cmake configure + compile of both translation units on
Ubuntu 25.04 / Qt 6.8.3 (system KF6), cmake configure on Qt 5.15.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 12:29:56 +02: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
zi-mozhuang e32e5595c0 syn 2026-08-12 15:20:03 +08:00
zi-mozhuang 1684d2cfe6 syn 2026-08-12 15:13:52 +08:00
zi-mozhuang 6f66745ce3 Apply minimal title block fix to zh (from c77f78e4a) 2026-08-12 15:07:52 +08:00
Levi Jetzer 5dbb9f28de Fix numeric field validation gaps found in review
Address feedback on the width/height/depth elementInformation fields:

- The regex accepted "." alone as a complete value ([0-9]* permits
  zero digits on both sides), meaning a field could be committed with
  a literal "." saved to the XML. Require at least one digit either
  before or after the separator.
- The same pattern was duplicated verbatim in elementinfopartwidget.cpp
  and elementpropertieseditorwidget.cpp's EditorDelegate. Factored into
  QETInformation::numericInfoPattern(), a single shared definition both
  call sites now use.
- Tightened the pattern to at most 2 decimal places (down from 4) to
  match the precision actually meaningful for these fields.

Not changed, by design:
- Storage stays a plain string, consistent with every other numeric
  elementInformation field (quantity etc.) in this codebase -- values
  round-trip through XML text regardless, so a long/micron
  representation wouldn't avoid the string<->number conversion, only
  relocate it.
- No decimal-comma normalization needed: with the fixed pattern, only
  digits and "." are ever accepted at the keystroke level, so an
  alternate separator can't enter the field in the first place.
2026-08-12 08:43:42 +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 162d43e1c9 Fix PDF export truncating project filenames at the first dot
Forum report (qelectrotech.org/forum, topic 3005, reporter oc67): a
project named e.g. "Mon_projet.avec_un_point.qet" exported to PDF as
"Mon_projet.pdf" - everything after the first "." in the filename was
silently dropped.

Root cause: ProjectPrintWindow::docName() used QFileInfo::baseName(),
which returns the filename up to the FIRST "." rather than stripping
only the final suffix. docName() feeds both the PDF print job's
setOutputFileName() and the QFileDialog::getSaveFileName default in
exportToPDF(), so the truncation showed up as the actual exported
file's name, not just a dialog suggestion.

sources/exportdialog.cpp's SVG/PNG/DXF export path already uses the
correct QFileInfo::completeBaseName() (strips only the last suffix) -
this fix brings the PDF/print path in line with that existing,
correct pattern rather than introducing a new approach.

Verified the exact before/after behavior with a standalone QFileInfo
test: baseName() on "Mon_projet.avec_un_point.qet" returns
"Mon_projet" (the bug); completeBaseName() returns
"Mon_projet.avec_un_point" (correct). Also did a clean incremental
build with no new warnings/errors.
2026-08-12 10:31:04 +12:00
ispyisail c26cf34397 Fix wire-name export doubling every conductor's count
Forum report (qelectrotech.org/forum, topic 3125): "Export the names
of list of wires" doubled every conductor's name in the output - a
single conductor named "16AWG" was exported as two "16AWG" lines.

Root cause: ConductorNumExport::fillHash() incremented the name's
tally once per terminal instead of once per conductor - a separate
if-block for terminal1 and another for terminal2, each bumping the
same m_hash entry. Since an ordinary conductor has two terminals and
neither is a folio-report terminal in the common case, both blocks
fired and every real conductor was counted twice. wiresNum() then
faithfully repeats each name m_hash.value(key) times, so the doubled
count became doubled output lines.

Fixed by incrementing once per conductor, only skipping it entirely
when *both* ends are folio-report terminals (neither represents a
real connection) rather than checking each terminal independently.

Verified with a minimal two-conductor project via the --export-wires
CLI verb: pre-fix build produced 4 lines for 2 named conductors
(exact doubling), post-fix build produces the correct 2.
2026-08-12 10:13:05 +12:00
Levi Jetzer c6e7c5d371 Fixed issue of taking wrong variable (key instead of key_) in elementinfopartwidget.cpp for regex checker and helping info (tooltip, placeholder) 2026-08-11 18:28:29 +02:00
Levi Jetzer 7347322221 Replace QDoubleValidator with QRegularExpressionValidator on width/height/depth fields
The selection properties dock (elementinfopartwidget.cpp) and the
element editor's information tree (elementpropertieseditorwidget.cpp's
EditorDelegate) both restrict the width/height/depth fields added for
cabinet layout support to numeric input via a validator.

QDoubleValidator follows the system/UI locale for its decimal
separator, which meant a comma was accepted as an intermediate state
and left the field impossible to leave in some contexts, even though
it was never a valid final value.

Switch both to a QRegularExpressionValidator matching
^[0-9]*\.?[0-9]{0,4}$: "." is a literal character in the pattern, not
locale-dependent, and [0-9] (rather than \d) excludes non-ASCII
digits. This guarantees a value entered this way can always be read
back with QString::toDouble() without locale handling. The check for
which keys are numeric (QETInformation::isNumericInfoKey) is shared
between both call sites; the validator setup itself stays local to
each, since QETInformation intentionally has no Qt Widgets dependency.

Also adds a placeholder ("ex. 80.5") and tooltip explaining the
expected format.
2026-08-11 18:01:10 +02:00
plc-user 10cc162c4e Merge pull request #715 from ispyisail/fix/properties-dialog-mac-sheet-bug275
Fix bugtracker #275: element properties window stuck centered on macOS

That addition definitely makes sense!
2026-08-11 17:33:56 +02:00
Levi Jetzer c23999acd1 Added width/height/depth properties to element definitions
Adds three new elementInformation keys — width, height, depth (in mm)
— alongside the existing manufacturer/manufacturer_reference fields.
These describe the physical dimensions of the device a symbol
represents, set once per element definition.

Values are restricted to plain decimal numbers via a QDoubleValidator
on the information tree's item delegate (fixed-point, "." as decimal
separator via QLocale::c(), independent of the UI language), so a
later consumer can always parse them with toDouble() without
additional sanitization.
2026-08-11 16:09:34 +02:00
plc-user 3a3182862c move "diagnostics_action_" upwards in help-menu 2026-08-11 14:11:00 +02:00
plc-user 0d432f6159 Merge pull request #714 from ispyisail/fix/newpart-wizard-window-focus-bug281
Fix bugtracker #281: new-part wizard's element editor opens behind main window
Cannot reproduce on Debian/GNU Linux, but implementation is reasonable and clean!
2026-08-11 13:02:22 +02:00
plc-user 45458c2f2a Merge pull request #717 from ispyisail/fix/titleblock-invalid-name-bug251
Fix bugtracker #251: title block template with slash in name fails silently
There are some characters that are not allowed in filenames.
Absolutely correct to mark a filename containing (one of) them as invalid!
2026-08-11 12:52:52 +02:00
plc-user 472786fd23 Merge pull request #712 from ispyisail/fix/xref-default-alignment-bug296
Fix bugtracker #296: cross-reference text overlaps element label by default
Sounds and looks reasonable!
2026-08-11 12:47:42 +02:00
plc-user 0732bf64a7 Merge pull request #716 from ispyisail/fix/saveas-qet-extension-bug270
Fix bugtracker #270: Save As on Snap produces file with no .qet extension

Absolutely correct implementation for portability!
2026-08-11 12:42:24 +02: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
ispyisail 0c2027fd77 Fix bugtracker #245: bare %name custom variables not detected in title blocks
TitleBlockTemplate::listOfVariables() -- which scans a title block
template's cells to auto-populate the "Custom" tab in Project
Properties (a feature recently added by another contributor, see
TitleBlockPropertiesWidget::addTemplateVariables()) -- only matched
the braced "%{name}" placeholder form. The bare "%name" form (also a
legitimate, fully-supported substitution syntax -- see
TitleBlockTemplate::interpreteVariables(), which already replaces both
forms) was never matched at all, not merely mishandled on edge cases:
a cell containing "%name2" alone, "%name2 " with a trailing space, or
"%name2 %name3" with two bare variables all produced zero detected
variables, exactly matching the report (manually adding the variable
in Project Properties works fine and renders correctly, since
rendering goes through interpreteVariables()'s simple string
replacement against already-known keys, not this regex).

Fix: extend the regex to also match a bare "%name" as the longest run
of identifier characters immediately after '%', via a second
alternative/capture group. This naturally stops at whitespace, so
"%name2 " and "%name2 %name3" are both now correctly detected -- no
change to the existing braced-form handling, and the existing
globalMatch() loop already correctly finds multiple matches per cell.

Verified: clean rebuild, only the intended object file recompiled and
linked successfully. Wrote a standalone test of the regex/extraction
logic covering exactly the reported repro cases -- "%name2", "%name2 "
(trailing space), "%name2 %name3" (two bare variables), "%{name2}"
(braced form, unaffected), a braced+bare mix, plain text with no
variables, and two built-in-style names -- all extracted correctly
with no regressions to the previously-working braced form.

Not verified: the actual Project Properties "Custom" tab UI
auto-populating live, since exercising the full Xvfb GUI flow (title
block template editor > add a bare-form custom variable to a cell >
save > open Project Properties > select that template > confirm the
Custom tab lists it) was out of scope for the time available given the
extraction logic itself was already precisely verified in isolation.
2026-08-11 13:02:03 +12:00
ispyisail f9cbf2365d Fix bugtracker #247: XRef slave reference hidden with dark themes
DynamicElementTextItem's slave cross-reference sub-item
(m_slave_Xref_item, the small "_(1-D3)_"-style text next to a slave
element pointing back to its master) hardcoded Qt::black in three
places: on creation, on hover-leave, and when restoring color after
text editing. The PARENT text item's color is a real, user-configurable
property (color()/setColor(), persisted in the diagram XML, exposed in
the text editor's color picker) -- but the slave-Xref sub-item never
used it, so a user applying a dark theme/stylesheet had no way to make
this specific text visible even by explicitly setting a text color,
unlike every other text item in the diagram.

Fix: use color() (the parent DynamicElementTextItem's own configured
color, inherited from DiagramTextItem) instead of the Qt::black
constant in all three places. This doesn't change the default
appearance (color() defaults to black, same as before) but makes the
slave-Xref text finally respect whatever color the user sets on the
parent text field, giving dark-theme users the same escape hatch
already available for all other diagram text.

Verified: clean rebuild, only the intended object file recompiled and
linked successfully.

Not verified: a live visual confirmation of the slave-Xref text
picking up a non-default color, since reproducing this requires
constructing a master/slave-linked element pair with composite text
containing %{label} in an actual multi-folio project, which was out of
scope for the time available. Confidence rests on this being a direct,
mechanical substitution of an existing, already-used accessor
(color()) for a hardcoded constant, applied identically to the exact
three call sites that previously hardcoded Qt::black for this item,
with no other logic changed.
2026-08-11 12:51:54 +12:00
ispyisail 2d889568a5 Fix bugtracker #251: title block template with slash in name fails silently
Saving a new user title block template (right-click "Cartouches
utilisateur" > "Nouveau modèle" > "Enregistrer sous") with a name
containing a slash (or other filesystem-reserved character) silently
did nothing, with no error shown. The entered name is turned directly
into a filename (TitleBlockTemplatesFilesCollection::toFileName()), so
e.g. "foo/bar" becomes a path "foo/bar.titleblock" -- since "foo/"
essentially never exists as a directory, the underlying file write
fails, but that failure was never surfaced:

- TitleBlockTemplateLocation::isValid() only checked for an empty
  name, so an invalid name still counted as "valid" and got passed
  through to save.
- QETTitleBlockTemplateEditor::saveAs(const TitleBlockTemplateLocation&)
  discarded the bool result of setTemplateXmlDescription() and
  unconditionally returned true, marking the undo stack clean as if
  the save had actually succeeded.

Fix:
- isValid() now also rejects names containing \ / : * ? " < > |,
  matching the character set that's actually unsafe once the name
  becomes a filename.
- saveAs() (the no-arg entry point that asks the user for a location)
  now shows a clear error dialog when the entered name is rejected,
  distinguishing "user cancelled" (location.name() empty) from
  "name was invalid" (non-empty but rejected by isValid()).
- saveAs(location) now checks setTemplateXmlDescription()'s return
  value and shows an error dialog instead of reporting false success
  on any future/other write failure, not just this one.

Verified: clean rebuild, only the intended files recompiled and
linked successfully. Live-tested under Xvfb: creating a new template
and using "Enregistrer sous" with the name "foo/bar" now shows
"Le nom « foo/bar » n'est pas valide : il ne doit pas contenir les
caractères suivants : \ / : * ? " < > |" instead of silently doing
nothing; reopening the save-as dialog afterward showed the name field
correctly empty (nothing was partially written). Saving again with a
valid name ("mytemplate_valid") completed with no error dialog, and
the resulting mytemplate_valid.titleblock file was confirmed present
on disk in the user's title-block collection directory.
2026-08-11 12:36:31 +12:00
ispyisail 55250a6de9 Fix bugtracker #270: Save As on Snap produces file with no .qet extension
ProjectView::askUserForFilePath() only appended the .qet extension when
FLATPAK_ID/SNAP_NAME were NOT set, on the assumption that the
xdg-desktop-portal file dialog used by sandboxed Snap/Flatpak builds
always appends the selected filter's extension itself (avoiding a
double ".qet.qet"). In practice, on the reporter's Snap/Ubuntu 22.04
setup the portal dialog does not append it, so the environment-based
skip left Save As producing a file with no extension at all.

Portal behavior isn't something QET controls or can reliably detect via
environment variables -- it depends on the desktop's actual portal
implementation/version. Rather than guessing per-environment, normalize
unconditionally: strip any existing .qet suffix (case-insensitive) and
re-append exactly one. This produces the correct single extension
whether or not the dialog already added it, on every environment.

Verified: clean rebuild, only the intended object file recompiled and
linked successfully. Wrote a standalone test of the normalization logic
covering no-extension, already-has-extension, uppercase-extension, and
a literal dot in the base filename -- all four produced exactly one
correct ".qet" suffix with no double-extension and no missing extension.

Not verified: the actual Snap-sandboxed portal dialog behavior itself,
since building/running the Snap package and testing its file-save
dialog under a portal is outside what's practical to set up in this
sandbox. Confidence rests on the fix removing the environment-guessing
entirely in favor of unconditional, dialog-implementation-agnostic
normalization, which is correct regardless of what the underlying
dialog does.
2026-08-11 12:01:24 +12:00
ispyisail 325b895d0b Fix bugtracker #275: element properties window stuck centered on macOS
Double-clicking a placed element (or right-click > "Éditer l'élément")
opens its properties via Element::editProperty(), which constructs a
PropertiesEditorDialog with a real parent (QApplication::activeWindow()).
On macOS, a QDialog that has both a parent and Qt::WindowModal set falls
back to Cocoa's automatic sheet presentation. Reports (and this
codebase's own existing workarounds) indicate this can render stuck
centered on screen, non-draggable, with symmetric resize -- rather than
a proper attached, movable window -- unlike Linux/X11 where the same
dialog behaves as a normal draggable QDialog.

Two other dialogs in this codebase already explicitly opt into the
correct macOS sheet presentation for this exact reason:
ElementDialog::setUpWidget() and DiagramPropertiesDialog's setup both do

    setWindowModality(Qt::WindowModal);
#ifdef Q_OS_MACOS
    setWindowFlags(Qt::Sheet);
#endif

PropertiesEditorDialog -- used for editing Element, QetShapeItem, and
DiagramImageItem properties, all reached via double-click on a diagram
item -- had neither this opt-in nor an opt-out, so it likely fell into
the same automatic-sheet behavior but without the explicit flag,
matching the reported "stuck centered, can't drag" symptom.

Fix: apply the same setWindowModality()/Q_OS_MACOS Qt::Sheet pattern
already used by the other two dialogs, in PropertiesEditorDialog's
constructor -- fixing all three call sites (element, shape, and image
property editing) at once, since they share this one dialog class.

Verified: clean rebuild, all three call sites (element.cpp,
qetshapeitem.cpp, diagramimageitem.cpp) recompiled and linked
successfully with no errors or warnings.

Not verified: the actual reported symptom is macOS/Cocoa-specific
window presentation behavior, which cannot be reproduced or confirmed
fixed in this Linux/Xvfb sandbox -- no macOS environment is available
here. Confidence rests on the exact same fix pattern already being
established and presumably working for two other dialogs in this
codebase for the identical class of problem.
2026-08-11 11:48:58 +12:00
ispyisail 6ad2a63575 Fix bugtracker #281: new-part wizard's element editor opens behind main window
NewElementWizard::createNewElement() creates and show()s a QETElementEditor
for the freshly-created part, but never calls raise()/activateWindow().
On the reporter's macOS setup, the wizard (a modal sheet/child of the main
window) closing right before the new editor is shown apparently leaves the
main window as the active/key window, so the new editor window is created
but stays behind it -- and, being neither key nor frontmost, it also never
surfaces in the Dock's window list or the app's own Windows menu. This
matched the report exactly: the reporter saw the wizard finish with
seemingly no result, when in fact a new part genuinely was created and its
editor genuinely was opened, just hidden from view.

Fix: explicitly raise() and activateWindow() the new editor after show(),
so it becomes the frontmost/key window regardless of what state the wizard
leaves the main window in.

Verified: clean rebuild, only the intended object file recompiled and
linked successfully. Ran the full wizard flow live under Xvfb on Linux
(right-click user collection > "Nouvel élément" > through all 3 steps >
Finish) and confirmed the element editor opens correctly with a blank new
part, with no regression in the flow.

Not verified: the actual reported symptom is macOS-specific window-manager
behavior (key/frontmost window handling, Dock window-list registration),
which cannot be reproduced or confirmed fixed in this Linux/Xvfb sandbox --
no macOS or Wine-with-Cocoa environment is available here. raise()/
activateWindow() are the standard cross-platform Qt calls for this exact
problem and match the pattern already used elsewhere in the codebase
(QETApp::openElementLocations()'s already-open-editor branch), so
confidence rests on that precedent rather than a macOS-side confirmation.
2026-08-11 11:33:28 +12:00
ispyisail 99dac17327 Fix bugtracker #296: cross-reference text overlaps element label by default
XRefProperties::fromSettings() read the "xrefpos" QSettings key with no
default value. On a fresh install/project, the key doesn't exist yet, so
settings.value(...).toString() returns an empty string. QMetaEnum::keyToValue("")
returns -1 (invalid), which was then cast directly into m_xref_pos as
Qt::AlignmentFlag(-1) -- garbage, despite the class's own default
constructor documenting the intended default as Qt::AlignBottom.

This explains the reported symptom: dynamically generated cross-reference
text for master/slave-linked elements (e.g. magneto-thermal breaker,
thermal relay NC) rendered at an undefined position and overlapped the
element's own label, making the reference unreadable. The reporter's
manual workaround -- explicitly setting alignment to "Bottom" in Project
Properties > New Folio/Cross Referencing -- side-steps the bug precisely
by writing a valid "AlignBottom" value into QSettings, which fromSettings()
then reads back correctly on subsequent loads.

Fix: supply "AlignBottom" as the fallback default for the QSettings read,
matching the constructor's documented default and the reporter's
functioning workaround.

Verified: clean rebuild, only the intended object file recompiled and
linked successfully. Confirmed via a small standalone QMetaEnum test that
keyToValue("") returns -1/invalid while keyToValue("AlignBottom") returns
64 (== Qt::AlignBottom), reproducing the exact mechanism before the fix and
confirming the corrected default resolves to the intended value.

Not verified: a live before/after visual comparison of the rendered
cross-reference text position on an actual magneto-thermal/thermal-relay
diagram (would require constructing a multi-folio project with linked
master/slave elements and comparing label geometry, which was out of
scope for the time available). Confidence rests on the QMetaEnum
mechanism being unambiguous and the fix being a one-line default-value
correction with no other code path affected.
2026-08-11 10:27:52 +12:00
ispyisail 52992b31eb Fix bugtracker #306: crash when restoring backup files on startup
QETDiagramEditor::openBackupFiles() deleted the just-constructed
QETProject when it failed to reach ProjectState::Ok, but had no
continue/else after the delete - so addProject(project) ran
unconditionally on the now-dangling pointer, and addProject()
immediately dereferences it (new ProjectView(project), etc.).

This matches the report exactly: clicking Cancel on the restore-files
dialog (which just deletes the stale markers directly, never calling
openBackupFiles()) works fine, while clicking OK crashes whenever any
listed backup fails to open cleanly. Because the crash happens mid-
loop, cleanup for that file (and any later ones in the same batch)
never completes, which also explains the reporter's second complaint
that the restore list kept growing across sessions.

Fix: add the missing `continue` so a failed project is skipped
instead of being passed use-after-free to addProject().

Verified: clean rebuild, only the intended object file recompiled
and linked successfully. I attempted a live repro by crafting a
malformed stale-file marker to force ProjectState != Ok and clicking
OK under Xvfb, but this local build links against real KDE Frameworks
(BUILD_WITH_KF5=ON, confirmed via CMakeCache.txt) rather than the
in-tree nokde/kautosavefile.cpp reimplementation I initially targeted,
which uses a different marker directory/naming scheme
(~/.local/share/stalefiles/<app>/ via real KF5::KAutoSaveFile) that
I wasn't able to reverse-engineer well enough in the time available
to produce a matching malformed marker. Confidence in the fix instead
rests on the code being an unambiguous, textbook use-after-free (this
exact object is deleted on the line immediately above the missing
continue) with a single-line, side-effect-free fix.
2026-08-11 10:08:51 +12:00
plc-user 13e245b104 Merge pull request #706 from ispyisail/fix/search-hit-scroll-bug309
Scroll the diagram view to the selected search hit (bugtracker #309)
2026-08-10 22:08:31 +02:00
plc-user 6bf6a17dc9 update German translations 2026-08-10 21:33:24 +02:00
plc-user 550e085b82 Merge pull request #693 from ispyisail/fix/color-editor-crash-bug323
Fix crash changing dynamic text color and confirming with Enter (bugtracker #323)

Works like charm: 
- color is updated immediately
- no additional errors or warnings 
- no crash anymore!
2026-08-10 21:24:04 +02:00