Compare commits

...

196 Commits

Author SHA1 Message Date
Laurent Trinques e9a53dbec2 git submodule update --remote elements 2026-07-26 05:44:21 +02:00
Laurent Trinques f9f03c79ea Skip signing the Qt6 MSI, and guard against triggering a signing request from a fork (no SignPath secrets there).
cf. DieterMayerOSS:fix/msi-signing-fork-guard (d3f60c88)
2026-07-24 10:20:01 +02:00
plc-user 7247257a9b add German translations 2026-07-23 19:51:55 +02:00
Laurent Trinques a8c4612fd4 Update translations files and git submodule update --remote elements 2026-07-23 14:08:11 +02:00
Laurent Trinques d02514141c Update qelectrotech.pro for https://github.com/qelectrotech/qelectrotech-source-mirror/pull/513 2026-07-23 14:02:26 +02:00
Laurent Trinques 42d2c824d2 Merge pull request #513 from ispyisail/feature/edz-import
Import EPLAN Data Portal parts (.edz) into element collections
2026-07-23 13:58:56 +02:00
Laurent Trinques 324c818007 Merge pull request #551 from Kellermorph/master
German Translation
2026-07-20 20:17:13 +02:00
Kellermorph 0a4b337115 German Translation 2026-07-20 20:15:28 +02:00
ispyisail 1b8dea3946 Add consent dialog before EPLAN (.edz) import
Shows the licensing/liability warning text agreed on in PR #513
(scorpio810) before the file picker opens. Import stays disabled
until the "I have read and accept these terms" checkbox is ticked.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 21:11:35 +12:00
Laurent Trinques adb3473a2c Improve Windows Qt5/Qt6 CI test, enable -platform windows:fontengine=freetype add new .bat for Qt6 installer and portable version 2026-07-19 21:15:13 +02:00
Laurent Trinques 3c1eb9b970 New Windows Qt5/Qt6 CI test, enable -platform windows:fontengine=freetype add new .bat for Qt6 installer and portable version 2026-07-19 19:26:25 +02:00
Laurent Trinques fd402bb9b5 Update windows-msi.yml 2026-07-19 19:00:06 +02:00
Laurent Trinques 8e736c59ba New Windows Qt5/Qt6 CI test, enable -platform windows:fontengine=freetype 2026-07-19 18:55:26 +02:00
Laurent Trinques 6941edcdf5 New Windows Qt5/Qt6 CI test 2026-07-19 16:48:42 +02:00
Laurent Trinques e1aa65f1ee Revert "Set QET version to 0.200.1 when built with Qt6"
This reverts commit 608ca984a4.
2026-07-19 13:26:34 +02:00
scorpio810 629bd7cdef Add SQLite3::SQLite3 compat alias, use modern target name
CMake's bundled FindSQLite3 module only creates the SQLite3::SQLite3
target since CMake 4.3; earlier versions (still used by most current
Linux distros) only provide SQLite::SQLite3, which CMake >= 4.3 now
flags as deprecated.

Add the missing alias ourselves right after find_package(SQLite3)
when it isn't already provided, so the project can link against the
modern SQLite3::SQLite3 name on every supported CMake version without
triggering the deprecation warning on newer ones.
2026-07-19 12:30:19 +02:00
Laurent Trinques 88e42a435b Merge pull request #519 from ispyisail/fix/asan-memory-leaks
Fix four memory leaks found by AddressSanitizer
2026-07-19 11:51:47 +02:00
Laurent Trinques 100e924aed Fix: Windows Qt6 CI test 2026-07-19 11:26:19 +02:00
Laurent Trinques 90946537c0 Add windows Qt6 CI test 2026-07-19 11:12:48 +02:00
scorpio810 608ca984a4 Set QET version to 0.200.1 when built with Qt6
Use QT_VERSION_CHECK to detect Qt6 at compile time and report
version 0.200.1 instead of 0.100.1 in that case, so Qt6 builds
are clearly distinguishable from Qt5 builds.
2026-07-19 10:56:12 +02:00
Laurent Trinques 7dbfc5fb61 Update translations files 2026-07-18 12:00:51 +02:00
Laurent Trinques a9474d82b8 Update windows-build.yml 2026-07-18 08:24:58 +02:00
Laurent Trinques 7a87754024 Merge pull request #545 from Kellermorph/terminal-name
Implement slave contact groups — label transfer, terminal assignment and UI fixes
2026-07-18 08:00:23 +02:00
Laurent Trinques 964ec23adc Merge pull request #547 from DieterMayerOSS/fix/remaining-qt6-compile-blockers
Fix the remaining Qt6 compile blockers
2026-07-17 23:29:32 +02:00
Laurent Trinques 2eb6632f6f Merge pull request #546 from DieterMayerOSS/fix/qt5-guiprivate-component
Request the GuiPrivate component only on Qt6
2026-07-17 23:07:12 +02:00
Dieter Mayer 12afadd095 Fix the remaining Qt6 compile blockers
Clears the last five spots that stop master from compiling against Qt6
(all mirrored from the proven qt6-build line):

- qgimanager.h/.cpp: in Qt6 QVector is an alias for QList, so the
  deprecated QList overloads of manage()/release() collide with the
  QVector ones (same signature). Keep them on Qt5 only.
- diagramview.cpp: one unguarded QTextStream::setCodec() call (removed
  in Qt6, which defaults to UTF-8).
- print/projectprintwindow.cpp: QApplication::desktop() was removed in
  Qt6; use QWidget::screen() there, keep the old path on Qt5.
- titleblocktemplate.cpp: QDomDocument::setContent() returns a
  ParseResult in Qt6 whose operator bool is explicit; static_cast keeps
  the bool initialization working on both.

With these, master configures and builds to a running binary with
Qt 6.11 (mingw, BUILD_WITH_KF5=OFF); every change is guarded or
dual-safe, the Qt5 build is unaffected.
2026-07-17 21:01:26 +02:00
Dieter Mayer 683eefdac1 Request the GuiPrivate component only on Qt6
Listing GuiPrivate unconditionally in QET_COMPONENTS breaks the whole
Qt5 configure: find_package(Qt5 COMPONENTS GuiPrivate) looks for a
Qt5GuiPrivateConfig.cmake that has never existed - Qt5 creates the
Qt5::GuiPrivate target implicitly together with Gui. Only Qt6 requires
(and provides) the explicit component.

Move the request into a QT_VERSION_MAJOR-guarded find_package after the
main one, both for the application and for tests/catch (whose targets
link Qt::GuiPrivate via QET_PRIVATE_LIBRARIES). Fixes the msys2/Qt5
Windows CI configure failure:
"Could not find a package configuration file provided by Qt5GuiPrivate".

Verified: Qt 6.11 configure passes and the Qt6::GuiPrivate target is
created (the private-module warning now fires from the guarded call).
The Qt5 path simply no longer requests the component, restoring the
pre-existing implicit behaviour.
2026-07-17 19:25:26 +02:00
Laurent Trinques 5785f57679 Update windows-build.yml 2026-07-17 17:16:53 +02:00
Laurent Trinques 6903b3422a Update windows-build.yml 2026-07-17 16:43:01 +02:00
Laurent Trinques 38fa44dbf0 Update windows-build.yml 2026-07-17 16:36:53 +02:00
Laurent Trinques f9a87d81f2 Update windows-build.yml 2026-07-17 15:49:39 +02:00
Laurent Trinques fddec5cbf4 Update windows-build.yml 2026-07-17 15:41:47 +02:00
Laurent Trinques 6a4554a677 Re-enable multi-threading to load collection
The name of the elements and folders of the collection are not displayed
until we hover the item with the mouse.
This due that QtConcurent::run was disabled at loading of collection in
the goal of use QtConcurrent::run with Qt6.
Run is made to run a function once.
Map is made to run a fonction for each item of a sequence (what we need
in this case).
Remove code of run and re-enable code for map.
2026-07-17 10:44:36 +02:00
joshua ae2972a143 Fix : can't open recent file 2026-07-17 10:29:13 +02:00
scorpio810 ed1b6e9ba0 terminalstripdrawer.cpp: fix two Qt6 compile errors
- Add missing <QHash> include: QHash<QUuid, QVector<QPointF>> was
  only forward-declared transitively under Qt5's heavier headers;
  Qt6's leaner <QPainter> etc. no longer pull it in.

- Replace QPolygonF{points_} with QPolygonF(points_): under Qt6,
  QPolygonF inherits QList<QPointF>'s constructors via 'using
  QList<QPointF>::QList;', including the std::initializer_list<T>
  one. Brace-init-list construction with a single argument first
  considers only initializer-list constructors before falling
  back to regular ones, which trips up overload resolution here
  even though points_ is exactly a QList<QPointF> (QVector is a
  plain alias for QList under Qt6). Plain parenthesised
  construction sidesteps that resolution phase entirely and binds
  directly to QPolygonF(const QList<QPointF>&).
2026-07-17 10:26:43 +02:00
scorpio810 33013477ad physicalterminal.cpp: fix std::min template deduction under Qt6
QVector::size() (== QList::size() under Qt6) returns qsizetype
(64-bit), while 'level' is a plain int. std::min(level,
m_real_terminal.size()-1) therefore tries to deduce a single T
from two different argument types, which fails - GCC reports it
against the unrelated std::min(initializer_list<T>) overload,
but the real issue is the type mismatch between the two-argument
candidates. Under Qt5, QVector::size() returned int, so this
compiled fine.
Force T=int explicitly via std::min<int>(...) and cast size()
down to int (physical terminal counts are always tiny), matching
the pattern already used safely elsewhere in the codebase (e.g.
qetgraphicstableitem.cpp).
2026-07-17 10:26:43 +02:00
scorpio810 287b532953 templatescollection.cpp: fix QDomDocument::ParseResult->bool conversion
Since Qt 6.5, QDomDocument::setContent() returns a ParseResult
struct with an *explicit* operator bool(), so 'bool x =
doc.setContent(...)' (copy-initialization) no longer compiles -
explicit conversions aren't considered there.

This exact issue was already fixed in titleblocktemplate.cpp by
dropping the intermediate bool and testing the call directly in
the if condition (contextual bool conversion in an if() is fine
even for an explicit operator bool), but this second occurrence
in templatescollection.cpp used the same pattern and was missed.
Applying the same fix here for consistency.
2026-07-17 10:26:35 +02:00
scorpio810 6716c267b8 templateview.h: add missing QGraphicsGridLayout/QGraphicsLayoutItem includes
templateview.h only included <QGraphicsView> but uses
QGraphicsGridLayout (tbgrid_ member) and QGraphicsLayoutItem
(indexOf/removeItem signatures) directly. Some Qt5 header
apparently pulled these in transitively; Qt6's leaner headers
don't, so the class fields/methods silently failed to resolve
and the compiler picked bogus 'int*' overloads instead.
Other files in the same directory already get these symbols
either via the <QtWidgets> umbrella header or a direct include,
so this was an isolated gap.
2026-07-17 10:26:26 +02:00
scorpio810 62dc1e7c11 Fix QRegularExpression API misuse in ElementsLocation::setXml (Qt6 path)
The Qt6 branch of the #if QT_VERSION guard swapped QRegExp for
QRegularExpression but kept calling QRegExp-only methods
(exactMatch()/cap()), which QRegularExpression doesn't have.
Use the correct QRegularExpression API instead: match() returns
a QRegularExpressionMatch, tested with hasMatch() and read with
captured(n).
2026-07-17 10:26:17 +02:00
scorpio810 fea4752a06 Fix remaining Qt6 build errors after PR #540
- qetxml.h: add missing <QUuid> include (used in propertyUuid/
  createXmlProperty signatures but never included directly).
- machine_info.cpp: fix ambiguous QString/int operator> in
  send_info_to_debug() for it1/it2/it3; just count every
  matching file found instead of the meaningless comparison.
2026-07-17 10:25:49 +02:00
Laurent Trinques 424a1c945e Try to fix compile with cmake .. -G Ninja -DQT_VERSION_MAJOR=6 -DBUILD_WITH_KF5=OFF -DPACKAGE_TESTS=OFF 2026-07-17 10:25:30 +02:00
Kellermorph b025bd205d Implement slave contact groups — label transfer, terminal assignment and UI fixes 2026-07-17 09:47:32 +02:00
Laurent Trinques 118a62adb2 Merge pull request #540 from DieterMayerOSS/cleanup/qt6-deprecation-warnings
Cleanup/qt6 deprecation warnings
2026-07-16 11:57:13 +02:00
Laurent Trinques 9a35d6c404 Merge pull request #541 from DieterMayerOSS/cleanup/qt6-remaining-warnings
Fix remaining Qt6 build warnings (narrowing, nodiscard, qHash)
2026-07-16 11:56:22 +02:00
Laurent Trinques e84180da21 Merge pull request #542 from DieterMayerOSS/fix/translation-build-race
Run lupdate only via an explicit update_translations target
2026-07-16 11:55:38 +02:00
Laurent Trinques a220a5320b Merge pull request #543 from DieterMayerOSS/doc/qt6-private-headers-dependency
Document qt6-base-private-dev as a Qt6 build dependency
2026-07-16 11:55:16 +02:00
Laurent Trinques 34bf63e237 Merge pull request #544 from DieterMayerOSS/fix/duplicate-folio-element-uuids
Renew element uuids when duplicating a folio
2026-07-16 11:54:48 +02:00
Laurent Trinques 8884e79133 Delete QElectroTech.qch files 2026-07-15 06:19:52 +02:00
Dieter Mayer 20a7047b27 Renew element uuids when duplicating a folio
The project panel's "copy and paste" action duplicates a folio through
an XML round-trip (toXml/fromXml), and Element::fromXml adopts the uuid
stored in the XML - so every element on the duplicated folio kept the
uuid of its source element. On-diagram copy/paste already handles this
(PasteDiagramCommand::redo() calls newUuid()), but the folio-duplicate
path bypasses that command.

Since element.uuid is the PRIMARY KEY of the project database, the
duplicated elements failed to insert ("UNIQUE constraint failed:
element.uuid" spam in the log) and silently disappeared from
nomenclature/summary tables, even though they are valid on the folio.

Renew the uuid of every element on the freshly duplicated folio, exactly
as the paste command does. In-memory links established during fromXml
are pointer-based and unaffected; the new uuids are written on save.
2026-07-14 19:48:31 +02:00
Dieter Mayer b7a8759cc6 Document qt6-base-private-dev as a Qt6 build dependency
On Debian/Ubuntu qt6-base-dev ships the Qt6::GuiPrivate CMake config but
the actual private headers live in the separate qt6-base-private-dev
package, so find_package succeeds and CMake only fails later at generate
time with a non-obvious "non-existent path" error. QET genuinely needs
the private QtGui API (QPdfEngine) for clickable hyperlinks in the PDF
export, so document the package instead of degrading the feature.
Observed on Ubuntu 26.04 LTS (Qt 6.10.2); Debian sid and the Qt online
installer ship the headers together.
2026-07-14 19:31:07 +02:00
Dieter Mayer 46f479240e Run lupdate only via an explicit update_translations target
The default build ran both lupdate (qt5_create_translation, which
rewrites the tracked .ts files in the source tree) and lrelease
(qt5_add_translation, which reads the same .ts files). Under high
parallelism lrelease could read a .ts while lupdate was rewriting it,
failing the build with "Premature end of document"; every build also
modified tracked files as a side effect, and each .qm was generated
twice (once into the build dir, once into lang/).

Keep only lrelease in the default build and move lupdate behind an
explicit developer target (cmake --build . --target update_translations).
The target scans sources/ instead of the whole source tree, which also
stops lupdate from parsing unrelated third-party .js files.
2026-07-14 19:29:19 +02:00
Dieter Mayer a0f66d22cc Fix remaining Qt6 build warnings (narrowing, nodiscard, qHash)
Clears the 9 non-deprecation warnings from the Qt6 build:
- qHash(QColor): hash rgba() (unambiguous QRgb) instead of name(), and
  use the size_t seed signature on Qt6 (guarded for Qt5). Fixes the
  ambiguous-overload warning in terminalstripmodel.h.
- Two qsizetype->int narrowings in brace-init: explicit static_cast<int>
  (elementscene.cpp, terminalstrip.cpp).
- main.cpp: keep the QtConcurrent::run QFuture in a [[maybe_unused]]
  variable (nodiscard).
- qetapp.cpp: guard the stylesheet load on QFile::open() succeeding
  (nodiscard) instead of ignoring the result.
2026-07-14 19:27:37 +02:00
Dieter Mayer d5027c4ef9 Replace deprecated QVariant::canConvert(int)
QVariant::canConvert(int) is deprecated in Qt6. Use the non-deprecated
canConvert<T>() template (canConvert<QString>() / canConvert<int>()),
which is available on Qt5 too. Clears the last 2 -Wdeprecated-
declarations warnings.
2026-07-14 19:27:18 +02:00
Dieter Mayer e099fca5ad Guard Qt6-only deprecation replacements for Qt5 compatibility
Three deprecated APIs have replacements that only exist in newer Qt6:
- QLocale::nativeCountryName() -> nativeTerritoryName() (Qt 6.2)
- QDomDocument::setContent() overload -> ParseResult (Qt 6.5)
- qt_ntfs_permission_lookup -> QNtfsPermissionCheckGuard RAII (Qt 6.6)
Each is wrapped in QT_VERSION_CHECK so Qt5 keeps the old path. Clears
4 -Wdeprecated-declarations warnings.
2026-07-14 19:27:18 +02:00
Dieter Mayer f57c921b78 Fix trivial Qt6 deprecations (QString::count, QColor::setNamedColor)
QString::count() (no-arg) is deprecated -> size(); QColor::setNamedColor()
is deprecated -> the QColor(QString) constructor. Both replacements are
non-deprecated on Qt5 too. Clears 2 -Wdeprecated-declarations warnings.
2026-07-14 19:27:17 +02:00
Dieter Mayer c3392bf025 Wrap deprecated QSqlDatabase::exec() in QSqlQuery
QSqlDatabase::exec(const QString&) is deprecated in Qt6. Route the
PRAGMA/CREATE TABLE statements through QSqlQuery(db).exec() instead.
Clears 11 -Wdeprecated-declarations warnings; same statements, same
database connection, no behavioural change.
2026-07-14 19:27:17 +02:00
Dieter Mayer 7e08cd1285 Replace deprecated QVariant::Type with QMetaType in UserProperties
QVariant::type() and the QVariant::Type enum are deprecated in Qt6.
Switch on userType() (non-deprecated, returns the QMetaType id and
works on Qt5 too) with QMetaType enum cases. Clears 6 -Wdeprecated-
declarations warnings; the numeric type ids are unchanged.
2026-07-14 19:27:17 +02:00
Dieter Mayer 1265e51ebe Replace deprecated qAsConst with std::as_const
qAsConst was deprecated in Qt 6.6; std::as_const (C++17, already the
project standard) is the drop-in replacement. Clears 46 -Wdeprecated-
declarations warnings across 18 files. No behavioural change.
2026-07-14 19:27:16 +02:00
Laurent Trinques 5c65bf6486 Merge pull request #539 from DieterMayerOSS/add-qet-de-qm
Add compiled qet_de.qm for the completed German translation
2026-07-12 11:04:40 +02:00
Dieter Mayer 64a0c7abf5 Add compiled qet_de.qm for the completed German translation
Regenerate lang/qet_de.qm from lang/qet_de.ts with lrelease so the
committed binary matches the strings completed in #538
(2621 finished, 0 unfinished for de_DE).
2026-07-12 09:29:35 +02:00
Laurent Trinques 0ef47ce9b9 fix typo on publiccode.yml 2026-07-12 08:27:52 +02:00
Laurent Trinques 96e283a25b fix typo on publiccode.yml 2026-07-12 08:05:58 +02:00
Laurent Trinques f16ebeb2a6 Add publiccode.yml 2026-07-12 07:53:24 +02:00
Laurent Trinques b97a87c889 Merge pull request #537 from DieterMayerOSS/fix-collection-names-base-language
Fall back to the base language for element and folder names
2026-07-11 23:15:12 +02:00
Laurent Trinques 81d0045514 Merge pull request #538 from DieterMayerOSS/complete-german-terminal-translations
Complete German translation of unfinished terminal-label strings
2026-07-11 22:28:19 +02:00
Dieter Mayer b6124b065c Complete German translation of unfinished terminal-label strings
qet_de.ts had 20 unfinished entries in the PartTerminal and
TerminalEditor contexts: 12 empty ones (shown in French at runtime,
since French is the source language of the tr() literals) and 8 that
already carried German text but were still flagged unfinished.

Translate the 12 empty strings, matching the terminology already
established in these contexts (borne/terminal -> "Anschluss",
label -> "Beschriftung", cadre -> "Rahmen", police -> "Schriftart"),
and mark the 8 existing drafts as finished. lrelease now reports
2621 finished and 0 unfinished translations for de_DE.
2026-07-11 21:52:51 +02:00
Dieter Mayer c211b68139 Fall back to the base language for element and folder names
NamesList::name() looked up the display name using the full locale from
langFromSetting() (e.g. "de_DE") and jumped straight to English if it was
absent. Element and folder names in the collection are keyed by 2-letter
codes (<name lang="de">), so a "de_DE" UI showed the whole collection in
English/French even though German names exist.

Try the base language ("de") before the English fallback, mirroring what
setLanguage() already does for the UI translations.
2026-07-11 21:47:04 +02:00
Laurent Trinques 0f129ac504 git submodule update --remote elements 2026-07-11 06:47:58 +02:00
Laurent Trinques e23dc24283 Update translations files 2026-07-11 06:45:03 +02:00
Laurent Trinques 6d7b38c7a1 Merge pull request #536 from Kellermorph/terminal-name
Feature: Add terminal name label display in element editor
2026-07-10 15:11:49 +02:00
Kellermorph b543adcb46 Restore comments 2026-07-10 15:04:04 +02:00
Kellermorph f62ce7e4ca Update terminal name 2026-07-10 14:36:47 +02:00
Kellermorph c884d32dbe Feature: Add terminal name label display in element editor 2026-07-09 14:02:27 +02:00
Laurent Trinques 99ad9aa459 Merge pull request #535 from Kellermorph/translation
Add German translation
2026-07-08 13:33:58 +02:00
Kellermorph c1c72c5a62 Add complete German translation for QElectroTech 2026-07-08 07:09:23 +02:00
Laurent Trinques eeabea10f0 Update translations files 2026-07-08 06:57:07 +02:00
Laurent Trinques e034cfe9cf Merge pull request #534 from Kellermorph/safety-check
feat: add backup dialog when opening an existing project
2026-07-08 06:34:13 +02:00
Kellermorph 2db6c3968a feat: add backup dialog when opening an existing project 2026-07-07 21:42:45 +02:00
Laurent Trinques 14253930ae Merge pull request #509 from Kellermorph/master
Add Custom Guides
2026-07-07 16:34:56 +02:00
Laurent Trinques ec0a9f45d3 Update windows-msi.yml 2026-07-06 18:43:55 +02:00
Laurent Trinques 1121ccea26 Fix ci: update GitHub Actions to latest major versions 2026-07-06 17:57:37 +02:00
Laurent Trinques 94cc9cfef5 Fix ci: update GitHub Actions to latest major versions 2026-07-06 17:54:46 +02:00
Laurent Trinques 346aad75fd Fix ci: update GitHub Actions to latest major versions 2026-07-06 16:49:51 +02:00
Laurent Trinques 2b8cdd3d67 ci: update GitHub Actions to latest major versions 2026-07-06 16:46:54 +02:00
Laurent Trinques be008fb5f6 ci: update GitHub Actions to latest major versions 2026-07-06 16:43:16 +02:00
Laurent Trinques 82cd4d359a macOS fix: add explicit QGraphicsLayoutItem include in helpercell.h
MOC on macOS does not resolve QGraphicsLayoutItem through the bulk
QtWidgets include, causing an 'Undefined interface' error at build time.
Adding an explicit include resolves this. Linux builds are unaffected. Thanks hairykiwi 8ef4e04
2026-07-06 14:45:58 +02:00
Laurent Trinques 6dca56f823 git submodule update SingleApplication to v3.5.6 2026-07-06 13:08:34 +02:00
Laurent Trinques 545006bed2 Merge pull request #533 from geri1701/no-kf5-qt-only
Fix Qt-only build when BUILD_WITH_KF5=OFF
2026-07-05 18:00:35 +02:00
Gerhard Schwanzer dcec0bf7ff Skip actively locked autosave files
Check the QLockFile in staleFiles() before returning a no-KF5 recovery candidate, matching the KAutoSaveFile contract that actively owned autosave files are not stale.

Extend the no-KF5 Catch test so a child process keeps the autosave lock alive while allStaleFiles() runs, then verify recovery after the child is killed.

Assisted-by: pi coding agent / Mika (OpenAI GPT-5.5)
2026-07-05 17:39:38 +02:00
Gerhard Schwanzer 7a97e873d9 Test Qt-only autosave recovery fallback
Add a no-KF5 Catch regression test that leaves a KAutoSaveFile-compatible backup behind from a child process, then verifies stale-file discovery, stale-lock recovery, reading, and cleanup.

Assisted-by: pi coding agent / Mika (OpenAI GPT-5.5)
2026-07-05 15:52:25 +02:00
Gerhard Schwanzer e6124e941a Add Qt-only autosave recovery fallback
Provide a small KAutoSaveFile-compatible implementation for the no-KF5 build path and use it to keep the existing crash-recovery code active when BUILD_WITH_KF5=OFF.

The normal KF5 build still uses the KDE KAutoSaveFile implementation.

Assisted-by: pi coding agent / Mika (OpenAI GPT-5.5)
2026-07-05 13:23:49 +02:00
Gerhard Schwanzer d0cea474a6 Fix Qt-only build without KF5
The BUILD_WITH_KF5 option was checked with DEFINED, so passing -DBUILD_WITH_KF5=OFF still entered the KF5 setup path.

Skip the KF5 setup when disabled and provide small Qt-only replacements for the KDE color widgets used by .ui files in that build mode.

Assisted-by: pi coding agent / Mika (OpenAI GPT-5.5)
2026-07-05 11:10:44 +02:00
Laurent Trinques 3c8ba1b1ca Update ChangeLog with narrative summary of post-0.100 changes
Add a hand-written "Version 0.101 (Unreleased)" section covering the
headless CLI export mode, PDF hyperlink cross-references, diagram
duplication, the Windows MSI versioning fix, the macOS file-open
regression fix, and expanded Korean translation support.

Add git-cliff config for changelog generation

Add cliff.toml, configured to group commits by keyword (fix/feat/
refactor/etc. in FR+EN) since the project history doesn't follow
Conventional Commits. Handles QET's tag format (X.Y / X.Y.Z, no v
prefix), excludes the floating "nightly" tag, dedupes repeated commit
messages per release, and truncates commit bodies to their summary
line to keep the generated changelog valid Markdown.

Usage:
export GITHUB_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
git-cliff --config cliff.toml <last_tag>..HEAD --prepend ChangeLog.md.
2026-07-04 11:09:49 +02:00
Laurent Trinques e19f523227 fix(windows-msi): inject rev into MSI Version Build field
Version was static (X.Y.Z.0) across nightlies, so MajorUpgrade never triggered the automatic uninstall; the Windows Installer only compares Major.Minor.Build, ignoring the 4th field.
2026-06-30 18:49:43 +02:00
Laurent Trinques 5dac26d9c7 Merge pull request #524 from ispyisail/fix/collection-unicode-path
Fix #391: collection panel blank when path contains accented chars or is too long (Windows)
2026-06-29 23:11:17 +02:00
Laurent Trinques e7873b40d5 git submodule update --remote pugixml/ 2026-06-27 22:49:23 +02:00
Laurent Trinques cd6c66c3c6 git submodule update --remote elements 2026-06-27 22:01:36 +02:00
Laurent Trinques ef04497ca6 Translate debug message to English 2026-06-27 19:41:28 +02:00
Laurent Trinques 58000283e6 Merge pull request #522 from ispyisail/fix/issue-283-table-center-alignment
fix(#283): restore center alignment when loading table config
2026-06-27 13:58:19 +02:00
Laurent Trinques 73b96dd1b8 Merge pull request #530 from vinicius-ap-santos/improve-ptbr-translation
Improve Brazilian Portuguese translation (pt_BR)
2026-06-24 06:10:57 +02:00
Vinícius Santos 682c6a0ccb Improve Brazilian Portuguese translation (pt_BR)
Fix 9 critical meaning errors, remove anglicisms, standardize
terminology and fill 81 previously untranslated strings.

Details:
- Nombre de phase: Nome da fase -> Numero de fases
- Ajouter un tableau: Ajustes da tabela -> Adicionar uma tabela
- Parcourir: Personalizado -> Navegar
- Desactive: Invalido -> Desativado
- Longueur: Largura -> Comprimento
- Variables de cartouche: Variaveis de armazenamento -> Variaveis do carimbo
- Aller a la correspondance: Ir para a aba -> Ir para a ocorrencia
- Creer de nouveaux folios: Cria um novo projeto -> Criar novas paginas
- Ponter/Deponter les bornes: verb form and meaning corrected
- Removed anglicism resetar -> Restaurar/Redefinir
- conducteur standardized to condutor (was mixed with fio)
- nomenclature standardized to nomenclatura (was lista de nomes)
- WiringListExport: entire feature translated
- TerminalNumberingDialog: entire dialog translated
- QETElementEditor: Mirror, Flip, Fine-Rotation translated
- TerminalEditor: NO/NC contacts -> NA/NF (Brazilian standard)
- Include compiled .qm file
2026-06-23 18:25:22 -03:00
Laurent Trinques d3cf8f2635 Remove github action test-vs2026.yml 2026-06-23 13:44:05 +02:00
plc-user 6aa14a7536 Merge pull request #518 from ispyisail/fix/terminal-data-leak
looks plausible, compiles fine

thank you @ispyisail
2026-06-23 09:39:46 +02:00
plc-user 6ce688a709 Merge pull request #520 from ispyisail/fix/element-editor-first-click-481
fixed:
view jumps, but graphic primitives stay at position
all parts can be moved as before
compile-warning is gone

thank you @ispyisail
2026-06-23 09:26:02 +02:00
Shane Ringrose 28357b0f55 fix(editor): correct initializer list order to silence -Wreorder warning
m_first_move was initialized before _linestyle in the constructor
initializer list, but _linestyle is declared first in the class. Reorder
to match declaration order.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 07:04:34 +12:00
plc-user e21f49d2cf Merge pull request #528 from ispyisail/fix/project-props-dialog-modality
Merged as discussed in #527 
Thanks @ispyisail
2026-06-22 20:28:27 +02:00
Shane Ringrose 2a115e4381 fix(editor): suppress spurious first-click element moves (#481)
When an item type is selected for the first time the properties dock
expands, causing the QGraphicsView viewport to shrink. Qt recalculates
scene coordinates and fires one or more synthetic mouseMoveEvents before
the user has actually moved the mouse.

The original code used a single-shot m_first_move flag in
CustomElementGraphicPart, which absorbed exactly one spurious event.
PartText and PartDynamicTextField had no protection at all.

Fix: compare screen-coordinate displacement against
QApplication::startDragDistance() (~4 px). Screen coordinates are
stable across viewport resizes, so the check correctly rejects
synthetic dock-expansion events while allowing genuine drags.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 05:38:11 +12:00
Shane Ringrose bab32b3764 Fix #527 follow-up: use ApplicationModal for app config dialog (configureQET)
Same root cause as ProjectPropertiesDialog: Qt::WindowModal only blocks the
direct parent window, leaving the rest of the MDI area live.  If new_project
or close_project fires while the app settings dialog is open, any raw pointers
derived from the project list become stale.  Switch to ApplicationModal to
block all windows for the duration of the dialog.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 17:48:19 +12:00
Shane Ringrose 5cc2e165bf Fix #527: use ApplicationModal for Project Properties to prevent SIGSEGV
ProjectPropertiesDialog::exec() was using Qt::WindowModal, which only
blocks the parent ProjectView window.  The MDI workspace and its other
subwindows remained interactive, so actions like new_project or
close_project could fire while the dialog's config pages still held raw
QETProject* pointers — leading to a SIGSEGV when Qt's event loop later
dispatched a signal through one of those stale pointers.

Detected by the 8-hour GUI fuzzer: action sequence add_diagram_page →
flood_wires ×18 → new_project while Project Properties was open
produced exit code -11 (SIGSEGV) on the first of 12,717 actions.

Switch to Qt::ApplicationModal so no window can receive input while the
dialog is open.  Project Properties is a short-lived dialog; blocking
the whole application for its duration matches user expectation and
removes the lifetime hazard without requiring QPointer surgery across
four config-page classes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 17:30:20 +12:00
scorpio810 1c764babd1 macOS: buffer QFileOpenEvent during cold launch before QETApp exists
Follow-up to the eventFilter fix: testing showed double-click works
when QET is already running, but a cold launch (app not running yet)
still opens an empty window. Finder/Launch Services can deliver the
QFileOpenEvent to the QApplication's native event loop before main()
reaches the point where QETApp is constructed and its real eventFilter
is installed -- there's a window between 'SingleApplication app(...)'
and 'QETApp qetapp;' during which the event can arrive and be lost.

Add a minimal EarlyFileOpenCatcher installed on app immediately after
it's constructed (before anything else can run an event loop). It only
buffers the file path. Once QETApp exists, main() swaps it out for the
real QETApp::eventFilter and drains anything that was buffered via
qetapp.openFiles(), so no cold-launch QFileOpenEvent is silently
dropped.

Confirmed by manual testing:
- 'open app --args file' on .qet/.elmt/.titleblock: OK (already worked)
- double-click while app already running: OK (already worked)
- double-click cold launch: previously opened an empty window, this
  buffers and replays the event so it now opens the right editor.
2026-06-21 13:04:07 +02:00
scorpio810 8d76354647 macOS: fix QFileOpenEvent routing for .qet/.elmt/.titleblock double-click
Root cause (see issue #218 discussion):
- QETApp::eventFiltrer (Q_OS_DARWIN) was correct in intent but never
  actually installed as an event filter anywhere, and its name didn't
  match the QObject::eventFilter virtual signature, so even if it had
  been installed it would never have been invoked as an override.
  Confirmed dead code.
- main.cpp instead routed Finder's QFileOpenEvent through
  MacOSXOpenEvent -> SingleApplication::sendMessage(), which is the
  secondary-to-primary IPC channel. Called from within the primary
  instance itself, sendMessage() fails silently and the file path is
  dropped, which is exactly what double-click does (Finder doesn't spawn
  a secondary process, the running instance receives the FileOpen event
  directly).
- openFiles() takes a QETArguments, not a QStringList. The dead code's
  openFiles(QStringList() << filename) only worked via an untested
  implicit QStringList -> QList<QString> -> QETArguments conversion
  chain.

Fix:
- Rename eventFiltrer -> eventFilter (qetapp.h/.cpp) so it's a proper
  override of QObject::eventFilter, and make it public so main.cpp can
  install it on QApplication.
- Build the QETArguments explicitly instead of relying on implicit
  conversion.
- main.cpp: drop MacOSXOpenEvent entirely (include + instantiation),
  install qetapp as the Q_OS_MACOS event filter on app right after
  QETApp qetapp; is constructed and before app.exec(). No race window:
  the event loop hasn't started, so no QFileOpenEvent can be delivered
  before the filter is installed.

QETArguments::handleFileArgument() already sorts files by extension
(.elmt, titleblock, else project) and openFiles() already fans out to
openProjectFiles()/openElementFiles()/openTitleBlockTemplateFiles()
accordingly, so this single fix covers .qet, .elmt and .titleblock
double-click/drag-to-dock on macOS, not just .qet.

SingleApplication's sendMessage/receivedMessage flow (used for CLI args
on all platforms) is untouched; this only touches the Q_OS_MACOS block,
so there is no behavior change on Windows/Linux.

Follow-up (not included here): the macOS Info.plist (misc/Info.plist)
has an empty CFBundleShortVersionString, which may affect macOS's
willingness to retain file associations across app updates.
2026-06-21 12:10:13 +02:00
Shane Ringrose 31edf30c61 Fix #391: use wide-char path for pugixml on Windows to handle Unicode paths
pugi::xml_document::load_file(const char*) calls fopen/fopen_s on Windows,
which uses the ANSI codepage — not UTF-8. This silently fails when the
collection path contains accented characters (é, ü, ñ, …) or is longer
than the narrow-API MAX_PATH limit, leaving the collection panel with no
element names or illustrations.

Switch both call sites to toStdWString().c_str() which invokes the
load_file(const wchar_t*) overload. On Windows pugixml calls _wfopen,
the wide Unicode API that handles all valid Unicode paths. On Linux/macOS
the same overload converts wchar_t to UTF-8 internally and calls fopen,
so behaviour is unchanged on those platforms.

Affected files:
  sources/ElementsCollection/fileelementcollectionitem.cpp  (qet_directory load)
  sources/ElementsCollection/elementslocation.cpp           (element .elmt load, both branches)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 22:08:11 +12:00
Shane Ringrose 734391eabf Merge master: add cli_export, pdf_links; EDZ: 10-slot grid, group headers, ToS notice
- Resolve cmake/qet_compilation_vars.cmake conflict: keep both upstream's
  cli_export.cpp/h and pdf_links.cpp/h and the EDZ source additions.

- 10-position grid alignment: pin_y values are multiples of 10 so terminals
  snap cleanly to QET's default grid.  group_gap raised to 10 (one full slot).

- Named connector groups get a header label (group name) placed in the gap
  above the first pin, so the electrician sees block names (XDI, XPOW, …)
  without reading individual terminal designations.

- Device-tag dynamic_text now uses 9pt LABEL_FONT and y = min_y - 9 so it
  clears the element body and is legible at normal zoom.

- Add EPLAN Data Portal Terms of Use disclaimer to sources/import/edz/README.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 21:00:49 +12:00
Shane Ringrose f55ba568f6 fix(#283): restore center alignment when loading table config
saveConfig() serialises Qt::AlignHCenter as the string "AlignHCenter"
via QMetaEnum::valueToKey(), but loadConfig() matched against
Qt::AlignCenter (0x0084 = AlignHCenter|AlignVCenter) instead of
Qt::AlignHCenter (0x0004).  The two values differ, so the switch fell
through to the default (Right) every time center was saved and reloaded.

Add Qt::AlignHCenter as the primary case and keep Qt::AlignCenter as a
fallthrough for any config files that were hand-edited by users following
the workaround documented in issue #283.

Verified with a standalone Qt test: QMetaEnum::keyToValue("AlignHCenter")
returns 4 (AlignHCenter), which now correctly resolves to combobox index 1
(Center) instead of 2 (Right).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 20:41:25 +12:00
plc-user 1410e70d13 Merge pull request #521 from ispyisail/fix/iscustom-collection-prefix
Sounds plausible! 
Thank you @ispyisail
2026-06-21 09:24:42 +02:00
Shane Ringrose 7669a95694 fix(collection): isCustomCollection() false-positive on company path
The default user-collection path ends in "elements" and the default
company-collection path ends in "elements-company".  Both
FileElementCollectionItem::isCustomCollection() and
ElementsLocation::isCustomCollection() used startsWith(customDir),
so "…/elements-company/…" matched "…/elements" and returned true.

This caused ElementsCollectionModel::addLocation() to insert a
newly-saved user-collection element as a child of the company-
collection branch in the tree, making it appear in the wrong panel.

Fix: require the path to equal the directory root exactly, or to
start with the directory root followed by '/'.

  path == dir || path.startsWith(dir + QLatin1Char('/'))

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 12:10:22 +12:00
Shane Ringrose 8268df8a80 edz: name terminals terminalNr.designation (e.g. "XDI.2")
Previous logic resolved duplicate connectionDesignation values by
appending sanitised description text or numeric suffixes, which was
fragile and produced names an electrician could not easily map back to
the physical wiring.

New scheme:
  • terminalNr present  → "XDI.2", "XRO1.3", "XPOW.1" …
  • terminalNr absent   → designation as-is ("L1/U1", "UDC+", "PE") —
    these are busbar / power connections and are already globally unique
  • collision (malformed data) → numeric suffix as safety net

The description (connectiondescription) remains as the human-readable
label beside the terminal symbol, exactly as suggested by plc-user.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 08:58:30 +12:00
Shane Ringrose 03e6e76b3f edz: fix missing-field-initializer warning in EdzElementBuilder
EdzPin gained a third field (group) but the fallback initializer at
line 70 still listed only two fields, triggering -Wmissing-field-initializers.
Added the explicit QString() for group.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 03:02:31 +12:00
Shane Ringrose 2aeeb74e72 edz: group terminals by physical connector (terminalNr), drop separator lines
EPLAN 2022-style part.xml files (e.g. IFM AL1122) use a numeric
functiondefgroup attribute and do not carry the text functiondefinition
block name that the previous grouping logic relied on.  Those parts
fell back to grouping by pin designation, producing symbols with all
pin "1"s stacked together, then all "2"s, etc. — the bug reported in
PR #513.

Fix: read terminalNr first (the physical M12/connector socket identifier,
e.g. "X01", "X31") as the primary group key; fall back to functiondefinition
text for older EPLAN formats that omit terminalNr.  Pins within each
connector group are still sorted by designation using natural sort.

Also remove the dashed inter-group separator lines; the existing 5 px
gap between groups provides sufficient visual separation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 02:57:14 +12:00
Laurent Trinques ee53f20303 Merge pull request #517 from ispyisail/fix/snap-xcb-cursor-missing
snap: stage libxcb-cursor0 to fix xcb plugin crash on Ubuntu 24.04 (issue #373)
2026-06-20 16:44:59 +02:00
Shane Ringrose 756cfd98c0 Fix terminal grouping: use functiondefinition block, not pin designation
The previous grouping compared `connectionDesignation` values (e.g. "1",
"2", "3") to detect group boundaries.  Those values are pin position
numbers within a terminal block, not functional group identifiers, so
devices like the ABB ACS880 produced 11+ tiny single-pin "groups" instead
of the ~8 functional blocks (AC-IN, Motor-OUT, DC-Bus, Brake-Resistor,
Analog-I/O, Digital-I/O, ...) the reviewer identified.

Fix:
- Add `group` field to EdzPin, populated from the `functiondefinition`
  attribute on <functiontemplate> (newer EPLAN) or its parent <function>
  element (older EPLAN).
- Sort pins by group first (preserving XML appearance order per group),
  then by designation within each group using natural sort.
- Use `groupKey()` — group when present, designation as fallback — for
  the group-break detection that drives separator lines and Y-gaps.

Parts without any functiondefinition data retain the previous
designation-based behaviour unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 01:54:23 +12:00
Shane Ringrose 8a837a11d4 Fix four memory leaks found by AddressSanitizer
- StyleEditor: QGridLayout(this) pre-empted the widget's layout slot,
  causing setLayout(main_layout) to silently fail and orphan main_layout.
  Fix: use QGridLayout() without a parent so setLayout() succeeds.

- ExportDialog: ~ExportDialog() was empty, leaving ExportDiagramLine
  heap objects in diagram_lines_ unfreed. Fix: qDeleteAll(diagram_lines_).

- GenericPanel::getItemForDiagram: when called without the bool* created
  arg, it created a parentless QTreeWidgetItem that callers immediately
  discarded. Fix: return nullptr when created==nullptr and item not found
  (all callers already guard with if (item)).

- ElementScene: m_paste_area (created in initPasteArea) was temporarily
  added/removed from the scene during XML loading but never freed in the
  destructor. Fix: delete it if not currently in the scene.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 01:45:07 +12:00
Shane Ringrose df5f622418 Fix TerminalData memory leak in Terminal destructor
Terminal stores its TerminalData* as member d but never deletes it.
Every Element creation (placing on diagram, loading icon for the
element browser, drag previews) leaks one TerminalData per terminal.
ASan confirmed 112 leaked objects (9856 bytes) in a short session
across four call sites all rooted in Element::parseTerminal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 00:38:07 +12:00
plc-user 71ff7f925d Merge pull request #515 from ispyisail/fix/valgrind-uninit-machineinfo-firstshow
Thank you @ispyisail
2026-06-20 13:19:39 +02:00
Shane Ringrose 2fdc07b81b snap: stage libxcb-cursor0 to fix xcb plugin load failure on Ubuntu 24.04
Qt 5.15.x added libxcb-cursor0 as a hard runtime dependency of the xcb
platform plugin (libqxcb.so).  The kf5-5-110-qt-5-15-11-core22 content
snap does not bundle this library, so when the snap runs on an Ubuntu 24.04
host the dlopen() of the plugin fails with:

  qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in ""
  even though it was found.

Staging libxcb-cursor0 from the Ubuntu 22.04 archive satisfies the
dependency without changing the snap base, Qt version, or any other
dependency.  No ABI mismatch: the plugin and the staged library are
both built against the core22 (22.04) ABI.

Fixes issue #373.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 22:51:11 +12:00
Shane Ringrose 27534a379b Group terminals by designation with visual separator lines
Pins are already sorted by designation (see EdzPart::parse natural sort).
This change makes same-designation groups visually obvious in the element
symbol by:

  - Inserting a 5 px gap between consecutive terminals whose designation
    differs, so each group reads as a distinct block.
  - Drawing a thin dashed horizontal line through each gap, mirroring
    the grouped-I/O style shown in typical manufacturer datasheets.

The body rectangle and bounding box grow automatically to accommodate the
extra gaps, so no fixed sizes change.  Unique terminal names (added in the
previous commit) are unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 22:44:06 +12:00
plc-user 32bb247d68 Merge pull request #514 from ispyisail/fix/thread-safe-datadir-configdir
Thank you @ispyisail
2026-06-20 12:39:12 +02:00
Shane Ringrose 207c0c9544 Fix copyright years and deduplicate terminal names
Two issues raised in PR review:

1. Copyright year: new files carried "2006" (the project's founding year).
   Updated to "2006-2026" to reflect the actual authorship period.

2. Duplicate terminal names: EPLAN parts can have multiple connection
   templates sharing the same connectionDesignation (e.g. a drive where
   both wire entries of terminal "1" are labelled "1").  QET requires
   unique terminal names for wiring and terminal-diagram generation.

   Resolution order in EdzElementBuilder::build():
   - Unique designation → used as-is.
   - Duplicated designation with distinct sanitised description →
     "designation_description" (e.g. "1_L_P").
   - Otherwise → numeric suffix: "1", "1_2", "1_3", …

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 22:39:11 +12:00
Shane Ringrose c586a2d3a3 Fix three uninitialised-value bugs found by Valgrind
1. machine_info.h: zero-initialise Screen struct members
   Max_width, Max_height, count, width[] and height[] were bare
   int32_t with no initialiser. The comparisons in
   init_get_Screen_info() read them before any write, producing
   undefined behaviour flagged by Valgrind as 'Conditional jump
   or move depends on uninitialised value(s)'.

2. main.cpp: pre-initialise MachineInfo on the main thread
   MachineInfo::instance() was first called inside QtConcurrent::run(),
   causing its constructor (which calls qApp->screens()) to run on a
   background thread. QScreen methods are not thread-safe in Qt5.
   Calling instance() once on the main thread before the worker
   launches guarantees the singleton is fully built first; subsequent
   calls from the worker just return the cached pointer.

3. qetdiagrameditor.h: move m_first_show before the QActionGroup members
   C++ initialises members in declaration order. m_first_show was
   declared after the QActionGroup members (line 256 vs 168). During
   construction of m_row_column_actions_group(this), Qt dispatches a
   QObject parent-change event that reaches QETDiagramEditor::event(),
   which reads m_first_show before it has been initialised.
   Moving the declaration to the top of the first private: block
   ensures it is initialised before any member that can trigger events.

All three found via Valgrind --tool=memcheck on Ubuntu 22.04 / Qt 5.15.3.
Relates-to: PR #514 (same QtConcurrent thread-safety pattern).
2026-06-20 22:31:06 +12:00
Shane Ringrose f301196f61 Rename static locals to match original variable names per review
Reviewer requested configdir/datadir instead of cached for consistency
with the surrounding code style.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 22:26:32 +12:00
Shane Ringrose f2d297b0d8 Fix thread-unsafe QStandardPaths calls in dataDir/configDir
QStandardPaths::writableLocation() is not thread-safe in Qt5.
ElementsCollectionModel::reload() launches:

  QtConcurrent::map(m_items_list_to_setUp, setUpData)

Each worker calls FileElementCollectionItem::setUpData()
→ collectionPath() → isCollectionRoot()
→ QETApp::userMacrosDir() → QETApp::dataDir()
→ QStandardPaths::writableLocation()  ← SIGSEGV (null deref)

The crash was confirmed by Valgrind (address 0x0, inside
libQt5Core's writableLocation internals).

Fix: replace the bare QStandardPaths calls in dataDir() and
configDir() with a C++11 static-local lambda.  The compiler
guarantees the lambda body runs exactly once across all threads
(magic statics, ISO C++11 §6.7).  After the first (main-thread)
call the result is returned lock-free.

Relates-to: #492 (same QtConcurrent lifetime pattern fixed in
QETProject::writeBackup by PR #512).
2026-06-20 20:09:48 +12:00
Shane Ringrose d56bca66da Harden EPLAN import: format detection, trim SDK, docs (M4)
- EdzArchive checks the archive magic up front: gives a clear message for
  zip-format .edz (not yet supported) and unrecognised data, instead of an
  opaque 7z decode error.
- Trim the vendored LZMA SDK headers to the decode closure actually used
  (removes 21 unused encoder/multithread/Xz/Aes headers; 18 .c + 18 .h remain).
- Add sources/import/edz/README.md documenting the feature, the data mapping
  and the bundled SDK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 08:14:53 +12:00
Shane Ringrose aa6a0b941a Add English translations for the EPLAN import strings
The new import action and dialogs used French source strings (QET convention)
but had no English translation, so they showed French in the English UI. Add
the five strings to qet_en.ts (menu action, dialog title, file filter, error
box title and message).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 08:03:00 +12:00
Shane Ringrose e4b4ba875b Bundle LZMA SDK for .edz extraction; drop 7z CLI dependency (M3)
Replaces the QProcess->7z shim with the public-domain LZMA SDK (23.01) 7-Zip
reader, vendored under sources/import/edz/lzma/ (decode-only subset). New
edzsevenzip.cpp wraps SzArEx_Open/SzArEx_Extract and writes entries via Qt, so
EdzArchive no longer needs an external 7-Zip at runtime. Enables the C language
in CMake for the vendored sources.

Verified: the bundled decoder extracts all three ifm sample .edz and the
generated elements still match the Python oracle exactly (byte-correct decode),
with no 7z on the path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 07:49:14 +12:00
Shane Ringrose f4ff6c81f9 Add EdzImporter + collection-panel import action (M2)
Wires EPLAN .edz import into the elements panel. EdzImporter orchestrates
EdzArchive -> EdzPart -> EdzElementBuilder and writes the generated .elmt into a
destination collection folder (named by order number). A right-click
"Importer une piece EPLAN (.edz)..." action on a writable collection directory
opens a file picker, runs the importer into that folder's fileSystemPath() and
reloads the panel; errors surface via QetMessageBox. Modeled on newElement().

EdzImporter verified headless against the Python oracle for KG6000/MFH200/
R1D200; the panel wiring is built/tested via the WSL Qt5+KF5 build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 07:34:52 +12:00
Shane Ringrose 7cc5790f7c Add EdzPart + EdzElementBuilder: .edz part -> .elmt (M1)
Port of the edz2qet.py prototype's mapping to C++. EdzPart parses an EPLAN
part.xml into a portable model (identity/metadata, localized names, connection
list); EdzElementBuilder turns that into a QET element (generic symbol: body
rectangle + one west-facing terminal per pin, per-pin labels, localized <name>s,
and elementInformations for the BOM).

Pins are natural-sorted by designation so they stack 1,2,3,4 regardless of the
order EPLAN lists them (MFH200 lists 1,3,4,2). Output verified structurally
identical (uuids aside) to the Python oracle for three ifm samples — KG6000
(4-pin), MFH200 (4-pin, reordered) and R1D200 (5-pin, incl. Dutch name) — and
the generated element loads in the QET editor with correct UTF-8.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 07:11:09 +12:00
Shane Ringrose 82884d1cf7 Add EdzArchive: extract EPLAN .edz packages (M0)
First piece of native EPLAN Data Portal (.edz) import. A .edz is a 7-Zip
archive; QET previously had no archive handling. EdzArchive unpacks one to a
temporary directory and locates the contained part.xml.

The extraction backend is isolated behind extractWithSevenZipCli() so it can be
replaced with a bundled decompressor later without touching callers; this M0
step shells out to a 7-Zip CLI via QProcess. Verified on three ifm sample
parts (KG6000, MFH200, R1D200 — all 7z), plus the corrupt/missing-file paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 07:05:42 +12:00
plc-user a8e2a7acff concat QString with '%' 2026-06-19 17:06:58 +02:00
plc-user 53096fa3be Merge pull request #512 from ispyisail/fix-492-backup-uaf
Although I haven’t encountered the problems described myself (nor do I need to!), the changes and additions look plausible and compile without errors or warnings, so I’m approving this PR!

But as a remark:
I'm not particularly familiar with the Qt functions used here. But when I see that there is a version-specific implementation for Qt5 and only a debug-message mentioned for Qt6, it makes me wonder:
Is it implemented differently there, or is it not even needed there — which I don't think is the case...
If possible, "we" should also include something for Qt6 and later versions in another PR.
Do you know what’s needed for Qt6, @ispyisail ?
2026-06-19 12:35:47 +02:00
ispyisail bf4d3353ae Fix #492: wait for async backup before destroying QETProject
writeBackup() fires QtConcurrent::run(QET::writeToFile, ..., &m_backup_file)
fire-and-forget: the QFuture was discarded and nothing kept m_backup_file
alive until the worker finished. If the QETProject was destroyed first, the
worker wrote through the freed member -> use-after-free crash in
QET::writeToFile (intermittent; ~1/6 on short-lived CLI runs).

Store the QFuture and waitForFinished() in ~QETProject (and before
setFilePath() re-points the managed backup file). Also skip launching a new
backup while one is still running, so two threads never write m_backup_file
at once.

The Qt6 path is still a TODO stub and the QtConcurrent block is KF5-only, so
this affects only the Qt5/KF5 build that actually has the backup code.
2026-06-19 08:34:02 +12:00
Kellermorph 2e4fa9ae02 Drop translation files from this PR to handle them separately 2026-06-18 21:48:12 +02:00
Kellermorph cd0ae76141 Clean up lang/qet_de diff by isolating new translation strings 2026-06-18 21:45:31 +02:00
plc-user bd37f12edc upgrade 'osifont.ttf' from upstream 2026-06-18 15:20:25 +02:00
plc-user b873b05245 concat QString with '%' 2026-06-18 14:51:56 +02:00
plc-user eb02e1dce0 fix warning: 'if does not guard...' 2026-06-18 14:33:10 +02:00
plc-user ac1e8b3502 fix warning: name 'label_11' already used... 2026-06-18 14:30:35 +02:00
plc-user 215962873b fix warning: unused variable "pdfExport" (should be fixed properly by original author by evaluating function-result) 2026-06-18 14:26:32 +02:00
Kellermorph 0555cd9045 Address review feedback: double spinboxes, tabs, and fix export bug 2026-06-18 13:37:24 +02:00
plc-user 02cc4f043b Merge pull request #511 from ispyisail/fix-highlight-unused-reset
With this change we can close #159 as well!
Thank you @ispyisail
2026-06-18 12:42:00 +02:00
ispyisail 8791d2d202 Highlight reset: only clear the red unused-highlight
Per review (plc-user): scope the reset to items currently painted with the
red Dense4Pattern instead of clearing every item's background. This avoids
clobbering other backgrounds (e.g. the amber "show this dir" highlight)
and skips needless item updates on large collections.
2026-06-18 22:29:42 +12:00
ispyisail 4625964bb1 Fix #159: reset unused-element highlight when elements become used again
ElementsCollectionModel::highlightUnusedElement() only ever painted the
currently-unused elements red; it never cleared the background of items
that were no longer unused. So when an element was re-added to a project
and saved, its red 'unused' highlight persisted until the model was
rebuilt from scratch.

Reset every item's background before re-applying the highlight to the
current unused set.
2026-06-18 21:09:49 +12:00
Kellermorph 7a80ce40b7 Sync with upstream master and resolve conflict in qet_de.qm 2026-06-17 22:07:41 +02:00
plc-user 342ac3626d fix also German binary-translation 2026-06-17 14:11:11 +02:00
Laurent Trinques 19a75186b7 Merge pull request #506 from ispyisail/fix/snap-pin-sources
snap: pin qet-tb-generator source to tag v1.31
2026-06-17 13:24:10 +02:00
plc-user 9122f5d687 fix German translation 2026-06-16 21:13:14 +02:00
plc-user 482fd32dc2 element-editor: no warning on save, when element without terminals is frontview (and fix indention) 2026-06-16 20:40:08 +02:00
Kellermorph 4e0c075575 Fix grid and guide startup behavior and update german translation 2026-06-16 17:41:03 +02:00
plc-user ae42198882 Merge pull request #508 from ispyisail/fix-tbgen-drop-legacy-appdata
Drop dead ~/Application Data/qet fallback for qet_tb_generator (Windows)
As discussed in #199 ...
2026-06-16 12:37:07 +02:00
Shane Ringrose a666d2d0ae qet_tb_generator: drop dead ~/Application Data/qet fallback (Windows)
The Windows search list for the qet_tb_generator plugin included
`~/Application Data/qet/qet_tb_generator.exe` as a fallback. That legacy
junction path is the same inaccessible location the standard-directories
change moved QET away from, and it never matched a pip install anyway:
`pip install qet_tb_generator` puts the executable in the Python Scripts
directory (`...\PythonXX\Scripts` on PATH, or
`%APPDATA%\Python\PythonXX\Scripts` for --user installs), not in
`QETApp::dataDir()`.

Pip installs are already found via QStandardPaths::findExecutable (PATH),
and manual binary drops via dataDir()/binary and the working directory.
The legacy entry only matched old manual drops into the inaccessible
folder, so remove it.

Refs qelectrotech-source-mirror#199

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 22:11:22 +12:00
Shane Ringrose 15e7d39243 snap: pin qet-tb-generator source to tag v1.31
Without a source-tag or source-commit, snapcraft pulls the latest
HEAD of qet_tb_generator-plugin on every build.  This makes builds
non-reproducible and risks breakage whenever the upstream repo changes.

Pin to the only published release tag (v1.31, commit d6ee3cf) so
the snap always builds against a known-good version of the plugin.

Closes #202

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 10:15:09 +12:00
Laurent Trinques 5574b4d3e9 CMake: guard Linux-only install rules with UNIX AND NOT APPLE
The .desktop, MIME package, and appdata install rules are
freedesktop.org conventions and only apply on Linux. Wrapping
them in if(UNIX AND NOT APPLE) prevents a configure failure on
macOS and Windows where QET_APPDATA_PATH and QET_MIME_PACKAGE_PATH
are not defined.

Also replace the hardcoded share/mime/packages path with
${QET_MIME_PACKAGE_PATH} for consistency with
paths_compilation_installation.cmake.

No change to Linux build behaviour.
2026-06-14 13:58:37 +02:00
Laurent Trinques 918db632ed Update windows-msi.yml 2026-06-13 10:56:07 +02:00
Laurent Trinques f465b33e2b Update windows-msi.yml 2026-06-13 10:45:41 +02:00
Laurent Trinques 492528136e Update windows-msi.yml 2026-06-13 10:40:37 +02:00
Laurent Trinques 564a0e64a4 Update windows-msi.yml 2026-06-13 10:31:58 +02:00
Laurent Trinques 7f5a42a055 Update windows-msi.yml 2026-06-13 10:14:05 +02:00
Laurent Trinques 14d4aa772b Update windows-msi.yml 2026-06-13 09:59:17 +02:00
Laurent Trinques 81419bd27d Merge pull request #498 from ispyisail/fix-lang-path-fallback
Find translations when lang/ is beside bin/, not inside it (fixes #86)
2026-06-13 04:49:14 +02:00
Laurent Trinques ebefc269af Update Changelog file 2026-06-12 19:43:57 +02:00
Laurent Trinques c6bfd46981 Merge pull request #501 from ispyisail/fix-parttext-position-158
PartText: keep text position stable across save/reopen on font-size change (#158)
2026-06-12 16:49:26 +02:00
Laurent Trinques 998c5e8a0d Update translations files 2026-06-12 13:28:08 +02:00
Shane Ringrose ae382f6b12 parttext: re-anchor on font change so text position is stable across save/reopen (#158) 2026-06-12 23:05:15 +12:00
Laurent Trinques d4061d17fa Merge pull request #497 from ispyisail/fix-readonly-after-saveas
Clear read-only state when a project is saved to a writable file
2026-06-12 11:48:05 +02:00
Laurent Trinques fb8c86ec12 Merge pull request #495 from ispyisail/feature-folio-template-variables
Folio properties: auto-add a title block's custom variables
2026-06-12 11:47:33 +02:00
Laurent Trinques d62479e6e4 Merge pull request #496 from ispyisail/fix-system-regional-locale
Fix regional system locale loading the wrong translation (pt_BR/nl_BE/nl_NL)
2026-06-12 11:46:56 +02:00
Laurent Trinques 1a4bb91285 Merge pull request #494 from ispyisail/fix-elementdialog-filename-label
Element editor Save As: label the field as a file name, not 'element name'
2026-06-12 11:46:12 +02:00
Laurent Trinques aa96d5e7df Merge pull request #493 from ispyisail/cli-set-titleblock
CLI: add --set-titleblock, and fix headless backup crash
2026-06-12 11:42:04 +02:00
Shane Ringrose e63c303078 Find translations when lang/ is beside the bin/ folder, not inside it (#86)
QETApp::languagesPath() defaulted to applicationDirPath() + "/lang/".
The Windows installer puts the executable in a bin/ subfolder while the
lang/ folder sits next to it (../lang), so that default points at a
non-existent bin/lang/ — qetTranslator.load() fails and setLanguage()
silently falls back to the French source language. This is the root
cause behind the long-standing 'language won't change / resets to
French' reports, and why launching via 'Lancer QET.bat' (which passes
--lang-dir=lang/) works around it.

When the folder next to the binary doesn't exist, fall back to the
sibling ../lang folder if present. Behaviour is unchanged for builds
that already ship lang/ next to the binary, and for the QET_LANG_PATH
and --lang-dir paths.

Fixes #86.
2026-06-12 09:09:39 +12:00
Shane Ringrose a8e408ad39 Clear read-only state when a project is saved to a writable file (#217)
Saving a read-only project to a writable location (e.g. Save As to /tmp)
left it marked read-only, so it stayed uneditable until closed and
reopened. Two issues in QETProject::write():

- The guard refused to write whenever QFileInfo(path).isWritable() was
  false. For a Save As to a *new* file that test is always false (the file
  doesn't exist yet), so it could wrongly block saving a read-only project
  elsewhere. Now it checks the directory's writability for a new file.
- After a successful write the read-only flag was never cleared. Since the
  file was just written, it is writable, so clear it (setReadOnly(false)
  emits readOnlyChanged, re-enabling editing live).

Fixes #217.
2026-06-12 06:09:48 +12:00
Shane Ringrose 0eb3e1e436 Fix regional system locale loading the wrong translation (#421)
langFromSetting() truncated the system locale to two letters
(QLocale::system().name().left(2)), so a user on the default 'Système'
language whose locale is regional got the base-language translation
instead of their regional one. QET ships qet_pt_BR, qet_nl_BE and
qet_nl_NL, so e.g. a Brazilian user saw European Portuguese (and
untranslated strings fell back to the French source).

Keep the full locale name and, in setLanguage(), try the exact
translation, then the base language, then English (French stays the
native source). Brazilian/Belgian/Dutch users on 'system' now get their
regional translation; everyone else is unaffected.

Refs #421.
2026-06-12 05:58:04 +12:00
Shane Ringrose ba6320bff8 Folio properties: auto-add a title block's custom variables (#271)
When a title block template uses custom variables (e.g. %{department},
%{owner}), the user previously had to declare each one by hand in the
folio properties 'Custom' tab before a value could be entered. Now the
template's undefined custom variables are added automatically, so the
user only fills in the values.

- listOfVariables() now extracts %{name} placeholders with a regex
  (deduplicated) instead of a crude '%' strip that returned '{name}'.
- The folio properties widget merges the template's custom variables into
  the Custom tab both on open (setProperties) and when the template is
  changed, preserving any values already entered and skipping the
  standard fields (title, author, date, ...) which have their own inputs.

Fixes #271 (variable auto-population; the revision-history request in the
thread is a separate feature).
2026-06-12 05:45:08 +12:00
Shane Ringrose 86b5d7ac95 Element editor Save As: label the field as a file name, not element name (#469)
The Save As 'location' dialog used a QFileNameEdit (accepts only
[0-9a-z_-.]) but labelled it 'New element name', which is confusing —
QET also has a separate, translatable display name shown in the
collection. Users reasonably tried to type a display name (spaces,
capitals) and it was rejected.

Rename the placeholder to 'Element file name' and add a tooltip noting
the accepted characters and that the display name is edited separately
in the element properties. Updates the English translation; other
languages fall back until re-translated.

Fixes #469.
2026-06-12 05:34:20 +12:00
Shane Ringrose 19e99aab02 CLI: disable async crash-recovery backup in headless mode (fixes segfault)
QETProject schedules an asynchronous crash-recovery backup on construction
(writeBackup() -> QtConcurrent::run(QET::writeToFile, ..., &m_backup_file)).
In one-shot CLI mode the QETProject is destroyed as soon as the command
returns, while that background write still references its m_backup_file
member — an intermittent use-after-free segfault during teardown (~1 in 6
runs; observed on --resave and --set-titleblock).

A crash-recovery backup is meaningless for a short-lived headless command,
so add QETProject::setBackupEnabled(false), called from the CLI entry in
main(). writeBackup() then early-returns, so no background write is ever
launched. Fixes the crash for all CLI commands. See #492.
2026-06-12 05:25:44 +12:00
Shane Ringrose 44f0abbb56 CLI: add --set-titleblock to stamp title-block fields headlessly
The first write-to-project CLI command, aimed at CI / revision workflows:
stamp title-block metadata onto every folio (and the project default),
then save. Each argument is key=value:

  qelectrotech --set-titleblock in.qet out.qet revision=B date=today

Standard keys map to the documented title-block fields (title, author,
date, plant, location, revision, version, filename); date=today uses the
current date and an explicit date forces UseDateValue mode; any other key
is stored as a custom title-block field. Assignments are parsed up front
so a malformed one fails before writing.

Addresses the 'saving' side of the CLI-for-scripts request (#162).
2026-06-12 05:25:44 +12:00
Laurent Trinques e7787daa2c Update qet_zh.qm 2026-06-11 16:26:31 +02:00
Laurent Trinques c7fd3416f6 Merge pull request #491 from zi-mozhuang/master
Update qet_zh.ts
2026-06-11 16:25:42 +02:00
子墨庄 b782a1612a Update qet_zh.ts
Checked the format and conducted a pre-test using the linguist.
2026-06-11 22:16:49 +08:00
Laurent Trinques 2fdbc3c243 Merge pull request #490 from ispyisail/cli-pdf-links
CLI: clickable cross-reference hyperlinks in PDF export
2026-06-11 14:39:53 +02:00
Shane Ringrose a219c3f587 CLI: clickable cross-reference hyperlinks in PDF export
Wire the shared PdfLinks helper into the headless --export-pdf path so
CLI-exported PDFs get the same internal cross-reference / folio-report
navigation as the GUI print export.

For each page, after rendering, the scene-to-page geometry is rebuilt
from the QPdfWriter (96 dpi, zero margins, page sized to the diagram so
the scale is ~1 with no centering) — deliberately NOT reusing the
QPrinter-based mapping — and passed to PdfLinks::injectCrossRefLinks().
After the painter closes, PdfLinks::convertUriToGoTo() rewrites the URI
annotations into native GoTo/FitR actions.

Builds on the helper extracted in the previous commit; no change to the
other CLI tools.
2026-06-11 23:48:45 +12:00
Shane Ringrose 6b3b55b0e1 PDF links: extract pdf_links.{cpp,h} shared helper
Move the PDF cross-reference hyperlink logic out of ProjectPrintWindow
into a standalone translation unit so it can be reused (the CLI PDF
export will call it next):

- injectCrossRefLinks(): emits the URI link annotations for a diagram's
  cross-references and folio reports. The scene-to-page mapping is passed
  in as a PageGeometry (transform + devToPdf + source-rect lookup) so each
  caller supplies its own correct geometry, rather than the helper assuming
  a QPrinter.
- convertUriToGoTo(): the PDF post-processor, moved verbatim.

ProjectPrintWindow stays a pure caller: it builds its PageGeometry from the
printer page layout exactly as before and calls the helper. No behavioural
change to GUI PDF export; no class-structure changes.

Per review guidance on #483.
2026-06-11 23:48:14 +12:00
Laurent Trinques 36d0121038 Merge pull request #489 from ispyisail/cli-tools
CLI: add verification & data-export tools (info, BOM, nets, links, check-elements, resave)
2026-06-11 13:42:59 +02:00
Laurent Trinques 8235ecdbc9 Merge pull request #488 from Kellermorph/master
Issues 482
2026-06-11 13:32:30 +02:00
Shane Ringrose b6e4cd4786 CLI: add --export-nets, --export-links and --resave
Three more read-only command-line tools for verifying connectivity and
cross-reference intelligence (useful for import / migration pipelines):

  qelectrotech --export-nets    <project.qet> <output.json>
  qelectrotech --export-links   <project.qet> <output.csv>
  qelectrotech --resave         <project.qet> <output.qet>

- --export-nets walks Conductor::relatedPotentialConductors() to group
  every electrically-connected terminal into a net (potential), following
  folio reports and terminal blocks across all folios. Output is JSON:
  per net, the wire number and the list of {element, terminal, folio}.
  This is the connectivity ground truth.

- --export-links reports each linkable element (master/slave/report/
  terminal), its link type and the elements it links to, flagging
  masters/slaves with no link as UNRESOLVED. Verifies coil<->contact
  cross-references. Verified on examples/industrial.qet: 436 linkable
  (76 master, 41 slave, ...), 37 unresolved.

- --resave loads the project and writes its XML back out, so an external
  diff can reveal markup QET silently normalises on load
  (tolerated-but-invalid XML). Round-trip verified: the re-saved project
  reloads with identical diagram/element/conductor counts.
2026-06-11 23:23:13 +12:00
Shane Ringrose fb35027624 CLI: add --info, --export-bom and --check-elements verification tools
Extends the headless command-line interface with three read-only tools
aimed at validating projects and element libraries (useful for batch
import / migration pipelines):

  qelectrotech --info           <project.qet> [output.json]
  qelectrotech --export-bom     <project.qet> <output.csv>
  qelectrotech --check-elements <element.elmt | directory>

- --info dumps a structural summary as JSON straight from QET's loaded
  model: per-diagram element / conductor counts, page size, and the
  number of unconnected ("free") terminals, plus project totals. Because
  it uses the real loader it reports what the editor actually sees.

- --export-bom writes a bill of materials (one row per element) as CSV,
  querying the project's own element_nomenclature_view (the same source
  as the GUI BOM export). updateDB() is called first so the database is
  populated in a headless run.

- --check-elements validates one .elmt file, or every .elmt under a
  directory (recursively), against the element schema: XML well-formed,
  root <definition type="element">, a usable bounding box, and terminal
  count. Reports OK / WARN / FAIL per file and a summary; exit code is
  non-zero if any file fails. Verified against the full bundled
  collection (8483 elements): 0 false failures, agreeing with QET's own
  loader (e.g. a negative-height element it tolerates is a WARN, not a
  FAIL).

run() is restructured to handle the differing argument arity (info takes
an optional output, check-elements takes a path rather than a project).
2026-06-11 23:23:13 +12:00
Kellermorph 08a441d1f6 Issues 482 2026-06-11 13:22:01 +02:00
Laurent Trinques e9840728b4 Merge pull request #486 from qelectrotech/revert-484-master
Revert "Update-UI-Chinese-translation"
2026-06-11 12:28:55 +02:00
258 changed files with 57202 additions and 21994 deletions
-112
View File
@@ -1,112 +0,0 @@
name: Test Windows VS2026 migration
# Ce workflow vérifie que le build QElectroTech fonctionne sur l'image
# windows-2025-vs2026, avant la migration forcée du 8 juin 2026.
# Il peut être supprimé une fois la migration confirmée OK.
on:
workflow_dispatch: # déclenchement manuel uniquement
schedule:
- cron: '0 4 * * 1' # chaque lundi à 4h00 UTC (optionnel)
jobs:
test-vs2026:
name: Build on windows-2025-vs2026
runs-on: windows-2025-vs2026 # <-- image avec VS 2026
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Install MSYS2 + dependencies
uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
update: false
install: >-
mingw-w64-ucrt-x86_64-gcc
mingw-w64-ucrt-x86_64-cmake
mingw-w64-ucrt-x86_64-ninja
mingw-w64-ucrt-x86_64-qt5-base
mingw-w64-ucrt-x86_64-qt5-svg
mingw-w64-ucrt-x86_64-qt5-tools
mingw-w64-ucrt-x86_64-qt5-translations
mingw-w64-ucrt-x86_64-sqlite3
mingw-w64-ucrt-x86_64-pkgconf
mingw-w64-ucrt-x86_64-extra-cmake-modules
mingw-w64-ucrt-x86_64-kwidgetsaddons-qt5
mingw-w64-ucrt-x86_64-kcoreaddons-qt5
mingw-w64-ucrt-x86_64-nsis
mingw-w64-ucrt-x86_64-ccache
mingw-w64-ucrt-x86_64-7zip
git
- name: Force Qt5 (remove Qt6 interference)
shell: msys2 {0}
run: |
rm -rf /ucrt64/lib/cmake/Qt6 || true
pacman -R --noconfirm mingw-w64-ucrt-x86_64-qt6-tools 2>/dev/null || true
- name: Cache ccache
uses: actions/cache@v4
with:
path: C:\Users\runneradmin\AppData\Local\ccache
key: ccache-vs2026-${{ runner.os }}-${{ github.sha }}
restore-keys: |
ccache-vs2026-${{ runner.os }}-
- name: Configure (CMake)
shell: msys2 {0}
run: |
set -euo pipefail
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DQt5_DIR=/ucrt64/lib/cmake/Qt5 \
-DQT_VERSION_MAJOR=5 \
-DCMAKE_DISABLE_FIND_PACKAGE_Qt6=ON \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_FLAGS="-DQET_EXPORT_PROJECT_DB" \
-DBUILD_TESTING=OFF \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_C_COMPILER_LAUNCHER=/ucrt64/bin/ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=/ucrt64/bin/ccache \
-DSQLite3_INCLUDE_DIR=/ucrt64/include \
-DSQLite3_LIBRARY=/ucrt64/lib/libsqlite3.dll.a \
- name: Build
shell: msys2 {0}
run: |
set -euo pipefail
cmake --build build --parallel $(nproc)
- name: Verify executable
shell: msys2 {0}
run: |
set -euo pipefail
EXE=$(find build -name "qelectrotech.exe" | head -1)
if [ -z "$EXE" ]; then
echo "ERROR: qelectrotech.exe introuvable après le build"
exit 1
fi
SIZE=$(stat -c%s "$EXE")
echo "Executable trouvé : $EXE ($SIZE octets)"
if [ "$SIZE" -lt 100000 ]; then
echo "ERROR: exe trop petit ($SIZE octets), build probablement incomplet"
exit 1
fi
echo "BUILD VS2026 : OK ✓"
- name: Summary
if: always()
shell: msys2 {0}
run: |
echo "=== Résumé de compatibilité VS2026 ==="
gcc --version
cmake --version
ninja --version
echo "Image runner : windows-2025-vs2026"
echo "Date du test : $(date -u)"
+369 -25
View File
@@ -10,11 +10,14 @@ concurrency:
cancel-in-progress: true
jobs:
# =============================================================================
# Job 1: Qt5 build (stable track)
# =============================================================================
build-windows:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
submodules: recursive
fetch-depth: 0
@@ -35,6 +38,7 @@ jobs:
mingw-w64-ucrt-x86_64-qt5-svg
mingw-w64-ucrt-x86_64-qt5-tools
mingw-w64-ucrt-x86_64-qt5-translations
mingw-w64-ucrt-x86_64-qt5-pdf
mingw-w64-ucrt-x86_64-sqlite3
mingw-w64-ucrt-x86_64-pkg-config
mingw-w64-ucrt-x86_64-kwidgetsaddons
@@ -44,7 +48,7 @@ jobs:
mingw-w64-ucrt-x86_64-angleproject
- name: Cache ccache
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: C:\Users\runneradmin\AppData\Local\ccache
key: ccache-windows-${{ github.ref_name }}-${{ github.sha }}
@@ -110,6 +114,7 @@ jobs:
-DQT_VERSION_MAJOR=5 \
-DCMAKE_DISABLE_FIND_PACKAGE_Qt6=ON \
-DBUILD_TESTING=OFF \
-DCMAKE_POLICY_DEFAULT_CMP0077=NEW \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_CXX_FLAGS="-DQET_EXPORT_PROJECT_DB" \
-DCMAKE_C_COMPILER_LAUNCHER=/ucrt64/bin/ccache \
@@ -306,7 +311,7 @@ jobs:
- name: Upload build logs on failure
if: failure()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: build-logs
path: |
@@ -334,54 +339,391 @@ jobs:
"zip_name=$zipName" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
- name: Upload portable (files/ without installer)
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: qelectrotech-${{ steps.qet_version.outputs.base_version }}+git${{ steps.qet_version.outputs.head }}-x86-win64-readytouse
path: dist/${{ steps.zip_portable.outputs.zip_name }}
retention-days: 14
- name: Upload NSIS installer
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: qelectrotech-windows-installer
path: dist/Installer_*.exe
retention-days: 14
- name: Upload portable (nom fixe pour le workflow MSI)
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: qelectrotech-windows-portable
path: nsis_root/files/
retention-days: 14
# =============================================================================
# Job 2: Qt6 build (EXPERIMENTAL track)
#
# Version label: the C++ source (sources/qetversion.cpp) intentionally stays
# Qt-agnostic — QT_VERSION-based detection inside the binary proved unreliable
# (see commit e1aa65f, reverting 608ca984). Here the CI job itself knows with
# certainty which Qt major version it configured (-DQT_VERSION_MAJOR=6), so it
# is safe to label the *package* "0.200.1" at this level, without touching
# QetVersion::currentVersion() or making the binary self-detect its Qt build.
# =============================================================================
build-windows-qt6:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
submodules: recursive
fetch-depth: 0
- name: Install MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
update: true
cache: true
install: >-
git
mingw-w64-ucrt-x86_64-ccache
mingw-w64-ucrt-x86_64-gcc
mingw-w64-ucrt-x86_64-cmake
mingw-w64-ucrt-x86_64-ninja
mingw-w64-ucrt-x86_64-qt6-base
mingw-w64-ucrt-x86_64-qt6-svg
mingw-w64-ucrt-x86_64-qt6-tools
mingw-w64-ucrt-x86_64-qt6-translations
mingw-w64-ucrt-x86_64-qt6-pdf
mingw-w64-ucrt-x86_64-sqlite3
mingw-w64-ucrt-x86_64-pkg-config
mingw-w64-ucrt-x86_64-nsis
mingw-w64-ucrt-x86_64-angleproject
- name: Cache ccache
uses: actions/cache@v5
with:
path: C:\Users\runneradmin\AppData\Local\ccache
key: ccache-windows-qt6-${{ github.ref_name }}-${{ github.sha }}
restore-keys: |
ccache-windows-qt6-${{ github.ref_name }}-
ccache-windows-qt6-
- name: Configure ccache
shell: msys2 {0}
run: |
/ucrt64/bin/ccache --set-config=max_size=500M
/ucrt64/bin/ccache --set-config=compression=true
/ucrt64/bin/ccache -z
echo "=== ccache config ==="
/ucrt64/bin/ccache -p
- name: Patch NSIS Welcome page — fix title font size
shell: msys2 {0}
run: |
set -euo pipefail
WELCOME_NSH=$(find /ucrt64 -path "*/Modern UI 2/Pages/Welcome.nsh" | head -1)
if [ -z "$WELCOME_NSH" ]; then
echo "WARNING: Welcome.nsh not found, skipping font patch"
else
echo "Patching: $WELCOME_NSH"
sed -i '/WelcomePage\.Title\.Font/s/"[0-9]\+" "700"/"10" "700"/' "$WELCOME_NSH"
grep 'WelcomePage.Title.Font' "$WELCOME_NSH"
echo " OK font size patched to 10"
fi
FINISH_NSH=$(find /ucrt64 -path "*/Modern UI 2/Pages/Finish.nsh" | head -1)
if [ -z "$FINISH_NSH" ]; then
echo "WARNING: Finish.nsh not found, skipping font patch"
else
echo "Patching: $FINISH_NSH"
sed -i '/FinishPage\.Title\.Font/s/"[0-9]\+" "700"/"10" "700"/' "$FINISH_NSH"
grep 'FinishPage.Title.Font' "$FINISH_NSH"
echo " OK font size patched to 10"
fi
- name: Build with cmake
shell: msys2 {0}
run: |
set -euo pipefail
cd "$GITHUB_WORKSPACE"
mkdir build && cd build
NPROC=$(nproc)
echo "Available CPUs: $NPROC"
cmake -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH=/ucrt64 \
-DQt6_DIR=/ucrt64/lib/cmake/Qt6 \
-DQT_VERSION_MAJOR=6 \
-DBUILD_WITH_KF5=OFF \
-DPACKAGE_TESTS=OFF \
-DCMAKE_POLICY_DEFAULT_CMP0077=NEW \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_CXX_FLAGS="-DQET_EXPORT_PROJECT_DB" \
-DCMAKE_C_COMPILER_LAUNCHER=/ucrt64/bin/ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=/ucrt64/bin/ccache \
-DSQLite3_INCLUDE_DIR=/ucrt64/include \
-DSQLite3_LIBRARY=/ucrt64/lib/libsqlite3.dll.a \
..
ninja -j"$NPROC"
- name: Show ccache stats
shell: msys2 {0}
run: |
echo "=== ccache statistics ==="
/ucrt64/bin/ccache -s
- name: Verify exe was built
shell: msys2 {0}
run: |
set -euo pipefail
EXE=$(find "$GITHUB_WORKSPACE/build" -maxdepth 3 -iname "qelectrotech.exe" | head -1)
if [ -z "$EXE" ]; then
echo "ERROR: no qelectrotech.exe found in build/"
find "$GITHUB_WORKSPACE/build" -maxdepth 3 -name "*.exe" || true
exit 1
fi
SIZE=$(stat -c%s "$EXE")
echo "Exe found: $EXE ($SIZE bytes)"
[ "$SIZE" -gt 100000 ] || { echo "ERROR: exe too small"; exit 1; }
- name: Deploy — copy exe + windeployqt + DLLs
shell: msys2 {0}
run: |
set -euo pipefail
NSIS_ROOT="$GITHUB_WORKSPACE/nsis_root"
FILES="$NSIS_ROOT/files"
BIN="$FILES/bin"
mkdir -p "$BIN"
EXE=$(find "$GITHUB_WORKSPACE/build" -maxdepth 3 -iname "qelectrotech.exe" | head -1)
echo "Copying exe: $EXE -> $BIN/QElectroTech.exe"
cp "$EXE" "$BIN/QElectroTech.exe"
cd "$BIN"
/ucrt64/bin/windeployqt6 \
--release \
--no-translations \
--no-compiler-runtime \
./QElectroTech.exe || true
echo "=== 3-pass transitive DLL scan ==="
set +e
for PASS in 1 2 3; do
echo "-- Pass $PASS --"
for bin_file in "$BIN"/*.dll "$BIN"/*.exe "$BIN"/sqldrivers/*.dll "$BIN"/platforms/*.dll "$BIN"/imageformats/*.dll; do
[ -f "$bin_file" ] || continue
while IFS= read -r line; do
dll_path=$(echo "$line" | awk '{print $3}')
[ -f "$dll_path" ] || continue
dll_name=$(basename "$dll_path")
dst="$BIN/$dll_name"
if [ ! -f "$dst" ]; then
cp "$dll_path" "$dst"
echo " Copied (pass $PASS): $dll_name"
fi
done < <(ldd "$bin_file" 2>/dev/null | grep -i '/ucrt64/bin/')
done
done
set -e
DLL_COUNT=$(find "$BIN" -name "*.dll" | wc -l)
echo "=== $DLL_COUNT DLLs present after scan ==="
ls -lh "$BIN/QElectroTech.exe" || { echo "ERROR: exe missing from bin/"; exit 1; }
[ "$DLL_COUNT" -gt 5 ] || { echo "ERROR: too few DLLs"; exit 1; }
cd "$GITHUB_WORKSPACE"
cp /ucrt64/bin/libgcc_s_seh-1.dll "$BIN/"
cp /ucrt64/bin/libstdc++-6.dll "$BIN/"
cp /ucrt64/bin/libwinpthread-1.dll "$BIN/"
SQLITE=$(find /ucrt64/bin -name "libsqlite3*.dll" | head -1)
if [ -n "$SQLITE" ]; then
cp "$SQLITE" "$BIN/"
echo "SQLite3 copied: $(basename $SQLITE)"
else
echo "WARNING: libsqlite3 not found in /ucrt64/bin/"
fi
cp "$GITHUB_WORKSPACE/build-aux/windows/QET64.nsi" "$NSIS_ROOT/"
cp "$GITHUB_WORKSPACE/build-aux/windows/lang_extra.nsh" "$NSIS_ROOT/"
cp "$GITHUB_WORKSPACE/build-aux/windows/lang_extra_fr.nsh" "$NSIS_ROOT/"
cp "$GITHUB_WORKSPACE/build-aux/windows/lang_extra_missing.nsh" "$NSIS_ROOT/"
cp -r "$GITHUB_WORKSPACE/build-aux/windows/nsis_base/." "$NSIS_ROOT/"
curl -fsSL \
"https://raw.githubusercontent.com/qelectrotech/qelectrotech-source-mirror/refs/heads/master/misc/Lancer%20QET_qt6.bat" \
-o "$FILES/Lancer QET_qt6.bat"
cp -r "$GITHUB_WORKSPACE/elements" "$FILES/elements" || true
cp -r "$GITHUB_WORKSPACE/titleblocks" "$FILES/titleblocks" || true
cp -r "$GITHUB_WORKSPACE/examples" "$FILES/examples" || true
cp -r "$GITHUB_WORKSPACE/fonts" "$FILES/fonts" || true
cp -r "$GITHUB_WORKSPACE/lang" "$FILES/lang" || true
find "$GITHUB_WORKSPACE/build" -name "*.qm" -exec cp {} "$FILES/lang/" \; 2>/dev/null || true
echo "=== .qm files in files/lang/ ==="
ls "$FILES/lang/"*.qm 2>/dev/null | wc -l || echo "0 .qm files"
for f in LICENSE ChangeLog CREDIT README ELEMENTS.LICENSE; do
cp "$GITHUB_WORKSPACE/$f" "$FILES/$f" 2>/dev/null || true
done
echo "=== Verification of key files in files/ ==="
for f in LICENSE ChangeLog CREDIT README ELEMENTS.LICENSE \
qet_uninstall_file_associations.reg register_filetypes.bat "Lancer QET_qt6.bat"; do
[ -f "$FILES/$f" ] \
&& echo " OK : $f" \
|| echo " MISSING: $f"
done
for d in ico elements lang titleblocks fonts examples bin; do
[ -d "$FILES/$d" ] \
&& echo " OK : $d/" \
|| echo " MISSING: $d/"
done
- name: Extract version for installer name (Qt6 — labelled 0.200.1)
shell: msys2 {0}
id: qet_version
run: |
set -euo pipefail
GITCOMMIT=$(git -C "$GITHUB_WORKSPACE" rev-parse --short HEAD)
A=$(git -C "$GITHUB_WORKSPACE" rev-list HEAD --count)
HEAD=$(( A + 473 ))
# Deliberately NOT parsed from sources/qetversion.cpp: the CI job
# already knows for certain it configured Qt6 (-DQT_VERSION_MAJOR=6),
# so the "0.200.1" experimental-track label is set here explicitly
# rather than relying on in-binary Qt version detection.
VERSION="0.200.1"
FULL_VERSION="${VERSION}-qt6-r${HEAD}-${GITCOMMIT}_x86_64-win64"
BASE_VERSION="${VERSION}-qt6"
echo "version=$FULL_VERSION" >> "$GITHUB_OUTPUT"
echo "base_version=$BASE_VERSION" >> "$GITHUB_OUTPUT"
echo "gitcommit=$GITCOMMIT" >> "$GITHUB_OUTPUT"
echo "head=$HEAD" >> "$GITHUB_OUTPUT"
echo "VERSION : $VERSION"
echo "GITCOMMIT : $GITCOMMIT"
echo "HEAD (rev) : $HEAD"
echo "FULL : $FULL_VERSION"
- name: Patch QET64.nsi — version + exe name + absolute paths
shell: msys2 {0}
run: |
set -euo pipefail
VERSION="${{ steps.qet_version.outputs.version }}"
NSI="$GITHUB_WORKSPACE/nsis_root/QET64.nsi"
FILES_WIN=$(cygpath -w "$GITHUB_WORKSPACE/nsis_root/files")
SCRIPT="$GITHUB_WORKSPACE/build-aux/windows/patch_nsi.py"
python3 "$SCRIPT" "$NSI" "$VERSION" "$FILES_WIN"
echo "=== Verification ==="
grep 'SOFT_VERSION' "$NSI" | head -1
grep -m2 'nsis_root' "$NSI" | head -2
echo "=== Contents of nsis_root/files/ ==="
ls "$GITHUB_WORKSPACE/nsis_root/files/"
- name: Build NSIS installer
shell: msys2 {0}
run: |
set -euo pipefail
NSIS_ROOT="$GITHUB_WORKSPACE/nsis_root"
cd "$NSIS_ROOT"
echo "=== CWD : $(pwd) ==="
MSYS2_ARG_CONV_EXCL="*" makensis /V4 QET64.nsi
RC=$?
echo "=== Contents of nsis_root after makensis ==="
ls "$NSIS_ROOT/"
[ $RC -eq 0 ] || { echo "ERROR: makensis failed (exit $RC)"; exit 1; }
- name: Move installer to dist/
shell: msys2 {0}
run: |
set -euo pipefail
mkdir -p "$GITHUB_WORKSPACE/dist"
INSTALLER=$(find "$GITHUB_WORKSPACE/nsis_root" -maxdepth 1 -iname "installer_*.exe" | head -1)
if [ -z "$INSTALLER" ]; then
echo "ERROR: no installer .exe found in nsis_root/"
ls "$GITHUB_WORKSPACE/nsis_root/"
exit 1
fi
echo "Moving: $INSTALLER -> dist/"
mv "$INSTALLER" "$GITHUB_WORKSPACE/dist/"
- name: Upload build logs on failure
if: failure()
uses: actions/upload-artifact@v7
with:
name: build-logs-qt6
path: |
build/CMakeFiles/*.log
nsis_root/files/bin/
if-no-files-found: warn
- name: Zip portable (readytouse)
id: zip_portable
shell: pwsh
run: |
$version = "${{ steps.qet_version.outputs.base_version }}"
$head = "${{ steps.qet_version.outputs.head }}"
$zipName = "qelectrotech-${version}+git${head}-x86-win64-readytouse.zip"
$src = "$env:GITHUB_WORKSPACE\nsis_root\files"
$dst = "$env:GITHUB_WORKSPACE\dist\$zipName"
$7z = "C:\Program Files\7-Zip\7z.exe"
New-Item -ItemType Directory -Force -Path "$env:GITHUB_WORKSPACE\dist" | Out-Null
& $7z a -tzip -mx=5 -mmt=on $dst "$src\*"
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
$sizeMB = [math]::Round((Get-Item $dst).Length / 1MB, 1)
Write-Output "ZIP created: $zipName ($sizeMB MB)"
"zip_name=$zipName" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
- name: Upload portable (files/ without installer)
uses: actions/upload-artifact@v7
with:
name: qelectrotech-${{ steps.qet_version.outputs.base_version }}+git${{ steps.qet_version.outputs.head }}-x86-win64-readytouse
path: dist/${{ steps.zip_portable.outputs.zip_name }}
retention-days: 14
- name: Upload NSIS installer
uses: actions/upload-artifact@v7
with:
name: qelectrotech-windows-installer-qt6
path: dist/Installer_*.exe
retention-days: 14
- name: Upload portable (nom fixe pour le workflow MSI)
uses: actions/upload-artifact@v7
with:
name: qelectrotech-windows-portable-qt6
path: nsis_root/files/
retention-days: 14
# ---------------------------------------------------------------------------
# Job 2 : Publie une release nightly + page GitHub Pages
# Job 3 : Publie les assets nightly (exe + zip, Qt5 et Qt6) sur la release
# Ne tourne que sur push master (pas sur les PRs)
# ---------------------------------------------------------------------------
deploy-pages:
needs: build-windows
publish-nightly-assets:
needs: [build-windows, build-windows-qt6]
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
permissions:
contents: write
steps:
- name: Checkout master (for build-aux scripts)
uses: actions/checkout@v4
- name: Download installer artifacts (Qt5 + Qt6)
uses: actions/download-artifact@v8
with:
ref: master
path: source
sparse-checkout: build-aux/generate-page.py
sparse-checkout-cone-mode: false
- name: Download installer artifact
uses: actions/download-artifact@v4
with:
name: qelectrotech-windows-installer
pattern: qelectrotech-windows-installer*
path: downloaded/installer/
merge-multiple: true
- name: Download portable artifact
uses: actions/download-artifact@v4
- name: Download portable artifacts (Qt5 + Qt6)
uses: actions/download-artifact@v8
with:
pattern: qelectrotech-*-readytouse
path: downloaded/portable/
@@ -392,7 +734,6 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
run: |
# Fetch existing .exe and .zip asset names and delete them
gh release view nightly --repo "$REPO" --json assets \
--jq '.assets[] | select(.name | test("\\.(exe|zip)$")) | .name' \
| while read -r name; do
@@ -402,7 +743,7 @@ jobs:
echo "Old .exe and .zip assets deleted."
- name: Update nightly release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
with:
tag_name: nightly
name: "Nightly Build – Windows"
@@ -417,6 +758,9 @@ jobs:
> ⚠️ This is a development version; it introduces new features you want, but may cause bugs that have not yet been identified yet.
> For stable releases, see the [Releases page](https://github.com/${{ github.repository }}/releases).
> 🧪 **Qt6 builds are experimental.** Files tagged `-qt6-` are built against Qt6 and are not yet
> as tested as the Qt5 track. Expect rough edges; report issues clearly labelled "Qt6".
prerelease: true
make_latest: false
files: |
@@ -425,4 +769,4 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
# GitHub Pages is generated and deployed by windows-msi.yml
# after the MSI upload, so that all 3 URLs (exe, zip, msi) are known.
# after the MSI upload, so that all URLs (exe/zip/msi, Qt5+Qt6) are known.
+196 -128
View File
@@ -16,80 +16,126 @@ on:
jobs:
build-msi:
name: Build MSI with WiX v7
name: Build MSI with WiX v7 (${{ matrix.flavor }})
runs-on: windows-latest
# Only runs if Windows Build succeeded (or triggered manually)
if: >
github.event_name == 'workflow_dispatch' ||
github.event.workflow_run.conclusion == 'success'
strategy:
fail-fast: false
matrix:
include:
- flavor: qt5
portable_artifact: qelectrotech-windows-portable
version_source: qetversion # parsed from sources/qetversion.cpp
label_suffix: ""
experimental: false
- flavor: qt6
portable_artifact: qelectrotech-windows-portable-qt6
version_source: hardcoded # see note in "Extract version" step
label_suffix: "-qt6-EXPERIMENTAL"
experimental: true
permissions:
contents: write
pages: write
id-token: write
id-token: write # Required by SignPath
outputs:
qt5_msi: ${{ steps.export.outputs.msi_name_qt5 }}
qt6_msi: ${{ steps.export.outputs.msi_name_qt6 }}
steps:
# ----------------------------------------------------------------
# 1. Checkout (to retrieve QElectroTech.wxs and sources)
# ----------------------------------------------------------------
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
fetch-depth: 0
# ----------------------------------------------------------------
# 2. Download the portable artifact from the main build
# 2. Download the portable artifact for this flavor
# ----------------------------------------------------------------
- name: Download portable artifact
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: qelectrotech-windows-portable
name: ${{ matrix.portable_artifact }}
path: artifact\files
# workflow_run => use the triggering run's ID
# workflow_dispatch => use input run_id if provided, otherwise current run
run-id: ${{ github.event.workflow_run.id || github.event.inputs.run_id || github.run_id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
# ----------------------------------------------------------------
# 3. Extract version from sources
# 3. Extract version
# Qt5: parsed from sources/qetversion.cpp (single source of truth
# for the software's own reported version).
# Qt6: hardcoded "0.200.1" here — deliberately NOT parsed from the
# binary/source, since Qt-version self-detection inside the
# compiled code proved unreliable (see commit e1aa65f). The CI
# matrix entry already knows for certain which flavor it is
# packaging, so the experimental-track label is set explicitly
# at the packaging level instead.
# ----------------------------------------------------------------
- name: Extract version
id: version
shell: pwsh
run: |
$src = Get-Content "sources\qetversion.cpp" -Raw -ErrorAction SilentlyContinue
if ($src -match 'return QVersionNumber\{([^}]+)\}') {
$ver = $Matches[1] -replace '\s','' -replace ',','.'
if ("${{ matrix.version_source }}" -eq "hardcoded") {
$ver = "0.200.1"
} else {
$cmake = Get-Content "CMakeLists.txt" -Raw
if ($cmake -match 'project\s*\([^)]*VERSION\s+([\d]+\.[\d]+\.[\d]+)') {
$ver = $Matches[1]
$src = Get-Content "sources\qetversion.cpp" -Raw -ErrorAction SilentlyContinue
if ($src -match 'return QVersionNumber\{([^}]+)\}') {
$ver = $Matches[1] -replace '\s','' -replace ',','.'
} else {
$ver = "0.0.0"
# Fallback: CMakeLists.txt
$cmake = Get-Content "CMakeLists.txt" -Raw
if ($cmake -match 'project\s*\([^)]*VERSION\s+([\d]+\.[\d]+\.[\d]+)') {
$ver = $Matches[1]
} else {
$ver = "0.0.0"
}
}
}
$verMsi = "$ver.0"
# Short SHA for the display version
$sha = git rev-parse --short HEAD 2>$null
if (-not $sha) { $sha = "unknown" }
# Cumulative revision number (same calculation as windows-build.yml)
$count = git rev-list HEAD --count 2>$null
$rev = [int]$count + 473
$verDisplay = "${ver}-r${rev}-${sha}_x86_64-win64"
# Generate a unique ProductCode GUID from the commit SHA
# This ensures MajorUpgrade always triggers, even for same-version builds
$fullSha = git rev-parse HEAD 2>$null
if (-not $fullSha) { $fullSha = [System.Guid]::NewGuid().ToString() }
$bytes = [System.Text.Encoding]::UTF8.GetBytes($fullSha)
$md5 = [System.Security.Cryptography.MD5]::Create().ComputeHash($bytes)
$guidBytes = [byte[]]$md5[0..15]
$productGuid = [System.Guid]::new($guidBytes).ToString().ToUpper()
# MSI Version only compares Major.Minor.Build (the 4th field is
# ignored by Windows Installer for upgrade detection), so we
# inject rev into Build to force a real increase between
# nightlies and trigger MajorUpgrade's automatic uninstall.
$verParts = $ver -split '\.'
$verMsi = "$($verParts[0]).$($verParts[1]).$($rev % 65535)"
$flavorTag = "${{ matrix.label_suffix }}"
$verDisplay = "${ver}${flavorTag}-r${rev}-${sha}_x86_64-win64"
echo "VERSION_MSI=$verMsi" >> $env:GITHUB_OUTPUT
echo "VERSION_DISPLAY=$verDisplay" >> $env:GITHUB_OUTPUT
echo "PRODUCT_GUID=$productGuid" >> $env:GITHUB_OUTPUT
Write-Host "Version MSI : $verMsi"
Write-Host "Version display : $verDisplay"
Write-Host "Product GUID : $productGuid"
# Qt platform argument: only Qt5 needs the QTBUG-83161 font-rendering
# workaround (GDI backend). Qt6 uses DirectWrite by default and does
# not need it. Computed once here so both the bundled "Lancer QET.bat"
# and the MSI shortcuts (wix build -d QtPlatformArgs=...) stay in sync.
if ("${{ matrix.flavor }}" -eq "qt5") {
$qtArgs = "-platform windows:fontengine=freetype"
} else {
$qtArgs = ""
}
echo "QT_ARGS=$qtArgs" >> $env:GITHUB_OUTPUT
Write-Host "Qt platform args: '$qtArgs'"
# ----------------------------------------------------------------
# 4. Install WiX v7, accept EULA and install WixUI extension
@@ -104,7 +150,7 @@ jobs:
wix eula accept wix7
wix extension add WixToolset.UI.wixext/7.0.0
wix extension add WixToolset.Util.wixext/7.0.0
Write-Host "WiX v7 installed, EULA accepted, UI extension added."
Write-Host "WiX v7 installed, EULA accepted, UI + Util extensions added."
# ----------------------------------------------------------------
# 5. Check that the WXS file exists in the repository
@@ -125,10 +171,6 @@ jobs:
- name: Check artifact structure
shell: pwsh
run: |
Write-Host "=== Contents of artifact\files (2 levels) ==="
Get-ChildItem -Path "artifact\files" -Depth 2 |
Select-Object FullName | Format-Table -AutoSize
$exe = Get-ChildItem -Path "artifact\files" -Filter "qelectrotech.exe" -Recurse | Select-Object -First 1
if (-not $exe) {
$exe = Get-ChildItem -Path "artifact\files" -Filter "QElectroTech.exe" -Recurse | Select-Object -First 1
@@ -138,8 +180,8 @@ jobs:
exit 1
}
Write-Host "Executable: $($exe.FullName) ($([math]::Round($exe.Length/1MB,1)) MB)"
$binDir = $exe.Directory.FullName
$filesDir = Split-Path $binDir -Parent
$binDir = $exe.Directory.FullName
$filesDir = Split-Path $binDir -Parent
echo "FILES_DIR=$filesDir" >> $env:GITHUB_ENV
Write-Host "FILES_DIR: $filesDir"
@@ -171,28 +213,25 @@ jobs:
[void]$rtf.AppendLine('}')
[System.IO.File]::WriteAllText($licRtf, $rtf.ToString(), [System.Text.Encoding]::ASCII)
echo "LICENSE_RTF=$licRtf" >> $env:GITHUB_ENV
Write-Host "License.rtf generated: $licRtf ($([math]::Round((Get-Item $licRtf).Length/1KB,1)) KB)"
Write-Host "License.rtf generated: $licRtf"
# ----------------------------------------------------------------
# 8. Remove Lancer QET.bat from the artifact
# The MSI does not use the .bat: shortcuts point directly to
# qelectrotech.exe, and elements\ is set read-only via a
# CustomAction in QElectroTech.wxs.
# The .bat is kept as-is in the ZIP portable build.
# 8. Replace Lancer QET.bat with the MSI-specific version
# ----------------------------------------------------------------
- name: Remove Lancer QET.bat from artifact
- name: Replace Lancer QET.bat for MSI
shell: pwsh
run: |
$bat = "$env:FILES_DIR\Lancer QET.bat"
if (Test-Path $bat) {
Remove-Item $bat -Force
Write-Host "Lancer QET.bat removed from artifact (MSI uses direct exe shortcut)."
} else {
Write-Host "Lancer QET.bat not found in artifact (already absent)."
}
$qtArgs = "${{ steps.version.outputs.QT_ARGS }}"
$bat = "$env:FILES_DIR\Lancer QET.bat"
$content = "@echo off`r`nstart `"`" `"%~dp0bin\qelectrotech.exe`" --common-elements-dir=`"%~dp0elements/`" --common-tbt-dir=`"%~dp0titleblocks/`" --lang-dir=`"%~dp0lang/`" $qtArgs`r`n"
[System.IO.File]::WriteAllText($bat, $content, [System.Text.Encoding]::ASCII)
Write-Host "Lancer QET.bat replaced for MSI installation (qtArgs: '$qtArgs')."
# ----------------------------------------------------------------
# 9. Build the MSI
# 9. Build the MSI (unsigned)
# Qt6 (experimental) uses a distinct ProductCode seed so it never
# collides with / upgrades over the Qt5 MSI — they must be able to
# coexist as clearly separate installs.
# ----------------------------------------------------------------
- name: Build MSI
shell: pwsh
@@ -204,24 +243,30 @@ jobs:
$wxs = "build-aux\windows\QElectroTech.wxs"
$outputName = "QElectroTech-${verDisplay}.msi"
$seed = "qelectrotech-msi-${{ matrix.flavor }}-$version"
$sha1 = [System.Security.Cryptography.SHA1]::Create()
$hash = $sha1.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($seed))
$hash[6] = ($hash[6] -band 0x0F) -bor 0x50
$hash[8] = ($hash[8] -band 0x3F) -bor 0x80
$productCode = "{$([System.Guid]::new([byte[]]$hash[0..15]).ToString().ToUpper())}"
New-Item -ItemType Directory -Force -Path "dist" | Out-Null
Write-Host "=== wix build ==="
Write-Host " WXS : $wxs"
Write-Host " Version : $version"
Write-Host " FilesDir : $filesDir"
Write-Host " LicenseRtf : $licRtf"
Write-Host " Output : dist\$outputName"
Write-Host "=== wix build (${{ matrix.flavor }}) ==="
Write-Host " Version : $version"
Write-Host " ProductCode : $productCode"
Write-Host " Output : dist\$outputName"
$productGuid = "${{ steps.version.outputs.PRODUCT_GUID }}"
$qtArgs = "${{ steps.version.outputs.QT_ARGS }}"
wix build $wxs `
-arch x64 `
-d "Version=$version" `
-d "ProductVersion=$verDisplay" `
-d "ProductCode=$productGuid" `
-d "ProductCode=$productCode" `
-d "FilesDir=$filesDir" `
-d "LicenseRtf=$licRtf" `
-d QtPlatformArgs="$qtArgs" `
-ext WixToolset.UI.wixext `
-ext WixToolset.Util.wixext `
-o "dist\$outputName"
@@ -230,68 +275,61 @@ jobs:
Write-Error "MSI not generated: dist\$outputName"
exit 1
}
$size = [math]::Round((Get-Item "dist\$outputName").Length / 1MB, 1)
Write-Host "MSI generated: dist\$outputName ($size MB) ✓"
Write-Host "MSI generated: dist\$outputName ($size MB) OK"
echo "MSI_NAME=$outputName" >> $env:GITHUB_ENV
# ----------------------------------------------------------------
# 10. Sign the MSI with SignPath
# ----------------------------------------------------------------
- name: Install SignPath PowerShell module
shell: pwsh
run: |
Install-Module -Name SignPath -Force -Scope CurrentUser
- name: Sign MSI with SignPath
shell: pwsh
run: |
$msi = Get-ChildItem "$env:GITHUB_WORKSPACE\dist\*.msi" | Select-Object -First 1
if (-not $msi) {
Write-Error "No .msi found in dist/"
exit 1
}
Write-Host "Signing: $($msi.FullName)"
Submit-SigningRequest `
-InputArtifactPath $msi.FullName `
-ApiToken "${{ secrets.SIGNPATH_API_TOKEN }}" `
-OrganizationId "${{ secrets.SIGNPATH_ORGANIZATION_ID }}" `
-ProjectSlug "MSI" `
-SigningPolicySlug "test-signing" `
-OutputArtifactPath $msi.FullName `
-Force `
-WaitForCompletion
Write-Host "Signing complete: $($msi.Name)"
# ----------------------------------------------------------------
# 11. Upload the MSI artifact
# ----------------------------------------------------------------
- name: Upload MSI artifact
uses: actions/upload-artifact@v4
- name: Upload unsigned MSI artifact (pre-signing)
id: upload_unsigned
uses: actions/upload-artifact@v7
with:
name: qelectrotech-windows-msi
name: qelectrotech-windows-msi-unsigned-${{ matrix.flavor }}
path: dist\*.msi
retention-days: 1
if-no-files-found: error
# Qt6 stays on the unsigned/experimental track (no signing request for
# this flavor), and forks never have the SignPath secrets, so guard on
# both: only qt5, and only in the upstream repo.
# (cf. DieterMayerOSS:fix/msi-signing-fork-guard, d3f60c88)
- name: Sign MSI via SignPath
if: matrix.flavor == 'qt5' && github.repository == 'qelectrotech/qelectrotech-source-mirror'
uses: signpath/github-action-submit-signing-request@v2
with:
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }}
project-slug: 'qelectrotech-source-mirror'
signing-policy-slug: 'test-signing'
artifact-configuration-slug: 'MSI'
github-artifact-id: ${{ steps.upload_unsigned.outputs.artifact-id }}
wait-for-completion: true
output-artifact-directory: 'dist\'
- name: Upload signed MSI artifact
uses: actions/upload-artifact@v7
with:
name: qelectrotech-windows-msi-${{ matrix.flavor }}
path: dist\*.msi
retention-days: 14
if-no-files-found: error
# ----------------------------------------------------------------
# 11. Delete old .msi asset then upload new MSI to nightly release
# ----------------------------------------------------------------
- name: Delete old nightly .msi asset
- name: Delete old nightly .msi asset for this flavor
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
run: |
gh release view nightly --repo "$REPO" --json assets \
--jq '.assets[] | select(.name | test("\\.msi$")) | .name' \
| while read -r name; do
echo "Deleting old asset: $name"
gh release delete-asset nightly "$name" --repo "$REPO" --yes
done
echo "Old .msi assets deleted."
shell: bash
$pattern = if ("${{ matrix.flavor }}" -eq "qt6") { "-qt6-EXPERIMENTAL.*\\.msi$" } else { "\\.msi$" }
$names = gh release view nightly --repo $env:REPO --json assets --jq ".assets[] | select(.name | test(`"$pattern`")) | .name"
foreach ($name in ($names -split "`n" | Where-Object { $_ })) {
if ("${{ matrix.flavor }}" -eq "qt5" -and $name -match "-qt6-EXPERIMENTAL") { continue }
Write-Host "Deleting old asset: $name"
gh release delete-asset nightly $name --repo $env:REPO --yes
}
shell: pwsh
- name: Upload MSI to nightly release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
with:
tag_name: nightly
files: dist/*.msi
@@ -299,29 +337,41 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# ----------------------------------------------------------------
# 12. Summary
# ----------------------------------------------------------------
- name: Export MSI name for page generation
id: export
shell: pwsh
run: |
$name = "$env:MSI_NAME"
if ("${{ matrix.flavor }}" -eq "qt6") {
echo "msi_name_qt6=$name" >> $env:GITHUB_OUTPUT
} else {
echo "msi_name_qt5=$name" >> $env:GITHUB_OUTPUT
}
- name: Summary
if: always()
shell: pwsh
run: |
Write-Host "=== MSI build summary ==="
Write-Host "Version : ${{ steps.version.outputs.VERSION_DISPLAY }}"
Write-Host "WiX : v7.0.0"
Write-Host "Runner image : ${{ runner.os }} / ${{ runner.arch }}"
if (Test-Path "dist\$env:MSI_NAME") {
$size = [math]::Round((Get-Item "dist\$env:MSI_NAME").Length / 1MB, 1)
Write-Host "MSI : $env:MSI_NAME ($size MB) ✓"
} else {
Write-Host "MSI : FAILED ✗"
}
Write-Host "=== MSI build summary (${{ matrix.flavor }}) ==="
Write-Host "Version : ${{ steps.version.outputs.VERSION_DISPLAY }}"
Write-Host "Experimental : ${{ matrix.experimental }}"
# ----------------------------------------------------------------
# 13. Generate and deploy the GitHub Pages download page
# ----------------------------------------------------------------
- name: Checkout (for generate-page.py)
uses: actions/checkout@v4
# ---------------------------------------------------------------------------
# Job 2 : Génère et déploie la page GitHub Pages une fois les DEUX MSI
# (Qt5 + Qt6) publiés, pour que toutes les URLs soient connues.
# ---------------------------------------------------------------------------
deploy-pages:
needs: build-msi
runs-on: ubuntu-latest
if: always() && needs.build-msi.result == 'success'
permissions:
contents: write
pages: write
id-token: write
steps:
- name: Checkout master (for generate-page.py)
uses: actions/checkout@v7
with:
ref: master
path: source
@@ -335,22 +385,40 @@ jobs:
run: |
set -euo pipefail
REPO="${{ github.repository }}"
ASSETS=$(gh release view nightly --repo "$REPO" --json assets --jq '.assets[].name')
EXE_NAME=$(echo "$ASSETS" | grep '\.exe$' | head -1)
ZIP_NAME=$(echo "$ASSETS" | grep '\.zip$' | head -1)
MSI_NAME=$(echo "$ASSETS" | grep '\.msi$' | head -1 || echo "")
EXE_NAME=$(echo "$ASSETS" | grep -v 'qt6' | grep '\.exe$' | head -1)
ZIP_NAME=$(echo "$ASSETS" | grep -v 'qt6' | grep '\.zip$' | head -1)
MSI_NAME=$(echo "$ASSETS" | grep -v 'qt6' | grep '\.msi$' | head -1 || echo "")
EXE_QT6_NAME=$(echo "$ASSETS" | grep 'qt6' | grep '\.exe$' | head -1 || echo "")
ZIP_QT6_NAME=$(echo "$ASSETS" | grep 'qt6' | grep '\.zip$' | head -1 || echo "")
MSI_QT6_NAME=$(echo "$ASSETS" | grep 'qt6' | grep '\.msi$' | head -1 || echo "")
BASE="https://github.com/$REPO/releases/download/nightly"
INSTALLER_URL="$BASE/$EXE_NAME"
PORTABLE_URL="$BASE/$ZIP_NAME"
MSI_URL=""
[ -n "$MSI_NAME" ] && MSI_URL="$BASE/$MSI_NAME"
INSTALLER_QT6_URL=""
PORTABLE_QT6_URL=""
MSI_QT6_URL=""
[ -n "$EXE_QT6_NAME" ] && INSTALLER_QT6_URL="$BASE/$EXE_QT6_NAME"
[ -n "$ZIP_QT6_NAME" ] && PORTABLE_QT6_URL="$BASE/$ZIP_QT6_NAME"
[ -n "$MSI_QT6_NAME" ] && MSI_QT6_URL="$BASE/$MSI_QT6_NAME"
SHA="${{ github.event.workflow_run.head_sha || github.sha }}"
SHORT="${SHA:0:7}"
DATE=$(date -u '+%Y-%m-%d %H:%M UTC')
RUN_URL="https://github.com/$REPO/actions/runs/${{ github.run_id }}"
RUN_NUMBER="${{ github.run_number }}"
export DATE SHORT REPO SHA RUN_URL RUN_NUMBER
export INSTALLER_URL PORTABLE_URL MSI_URL
export INSTALLER_QT6_URL PORTABLE_QT6_URL MSI_QT6_URL
python3 source/build-aux/generate-page.py
- name: Add .nojekyll
@@ -358,7 +426,7 @@ jobs:
run: touch gh-pages/.nojekyll
- name: Upload GitHub Pages artifact
uses: actions/upload-pages-artifact@v3
uses: actions/upload-pages-artifact@v5
with:
path: gh-pages/
+71 -16
View File
@@ -22,12 +22,32 @@ project(qelectrotech
VERSION 0.100.1
DESCRIPTION "QET is a CAD/CAE editor focusing on schematics drawing features."
HOMEPAGE_URL "https://qelectrotech.org/"
LANGUAGES CXX)
LANGUAGES C CXX)
include(cmake/copyright_message.cmake)
set(QET_DIR ${PROJECT_SOURCE_DIR})
# QT_VERSION_MAJOR is chosen explicitly by whoever configures the build,
# via -DQT_VERSION_MAJOR=5 or -DQT_VERSION_MAJOR=6.
# Default to Qt5 (current stable) when not specified, so existing
# CI/scripts that don't pass this option keep working unchanged.
# This must happen BEFORE add_subdirectory(tests) and the fetch_*.cmake
# includes below, so every subdirectory and every FetchContent dependency
# sees a consistent, already-defined value.
if(NOT DEFINED QT_VERSION_MAJOR)
set(QT_VERSION_MAJOR 5)
endif()
# Some third-party CMake projects we pull in via FetchContent (e.g.
# SingleApplication) don't know about QET_VERSION_MAJOR: they follow Qt's
# own "QT_DEFAULT_MAJOR_VERSION" convention instead, and silently default
# to Qt5 if it isn't set. Propagate our choice so they stay in sync,
# otherwise they can end up linked against a different Qt major version
# than the rest of QET, which breaks AUTOMOC with an
# INTERFACE_QT_MAJOR_VERSION mismatch at generate time.
set(QT_DEFAULT_MAJOR_VERSION ${QT_VERSION_MAJOR} CACHE STRING "Qt version to use (5 or 6)" FORCE)
# Add sub directories
option(PACKAGE_TESTS "Build the tests" ON)
if(PACKAGE_TESTS)
@@ -52,28 +72,53 @@ set(CMAKE_AUTOUIC ON)
SET(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(
QT
NAMES
Qt5
COMPONENTS
${QET_COMPONENTS}
REQUIRED
)
find_package(
Qt${QT_VERSION_MAJOR}
COMPONENTS
${QET_COMPONENTS}
REQUIRED)
# Qt6 only creates the Qt::GuiPrivate target (used for QPdfEngine::drawHyperlink)
# when the GuiPrivate component is explicitly requested. Qt5 has no such
# component package and creates the target implicitly with Gui, so only
# request it on Qt6 - requesting it on Qt5 fails the whole configure.
if(QT_VERSION_MAJOR GREATER_EQUAL 6)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS GuiPrivate)
endif()
find_package(SQLite3 REQUIRED)
# CMake < 4.3 only creates the SQLite::SQLite3 target (no SQLite3::SQLite3
# alias yet), while CMake >= 4.3's bundled FindSQLite3 creates SQLite3::SQLite3
# and deprecates the old name. Add the missing alias ourselves so we can use
# the modern target name everywhere regardless of the CMake version in use
# (this project must keep building on CMake versions below 4.3, e.g. on most
# current Linux distros).
if(NOT TARGET SQLite3::SQLite3 AND TARGET SQLite::SQLite3)
add_library(SQLite3::SQLite3 ALIAS SQLite::SQLite3)
endif()
set(CMAKE_AUTOUIC_SEARCH_PATHS ${QET_DIR}/sources/ui)
qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
# The default build only compiles the tracked .ts files to .qm (lrelease).
# Refreshing the .ts from the sources (lupdate) is a developer action behind
# the explicit "update_translations" target below: running lupdate on every
# build rewrote tracked files as a side effect, and under high parallelism
# lupdate rewriting a .ts while lrelease read the same file made the build
# fail with "Premature end of document".
set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION "${QET_DIR}/lang")
qt5_add_translation(QM_FILES ${TS_FILES})
if(QT_VERSION_MAJOR EQUAL 6)
qt6_add_translation(QM_FILES ${TS_FILES})
else()
qt5_add_translation(QM_FILES ${TS_FILES})
endif()
add_custom_target(update_translations
COMMAND $<TARGET_FILE:Qt${QT_VERSION_MAJOR}::lupdate> ${CMAKE_SOURCE_DIR}/sources -ts ${TS_FILES}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Updating .ts files from sources/ (lupdate) - developer target, run explicitly"
VERBATIM
)
# als laatse
include(cmake/define_definitions.cmake)
@@ -106,7 +151,7 @@ target_link_libraries(
PRIVATE
pugixml::pugixml
SingleApplication::SingleApplication
SQLite::SQLite3
SQLite3::SQLite3
${KF5_PRIVATE_LIBRARIES}
${QET_PRIVATE_LIBRARIES}
)
@@ -148,6 +193,14 @@ target_include_directories(
${QET_DIR}/sources/svg
)
if(NOT BUILD_WITH_KF5)
target_include_directories(
${PROJECT_NAME}
PRIVATE
${QET_DIR}/sources/ui/nokde
)
endif()
install(TARGETS ${PROJECT_NAME})
if (NOT MINGW)
@@ -162,8 +215,10 @@ if (NOT MINGW)
install(DIRECTORY examples DESTINATION share/qelectrotech)
install(DIRECTORY titleblocks DESTINATION share/qelectrotech)
install(FILES LICENSE ELEMENTS.LICENSE CREDIT README ChangeLog DESTINATION share/doc/qelectrotech)
install(FILES misc/org.qelectrotech.qelectrotech.desktop DESTINATION share/applications)
install(FILES misc/qelectrotech.xml DESTINATION share/mime/packages)
install(FILES misc/qelectrotech.appdata.xml DESTINATION ${QET_APPDATA_PATH})
if(UNIX AND NOT APPLE)
install(FILES misc/org.qelectrotech.qelectrotech.desktop DESTINATION share/applications)
install(FILES misc/qelectrotech.xml DESTINATION ${QET_MIME_PACKAGE_PATH})
install(FILES misc/qelectrotech.appdata.xml DESTINATION ${QET_APPDATA_PATH})
endif()
install(FILES ${QM_FILES} DESTINATION ${QET_LANG_PATH})
endif()
+805
View File
@@ -1,5 +1,810 @@
# QElectroTech - CHANGELOG
## Version 0.101 (Unreleased)
_Compiled from commit history since 0.100._
## Overview
Since 0.100, development has centered on a new headless command-line workflow, terminal-strip and cross-reference improvements, a wave of crash and stability fixes, and continued packaging/CI modernization (Windows MSI, macOS, Snap). Translation coverage was extended again, notably with new Korean support.
## Highlights / Key Features
- **Headless CLI export**
- New command-line export mode for PDF, PNG and SVG, letting QET projects be rendered without opening the GUI.
- Added `--export-bom`, `--export-nets`, `--export-links`, `--check-elements`, `--info`, `--set-titleblock` and `--resave` CLI options for scripted/batch workflows.
- The editor grid is now disabled in CLI-rendered output, and async crash-recovery backups are disabled in headless mode to avoid a segfault.
- **PDF export improvements**
- Cross-references are now clickable hyperlinks in exported PDFs, jumping directly to the linked element or terminal.
- Wiring list and wire-number list can now be exported to CSV, both from the GUI and the CLI.
- **Diagram duplication**
- Diagrams/folios can now be duplicated along with all their metadata and embedded elements.
- **BOM / Nomenclature**
- Specific elements can now be excluded from the Bill of Materials (Nomenclature).
- **Terminal & cross-reference (Xref) work**
- Continued iteration on a `max_slaves` limit for Master elements (added, tuned, briefly reverted, then re-implemented with proper save/load handling).
- New "potential isolation" option for terminals, and new No/Nc/Common contact types for switch (SW) terminals.
- Cross-reference items gained an option to hide terminal names, fixed terminal-name sorting for power contacts, and fixed a couple of SIGSEGV crashes (including one when dropping a power NC contact on the diagram).
- **Windows installer**
- MSI nightlies now inject the Git revision count into the MSI version's Build field, fixing the long-standing regression where `MajorUpgrade` never triggered because the version string never changed — nightlies had to be uninstalled by hand before.
- The old `Lancer QET.bat` wrapper was removed in favor of handling launch natively in `QElectroTech.wxs`.
- NSIS installer updated to the 3.x line, with a bundled Fonts directory and corrected language tables.
## Detailed Changes
### Editor & UX
- Element panel and context-menu/link-button logic refactored for clarity; `MasterElement::isFull` and related conditional checks simplified.
- Font-size spin boxes in the text editor now enforce a 4pt minimum, fixing a SIGSEGV that occurred when the value reached 0.
- Text position (`PartText`) now stays stable across save/reopen when the font changes.
- Element editor: no more spurious warning on save for front-view elements without terminals; "Save As" field is now correctly labelled as a file name rather than an element name.
### Bug Fixes
- Fixed a Unicode-path bug in pugixml on Windows: collection or element paths containing accented characters (é, ü, ñ, …) silently failed to load because the narrow-char API was used instead of the wide-char one.
- Fixed center-alignment not being restored when reloading a saved table configuration (config serialised `AlignHCenter`, but the loader compared against `AlignCenter`).
- Fixed a `TerminalData` memory leak in the `Terminal` destructor (confirmed via ASan across several call sites).
- Fixed several uninitialised-value bugs found with Valgrind, and a couple of thread-unsafe `QStandardPaths` calls in the data/config directory lookup.
- Fixed a crash when destroying a `QETProject` before its asynchronous backup had finished.
- Fixed regional system locale sometimes loading the wrong translation.
- Fixed dynamic element text shifting/jumping when duplicating diagrams, and a wiring-list filter/timing issue.
- Various smaller fixes: a first-click spurious element move right after selecting a tool, an -Wreorder compiler warning, and several translation corrections (German, French, Chinese).
### macOS
- Fixed the long-standing bug (open since 2022) where double-clicking a `.qet`, `.elmt` or `.titleblock` file launched the app without opening the file — the file-open event is now buffered during a cold launch, before `QETApp` exists, and routed correctly once the app is already running.
- Continued work on the black-screen-after-PDF-export regression on Apple Silicon, tied to the Metal compositor's async timing.
### Build, Packaging & CI
- Windows nightly build pipeline continued its migration to GitHub Actions; test builds for the VS2026 toolchain were run against the same pipeline.
- Snap package now stages `libxcb-cursor0`, fixing an xcb plugin load failure on Ubuntu 24.04.
- CMake install rules for Linux-only targets are now correctly guarded against macOS.
- `qet-tb-generator` in the Snap build is now pinned to a fixed upstream tag instead of floating.
### Internationalization & Translations
- Expanded Korean (ko) support: UI strings, comments, generic names, installer language strings, translator credits and a new Korean man page.
- Additional updates to German, French, Chinese (zh), and other translation files, including strings related to the new duplicate-diagram and macro features.
## Developer & Contributor Notes
- Terminal strip and element data model continued to evolve incrementally (multiple passes on `max_slaves` handling, access modifiers, and storage), reflecting ongoing refinement of the terminal editor introduced in 0.100.
- PDF link handling was factored out into a shared `pdf_links.{cpp,h}` helper, reused by both the interactive export and the new CLI export path.
## Upgrade / Migration Notes
- No project file format changes are expected to break compatibility with 0.100 projects.
- Users relying on Windows nightlies should note that upgrades will now uninstall the previous nightly automatically, instead of requiring a manual uninstall first.
## How to get help / report bugs
- Use the project issue tracker to report regressions or new bugs, with detailed reproduction steps and example `.qet` files where possible.
- Include the output of Help → About (application version and Git revision) when reporting build/packaging issues.
## Version 0.100
_Compiled from provided commit logs and contributor notes._
## Overview
This release (v0.100) collects a large set of new features, UI and editor improvements, element and symbol updates, build and packaging fixes, dependency upgrades, translations, and a broad set of bug fixes and stability improvements. It is intended as a stable, feature-rich stepping stone toward the next major workflows for symbol editing, terminal/strip handling and export improvements.
## Highlights / Key Features
- **Terminal Strip / Terminal Strip Editor**
- New TerminalStripItem type and related editor workflow added.
- Support for drawing and displaying terminal bridges and links in the editor.
- Full editor support (layout preview, save/load into .qet files) and undo support for terminal strip operations.
- **New Example Projects**
- Several new example projects included, notably photovoltaic (PV) examples to help users getting started with PV designs.
- **Improved Export / Print Handling**
- Export limits adjusted and better handling of QPainter/printing boundaries to avoid export artefacts and out-of-range errors.
- Export dialog updated to allow larger pixel limits where appropriate.
- **Element & Symbol Additions**
- New elements and symbols added (including vendor-specific elements and additional sensors/Arduino components).
- Improvements to element import & metadata handling.
- **Packaging & Multi-arch Support**
- Updated packaging scripts for AppImage, Flatpak, Snap and macOS deployment. Improved aarch64/arm64 support.
## Detailed Changes
### Editor & UX
- Better handling for **rotation, flip and mirror** operations in the element editor:
- Primitives and text rotation behavior improved.
- Finer rotation increments and predictable text orientation after flips/rotations.
- **Wiring and conductor behavior**:
- More robust creation and movement of wires and conductor bundles.
- Improved text attachment and positioning for wires and improved stability while editing complex conductor networks.
- **TerminalStrip editor**: see Highlights - includes drawing, preview, layout editing, persistent storage in the project file and undo support.
- **Element Editor & Symbol Trim/Sort**:
- Improved trimming/normalization of element metadata.
- Better sorting and error handling for element imports (DXF and other formats).
- Small UI improvements: About dialog updates, autosave spinbox ranges, improved tooltips and mouse-hover help for dynamic texts.
### New & Updated Elements
- New elements added for industrial and automation workflows (including Siemens-related elements, logic elements, sensors and Arduino components).
- Symbol library additions and cleanup; improved defaults for newly added symbols.
- Element meta-data cleanup: article numbers, descriptions, and manufacturer fields were normalized and trimmed on import.
### Export / Printing / PDF
- Adjusted internal export limits to avoid hitting QPainter size restrictions; users can now export larger, high-resolution images/prints in more cases.
- Better handling of page sizes and printer-related geometry using QRectF improvements.
- PDF export improvements to increase reliability of exported vector content.
### Build, Dependencies, Packaging
- Upgrades of core test and build dependencies:
- Catch2 upgraded to v2.13.10.
- googletest upgraded to v1.17.0.
- CMake fixes and i18n handling corrected for nl_BE and other locales.
- Packaging scripts updated across platforms (AppImage/Flatpak/Snap/macOS deploy) including fixes for aarch64/arm64.
- Submodule updates (e.g., qelectrotech-elements, pugixml, SingleApplication) synchronized where needed.
### Internationalization & Translations
- Large translation updates across many languages: German (DE), French (FR), Dutch (NL, including nl_BE), Swedish (SV), Italian (IT), Polish (PL), Portuguese-BR (PT-BR), Serbian (SR), Chinese (Simplified) and others.
- Fixes and corrections for many UI strings and localized resources.
### Tests, QA & Logging
- Improved logging and machine/config-path reporting; Git revision display refined to only show a revision when available.
- Unit test updates and fixes to align with updated testing frameworks.
## Bug Fixes (selected)
- Fixed crashes and various null pointer access issues discovered by static and dynamic testing.
- Resolved multiple reported bugs that caused build failures on some platforms (FTBFS fixes for macOS and others).
- Fixed issues with automatic conductor/strand numbering in several edge cases (referenced Bug 293 in the commit logs).
- Resolved text/summary headline issues in the German-language summary generator.
- Fixes for a number of visually incorrect renderings and layout corner-cases during element transformation (rotate/flip/mirror).
- Fixed issues that affected export sizes and caused export artifacts (referenced fixes for bug IDs around #329/#330 in commit notes).
## Developer & Contributor Notes
- Reworked parts of the codebase to use QRectF consistently for better compatibility with QPrinter and export pipelines.
- Code-style cleanups and comment improvements applied throughout the project.
- Expanded test coverage and dependency refresh to keep CI builds stable.
## Contributors (selected)
Thanks to the many contributors who made this release possible. Selected contributors mentioned in the commit logs include:
- Laurent Trinques
- joshua
- plc-user
- Achim
- Pascal Sander
- Andre Rummler
- Magnus Hellströmer
- Martin Marmsoler
- Remi Collet
(See the full commit history for the complete contributor list.)
## Upgrade / Migration Notes
- No database or project file format breaking changes were reported in the provided logs. As always, back up projects before opening them with a new version.
- If you rely on custom element libraries or third-party submodules, verify submodule synchronization after upgrading.
- If you are using custom packaging pipelines, review the updated packaging scripts for any changes required by new dependency versions, especially on aarch64/arm64.
## Known Issues & Limitations
- Some very large exports may still be limited by platform-specific rendering restrictions; the export dialog now allows larger pixel limits but extreme sizes may still hit system-level limits.
- If you use niche element-import workflows (DXF → element import), occasionally metadata normalization may alter whitespace/trim rules - verify newly imported elements in the element editor.
## How to get help / report bugs
- Use the project issue tracker (see repository) to report regressions or new bugs with detailed reproduction steps and example .qet files where possible.
- Include the output of Help → About (application version and Git revision) when reporting build/packaging issues.
====== ChangeLog from 0.8 to 0.9 ======
*Diagram editor :
Improved QElectroTech speed (launch qet, open project, function)
A drop-down list has been added to the toolbar to change the size of the resize handles.
*Element Editor:
The "keep visual rotation" property of element texts is editable from the element editor.
Thanks to the work of antonioaja it is now possible to import a dxf directly from the element editor in a completely transparent way for the user.
In the background QElectroTech uses the dxf2elmt software. https://qelectrotech.org/forum/viewtopic.php?id=2265 https://github.com/antonioaja/dxf2elmt
Improved responsiveness when multiple shapes are selected or deleted, especially when working on a large converted DXF element.
https://qelectrotech.org/forum/viewtopic.php?pid=16612#p16612
*Other:
Add a "side project" tab in the "about" window.
In the general QElectroTech configuration, a drop down list allows to choose the scaling method for hdpi screens.
Allow open polygons (i.e. polylines) when saving in dxf format.
https://qelectrotech.org/forum/viewtopic.php?pid=16611#p16611
Added 'Other' option for slave device contact type.
https://github.com/qelectrotech/qelectrotech-source-mirror/pull/222
https://qelectrotech.org/forum/viewtopic.php?id=2264
*Logs:
Added a QElapsedTimer to calculate the time used to reload the item collection.
Improved QElapsedTimer to calculate the time used to reload the item collection in seconds instead of ms.
Added Linux pc.gpu.RAM information, but requires mesa-utils dependency on the Linux OS.
Added information about mounted disk volumes.
Added CPU architecture for which Qt was compiled in the aboutqetdialog widget and in the logs.
Added MSVC support to MachineInfo.
Added RAM information on Windows of available RAM.
Added QElectroTech version to the log file.
* Elements collection :
Improve collection 8274 elements in 1097 categories (i.e. 9371 files).
* macOS :
Fix sqlite3 database export on macOS, now I use macports with Digikam scripts instead off Homebrew Package Manager.
See: https://invent.kde.org/graphics/digikam/-/tree/master/project/bundles/macports
*Bug fix:
see: https://git.tuxfamily.org/qet/qet.git/log/?h=0.8.1
====== ChangeLog from 0.7 to 0.8 ======
* Moving the main QET repository SVN trunk to GIT.
* Add a mirror of the main QET repository, which is synced to hosted at tuxfamily.org to Github.
* Doxyfile update add QCH file for doxygen-generated docs using qhelpgenerator and then import them into Qt Creator.
* Improve portability of Doxyfile (Simon).
* Fix deprecated warnings (Simon).
* Wrap code for better readability (Simon, Damian).
* Elements collection :
Improve collection 7378 elements in 1092 categories
Thanks Sebastien, Dinozzo, Simon, Rafał, Arnaud, Bisku, Fernando, Riesermauf, Alexis, david, Plc-user, Christophe, Michele, Galexis, Jevgenijs, Gabor,
Benoit Michel, Franck, Ludovic, Cyrille, ossau2mation, Mitzot, Edgar, Nuri, Friskolon, Baboune41, Wiktor, shateks, Dik, Shateks, Marcin
* Diagram editor :
* The export of the nomenclature to csv file has been completely rewritten :
It is now possible to choose which information to export as well as the order in which it should be displayed.
An option allows filtering by type of element: all, terminal block, button / switch.
Another option allows to display or not the column headers in the csv file.
With these options, it is possible to create a nomenclature, an order list, but also for printing labels: list of terminals and list of buttons / switches.
It is possible to save / load a configuration easily.
Finally, the work being done by an SQLite database, a text field allows the user to create his own SQL query.
* Add Conductors numbering to csv file.
* Add new summary table.
* add BOM creation dialog :
nomenclature is now integrated into the project (accompanied by several parameters in order to be customizable).
Tables can have a name.
Tables an be added to any folio.
Font margin and alignment (right center left) separately adjustable for headers and table cells.
Position size and number of lines is adjustable.
Possibility of linking several tables together, especially when the entire nomenclature cannot be contained in a folio.
Automatic adjustment of the size of the table in relation to the folio.
Option to apply the geometry of an array to all the array linked to it, so that everything is homogeneous.
Save / load table configuration and content to make creation faster.
Option to automatically adjust the table to the folio.
Option to automatically add new tables in new folios if the nomenclature cannot be contained in 1 to N folios / tables.
* Table content:
Fully customizable, you display what you want or want (info to display in the desired order, filter on type of element, filter on content of the info "contains, not contains, not empty etc ..." ).
The content being generated from a sqlite database, you can write your own request.
* Loading of element collections is now faster (thanks to the pugixml parser)
* The loading of collections of elements no longer freezes QElectroTech.
* The appearance and disappearance of the search / replace menu is animated.
* Fix wrong position of slave xref after open a saved project
* Add font color of the conductors (Simon).
* Add section and color properties for wires.
* config dialog :
* Add QScrollArea to configdialog and resize to max_screen (Simon).
* Add gui resize depending on screen size (Simon).
* Add Screen info user (Simon).
* Mod ScrollArea on demand (Simon).
* Element editor:
* Polygon editing widget, when you click on a point in the list, the corresponding point changes color in order to better visualize what you are doing.
On this same list, a right click opens a contextual menu allowing to delete the selected point or inserted a point after the selected one.
When holding the ctrl + directional arrow key, the selected parts move by 0.1 instead of 1 point.
* with Ctrl key you can moving by keyboard primitives selected by 0.1 point instead by 1 points, added the same feature for moving the selected aera.
* Added 140 web standard colors In Element editor (Arnaud).
* Add multiedit feature (martin).
* Add terminals uuid for next features (martin).
* Windows :
* Fix bad fonts rendering if Qt version >= 5.13.1.
See : https://bugreports.qt.io/browse/QTBUG-83161
* Fix backup file on windows
For unknown reason KautoSaveFile don't write the file on Windows if file
is open in another part of the code.
No error is returned and use the method :
qint64 QIODevice::write(const QByteArray &byteArray) return the good
number of bytes written but the real file stay empty.
Probably the problem don't come from KautoSaveFile but QFileDevice or
QIODevice on windows.
The fix consist to open the file just before write on it and close it
just after.
* writeToFile on a other Thread to improve this for windows performance (Simon).
* macOS :
* Add Fusion style and fix tilesets tab bar size
* Enable mouse wheel on tilesets tab bar with command keyboard, thanks Giovanni.
(removed by Qt upstream) https://codereview.qt-project.org/gitweb?p=qt/qtbase.git;a=commitdiff;h=ea47d152b35158ba07a55d009f57df0e4c2a048f;hp=08cc9b9991ae9ab51bed5b857b6257401401ff6f
* Add Snap packages :
* thanks Max for help.
https://snapcraft.io/qelectrotech
See: https://qelectrotech.org/forum/viewtopic.php?id=1426
* Use kde-neon extension
The kde-neon extension reduces our boilerplate in snapcraft.yaml
and reduces the snap size considerably, as we do not need to ship
any library that is already included in the kde-frameworks-5-core18
snap itself.
This limits qelectrotech builds to the architectures supported
by kde-frameworks-5-core18, i.e. only amd64.
https://git.tuxfamily.org/qet/qet.git/log/?qt=grep&q=snap
* Add Flatpak packages :
* thanks Mathieu for help.
See: https://github.com/qelectrotech/qelectrotech-source-mirror/pull/18
* remove the file name extension added
automatically to the saved files even if the user sets an unknown file
extension for the program.
https://git.tuxfamily.org/qet/qet.git/log/?qt=grep&q=flatpak
====== ChangeLog from 0.6 to 0.7 ======
* Element editor :
* Element informations (manufacturer, reference etc...) can be created directly from the element editor. For that go to the widget "Element Property"
* It is no longer required to have a text field, for save the edited element.
* Improve the behavior with the arrow keys (depending to the current selection (nothing / one / several).
* Context menu display only enabled actions.
* Added new feature -> alignment.
* Alignment of text field can be edited.
* Added two new actions in context menu for insert or remove point of a selected polygon.
* Rectangle can have rounded corner.
* Polyline: finish the creation of polyline with the last point at the same position of the first point, close the polyline.
* Diagram editor :
* Conductors can now be drawn with two colors.
* Improve High-DPI support on Windows and Linux plateform.
* The code for the resize handles has been almost completely redesigned.
* Dissociate fonts policy and size for independent text item and for summarry pages (foliolist), added a 2 button in config page for open Qfontdialog widget and choose policy for independent text item.
* Add in config page a Qfontdialog widget for change dynamic text size, font family, orientation angle and text length, by default.
* Basic shape add new CustomDashLine style with Dash Pattern (<< 10 << 10 );
* It is now possible to add a text field to an element directly from the diagram.
* Element text item with are now converted to dynamic element text item.
* Element editor, part text can't be edited directly.
* User can export / import the configuration of the texts and texts group of an element.
* Context menu display only enabled actions.
* Added new action in the context menu, multiple paste, check box for autonum the pasted element.
* Multipaste -> improve the conductor autonum, conductors are numerated from top to bottom, and left to right.
* Text of conductor can be placed at top/bottom/left/right of conductor, and text never overlaps the conductor.
* Function for search conductor at the same potential.
When the search function is searching in a terminal element, they search only for the first terminal found, no matter if the terminal element have more than two terminals.
So the list of conductors at the same potential is missing some conductors.
This commit fix it, now the search function search for every terminals of a terminal element.
* When remove an element with several conductors connected to the same terminal, the electrical potential is partially or totally destroyed.
This commit fix it : When element is removed one or several conductors are created (if needed) to conserve the electrical potential.
* Added new feature -> alignment.
* Alignment of text field can be edited.
* Added new context menu action "group the selected texts".
* Widget used to edit text item group can edit the pos of the group.
* Element text item group can now be framed.
* Added two new actions in context menu for insert or remove point of a selected polygon.
* QETshapeItem rectangle can have rounded corner.
* Add in config the possibility to start the numbering of the columns of titleblocks at 0.
* Add new function Search and replace widget Crtl +F
* Diagram properties, Element properties, Independent text item can be changed (and mass changed) through the search and replace widget.
* Added 4 tools for edit the depth (Z value) of items.
* Element panel : elements can be searched by their name but also with by all their informations.
* New free selection style.
* Diagram editor : dock used to edit the shape item, can now edit several items in the same time.
* Dynamic element text item : The font of the dynamic texts can be individually be setted.
* Adding or revoming diagram set project to modified
* When user cleanning an project, set project to modified
* Add a shortcut "Ctrl+Shift+P" to quickly open the dialog used for create the auto numbering rules.
* Add missing StatusTip of some QAction
* When user add a polygon, a message in statusBar show how to finish this shape
* Polyline: finish the creation of polyline with the last point at the same position of the first point, close the polyline.
* Plug-in : Add StatusTip instruction for install and launching DXF plugin depending on the operating system
* when plugin qet-tb-generator"generate terminal blocks and connectors" isn't installed show an QMessageBox instruction now depending on the operating system for install it
Add in QMessageBox url encoding/decoding for easy download packages
* Elementspanelwidget: adds keyboard shortcuts to quickly move up, down,or move the targeted folio to the beginning of the project
F3 MoveUp
F4 MoveDown
F5 MoveUpTop
* Title block editor :
Added new title block variables %projectpath, %projectfilename, %projecttitle, previous-folio-num and next-folio-num
"%saveddate, %savedtime, %savedfilename and %savedfilepath" they variables should be updated after file save or save as dialog is confirmed,
before file is saved.
* NameList widget : add a combo box for easily paste texts, like the variables for title block.
* The font of the dynamic text field can be edited.
* The font of the static text field can be edited.
* The color of the static text field can be edited.
* Improve for new qet_tb_generator plug-in : added the full path of the current project as
an argument when calling the plug-in from QET if a project is open.
If not a file dialog is showed to select the QET project.
* QET create a backup file, use to restore the project when a crash occur.
* Use KAutoSaveFile for the backup system, instead of home made function.
* Use of QSAveFile instead a QFile.
* User can enable and edit autosave timer.
* let user define the file system path of the common,custom elements collections, and custom title blocks template.
* QetGraphicsItem, remove the function applyRotation and rotateBy, and use instead the native function of QGraphicsItem : setRotation
* Conductor is an herited class of QGraphicsObject, instead of QObject and QGraphicsPathItem
* Clean (and reduce the size) the class QETDiagramEditor, mostly by replacing the connection syntax "signal -> slot" by "signal -> lambda".
* Replace deprecated QMatrix by QTransform.
* DXF export : fix some double items in dxf file.
* DXF export : add some colors for basic shapes inside dxf.
* Bug fix :
* Fix compilation warning (clang and gcc).
* Fix element text item alignment work well when text rotation != 0.
* Fix crash when the properties of a element text item group
* Fix crash occurred by the conductor and shape "ghost".
* Fix element text alignment work also when font size change.
* fix :
1- When open a .qet by double click on it, QET ask user for open the backup file, of this .qet.
2- On windows, if user open a project from the recent files menu, when close QET the file is deleted  user lose her work.
clear the element texts when paste an element with the option "Do not store the labels of items in the copy paste" enabled.
* elements can't be moved up and left, when there rotation are different than 0.
* minor fix : slave link dialog doesn't display the good label, when the label of master element is build from formula.
* Fix : in some condition, dynamic text are not at the same position when open a project.
* On windows when user drag and drop an element from the common elements collection to the custom elements collection,
the element file stay in read only mode, and so user can't save the element
* Improvement : minimize the unwanted gap of the top right folio of the view (see https://qelectrotech.org/forum/viewtopic.php?pid=9379#p9379)
* Fix: bug 168
* Fix : when create multiple conductors with the free hand selection, the checking of existing potentiel don't search trought a folio report.
* Fix: DXF export.
* Minor fix : remove from the element information the html hexadecimal and decimal characters of line feed and carriage return.
* fix : in the diagram editor, when we select several shapes at the same time, the properties widget only apply the change to one shape.
* Bug fix : when user load a project which contains summary pages, project was marked modified (summary was created on the fly and moved from the end on second
position), now the project is no longer marked as amended when user have one or multiples summary pages when loading this project.
* Static text of element are now exported to dxf
* Fix Static text size of element exported to dxf
* Improvement : minimize the unwanted gap of the top right folio of the view
* Fix : when create multiple conductors with the free hand selection, the checking of existing potentiel don't search trought a folio report.
* Don't display gui when qet is launched with specific argument
====== ChangeLog from 0.5 to 0.6 ======
In the official collection, there are now 4106 elements, and 539 categoris for a total of 4645 files
* Improved performance, added multithreading to speed up the loading of items when launching QET.
* RAM consumption has been considerably reduced.
* New "collections" panel.
* Automatic numberings (autonum), Variables and prefix.
* Folio generator
* Management Policy
* New thickness properties for conductors.
* The thickness of the lines of all basic shapes (lines, rectangles, ellipses, polygons) can be changed from 0,2px to 50,0px.
* The color of lines and fillings of basic shapes can be choosed from a color palette or set with a html color code.
* Added Copy/paste from another project.
* Online documentation and links to download the latest packages of the version under development for Windows and MacOS are available directly from the software.
* Resetting the layout of the summary pages.
* In the panel left split the view into a several docks.
* High-DPI support (Qt 5.6.0)
* new python plugin to generate terminal block.
* Windows packages are now created on a Debian operating system using cross-compilation and targeted to make executable binary files for these operating systems.
This technical evolution allows a significant time saving during the creation of the packages. And we can provide also in the same time Windows XP and Vista packages by cross-compil with Qt 5.7.1 environment
* The Mac OS X executable binary files are created on a virtual environment, moved compiler to latest LLVM clan version, improved dmg packages with added Info.plist.
* An annoying memory leak has been found and solved. Afters hours of use, some users noticed that the RAM consumption growed steadily, up to 10GB or more. This problem is now solved.
====== ChangeLog from 0.4 to 0.5 ======
In the official collection, there are now 2625 elements, and 418 catégoris for a total of 3043 files.
* Port to Qt 5 framework
* New QSettings native format for config files.
* In the diagram editor, the grid is not displayed by default outside the diagram, the minimum zoom is blocked. A button allows you to un-validate this operation.
* It is now possible to put the tittle block on the right vertical mode.
* The default tittle block can be defined for the next folios of the project.
* The summary now takes the font set in the QElectroTech.conf
* The floating dock is now operational, variables, actions are taken into account on the fly.
* A transformation tool transforms quickly and finely each primitive by handles.
* Add UUID tag for element XML.
* The database enables faster loading a large number of managing symbols in tables changes pixmaps collections, it no longer compares the modification date of the files but their use UUID attributes to update the cache .
* In terms of basic shapes, the transform tool works directly on vectors, it replaces the reduction tool / enlargement that has just been deleted as unnecessary.
* Improve Undo command by QPropertyUndoCommand class.
====== ChangeLog from 0.3 to 0.4 ======
In the official collection, there are now 2298 elements, and 376 catégoris for a total of 2674 files.
* We have removed the flag '-fno-ipa-sra "This settled the compilation problems on Mac OS X and FreeBSD clang.
* The official collection has been redesigned, through the work of Nuri a new structure is in place.
* A menu has been added, allowing you to change the application language.
* we added a summary creation tool.
* Added button "export the nomenclature" transforms data from diagrams to CSV file for spreadsheet.
Arun wrote a detailed manual in English.
* New tools have been added, they can create mechanical connections and draw cabinets, desks, junction boxes, or areas on the schematic (line tool, rectangle, ellipse, polygon type: respect for style dashes).
* An aid in positioning cross, drawing, was added.
* The locked state images and basic forms (basic shapes) is now stored in the project.
* The "control" during the movement of an element, text field disables snapping to the grid, for free positioning.
It is now possible to choose the background folios in white or gray.
* Add supports trackpad gestures (multitouch).
The dates of the cartridges are now using the short system date and date format according to the language detected setting in the OS.
We take advantage of the transition to standard C ++ 11, and a big cleanup in the code was done.
* The undo action or redo the undo stack are now animated graphically.
When the action save, save as, the status bar displays the name and path of the backup job.
Qet is now able to come to load a style sheet (stylesheet) directly from the conf directory.
* A DXF export has been added, the entire project folios can be exported in this format.
* Added reports folio, Cross references.
* Added a variable font size for text of conductors.
* Added new properties to all conductors at the same potential, even through referrals.
* When several conductors have the same value potential equalization, it is not useful to display on all conductors.
* Added button to activates the automatic connection of the conductors of the element when moving it.
* Numbering rules are now available for the entire project.
Qet detects the Windows version and applies the appropriate graphic style, depending on the version of Windows.
====== ChangeLog from 0.3 rc to 0.3 ======
First, the collection of symbols has made a big step forward, with about 1560 new elements.
There are now symbols for pneumatics, hydraulics, process, solar, cold, etc. Considerable effort has been done to organize the collection in a better way.
We hope that the new organisation is clearer for all. We would like to thank all the contributors who send us symbols.
=====-Element Editor: =====
Considerable work has be done to replace the manual defining zone of the symbol, aka hotspot.And fix bugs, It is now automatic. You do not have to care about it anymore.
Primary colors have been added for the drawing shapes.
A contextual menu (right click) has been added. So, you can now work more quickly with symbols. It is also more user-friendly.
====== ChangeLog from v0.3 rc ======
=====-Element Editor: =====
* Replacing checkboxes with lists of colors.
* Removed the manual hotspot, it is now automatic and you do not have to worry.
Officially Collection: a large classification work on the structure was realized. It should be clear to everyone.
The collection is enriched with 1711 items in 286 categories (ie 1997 files)
=====-Schema Editor:=====
* Added import image, image rotation, image resizing and saving the file in the project.
(Double click on the image called a widget and cursor that reduce or enlarge the selected image.)
NB: Following the "edit image" entry will also be added in the right click menu.
* F5 keyboard shortcut can recharge symbol collections.
Some bugs have been resolved, and the translation status continues to grow.
======ChangeLog from v0.3 beta ======
Two more items for the changelog:
* In the official collection, there are now 1672 elements and 256 categoris for a total of 1928 files. In version 0.3 alpha, there were 1465 elements and 233 categories, while version 0.22 had153 elements and 51 categories.
*Progress in the translation (see http://qelectrotech.org/wiki/doc/translation/stats for current state)
* Functions (edit element and find in panel) have been moved to the context
Here is the changelog, for version 0.3 beta:
* Functions (edit element and find in panel) have been moved to the context menu, that can be accessed with right click. This is more user friendly.
* Refresh of categories when an element is moved.
* DateNow button added in the "Diagram property" dialog.
* Dotted lines can now been added between conductors.
* Rich text can be added to the diagram text fields.
[screenshot]
* HTML WYSIWYG editor for rich text: bold, italic, underlined, font size from 6 to 72 pixels, font colour, etc.
* You can change between the two modes(Selection mode <-> View mode) with the scroll button.
* Symbol editor: focus on the new value for language, languages sorted in alphabetical order.
* Added a widget that reflects the loading of a big project.
* Automated numbering of conductors according to your rules. See note from Joshua http://qelectrotech.org/wiki/doc/autonum
* Added a dialog to automatically rotate the text if the associated conductor is vertical or horizontal. Parameters are saved in qelectrotech.conf
* Added basic colours on the tools for lines and for the filling of the primitives, and also for the style line and point in the element editor.
* Added several protection to prevent from saving an element if one of its primitive is beyond the hotspot.
====== ChangeLog from 0.22 to 0.3a ======
===== Application =====
Elements collection: QElectroTech now provides 1465 elements within 233 categories (0.22 provided 153 elements within 51 categories). Most elements are related to electricity though some relate to chillers, solar, hydraulic and pneumatic engineering.
A new kind of collections appeared to store title block templates; as for elements, there is a distinction between common (system-wide) templates and custom (user-wide) templates.
Translations:
English, Spanish, French, Portuguese and Czech translations have been maintained.
Russian translations have been removed because they are not maintained anymore.
Polish, German, Italian, Arabic and Croatian translations have been added.
Following translation to Arabic, some work was done to improve Right-To-Left languages support.
Elements names are fully translated to English, French, Czech and Polish.
Main windows: added a “What's this?” action.
QElectroTech now handles *.titleblock files.
===== Diagram editor =====
It is now possible to move and rotate all texts on a diagram : element texts, conductor texts and independent texts.
When moving a text related to an electrical element, this element is highlighted.
Texts related to a conductor cannot be moved too far away from it.
It is now possible to create diagrams with more than 100 rows/columns.
Elements panel:
During a drag and drop operation, the hovered item is now expanded after a short time not moving the mouse.
Items are now expanded/collapsed by a double click.
Common, custom and embedded collections of title block templates are displayed within the elements panel.
Elements previews and names are now cached into a SQLite database stored in the user configuration directory, thus speeding up the elements panel (re)loading
The elements panel now displays the folio index before each diagram title.
UI consistency: renamed “Import element” to “Open an element file”, separated this action from those related to the current selection, and ensured elements-related actions are disabled when selecting a project/diagram/title block template.
Freshly integrated elements are now highlighted in the elements panel – this behaviour can be disabled though.
When clearing the search field, the panel state is restored to its previous state.
Title blocks are now rendered using templates:
For each diagram, users can choose the template to be used in the diagram properties.
They may also drag and drop it from the elements panel to the diagram.
Title block templates are always integrated within the parent project.
Fixed a bug in the print preview dialog.
Added a F2 shortcut for the widget “Edit the color of the given conductor”.
As elements, diagrams now have a “version” attribute for compatibility purposes.
Better handling of file opening for documents saved with newer versions of QElectroTech.
Diagram loading: removed an optimization that could lead to conductors not being loaded when several terminals share the same coordinates.
Users may now enter visualisation mode by pressing Ctrl and Shift.
Printing: when printing diagrams with no title block, use the space left by the title block.
Added a few status and “What's this?” tips.
Got rid of the green icon used for projects, changed a few other icons.
===== Element editor =====
Both static and dynamic texts can now be rotated
Added “dotted” line style
Added white color for texts
Newly added parts are placed above existing ones.
===== Title block template editor =====
A third kind of editor was implemented so users can create their own title block templates:
It allows users to customize the layout and content of cells that constitute the title block.
Cells can be merged and splitted.
Their width can be fixed, relative to the total width or relative to the remaining widths.
Their height is a simple fixed length.
They contain either a logo (be it in SVG or a usual bitmap format) or some text.
The text value is optionally preceded by a label.
As other texts within QElectroTech, labels and texts can be translated to other languages.
Texts and labels may contain variables (e.g. %company-name); these variables are replaced by real world values once the template is applied to a diagram.
Those real-world values can be set among the diagram properties.
====== Changelog 0.11 -> 0.2 ======
À partir de la version 0.2, QElectroTech est disponible en français, anglais, mais aussi :
* en espagnol, grâce aux traductions de Youssef ;
* en russe, grâce aux traductions de Yuriy ;
* en portugais, grâce aux traductions de José.
L'application utilise désormais le thème d'icônes Oxygen, réalisé par Nuno Pinheiro pour le projet KDE.
===== Notion de fichier projet =====
Un fichier .qet peut désormais contenir zéro, un ou plusieurs schémas électriques. Les éléments composant ces schémas sont embarqués dans le fichier projet au moment où ils sont posés sur un schéma. Le panel d'éléments affiche donc désormais :
* les projets ouverts, avec, sous chaque projet :
* les schémas de ce projet,
* la collection embarquée du projet (catégories et éléments utilisés dans les schémas)
* la collection commune fournie par QET,
* et la collection personnelle de l'utilisateur.
===== Éditeur de schémas =====
* Il est désormais possible de déplacer et copier les catégories et éléments par simple glisser-déposer (drag'n drop) dans le panel d'éléments.
* La collection embarquée est manipulable au même titre que la collection utilisateur. Les éléments inutilisés dans le projet apparaissent sur fond rouge et un dialogue permet de les purger rapidement.
* Chaque projet embarque également (au niveau de ses propriétés) les paramétrages par défaut pour les nouveaux schémas, cartouches et conducteurs.
* Il est possible de changer l'ordre des schémas dans le projet en déplaçant les onglets qui les représente. Dans le champ "Folio" des cartouches, on peut se référer à la position du schéma courant ou au nombre total de schémas dans le projet en écrivant respectivement %id et %total.
* Lors du chargement d'un fichier .qet, si des éléments ne sont pas trouvés, ils sont remplacés par un élément "fantôme", ce qui évite de perdre certaines informations lors de l'enregistrement du fichier.
* Le rendu avec un zoom réduit a été amélioré.
* Enfin, le logiciel gère l'ouverture en lecture seule d'un fichier projet.
==== Impression et export ====
À partir de la version 0.2, QElectroTech :
* propose d'utiliser une imprimante réelle ou bien de générer un document PDF ou PostScript, et ce sous Windows comme sous X11.
* génère un aperçu avant l'impression d'un projet. Cet aperçu permet de choisir les options d'impression mais également les schémas à imprimer ou non.
À noter toutefois une limitation pour les impressions PDF/PS sous Windows : le dialogue de mise en page, permettant de spécifier le format du papier ainsi que ses marges, n'est pas disponible.
Le dialogue "Exporter" (pour générer un fichier image d'un schéma) a également été refait dans l'optique d'un export simultané de tous les schémas du projet.
===== Éditeur d'éléments =====
* Lorsque l'on dessine une ligne dans l'éditeur d'éléments, il est possible de choisir un embout différent pour chaque extrémité, comme par exemple une flèche, un cercle, un carré ou, tout simplement, un bout de ligne normal.
* La forme "Rectangle" a été ajoutée.
* On peut enregistrer un élément en désignant un fichier (= comportement en 0.11) ou bien en choisissant un élément cible dans une liste reprenant l'arborescence du panel d'éléments.
* Si l'on maintient la touche Shift lorsque l'on ajoute une partie (droite, cercle, texte, ...), l'outil en cours est conservé après le dessin. Sinon l'éditeur repasse sur l'outil de sélection.
* La grille a été améliorée : sa densité varie en fonction du zoom ; les points correspondant à ceux de la grille de l'éditeur de schémas sont mis en valeur.
* L'accrochage à la grille (aka "snap to grid", également connu sous le nom de grille magnétique ou encore grille aimantée) a été ajouté. Le dessin s'y accroche désormais avec une précision de 1px. On peut travailler en coordonnées libres en maintenant la touche Ctrl enfoncée durant le dessin.
* Le copier-coller a été implémenté : il est possible de coller :
* avec le bouton du milieu de la souris
* en choisissant une "zone de collage" sur l'élément (Ctrl+Shift+V)
* directement (Ctrl+V) : les parties collées sont placées à côté des parties copiées ; si on recolle les parties, elles sont collées encore un cran à côté, et ce de manière incrémentale.
* Des contrôles sont désormais effectués à l'enregistrement : présence de bornes, respect du cadre, etc.
* Uniformisation des menus par rapport à l'éditeur de schémas
====== Changelog 0.1 -> 0.11 ======
===== Fonctionnalités et interface =====
* L'application est désormais capable d'ouvrir un fichier élément passe en paramètre
* L'application se lance désormais une seule fois par utilisateur
* Lors de l'ouverture d'un fichier en dehors de l'application alors que QET est déjà démarré celui-ci essaye de s'afficher ou d'attirer l'attention de l'utilisateur.
* L'application vérifie que ce fichier n'est pas déjà ouvert dans tous les éditeurs de schémas / éléments.
* Ajout de fichiers permettant d'automatiser les associations de fichiers sous Windows (.bat et .reg) et X11 (.desktop et .xml)
* Ajout de menus "Récemment ouverts" pour accéder aux fichiers récents dans les éditeurs de schémas et éléments.
* Ajout d'un splash screen
* La hauteur du schéma est désormais gérée via un système de lignes, dont le nombre et la hauteur sont ajustables.
* Il est également possible d'afficher ou non les en-têtes des lignes et/ou des colonnes.
* Ajout d'une option --lang-dir
* Ajout d'une description dans le dialogue des options d'impression
* Ajout de pages de manuel Unix (`man') en anglais et en français
===== Corrections de bugs =====
* Bug #12 : QET provoquait une erreur de segmentation dès son démarrage dans un environnement sans systray
* Bug #14 : il manquait un / dans le chemin proposé lors de l'impression vers un PDF
* Bug #15 : Mauvais positionnement des champs de texte sur le schéma
* Bug #16 : Mauvaise gestion des modifications du texte d'un conducteur
* La classe DiagramView écrivait sur la sortie d'erreur sans fin de ligne
* L'option --config-dir était mal prise en compte
* Après fermeture d'un schema, le menu Fenêtres n'était pas correctement mis à jour
* Les textes des éléments, des conducteurs, du cartouche ainsi que les textes indépendants utilisent désormais tous la même police.
* Remise à niveau de l'impression suite au passage à Qt 4.4
===== Code et détails techniques =====
* Corrections pour que QET compile avec gcc-4.3
* Les classes Conductor et Element héritent désormais de QObject (dépendance sur Qt 4.4)
* Affinage du constructeur de la classe QETApp
* Moins d'avertissements à la compilation (testé avec gcc 4.3)
* Moins d'inclusions non pertinentes
## Version 0.100
_Compiled from provided commit logs and contributor notes._
+91 -2
View File
@@ -2,13 +2,102 @@
## [Unreleased](https://github.com/qelectrotech/qelectrotech-source-mirror/tree/HEAD)
[Full Changelog](https://github.com/qelectrotech/qelectrotech-source-mirror/compare/0.9...HEAD)
[Full Changelog](https://github.com/qelectrotech/qelectrotech-source-mirror/compare/nightly...HEAD)
**Closed issues:**
- “Exclude from auto-numbering” and “Potential isolation” tick boxes fault [\#482](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/482)
- Add ability to change appearance of multiple lines at once [\#476](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/476)
- Save As dialog asks for "element name" but actually requires a file name [\#469](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/469)
- Some icons are illegible with dark theme [\#466](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/466)
- \[BUG\] Properties to all conductors [\#460](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/460)
- Internal links in PDF export [\#417](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/417)
- Apple silicon download is not working [\#400](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/400)
- Add missing title block variables to 'folio properties' window [\#271](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/271)
- Bug: Saving a read-only project doesn't clear the read-only state [\#217](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/217)
**Merged pull requests:**
- PartText: keep text position stable across save/reopen on font-size change \(\#158\) [\#501](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/501) ([ispyisail](https://github.com/ispyisail))
- Clear read-only state when a project is saved to a writable file [\#497](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/497) ([ispyisail](https://github.com/ispyisail))
- Fix regional system locale loading the wrong translation \(pt\_BR/nl\_BE/nl\_NL\) [\#496](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/496) ([ispyisail](https://github.com/ispyisail))
- Folio properties: auto-add a title block's custom variables [\#495](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/495) ([ispyisail](https://github.com/ispyisail))
- Element editor Save As: label the field as a file name, not 'element name' [\#494](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/494) ([ispyisail](https://github.com/ispyisail))
- CLI: add --set-titleblock, and fix headless backup crash [\#493](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/493) ([ispyisail](https://github.com/ispyisail))
- Update qet\_zh.ts [\#491](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/491) ([zi-mozhuang](https://github.com/zi-mozhuang))
- CLI: clickable cross-reference hyperlinks in PDF export [\#490](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/490) ([ispyisail](https://github.com/ispyisail))
- CLI: add verification & data-export tools \(info, BOM, nets, links, check-elements, resave\) [\#489](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/489) ([ispyisail](https://github.com/ispyisail))
- Issues 482 [\#488](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/488) ([Kellermorph](https://github.com/Kellermorph))
- Revert "Update-UI-Chinese-translation" [\#486](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/486) ([scorpio810](https://github.com/scorpio810))
- CLI export: don't draw the editor grid in PDF/PNG/SVG output [\#485](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/485) ([ispyisail](https://github.com/ispyisail))
- Update-UI-Chinese-translation [\#484](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/484) ([zi-mozhuang](https://github.com/zi-mozhuang))
- Add headless command-line export \(PDF / PNG / SVG / cable-list / wire-list\) [\#483](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/483) ([ispyisail](https://github.com/ispyisail))
- fix possible crashes in crossrefitem [\#479](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/479) ([ChuckNr11](https://github.com/ChuckNr11))
- Fix: Dynamic element text shifting/jumping when duplicating diagrams [\#477](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/477) ([Kellermorph](https://github.com/Kellermorph))
- Update German translations for duplicate diagram feature [\#475](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/475) ([Kellermorph](https://github.com/Kellermorph))
- Feat: Add ability to duplicate diagrams/folios with all metadata and … [\#473](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/473) ([Kellermorph](https://github.com/Kellermorph))
- Feature: Allow excluding specific elements from BOM \(Nomenclature\) [\#472](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/472) ([Kellermorph](https://github.com/Kellermorph))
- Potential Isolation option for terminals [\#471](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/471) ([Kellermorph](https://github.com/Kellermorph))
- Fix: Wiring list filter and dynamic text timing [\#470](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/470) ([Kellermorph](https://github.com/Kellermorph))
- New element: Line definition [\#464](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/464) ([Kellermorph](https://github.com/Kellermorph))
- Turkish Lang Update [\#463](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/463) ([scorpio810](https://github.com/scorpio810))
- follow up: wiring list [\#462](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/462) ([Kellermorph](https://github.com/Kellermorph))
- Fix and Improve Multi-selection for Diagram Operations [\#459](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/459) ([Kellermorph](https://github.com/Kellermorph))
## [nightly](https://github.com/qelectrotech/qelectrotech-source-mirror/tree/nightly) (2026-05-10)
[Full Changelog](https://github.com/qelectrotech/qelectrotech-source-mirror/compare/0.100...nightly)
**Closed issues:**
- Flatpak runtimes outdated [\#446](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/446)
- Move Flemish man pages from man/be/ to man/nl\_BE/ [\#439](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/439)
- you could share an PR to fix it? [\#438](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/438)
- Diacritics in some filenames can possibly lead to the problems during packaging [\#437](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/437)
- שרטוט חשמל [\#435](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/435)
- Feature request: add circuit simulation [\#432](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/432)
- No usable sources archive for version 0.100 [\#418](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/418)
- New release ? [\#411](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/411)
- options moving when opening "file", "edition" menus [\#299](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/299)
**Merged pull requests:**
- Try to add Windows build CI workflow [\#457](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/457) ([scorpio810](https://github.com/scorpio810))
- Fixed: Prevented the selection in the project tree from jumping to the last page when saving. [\#456](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/456) ([Kellermorph](https://github.com/Kellermorph))
- Fix Thumbnail in Makrotree [\#455](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/455) ([Kellermorph](https://github.com/Kellermorph))
- Update German translation for macro feature [\#454](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/454) ([Kellermorph](https://github.com/Kellermorph))
- Fix losing Focus on moving diagram position with keyboard [\#452](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/452) ([ChuckNr11](https://github.com/ChuckNr11))
- Draft: Feature - Introduce User Templates Collection and Dedicated UI Tab [\#451](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/451) ([Kellermorph](https://github.com/Kellermorph))
- Update translation [\#450](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/450) ([Kellermorph](https://github.com/Kellermorph))
- Automatic Terminal Numbering Tool [\#449](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/449) ([Kellermorph](https://github.com/Kellermorph))
- Supplement to pull request \#444 by Kellermorph [\#448](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/448) ([ChuckNr11](https://github.com/ChuckNr11))
- Add RAM-based wiring list export [\#447](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/447) ([Kellermorph](https://github.com/Kellermorph))
- Follow-up: Address review comments for slave limit feature [\#444](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/444) ([Kellermorph](https://github.com/Kellermorph))
- Feature: Auto-select active diagram in the elements panel tree [\#443](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/443) ([Kellermorph](https://github.com/Kellermorph))
- Revert "Feature: Implement max\_slaves limit for Master elements" [\#442](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/442) ([scorpio810](https://github.com/scorpio810))
- Feature: Implement max\_slaves limit for Master elements [\#441](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/441) ([Kellermorph](https://github.com/Kellermorph))
- Update qet\_cs.ts [\#434](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/434) ([pafri](https://github.com/pafri))
- Update QCH Help file [\#433](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/433) ([Int-Circuit](https://github.com/Int-Circuit))
- Create Korean man page for QElectroTech [\#431](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/431) ([Kyle-Code-CA](https://github.com/Kyle-Code-CA))
- Update ELEMENTS.LICENSE [\#430](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/430) ([Kyle-Code-CA](https://github.com/Kyle-Code-CA))
- Update CREDIT [\#429](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/429) ([Kyle-Code-CA](https://github.com/Kyle-Code-CA))
- Add Korean comments to QElectroTech XML file [\#428](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/428) ([Kyle-Code-CA](https://github.com/Kyle-Code-CA))
- Add Spanish and Korean summaries to appdata [\#427](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/427) ([Kyle-Code-CA](https://github.com/Kyle-Code-CA))
- Add Korean translations for comments and generic names [\#426](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/426) ([Kyle-Code-CA](https://github.com/Kyle-Code-CA))
- Restore copyright and license information in QET64.nsi [\#425](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/425) ([Kyle-Code-CA](https://github.com/Kyle-Code-CA))
- Add Korean language strings to lang\_extra.nsh [\#424](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/424) ([Kyle-Code-CA](https://github.com/Kyle-Code-CA))
- Add Korean translation author to aboutqetdialog [\#423](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/423) ([Kyle-Code-CA](https://github.com/Kyle-Code-CA))
- Add Korean language support in xml element collection [\#422](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/422) ([Kyle-Code-CA](https://github.com/Kyle-Code-CA))
- Add Korean translation \(ko\) – translated by jkh [\#419](https://github.com/qelectrotech/qelectrotech-source-mirror/pull/419) ([Kyle-Code-CA](https://github.com/Kyle-Code-CA))
## [0.100](https://github.com/qelectrotech/qelectrotech-source-mirror/tree/0.100) (2026-01-25)
[Full Changelog](https://github.com/qelectrotech/qelectrotech-source-mirror/compare/0.9...0.100)
**Closed issues:**
- error in doxygen action code [\#414](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/414)
- "NoName" is automatically inserted into empty text cells in title block [\#407](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/407)
- Apple silicon download is not working [\#400](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/400)
- Apple silicon download is not working [\#394](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/394)
- Differenciating connector for proper labeling [\#390](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/390)
- Non-perpendicular connections [\#368](https://github.com/qelectrotech/qelectrotech-source-mirror/issues/368)
+1087
View File
File diff suppressed because it is too large Load Diff
+15
View File
@@ -1,3 +1,18 @@
[Qt6 / CMake]
Building the Qt6 line with CMake additionally requires the private
development headers of QtGui. On Debian/Ubuntu these live in a separate
package that is NOT pulled in by qt6-base-dev:
apt install qt6-base-private-dev
(other distributions: install your Qt 6 "private headers" development
package, e.g. qt6-qtbase-private-devel on Fedora)
QET needs the private QtGui API (QPdfEngine) for clickable hyperlinks in
the PDF export. Without the package, find_package(Qt6 ... GuiPrivate)
succeeds but CMake later fails at generate time with:
"Imported target Qt6::GuiPrivate includes non-existent path".
[ca]
Dependències:
libQt5 (paquets libqt5*)
+49 -2
View File
@@ -1,10 +1,12 @@
#!/usr/bin/env python3
"""
generate-page.py — Generates gh-pages/index.html for QElectroTech nightly builds.
Called from windows-build.yml deploy-pages job.
Called from windows-msi.yml deploy-pages job.
Environment variables required:
DATE, SHORT, REPO, SHA, RUN_URL, RUN_NUMBER,
INSTALLER_URL, PORTABLE_URL, MSI_URL (optional)
Optional (Qt6 experimental track — omitted entirely if empty):
INSTALLER_QT6_URL, PORTABLE_QT6_URL, MSI_QT6_URL
"""
import os
@@ -18,6 +20,10 @@ installer_url = os.environ.get("INSTALLER_URL", "")
portable_url = os.environ.get("PORTABLE_URL", "")
msi_url = os.environ.get("MSI_URL", "")
installer_qt6_url = os.environ.get("INSTALLER_QT6_URL", "")
portable_qt6_url = os.environ.get("PORTABLE_QT6_URL", "")
msi_qt6_url = os.environ.get("MSI_QT6_URL", "")
msi_block = ""
if msi_url:
msi_block = f"""
@@ -26,6 +32,46 @@ if msi_url:
<span class="btn-text">Windows Installer .msi<small>.msi &mdash; for enterprise / GPO deployment</small></span>
</a>"""
# Qt6 experimental section — only rendered if at least one Qt6 asset exists.
qt6_block = ""
if installer_qt6_url or portable_qt6_url or msi_qt6_url:
qt6_msi_btn = ""
if msi_qt6_url:
qt6_msi_btn = f"""
<a class="btn btn-msi" href="{msi_qt6_url}">
<span class="btn-icon">&#11015;</span>
<span class="btn-text">Windows Installer .msi (Qt6)<small>.msi &mdash; experimental, for enterprise / GPO deployment</small></span>
</a>"""
qt6_installer_btn = ""
if installer_qt6_url:
qt6_installer_btn = f"""
<a class="btn btn-primary" href="{installer_qt6_url}">
<span class="btn-icon">&#11015;</span>
<span class="btn-text">Windows Installer (Qt6)<small>.exe &mdash; experimental, includes all dependencies</small></span>
</a>"""
qt6_portable_btn = ""
if portable_qt6_url:
qt6_portable_btn = f"""
<a class="btn btn-secondary" href="{portable_qt6_url}">
<span class="btn-icon">&#128230;</span>
<span class="btn-text">Windows Portable (Qt6)<small>.zip &mdash; experimental, no installation required</small></span>
</a>"""
qt6_block = f"""
<div class="card">
<h2>&#129514; Windows &mdash; x86_64 &mdash; Qt6 track</h2>
<div class="warning">
&#9888;&#65039; <strong>Experimental.</strong> These Qt6-based installer, portable and MSI
builds are new and not as thoroughly tested as the Qt5 track above. Expect rough
edges; please report issues and mention &quot;Qt6&quot; explicitly.
</div>
<div class="downloads">
{qt6_installer_btn}
{qt6_msi_btn}
{qt6_portable_btn}
</div>
</div>"""
html = f"""<!DOCTYPE html>
<html lang="en">
<head>
@@ -80,7 +126,7 @@ For production use, download a <a href="https://github.com/{repo}/releases">stab
</div>
</div>
<div class="card">
<h2>&#127993; Windows &mdash; x86_64</h2>
<h2>&#127993; Windows &mdash; x86_64 &mdash; Qt5 track</h2>
<div class="downloads">
<a class="btn btn-primary" href="{installer_url}">
<span class="btn-icon">&#11015;</span>
@@ -97,6 +143,7 @@ For production use, download a <a href="https://github.com/{repo}/releases">stab
</a>
</div>
</div>
{qt6_block}
</main>
<footer>
Auto-generated by GitHub Actions &nbsp;&middot;&nbsp;
+11 -1
View File
@@ -53,6 +53,7 @@ parts:
qet-tb-generator:
plugin: python
source: https://github.com/raulroda/qet_tb_generator-plugin.git
source-tag: v1.31
python-packages: [PySimpleGUI]
stage-packages:
- python3-lxml
@@ -76,7 +77,16 @@ parts:
after: [kde-sdk-setup]
plugin: nil
source: .
stage-packages: [ git, sqlite3, xdg-user-dirs ]
stage-packages:
- git
- sqlite3
- xdg-user-dirs
# libxcb-cursor0 was added as a hard dependency of the Qt5 xcb platform
# plugin in Qt 5.15.x. The kf5-5-110-qt-5-15-11-core22 content snap does
# not bundle it, so dlopen() of libqxcb.so fails on Ubuntu 24.04 hosts
# with "found but could not load" (issue #373). Staging the 22.04 build
# of this library satisfies the dep without changing base or Qt version.
- libxcb-cursor0
build-packages:
- git
- libsqlite3-dev
+1 -1
View File
@@ -10,5 +10,5 @@ rem "C:/Users/<USER>/AppData/Local/QElectroTech/QElectroTech"
rem Sans l'option --data-dir, les données utilisateur (elements, titleblocks,
rem log, ...) de QElectroTech sont stockées dans
rem "C:/Users/<USER>/AppData/Roaming/QElectroTech/QElectroTech"
set command=bin\qelectrotech.exe --common-elements-dir=elements/ --common-tbt-dir=titleblocks/ --lang-dir=lang/ -style windowsvista %*
set command=bin\qelectrotech.exe --common-elements-dir=elements/ --common-tbt-dir=titleblocks/ --lang-dir=lang/ -platform windows:fontengine=freetype %*
@start %command%
+5 -2
View File
@@ -11,6 +11,9 @@
-->
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
<?ifndef QtPlatformArgs ?>
<?define QtPlatformArgs="" ?>
<?endif?>
<Package
Name="QElectroTech"
@@ -58,7 +61,7 @@
Directory="DesktopFolder"
Name="QElectroTech"
Target="[INSTALLDIR]bin\qelectrotech.exe"
Arguments="--common-elements-dir=&quot;[INSTALLDIR]elements/&quot; --common-tbt-dir=&quot;[INSTALLDIR]titleblocks/&quot; --lang-dir=&quot;[INSTALLDIR]lang/&quot; -style windowsvista"
Arguments="--common-elements-dir=&quot;[INSTALLDIR]elements/&quot; --common-tbt-dir=&quot;[INSTALLDIR]titleblocks/&quot; --lang-dir=&quot;[INSTALLDIR]lang/&quot; $(var.QtPlatformArgs)"
Icon="qet.ico"
WorkingDirectory="INSTALLDIR" />
<RegistryValue Root="HKCU"
@@ -73,7 +76,7 @@
Directory="ProgramMenuFolder"
Name="QElectroTech"
Target="[INSTALLDIR]bin\qelectrotech.exe"
Arguments="--common-elements-dir=&quot;[INSTALLDIR]elements/&quot; --common-tbt-dir=&quot;[INSTALLDIR]titleblocks/&quot; --lang-dir=&quot;[INSTALLDIR]lang/&quot; -style windowsvista"
Arguments="--common-elements-dir=&quot;[INSTALLDIR]elements/&quot; --common-tbt-dir=&quot;[INSTALLDIR]titleblocks/&quot; --lang-dir=&quot;[INSTALLDIR]lang/&quot; $(var.QtPlatformArgs)"
Icon="qet.ico"
WorkingDirectory="INSTALLDIR" />
<RegistryValue Root="HKCU"
+63
View File
@@ -0,0 +1,63 @@
# Configuration for git-cliff, tuned to mimic github_changelog_generator's output style
# Doc: https://git-cliff.org/docs/configuration
[changelog]
header = """
# Changelog\n
All notable changes to QElectroTech are documented here.\n
"""
# Format proche de github_changelog_generator : titre de version avec lien de comparaison + date
body = """
{% if version %}\
## [{{ version }}]\
{%- if previous.version %}({{ previous.version }}...{{ version }}){% endif %} \
- {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [Unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{% for commit in commits | unique(attribute="message") %}
- {{ commit.message | trim | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}](../../commit/{{ commit.id }}))\
{% endfor %}
{% endfor %}\n
"""
footer = ""
trim = true
[git]
conventional_commits = false
filter_unconventional = false
split_commits = false
protect_breaking_commits = false
filter_commits = false
tag_pattern = "^[0-9]+\\.[0-9]+(\\.[0-9]+)?$"
skip_tags = "nightly"
ignore_tags = "nightly"
topo_order = false
sort_commits = "newest"
# Ne garder que la première ligne du message (résumé), le corps détaillé
# est retiré ici plutôt qu'au moment de l'affichage, pour que la
# déduplication par message fonctionne correctement.
commit_preprocessors = [
{ pattern = "(?s)\n.*", replace = "" },
]
# Groupement par mots-clés (FR + EN), puisque l'historique QET
# ne suit pas Conventional Commits strictement.
commit_parsers = [
{ message = "^[Mm]erge", skip = true },
{ message = "^(?i)(fix|corrig|répar|bug)", group = "🐛 Bug Fixes" },
{ message = "^(?i)(feat|ajout|add|nouvelle|nouveau)", group = "🚀 Features" },
{ message = "^(?i)(doc|traduc|translation)", group = "📝 Documentation" },
{ message = "^(?i)(refactor|clean|nettoy|optimi)", group = "♻️ Refactoring / Cleanup" },
{ message = "^(?i)(element|librairie|library)", group = "📦 Elements / Libraries" },
{ message = ".*", group = "🔧 Other Changes" },
]
[remote.github]
owner = "qelectrotech"
repo = "qelectrotech-source-mirror"
+1 -1
View File
@@ -16,7 +16,7 @@
message(" - fetch_kdeaddons")
if(DEFINED BUILD_WITH_KF5)
if(BUILD_WITH_KF5)
Include(FetchContent)
option(BUILD_KF5 "Build KF5 libraries, use system ones otherwise" YES)
+54
View File
@@ -16,6 +16,13 @@
message(" - qet_compilation_vars")
# Note: GuiPrivate is intentionally NOT in this list. Qt6's CMake config only
# creates the Qt::GuiPrivate target when "GuiPrivate" is explicitly requested
# as a component, but Qt5 has no Qt5GuiPrivate package at all (the target is
# created implicitly with Gui), so requesting it as a component breaks the
# whole Qt5 configure. It is requested separately, guarded by
# QT_VERSION_MAJOR, after the main find_package.
# (Needed for QPdfEngine::drawHyperlink, the PDF internal links.)
set(QET_COMPONENTS
LinguistTools
PrintSupport
@@ -109,6 +116,36 @@ set(QET_RES_FILES
set(QET_SRC_FILES
${QET_DIR}/sources/cli_export.cpp
${QET_DIR}/sources/cli_export.h
${QET_DIR}/sources/pdf_links.cpp
${QET_DIR}/sources/pdf_links.h
${QET_DIR}/sources/import/edz/edzarchive.cpp
${QET_DIR}/sources/import/edz/edzarchive.h
${QET_DIR}/sources/import/edz/edzpart.cpp
${QET_DIR}/sources/import/edz/edzpart.h
${QET_DIR}/sources/import/edz/edzelementbuilder.cpp
${QET_DIR}/sources/import/edz/edzelementbuilder.h
${QET_DIR}/sources/import/edz/edzimporter.cpp
${QET_DIR}/sources/import/edz/edzimporter.h
${QET_DIR}/sources/import/edz/edzsevenzip.cpp
${QET_DIR}/sources/import/edz/edzsevenzip.h
${QET_DIR}/sources/import/edz/lzma/7zAlloc.c
${QET_DIR}/sources/import/edz/lzma/7zArcIn.c
${QET_DIR}/sources/import/edz/lzma/7zBuf.c
${QET_DIR}/sources/import/edz/lzma/7zCrc.c
${QET_DIR}/sources/import/edz/lzma/7zCrcOpt.c
${QET_DIR}/sources/import/edz/lzma/7zDec.c
${QET_DIR}/sources/import/edz/lzma/7zFile.c
${QET_DIR}/sources/import/edz/lzma/7zStream.c
${QET_DIR}/sources/import/edz/lzma/Bcj2.c
${QET_DIR}/sources/import/edz/lzma/Bra.c
${QET_DIR}/sources/import/edz/lzma/Bra86.c
${QET_DIR}/sources/import/edz/lzma/BraIA64.c
${QET_DIR}/sources/import/edz/lzma/CpuArch.c
${QET_DIR}/sources/import/edz/lzma/Delta.c
${QET_DIR}/sources/import/edz/lzma/Lzma2Dec.c
${QET_DIR}/sources/import/edz/lzma/LzmaDec.c
${QET_DIR}/sources/import/edz/lzma/Ppmd7.c
${QET_DIR}/sources/import/edz/lzma/Ppmd7Dec.c
${QET_DIR}/sources/borderproperties.cpp
${QET_DIR}/sources/borderproperties.h
${QET_DIR}/sources/bordertitleblock.cpp
@@ -614,6 +651,8 @@ set(QET_SRC_FILES
${QET_DIR}/sources/ui/borderpropertieswidget.h
${QET_DIR}/sources/ui/compositetexteditdialog.cpp
${QET_DIR}/sources/ui/compositetexteditdialog.h
${QET_DIR}/sources/ui/contactgroupselectiondialog.cpp
${QET_DIR}/sources/ui/contactgroupselectiondialog.h
${QET_DIR}/sources/ui/conductorpropertiesdialog.cpp
${QET_DIR}/sources/ui/conductorpropertiesdialog.h
${QET_DIR}/sources/ui/conductorpropertieswidget.cpp
@@ -630,6 +669,8 @@ set(QET_SRC_FILES
${QET_DIR}/sources/ui/diagrampropertieseditordockwidget.h
${QET_DIR}/sources/ui/diagramselection.cpp
${QET_DIR}/sources/ui/diagramselection.h
${QET_DIR}/sources/ui/backupdialog.cpp
${QET_DIR}/sources/ui/backupdialog.h
${QET_DIR}/sources/ui/dialogwaiting.cpp
${QET_DIR}/sources/ui/dialogwaiting.h
${QET_DIR}/sources/ui/dynamicelementtextitemeditor.cpp
@@ -683,6 +724,8 @@ set(QET_SRC_FILES
${QET_DIR}/sources/ui/configpage/generalconfigurationpage.h
${QET_DIR}/sources/ui/configpage/projectconfigpages.cpp
${QET_DIR}/sources/ui/configpage/projectconfigpages.h
${QET_DIR}/sources/ui/configpage/guidespropertieswidget.cpp
${QET_DIR}/sources/ui/configpage/guidespropertieswidget.h
${QET_DIR}/sources/undocommand/addelementtextcommand.cpp
${QET_DIR}/sources/undocommand/addelementtextcommand.h
@@ -722,6 +765,17 @@ set(QET_SRC_FILES
${QET_DIR}/sources/xml/terminalstriplayoutpatternxml.h
)
if(NOT BUILD_WITH_KF5)
list(APPEND QET_SRC_FILES
${QET_DIR}/sources/ui/nokde/kautosavefile.cpp
${QET_DIR}/sources/ui/nokde/kautosavefile.h
${QET_DIR}/sources/ui/nokde/kcolorbutton.cpp
${QET_DIR}/sources/ui/nokde/kcolorbutton.h
${QET_DIR}/sources/ui/nokde/kcolorcombo.cpp
${QET_DIR}/sources/ui/nokde/kcolorcombo.h
)
endif()
set(TS_FILES
${QET_DIR}/lang/qet_ar.ts
${QET_DIR}/lang/qet_ca.ts
-3
View File
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7b7798233e8251baac7717d4b0f991ad5fdf23a76d9fbe864d363e3b93458560
size 529821696
BIN
View File
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

BIN
View File
Binary file not shown.
+1106 -630
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1106 -630
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1105 -629
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1105 -629
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1126 -632
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1105 -629
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1115 -627
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1105 -629
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1102 -626
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1106 -630
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1105 -629
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1106 -630
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1104 -628
View File
File diff suppressed because it is too large Load Diff
+1105 -629
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1104 -628
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1104 -628
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1105 -629
View File
File diff suppressed because it is too large Load Diff
+1102 -626
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1105 -629
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1106 -630
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1220 -744
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1106 -630
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1103 -627
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1105 -629
View File
File diff suppressed because it is too large Load Diff
+1103 -627
View File
File diff suppressed because it is too large Load Diff
+1103 -627
View File
File diff suppressed because it is too large Load Diff
+1103 -627
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1104 -628
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1103 -627
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+1104 -628
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+2410 -1906
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -8,5 +8,5 @@ rem Met la collection QET en lecture seule
attrib +r elements/* /S /D
rem lance QElectroTech
set command=bin\qelectrotech.exe -platform windows:fontengine=freetype --common-elements-dir=elements/ --common-tbt-dir=titleblocks/ --lang-dir=lang/ --config-dir=conf/ --data-dir=conf/ -style plastique %*
set command=bin\qelectrotech.exe -platform windows:fontengine=freetype --common-elements-dir=elements/ --common-tbt-dir=titleblocks/ --lang-dir=lang/ --config-dir=conf/ --data-dir=conf/ %*
@start %command%
+12
View File
@@ -0,0 +1,12 @@
@echo off
rem Se rend dans le dossier qui convient
set current_dir=%~dp0
cd /d %current_dir%
rem Met la collection QET en lecture seule
attrib +r elements/* /S /D
rem lance QElectroTech
set command=bin\qelectrotech.exe --common-elements-dir=elements/ --common-tbt-dir=titleblocks/ --lang-dir=lang/ --config-dir=conf/ --data-dir=conf/ %*
@start %command%
+119
View File
@@ -0,0 +1,119 @@
# publiccode.yml — QElectroTech
# Standard: https://yml.publiccode.tools/ (v0.7)
# Place at the root of the main repository (qelectrotech-source-mirror)
# Validate before submission: https://publiccode-editor.developers.italia.it/
publiccodeYmlVersion: "0.4"
name: QElectroTech
applicationSuite: QElectroTech
url: "https://github.com/qelectrotech/qelectrotech-source-mirror.git"
landingURL: "https://qelectrotech.org/"
releaseDate: "2026-01-25"
softwareVersion: "0.100"
developmentStatus: stable
softwareType: standalone/desktop
platforms:
- windows
- mac
- linux
- bsd
# NB: check/adjust against the official category list
# (https://yml.publiccode.tools/categories.html) before submission
categories:
- cad
- it-development
- engineering
description:
en:
shortDescription: >-
Free electrical diagram editor, also used for plumbing, hydraulics,
pneumatics, automotive wiring and photovoltaic schematics.
longDescription: >-
QElectroTech (QET) is a free and open source CAD/CAE application to
create complex industrial and domestic electrical diagrams. While
originally focused on electrical engineering, it is also widely used
for plumbing, geothermal, air-conditioning, layout, hydraulics,
pneumatics, home automation, automotive wiring, process diagrams
(P&ID), photovoltaic installations and many other technical domains.
The software ships with a community-maintained library of over 9000
standardized symbols. It runs identically on Windows, macOS, Linux
and BSD, and files created on one platform can be opened on another
without conversion.
QET has been developed since 2007 and community-maintained since
2013. It is notably used as a free alternative to commercial
software such as EPLAN or SEE Electrical, by hobbyists, teachers,
students, professional electricians and companies worldwide.
documentation: "https://qelectrotech.github.io/qelectrotech-doc/index.html"
apiDocumentation: ""
features:
- Multi-domain electrical and schematic diagram creation
- Library of over 9000 standardized symbols
- Multi-sheet project management with configurable title blocks
- DXF import/export (via dxf2elmt)
- Bill of materials and terminal strip table generation
- "Companion tools: QET-elementScaler (symbol scaling) and qet_tb_generator (terminal block table generation)"
- Interface translated into 25 languages
- "Cross-platform: Windows, macOS, Linux, BSD"
legal:
license: GPL-2.0-only
mainCopyrightOwner: QElectroTech community
repoOwner: QElectroTech community
maintenance:
type: community
contacts:
- name: Laurent Trinques (scorpio810)
email: scorpio@qelectrotech.org
localisation:
localisationReady: true
availableLanguages:
- en
- fr
- ar
- ca
- cs
- da
- de
- el
- es
- hr
- hu
- it
- ja
- ko
- mn
- nb
- nl
- pl
- pt
- pt-BR
- ro
- ru
- sk
- sl
- sr
- sv
- tr
- uk
- zh
dependsOn:
open:
- name: Qt
versionMin: "5.15"
- name: KF5 (KDE Frameworks)
optional: true
+1 -1
Submodule pugixml updated: 5a1892b321...27b68329de
+10 -2
View File
@@ -171,7 +171,9 @@ HEADERS += $$files(sources/*.h) \
$$files(sources/xml/*.h) \
$$files(sources/dxf/*.h) \
$$files(sources/qet_elementscaler/*.h) \
$$files(sources/svg/*.h)
$$files(sources/svg/*.h) \
$$files(sources/import/edz/*.h) \
$$files(sources/import/edz/lzma/*.h)
SOURCES += $$files(sources/*.cpp) \
$$files(sources/editor/*.cpp) \
@@ -215,11 +217,17 @@ SOURCES += $$files(sources/*.cpp) \
$$files(sources/xml/*.cpp) \
$$files(sources/dxf/*.cpp) \
$$files(sources/qet_elementscaler/*.cpp) \
$$files(sources/svg/*.cpp)
$$files(sources/svg/*.cpp) \
$$files(sources/import/edz/*.cpp) \
$$files(sources/import/edz/lzma/*.c)
# Needed for use promote QTreeWidget in terminalstripeditor.ui
INCLUDEPATH += sources/TerminalStrip/ui
# Needed for the EPLAN .edz importer (PR #513) and its bundled lzma/7z sources
INCLUDEPATH += sources/import/edz
INCLUDEPATH += sources/import/edz/lzma
# Liste des fichiers qui seront incorpores au binaire en tant que ressources Qt
RESOURCES += qelectrotech.qrc
+1
View File
@@ -222,6 +222,7 @@
<file>ico/24x16/dk.png</file>
<file>ico/24x16/br.png</file>
<file>ico/22x22/grid.png</file>
<file>ico/22x22/guides.png</file>
<file>ico/22x22/terminalstrip.png</file>
<file>ico/16x16/diagram.png</file>
<file>ico/16x16/edit-clear-locationbar-rtl.png</file>
@@ -143,8 +143,12 @@ ElementsLocation ECHSFileToFile::copyElement(ElementsLocation &source, ElementsL
//On windows when user drag and drop an element from the common elements collection
//to the custom elements collection, the element file stay in read only mode, and so
//user can't save the element
#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
QNtfsPermissionCheckGuard ntfs_guard;
#else
extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
qt_ntfs_permission_lookup++;
#endif
QFile file(destination.fileSystemPath() % "/" % new_elmt_name);
if (!file.isWritable()) {
if (!file.setPermissions(file.permissions() | QFileDevice::WriteUser)) {
@@ -152,7 +156,9 @@ ElementsLocation ECHSFileToFile::copyElement(ElementsLocation &source, ElementsL
<< " in ECHSFileToFile::copyElement";
}
}
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
qt_ntfs_permission_lookup--;
#endif
#endif
return ElementsLocation (destination.fileSystemPath() % "/" % new_elmt_name);
}
@@ -469,7 +475,7 @@ bool ElementCollectionHandler::setNames(ElementsLocation &location,
root.appendChild(name_list.toXml(document));
QString filepath = location.fileSystemPath()
+ "/qet_directory";
% "/qet_directory";
if (!QET::writeXmlFile(document, filepath)) {
qDebug() << "ElementCollectionHandler::setNames : write qet-directory file failed";
return false;
@@ -25,12 +25,8 @@
#include "xmlelementcollection.h"
#include "xmlprojectelementcollectionitem.h"
#include <QFutureWatcher>
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt 6: remove
#include <QtConcurrentMap>
#else
#include <QtConcurrentRun>
#endif
/**
@brief ElementsCollectionModel::ElementsCollectionModel
@@ -297,11 +293,8 @@ void ElementsCollectionModel::loadCollections(bool common_collection,
this, &ElementsCollectionModel::loadingFinished);
connect(watcher, &QFutureWatcher<void>::finished, watcher, &QFutureWatcher<void>::deleteLater);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
m_future = QtConcurrent::map(m_items_list_to_setUp, setUpData);
#else
qDebug() << "Help code for QT 6 or later";
#endif
watcher->setFuture(m_future);
}
@@ -538,6 +531,16 @@ QList<QETProject *> ElementsCollectionModel::project() const
*/
void ElementsCollectionModel::highlightUnusedElement()
{
//Reset only the items currently highlighted in red, so elements that
//are no longer unused lose the highlight. Scoping to the red
//Dense4Pattern avoids touching other backgrounds (e.g. the amber
//"show this dir" highlight) and avoids needless updates on big
//collections (issue #159).
for (ElementCollectionItem *eci : items())
if (eci->background().style() == Qt::Dense4Pattern &&
eci->background().color() == Qt::red)
eci->setBackground(QBrush());
QList <ElementsLocation> unused;
foreach (QETProject *project, m_project_list)
@@ -19,6 +19,7 @@
#include "../editor/ui/qetelementeditor.h"
#include "../elementscategoryeditor.h"
#include "../import/edz/edzimporter.h"
#include "../newelementwizard.h"
#include "../qetapp.h"
#include "../qetdiagrameditor.h"
@@ -32,8 +33,14 @@
#include "fileelementcollectionitem.h"
#include "xmlprojectelementcollectionitem.h"
#include <QCheckBox>
#include <QDesktopServices>
#include <QDialog>
#include <QDialogButtonBox>
#include <QFileDialog>
#include <QLabel>
#include <QMenu>
#include <QPushButton>
#include <QTimer>
#include <QUrl>
#include <QVBoxLayout>
@@ -158,6 +165,8 @@ void ElementsCollectionWidget::setUpAction()
tr("Nouveau dossier"), this);
m_new_element = new QAction(QET::Icons::ElementNew,
tr("Nouvel élément"), this);
m_import_edz = new QAction(QET::Icons::ElementNew,
tr("Importer une pièce EPLAN (.edz)…"), this);
m_show_this_dir = new QAction(QET::Icons::FolderOnlyThis,
tr("Afficher uniquement ce dossier"),
this);
@@ -247,6 +256,8 @@ void ElementsCollectionWidget::setUpConnection()
this, &ElementsCollectionWidget::newDirectory);
connect(m_new_element, &QAction::triggered,
this, &ElementsCollectionWidget::newElement);
connect(m_import_edz, &QAction::triggered,
this, &ElementsCollectionWidget::importEdz);
connect(m_show_this_dir, &QAction::triggered,
this, &ElementsCollectionWidget::showThisDir);
connect(m_show_all_dir, &QAction::triggered,
@@ -329,6 +340,7 @@ void ElementsCollectionWidget::customContextMenu(const QPoint &point)
{
if (!feci->isMacrosCollection()) {
m_context_menu->addAction(m_new_element);
m_context_menu->addAction(m_import_edz);
}
m_context_menu->addAction(m_new_directory);
if (!feci->isCollectionRoot())
@@ -599,6 +611,108 @@ void ElementsCollectionWidget::newElement()
&ElementsCollectionWidget::locationWasSaved);
}
/**
@brief ElementsCollectionWidget::confirmEdzImportTerms
Show the EPLAN (.edz) import warning dialog. The user must tick the
acknowledgement checkbox before the Import button is enabled.
@return true if the user accepted the terms, false otherwise.
*/
bool ElementsCollectionWidget::confirmEdzImportTerms()
{
QDialog dialog(this);
dialog.setWindowTitle(tr("Avertissement — Importation d'un fichier EPLAN (.edz)"));
QLabel *text = new QLabel(
tr("Le format .edz peut provenir de deux sources différentes :\n"
"\n"
"• Le portail EPLAN Data Portal (dataportal.eplan.com), soumis "
"aux conditions d'utilisation de l'environnement EPLAN Cloud ;\n"
"• Le site d'un fabricant de composants (ou d'un distributeur) "
"qui met ses fichiers .edz à disposition directement, selon ses "
"propres conditions.\n"
"\n"
"QElectroTech ne peut pas déterminer automatiquement l'origine "
"du fichier que vous importez, ni les conditions qui s'y "
"appliquent.\n"
"\n"
"En important ce fichier, vous confirmez que :\n"
"\n"
"• vous connaissez son origine et êtes autorisé à l'utiliser "
"dans ce contexte, au regard des conditions applicables à cette "
"source ;\n"
"• cette importation est effectuée à vos propres risques et "
"responsabilité ;\n"
"• ni QElectroTech, ni ses mainteneurs, ni ses contributeurs ne "
"peuvent être tenus responsables d'une utilisation non conforme "
"de ces données."),
&dialog);
text->setWordWrap(true);
QCheckBox *accept_box = new QCheckBox(
tr("J'ai lu et j'accepte ces conditions."), &dialog);
QDialogButtonBox *buttons = new QDialogButtonBox(
QDialogButtonBox::Cancel, &dialog);
QPushButton *import_button = buttons->addButton(
tr("Importer"), QDialogButtonBox::AcceptRole);
import_button->setDefault(true);
import_button->setEnabled(false);
connect(accept_box, &QCheckBox::toggled,
import_button, &QPushButton::setEnabled);
connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
QVBoxLayout *layout = new QVBoxLayout(&dialog);
layout->addWidget(text);
layout->addWidget(accept_box);
layout->addWidget(buttons);
return dialog.exec() == QDialog::Accepted;
}
/**
@brief ElementsCollectionWidget::importEdz
Import an EPLAN Data Portal part (.edz) as a QET element into the directory
pointed at by the context menu.
*/
void ElementsCollectionWidget::importEdz()
{
ElementCollectionItem *eci = elementCollectionItemForIndex(
m_index_at_context_menu);
if (!eci || eci->type() != FileElementCollectionItem::Type) {
return;
}
FileElementCollectionItem *feci =
static_cast<FileElementCollectionItem*>(eci);
if (feci->isCommonCollection() || !feci->isDir()) {
return;
}
if (!confirmEdzImportTerms()) {
return;
}
const QString edz_path = QFileDialog::getOpenFileName(
this, tr("Importer une pièce EPLAN"), QString(),
tr("Pièces EPLAN (*.edz)"));
if (edz_path.isEmpty()) {
return;
}
EdzImporter importer;
if (!importer.importToDirectory(edz_path, feci->fileSystemPath())) {
QET::QetMessageBox::critical(
this, tr("Import EPLAN"),
tr("Impossible d'importer cette pièce :\n%1")
.arg(importer.errorString()));
return;
}
reload();
}
/**
@brief ElementsCollectionWidget::showThisDir
Hide all directories except the pointed dir;
@@ -830,7 +944,7 @@ void ElementsCollectionWidget::search()
}
//start the search when text have at least 3 letters.
if (text.count() < 3) {
if (text.size() < 3) {
return;
}
@@ -72,6 +72,8 @@ class ElementsCollectionWidget : public QWidget
void editDirectory();
void newDirectory();
void newElement();
bool confirmEdzImportTerms();
void importEdz();
void showThisDir();
void resetShowThisDir();
void dirProperties();
@@ -112,6 +114,7 @@ class ElementsCollectionWidget : public QWidget
*m_edit_dir,
*m_new_directory,
*m_new_element,
*m_import_edz,
*m_show_this_dir,
*m_show_all_dir,
*m_dir_propertie;
@@ -523,7 +523,9 @@ bool ElementsLocation::isCompanyCollection() const
*/
bool ElementsLocation::isCustomCollection() const
{
return fileSystemPath().startsWith(QETApp::customElementsDirN());
const QString dir = QETApp::customElementsDirN();
const QString path = fileSystemPath();
return path == dir || path.startsWith(dir + QLatin1Char('/'));
}
/**
@@ -701,11 +703,11 @@ pugi::xml_document ElementsLocation::pugiXml() const
if (!m_project)
{
#ifndef Q_OS_LINUX
if (docu.load_file(m_file_system_path.toStdString().c_str())) {
if (docu.load_file(m_file_system_path.toStdWString().c_str())) {
docu.save(m_string_stream);
}
#else
docu.load_file(m_file_system_path.toStdString().c_str());
docu.load_file(m_file_system_path.toStdWString().c_str());
#endif
}
else
@@ -802,14 +804,15 @@ bool ElementsLocation::setXml(const QDomDocument &xml_document) const
QString path_ = collectionPath(false);
QRegularExpression rx("^(.*)/(.*\\.elmt)$");
QRegularExpressionMatch match = rx.match(path_);
if (rx.exactMatch(path_))
if (match.hasMatch())
{
return project()
->embeddedElementCollection()
->addElementDefinition(
rx.cap(1),
rx.cap(2),
match.captured(1),
match.captured(2),
xml_document.documentElement());
}
else
@@ -138,7 +138,7 @@ QString FileElementCollectionItem::localName()
{
QString str(fileSystemPath() % "/qet_directory");
pugi::xml_document docu;
if(docu.load_file(str.toStdString().c_str()))
if(docu.load_file(str.toStdWString().c_str()))
{
if (QString(docu.document_element().name())
== "qet-directory")
@@ -274,7 +274,9 @@ bool FileElementCollectionItem::isCompanyCollection() const
*/
bool FileElementCollectionItem::isCustomCollection() const
{
return fileSystemPath().startsWith(QETApp::customElementsDirN());
const QString dir = QETApp::customElementsDirN();
const QString path = fileSystemPath();
return path == dir || path.startsWith(dir + QLatin1Char('/'));
}
/**
+7
View File
@@ -263,6 +263,13 @@ QString NamesList::name(const QString &fallback_name) const
QString system_language = QETApp::langFromSetting();
if (! map_names[system_language].isEmpty())
return (map_names[system_language]);
// langFromSetting() may return a full locale (e.g. "de_DE") while element
// and folder names are keyed by the 2-letter language code ("de"). Try the
// base language before falling back to English, mirroring what setLanguage()
// does for the UI translations.
const QString base_language = system_language.section('_', 0, 0);
if (base_language != system_language && ! map_names[base_language].isEmpty())
return (map_names[base_language]);
if (! map_names["en"].isEmpty()) return (map_names["en"]);
if (! fallback_name.isEmpty()) return (fallback_name);
if (map_names.count()) return (map_names.begin().value());
@@ -16,7 +16,7 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "searchandreplaceworker.h"
#include "../qetproject.h"
#include "../QPropertyUndoCommand/qpropertyundocommand.h"
#include "../diagram.h"
#include "../diagramcommands.h"
@@ -18,6 +18,7 @@
#include "terminalstripdrawer.h"
#include <QPainter>
#include <QHash>
namespace TerminalStripDrawer {
@@ -265,13 +266,13 @@ void TerminalStripDrawer::paint(QPainter *painter)
painter->restore();
//Draw the bridges
for (const auto &points_ : qAsConst(bridges_anchor_points))
for (const auto &points_ : std::as_const(bridges_anchor_points))
{
painter->save();
auto pen_{painter->pen()};
pen_.setWidth(2);
painter->setPen(pen_);
painter->drawPolyline(QPolygonF{points_});
painter->drawPolyline(QPolygonF(points_));
painter->restore();
}
}
@@ -16,7 +16,7 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "terminalstripitem.h"
#include "../../qetproject.h"
#include "../diagram.h"
#include "../../project/projectpropertieshandler.h"
@@ -126,7 +126,7 @@ void RemoveTerminalFromStripCommand::redo()
if (m_strip)
{
QVector<QSharedPointer<RealTerminal>> real_t;
for (const auto &real_t_vector : qAsConst(m_terminals)) {
for (const auto &real_t_vector : std::as_const(m_terminals)) {
real_t.append(real_t_vector);
}
@@ -68,7 +68,7 @@ void UnGroupTerminalsCommand::undo()
m_terminal_strip->groupTerminals(key, m_physical_real_H.value(key));
}
//Second, set level.
for (const auto &pair : qAsConst(m_real_t_level)) {
for (const auto &pair : std::as_const(m_real_t_level)) {
m_terminal_strip->setLevel(pair.first, pair.second);
}
}
@@ -78,7 +78,7 @@ void UnGroupTerminalsCommand::redo()
{
if (m_terminal_strip)
{
for (const auto &value : qAsConst(m_physical_real_H)) {
for (const auto &value : std::as_const(m_physical_real_H)) {
m_terminal_strip->unGroupTerminals(value);
}
}
+1 -1
View File
@@ -131,7 +131,7 @@ bool PhysicalTerminal::setLevelOf(const QSharedPointer<RealTerminal> &terminal,
if (i >= 0)
{
#if QT_VERSION >= QT_VERSION_CHECK(5,14,0)
m_real_terminal.swapItemsAt(i, std::min(level, m_real_terminal.size()-1));
m_real_terminal.swapItemsAt(i, std::min<int>(level, static_cast<int>(m_real_terminal.size())-1));
#else
auto j = std::min(level, m_real_terminal.size()-1);
std::swap(m_real_terminal.begin()[i], m_real_terminal.begin()[j]);
+5 -5
View File
@@ -466,7 +466,7 @@ QSharedPointer<RealTerminal> TerminalStrip::realTerminalForUuid(const QUuid &uui
QVector<QSharedPointer<RealTerminal>> TerminalStrip::realTerminals() const
{
QVector<QSharedPointer<RealTerminal>> vector_;
for (const auto &phy : qAsConst(m_physical_terminals)) {
for (const auto &phy : std::as_const(m_physical_terminals)) {
vector_.append(phy->realTerminals());
}
return vector_;
@@ -639,7 +639,7 @@ bool TerminalStrip::isBridgeable(const QVector<QSharedPointer<RealTerminal>> &re
// Get the physical terminal and pos
auto first_physical_terminal = first_real_terminal->physicalTerminal();
QVector<shared_physical_terminal> physical_vector{first_physical_terminal};
QVector<int> pos_vector{m_physical_terminals.indexOf(first_physical_terminal)};
QVector<int> pos_vector{static_cast<int>(m_physical_terminals.indexOf(first_physical_terminal))};
auto bridge_ = isBridged(first_real_terminal);
//bool to know at the end of this function if at least one terminal is not bridged
@@ -856,7 +856,7 @@ QSharedPointer<TerminalStripBridge> TerminalStrip::isBridged(const QSharedPointe
{
if (real_terminal)
{
for (const auto &bridge_ : qAsConst(m_bridge)) {
for (const auto &bridge_ : std::as_const(m_bridge)) {
if (bridge_->realTerminals().contains(real_terminal))
return bridge_;
}
@@ -983,7 +983,7 @@ QDomElement TerminalStrip::toXml(QDomDocument &parent_document)
}
root_elmt.appendChild(xml_layout);
for (const auto &bridge_ : qAsConst(m_bridge)) {
for (const auto &bridge_ : std::as_const(m_bridge)) {
root_elmt.appendChild(bridge_->toXml(parent_document));
}
@@ -1024,7 +1024,7 @@ bool TerminalStrip::fromXml(QDomElement &xml_element)
for (auto &xml_real : QETXML::findInDomElement(xml_physical, RealTerminal::xmlTagName()))
{
const auto uuid_ = QUuid(xml_real.attribute(QStringLiteral("element_uuid")));
for (auto terminal_elmt : qAsConst(free_terminals))
for (auto terminal_elmt : std::as_const(free_terminals))
{
if (terminal_elmt->uuid() == uuid_)
{
@@ -85,7 +85,7 @@ QDomElement TerminalStripBridge::toXml(QDomDocument &parent_document) const
root_elmt.setAttribute(QStringLiteral("color"), m_color.name());
auto terminals_elmt = parent_document.createElement(QStringLiteral("real_terminals"));
for (const auto &real_t : qAsConst(m_real_terminals))
for (const auto &real_t : std::as_const(m_real_terminals))
{
if (real_t)
{
@@ -106,7 +106,7 @@ void TerminalStripBridge::fromXml(const QDomElement &dom_element)
}
m_uuid = QUuid(dom_element.attribute(QStringLiteral("uuid"), m_uuid.toString()));
m_color.setNamedColor(dom_element.attribute(QStringLiteral("color")));
m_color = QColor(dom_element.attribute(QStringLiteral("color")));
const auto real_t_vector = QETXML::subChild(dom_element,
QStringLiteral("real_terminals"),
@@ -17,7 +17,7 @@
*/
#include "addterminalstripitemdialog.h"
#include "ui_addterminalstripitemdialog.h"
#include "../../qetproject.h"
#include "../../undocommand/addgraphicsobjectcommand.h"
#include "../terminalstrip.h"
#include "../GraphicsItem/terminalstripitem.h"
@@ -535,7 +535,7 @@ modelRealTerminalData TerminalStripModel::dataAtRow(int row) const
else
{
auto current_row = 0;
for (const auto &physical_data : qAsConst(m_physical_data))
for (const auto &physical_data : std::as_const(m_physical_data))
{
for (const auto &real_data : physical_data.real_data)
{
@@ -567,7 +567,7 @@ void TerminalStripModel::replaceDataAtRow(modelRealTerminalData data, int row)
auto current_row = 0;
auto current_physical = 0;
for (const auto &physical_data : qAsConst(m_physical_data))
for (const auto &physical_data : std::as_const(m_physical_data))
{
auto current_real = 0;
for (int i=0 ; i<physical_data.real_data.count() ; ++i)
@@ -606,7 +606,7 @@ modelPhysicalTerminalData TerminalStripModel::physicalDataAtIndex(int index) con
int current_phy = -1;
bool match_ = false;
for (const auto &ptd_ : qAsConst(m_physical_data))
for (const auto &ptd_ : std::as_const(m_physical_data))
{
current_checked_index += ptd_.real_data.size();
++current_phy;
@@ -637,9 +637,9 @@ modelRealTerminalData TerminalStripModel::realDataAtIndex(int index) const
int current_checked_index = -1;
for (const auto & ptd_ : qAsConst(m_physical_data))
for (const auto & ptd_ : std::as_const(m_physical_data))
{
for (const auto & rtd_ : qAsConst(ptd_.real_data)) {
for (const auto & rtd_ : std::as_const(ptd_.real_data)) {
++current_checked_index;
if (current_checked_index == index) {
return rtd_;

Some files were not shown because too many files have changed in this diff Show More