From 95c2f6cf6d3fe966ed153b9c1f7a04284089f6d6 Mon Sep 17 00:00:00 2001 From: Shane Ringrose Date: Sat, 13 Jun 2026 08:19:35 +1200 Subject: [PATCH 1/7] proto: conductor properties in selection-properties dock (#500) --- cmake/qet_compilation_vars.cmake | 2 + sources/factory/propertieseditorfactory.cpp | 17 +++ .../ui/conductorpropertieseditorwidget.cpp | 126 ++++++++++++++++++ sources/ui/conductorpropertieseditorwidget.h | 58 ++++++++ 4 files changed, 203 insertions(+) create mode 100644 sources/ui/conductorpropertieseditorwidget.cpp create mode 100644 sources/ui/conductorpropertieseditorwidget.h diff --git a/cmake/qet_compilation_vars.cmake b/cmake/qet_compilation_vars.cmake index 7e150a6e7..95f471694 100644 --- a/cmake/qet_compilation_vars.cmake +++ b/cmake/qet_compilation_vars.cmake @@ -616,6 +616,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/conductorpropertieseditorwidget.cpp + ${QET_DIR}/sources/ui/conductorpropertieseditorwidget.h ${QET_DIR}/sources/ui/conductorpropertiesdialog.cpp ${QET_DIR}/sources/ui/conductorpropertiesdialog.h ${QET_DIR}/sources/ui/conductorpropertieswidget.cpp diff --git a/sources/factory/propertieseditorfactory.cpp b/sources/factory/propertieseditorfactory.cpp index 6a18db924..f53ec4b1e 100644 --- a/sources/factory/propertieseditorfactory.cpp +++ b/sources/factory/propertieseditorfactory.cpp @@ -22,6 +22,7 @@ #include "../qetgraphicsitem/ViewItem/qetgraphicstableitem.h" #include "../qetgraphicsitem/ViewItem/ui/graphicstablepropertieseditor.h" #include "../qetgraphicsitem/ViewItem/ui/projectdbmodelpropertieswidget.h" +#include "../qetgraphicsitem/conductor.h" #include "../qetgraphicsitem/diagramimageitem.h" #include "../qetgraphicsitem/dynamicelementtextitem.h" #include "../qetgraphicsitem/element.h" @@ -30,6 +31,7 @@ #include "../qetgraphicsitem/qetshapeitem.h" #include "../ui/dynamicelementtextitemeditor.h" #include "../ui/elementpropertieswidget.h" +#include "../ui/conductorpropertieseditorwidget.h" #include "../ui/imagepropertieswidget.h" #include "../ui/inditextpropertieswidget.h" #include "../ui/shapegraphicsitempropertieswidget.h" @@ -100,6 +102,21 @@ PropertiesEditorWidget *PropertiesEditorFactory::propertiesEditor( switch (type_) { + case Conductor::Type: //1001 + { + //Prototype (#500): single-conductor editing in the dock. + if (count_ > 1) { + return nullptr; + } + auto conductor = static_cast(item); + + if (class_name == ConductorPropertiesEditorWidget::staticMetaObject.className()) + { + static_cast(editor)->setConductor(conductor); + return editor; + } + return new ConductorPropertiesEditorWidget(conductor, parent); + } case Element::Type: //1000 { if (count_ > 1) { diff --git a/sources/ui/conductorpropertieseditorwidget.cpp b/sources/ui/conductorpropertieseditorwidget.cpp new file mode 100644 index 000000000..33a73077d --- /dev/null +++ b/sources/ui/conductorpropertieseditorwidget.cpp @@ -0,0 +1,126 @@ +/* + Copyright 2006-2026 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#include "conductorpropertieseditorwidget.h" + +#include "../QPropertyUndoCommand/qpropertyundocommand.h" +#include "../diagram.h" +#include "../qetgraphicsitem/conductor.h" +#include "conductorpropertieswidget.h" + +#include + +/** + @brief ConductorPropertiesEditorWidget::ConductorPropertiesEditorWidget + @param conductor : conductor to edit + @param parent : parent widget +*/ +ConductorPropertiesEditorWidget::ConductorPropertiesEditorWidget( + Conductor *conductor, QWidget *parent) : + PropertiesEditorWidget(parent), + m_cpw(new ConductorPropertiesWidget(this)) +{ + auto *layout = new QVBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(m_cpw); + setDisabled(true); + setConductor(conductor); +} + +ConductorPropertiesEditorWidget::~ConductorPropertiesEditorWidget() +{} + +/** + @brief ConductorPropertiesEditorWidget::setConductor + Set (or change) the conductor whose properties are edited. + @param conductor +*/ +void ConductorPropertiesEditorWidget::setConductor(Conductor *conductor) +{ + if (!conductor) return; + m_conductor = conductor; + setEnabled(true); + updateUi(); +} + +/** + @brief ConductorPropertiesEditorWidget::apply + Push the edit onto the diagram's undo stack. +*/ +void ConductorPropertiesEditorWidget::apply() +{ + if (!m_conductor || !m_conductor->diagram()) return; + if (QUndoCommand *undo = associatedUndo()) + m_conductor->diagram()->undoStack().push(undo); + m_initial = m_conductor->properties(); +} + +/** + @brief ConductorPropertiesEditorWidget::reset + Discard the in-progress edit, restoring the conductor's current properties. +*/ +void ConductorPropertiesEditorWidget::reset() +{ + if (!m_conductor) return; + m_cpw->setProperties(m_initial); +} + +/** + @brief ConductorPropertiesEditorWidget::updateUi + Reload the widget from the conductor (e.g. when the selection changes). +*/ +void ConductorPropertiesEditorWidget::updateUi() +{ + if (!m_conductor) return; + m_initial = m_conductor->properties(); + m_cpw->setProperties(m_initial); +} + +/** + @brief ConductorPropertiesEditorWidget::associatedUndo + @return the edit as a QPropertyUndoCommand, or nullptr if unchanged. + + Prototype note: applies only to the selected conductor. The modal dialog + additionally offers to propagate to every conductor on the same potential + (relatedPotentialConductors()); whether/how to expose that in the dock is + the open design decision for #500. +*/ +QUndoCommand *ConductorPropertiesEditorWidget::associatedUndo() const +{ + if (!m_conductor) return nullptr; + + const ConductorProperties new_properties = m_cpw->properties(); + if (new_properties == m_conductor->properties()) return nullptr; + + QVariant old_value, new_value; + old_value.setValue(m_conductor->properties()); + new_value.setValue(new_properties); + + auto *undo = new QPropertyUndoCommand( + m_conductor, "properties", old_value, new_value); + undo->setText(tr("Modifier les propriétés d'un conducteur", "undo caption")); + return undo; +} + +/** + @brief ConductorPropertiesEditorWidget::title + @return the panel title. +*/ +QString ConductorPropertiesEditorWidget::title() const +{ + return tr("Conducteur"); +} diff --git a/sources/ui/conductorpropertieseditorwidget.h b/sources/ui/conductorpropertieseditorwidget.h new file mode 100644 index 000000000..365e34ff7 --- /dev/null +++ b/sources/ui/conductorpropertieseditorwidget.h @@ -0,0 +1,58 @@ +/* + Copyright 2006-2026 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#ifndef CONDUCTORPROPERTIESEDITORWIDGET_H +#define CONDUCTORPROPERTIESEDITORWIDGET_H + +#include "../PropertiesEditor/propertieseditorwidget.h" +#include "../conductorproperties.h" + +class Conductor; +class ConductorPropertiesWidget; + +/** + @brief The ConductorPropertiesEditorWidget class + Hosts the existing ConductorPropertiesWidget in the dockable selection- + properties panel, so a selected conductor can be edited in place like the + other item types, instead of only through the modal dialog (issue #500). + Prototype: single-conductor editing; applying to the whole potential is the + open design question (the modal dialog offers it via a prompt). +*/ +class ConductorPropertiesEditorWidget : public PropertiesEditorWidget +{ + Q_OBJECT + + public: + explicit ConductorPropertiesEditorWidget( + Conductor *conductor = nullptr, QWidget *parent = nullptr); + ~ConductorPropertiesEditorWidget() override; + + void setConductor(Conductor *conductor); + + void apply() override; + void reset() override; + void updateUi() override; + QUndoCommand *associatedUndo() const override; + QString title() const override; + + private: + ConductorPropertiesWidget *m_cpw = nullptr; + Conductor *m_conductor = nullptr; + ConductorProperties m_initial; +}; + +#endif // CONDUCTORPROPERTIESEDITORWIDGET_H From e3ede85efd2496f62c688a0f15edd8a653f4db02 Mon Sep 17 00:00:00 2001 From: Shane Ringrose Date: Sat, 13 Jun 2026 18:05:26 +1200 Subject: [PATCH 2/7] conductor dock: scrollable/narrowable + View-menu enable toggle (#500) --- sources/factory/propertieseditorfactory.cpp | 8 ++++++++ sources/qetdiagrameditor.cpp | 17 +++++++++++++++++ sources/ui/conductorpropertieseditorwidget.cpp | 13 ++++++++++++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/sources/factory/propertieseditorfactory.cpp b/sources/factory/propertieseditorfactory.cpp index f53ec4b1e..f08935423 100644 --- a/sources/factory/propertieseditorfactory.cpp +++ b/sources/factory/propertieseditorfactory.cpp @@ -37,6 +37,7 @@ #include "../ui/shapegraphicsitempropertieswidget.h" #include +#include /** @brief PropertiesEditorFactory::propertiesEditor @@ -104,6 +105,13 @@ PropertiesEditorWidget *PropertiesEditorFactory::propertiesEditor( { case Conductor::Type: //1001 { + //Feature toggle (#500): when disabled in the View menu, selecting a + //conductor brings up nothing in the dock. Default enabled. + if (!QSettings().value( + QStringLiteral("diagrameditor/conductor_properties_panel"), + true).toBool()) { + return nullptr; + } //Prototype (#500): single-conductor editing in the dock. if (count_ > 1) { return nullptr; diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index 2b1d9607c..c38acd2fa 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -879,6 +879,23 @@ void QETDiagramEditor::setUpMenu() menu_affichage -> addSeparator(); menu_affichage -> addAction(m_draw_grid); menu_affichage -> addAction(m_grey_background); + + // Toggle: show a selected conductor's properties in the selection-properties + // dock (#500). When off, selecting a conductor brings up nothing there. + QAction *cond_panel = menu_affichage -> addAction(tr("Propriétés du conducteur dans le panneau")); + cond_panel -> setCheckable(true); + cond_panel -> setStatusTip(tr("Affiche ou non les propriétés d'un conducteur sélectionné dans le panneau de sélection")); + { + QSettings settings; + cond_panel -> setChecked(settings.value(QStringLiteral("diagrameditor/conductor_properties_panel"), true).toBool()); + } + connect(cond_panel, &QAction::toggled, this, [this](bool on) { + QSettings().setValue(QStringLiteral("diagrameditor/conductor_properties_panel"), on); + // Apply immediately to the current selection. + if (DiagramView *dv = currentDiagramView()) + m_selection_properties_editor -> setDiagram(dv -> diagram()); + }); + menu_affichage -> addSeparator(); menu_affichage -> addActions(m_zoom_actions_group.actions()); diff --git a/sources/ui/conductorpropertieseditorwidget.cpp b/sources/ui/conductorpropertieseditorwidget.cpp index 33a73077d..e79450c71 100644 --- a/sources/ui/conductorpropertieseditorwidget.cpp +++ b/sources/ui/conductorpropertieseditorwidget.cpp @@ -22,6 +22,7 @@ #include "../qetgraphicsitem/conductor.h" #include "conductorpropertieswidget.h" +#include #include /** @@ -34,9 +35,19 @@ ConductorPropertiesEditorWidget::ConductorPropertiesEditorWidget( PropertiesEditorWidget(parent), m_cpw(new ConductorPropertiesWidget(this)) { + // The conductor widget is dialog-sized (min width ~600px), far too wide for + // a dock. Host it in a scroll area with a small minimum width so the dock + // can be dragged to any width (a scrollbar appears when narrower than the + // content). QET already persists dock geometry across restarts via + // QETDiagramEditor save/restoreState, so the chosen width is remembered. + auto *scroll = new QScrollArea(this); + scroll->setWidgetResizable(true); + scroll->setFrameShape(QFrame::NoFrame); + scroll->setWidget(m_cpw); auto *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(m_cpw); + layout->addWidget(scroll); + setMinimumWidth(120); setDisabled(true); setConductor(conductor); } From 280051745ae25fe6f21d81d251ab1c4fc1f2dc14 Mon Sep 17 00:00:00 2001 From: Shane Ringrose Date: Wed, 17 Jun 2026 04:12:47 +1200 Subject: [PATCH 3/7] Conductor dock: apply edits live, edit via label, fill height (#500) Addresses the testing feedback on the conductor selection-properties prototype: 1. Edits were never applied. The dock drives every editor through setLiveEdit(true), which each editor overrides to connect its field changes to apply(); ConductorPropertiesEditorWidget didn't override it, so the call was a no-op. Implement setLiveEdit() to connect the hosted ConductorPropertiesWidget's controls (commit-style signals) to apply(). A m_updating guard suppresses the signals emitted while the widget is loaded programmatically, so a partial mid-load state is never committed. 2. Clicking a conductor's text label showed nothing, because the label is a ConductorTextItem, not a Conductor. Map it to its parentConductor() in the editor factory, mirroring the double-click-the-label dialog behaviour. 3. The panel sat at a small size hint with empty space below it. Give the editor an Expanding vertical size policy (and a minimum height) so it fills the dock like the other editors. Refs #500 Co-Authored-By: Claude Opus 4.8 --- sources/factory/propertieseditorfactory.cpp | 12 +++ .../ui/conductorpropertieseditorwidget.cpp | 100 ++++++++++++++++++ sources/ui/conductorpropertieseditorwidget.h | 10 ++ 3 files changed, 122 insertions(+) diff --git a/sources/factory/propertieseditorfactory.cpp b/sources/factory/propertieseditorfactory.cpp index f08935423..8098f995a 100644 --- a/sources/factory/propertieseditorfactory.cpp +++ b/sources/factory/propertieseditorfactory.cpp @@ -23,6 +23,7 @@ #include "../qetgraphicsitem/ViewItem/ui/graphicstablepropertieseditor.h" #include "../qetgraphicsitem/ViewItem/ui/projectdbmodelpropertieswidget.h" #include "../qetgraphicsitem/conductor.h" +#include "../qetgraphicsitem/conductortextitem.h" #include "../qetgraphicsitem/diagramimageitem.h" #include "../qetgraphicsitem/dynamicelementtextitem.h" #include "../qetgraphicsitem/element.h" @@ -86,6 +87,17 @@ PropertiesEditorWidget *PropertiesEditorFactory::propertiesEditor( return nullptr; } QGraphicsItem *item = items.first(); + + //Selecting a conductor's text label edits its parent conductor (#500), + //mirroring how double-clicking the label opens the conductor dialog. + if (count_ == 1) { + if (auto *cti = qgraphicsitem_cast(item)) { + if (Conductor *parent_cond = cti->parentConductor()) { + items = {parent_cond}; + item = parent_cond; + } + } + } const int type_ = item->type(); //The editor widget can only edit one item diff --git a/sources/ui/conductorpropertieseditorwidget.cpp b/sources/ui/conductorpropertieseditorwidget.cpp index e79450c71..b0a0d7d33 100644 --- a/sources/ui/conductorpropertieseditorwidget.cpp +++ b/sources/ui/conductorpropertieseditorwidget.cpp @@ -21,8 +21,18 @@ #include "../diagram.h" #include "../qetgraphicsitem/conductor.h" #include "conductorpropertieswidget.h" +#include "../qtextorientationspinboxwidget.h" +#include + +#include +#include +#include +#include +#include #include +#include +#include #include /** @@ -48,6 +58,11 @@ ConductorPropertiesEditorWidget::ConductorPropertiesEditorWidget( layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(scroll); setMinimumWidth(120); + // Expand vertically to fill the dock like the other editors do (otherwise + // the panel sits at its small size hint with empty space below it, #500), + // while keeping a minimum height so it stays usable when the dock is short. + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + setMinimumHeight(200); setDisabled(true); setConductor(conductor); } @@ -74,12 +89,93 @@ void ConductorPropertiesEditorWidget::setConductor(Conductor *conductor) */ void ConductorPropertiesEditorWidget::apply() { + // Ignore the field-change signals emitted while the widget is being loaded + // programmatically (updateUi/reset): mid-load the widget holds a partial + // state that must not be committed onto the conductor. + if (m_updating) return; if (!m_conductor || !m_conductor->diagram()) return; if (QUndoCommand *undo = associatedUndo()) m_conductor->diagram()->undoStack().push(undo); m_initial = m_conductor->properties(); } +/** + @brief ConductorPropertiesEditorWidget::setLiveEdit + In live-edit mode (how the dock uses every editor), each field change is + applied immediately instead of via an explicit apply() call. Without this + override the base class is a no-op and edits in the dock were never applied + (issue #500). + @param live_edit true to enable live edit + @return always true +*/ +bool ConductorPropertiesEditorWidget::setLiveEdit(bool live_edit) +{ + if (m_live_edit == live_edit) return true; + m_live_edit = live_edit; + + if (m_live_edit) connectChangeSignals(); + else disconnectChangeSignals(); + + return true; +} + +/** + @brief ConductorPropertiesEditorWidget::connectChangeSignals + Wire every editable control of the hosted ConductorPropertiesWidget to + apply(). Commit-style signals (editingFinished / activated / toggled / + sliderReleased) are used rather than per-keystroke ones so each edit yields + a single, clean undo step. Loading the widget programmatically (updateUi) + also fires some of these, but apply() is a no-op then because + associatedUndo() returns nullptr when the properties are unchanged. +*/ +void ConductorPropertiesEditorWidget::connectChangeSignals() +{ + if (!m_cpw) return; + + const auto add = [this](QMetaObject::Connection c) { + m_live_connections << c; + }; + + for (auto *w : m_cpw->findChildren()) + add(connect(w, &QLineEdit::editingFinished, + this, &ConductorPropertiesEditorWidget::apply)); + for (auto *w : m_cpw->findChildren()) + add(connect(w, &QAbstractSpinBox::editingFinished, + this, &ConductorPropertiesEditorWidget::apply)); + for (auto *w : m_cpw->findChildren()) + add(connect(w, QOverload::of(&QComboBox::activated), + this, &ConductorPropertiesEditorWidget::apply)); + for (auto *w : m_cpw->findChildren()) + add(connect(w, &QSlider::sliderReleased, + this, &ConductorPropertiesEditorWidget::apply)); + for (auto *w : m_cpw->findChildren()) + add(connect(w, &KColorButton::changed, + this, &ConductorPropertiesEditorWidget::apply)); + for (auto *w : m_cpw->findChildren()) + add(connect(w, QOverload<>::of(&QTextOrientationSpinBoxWidget::editingFinished), + this, &ConductorPropertiesEditorWidget::apply)); + // Checkboxes and the checkable group boxes (single/multi wire, bicolor…). + for (auto *w : m_cpw->findChildren()) + if (w->isCheckable()) + add(connect(w, &QAbstractButton::toggled, + this, &ConductorPropertiesEditorWidget::apply)); + for (auto *w : m_cpw->findChildren()) + if (w->isCheckable()) + add(connect(w, &QGroupBox::toggled, + this, &ConductorPropertiesEditorWidget::apply)); +} + +/** + @brief ConductorPropertiesEditorWidget::disconnectChangeSignals + Tear down the live-edit connections made by connectChangeSignals(). +*/ +void ConductorPropertiesEditorWidget::disconnectChangeSignals() +{ + for (const QMetaObject::Connection &c : m_live_connections) + disconnect(c); + m_live_connections.clear(); +} + /** @brief ConductorPropertiesEditorWidget::reset Discard the in-progress edit, restoring the conductor's current properties. @@ -87,7 +183,9 @@ void ConductorPropertiesEditorWidget::apply() void ConductorPropertiesEditorWidget::reset() { if (!m_conductor) return; + m_updating = true; m_cpw->setProperties(m_initial); + m_updating = false; } /** @@ -97,8 +195,10 @@ void ConductorPropertiesEditorWidget::reset() void ConductorPropertiesEditorWidget::updateUi() { if (!m_conductor) return; + m_updating = true; m_initial = m_conductor->properties(); m_cpw->setProperties(m_initial); + m_updating = false; } /** diff --git a/sources/ui/conductorpropertieseditorwidget.h b/sources/ui/conductorpropertieseditorwidget.h index 365e34ff7..42df3b93b 100644 --- a/sources/ui/conductorpropertieseditorwidget.h +++ b/sources/ui/conductorpropertieseditorwidget.h @@ -21,6 +21,9 @@ #include "../PropertiesEditor/propertieseditorwidget.h" #include "../conductorproperties.h" +#include +#include + class Conductor; class ConductorPropertiesWidget; @@ -48,11 +51,18 @@ class ConductorPropertiesEditorWidget : public PropertiesEditorWidget void updateUi() override; QUndoCommand *associatedUndo() const override; QString title() const override; + bool setLiveEdit(bool live_edit) override; + + private: + void connectChangeSignals(); + void disconnectChangeSignals(); private: ConductorPropertiesWidget *m_cpw = nullptr; Conductor *m_conductor = nullptr; ConductorProperties m_initial; + QList m_live_connections; + bool m_updating = false; }; #endif // CONDUCTORPROPERTIESEDITORWIDGET_H From 0902725a5901c45a936f079b718a4522a4387a6c Mon Sep 17 00:00:00 2001 From: Shane Ringrose Date: Thu, 18 Jun 2026 07:48:14 +1200 Subject: [PATCH 4/7] Conductor dock: apply-to-all-potential checkbox (#500) Port the modal dialog's "apply to all conductors" option into the dock panel, resolving the open propagation question. A persisted checkbox, pinned above the tabs, makes each edit propagate to every conductor on the same potential in one undo step - identical semantics to ConductorPropertiesDialog, but the choice is remembered across edits. Co-Authored-By: Claude Opus 4.8 --- .../ui/conductorpropertieseditorwidget.cpp | 47 +++++++++++++++++-- sources/ui/conductorpropertieseditorwidget.h | 6 ++- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/sources/ui/conductorpropertieseditorwidget.cpp b/sources/ui/conductorpropertieseditorwidget.cpp index b0a0d7d33..a2b6d91f2 100644 --- a/sources/ui/conductorpropertieseditorwidget.cpp +++ b/sources/ui/conductorpropertieseditorwidget.cpp @@ -27,10 +27,12 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -50,12 +52,29 @@ ConductorPropertiesEditorWidget::ConductorPropertiesEditorWidget( // can be dragged to any width (a scrollbar appears when narrower than the // content). QET already persists dock geometry across restarts via // QETDiagramEditor save/restoreState, so the chosen width is remembered. + // "Apply to all conductors of the potential": same semantics as the modal + // dialog's checkbox (ConductorPropertiesDialog::applyAll), pinned at the top + // of the panel so it stays visible above the scrolling tabs (#500). Unlike + // the dialog the choice is persisted, so a user who always wants it on (or + // off) sets it once. It is a child of this editor, not of m_cpw, so it is + // deliberately outside the live-edit signal wiring in connectChangeSignals() + // (toggling it must not push an edit, only change how the next edit applies). + m_apply_all_cb = new QCheckBox( + tr("Appliquer à tous les conducteurs du potentiel"), this); + m_apply_all_cb->setChecked(QSettings().value( + QStringLiteral("diagrameditor/conductor_apply_all"), true).toBool()); + connect(m_apply_all_cb, &QCheckBox::toggled, this, [](bool on) { + QSettings().setValue( + QStringLiteral("diagrameditor/conductor_apply_all"), on); + }); + auto *scroll = new QScrollArea(this); scroll->setWidgetResizable(true); scroll->setFrameShape(QFrame::NoFrame); scroll->setWidget(m_cpw); auto *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(m_apply_all_cb); layout->addWidget(scroll); setMinimumWidth(120); // Expand vertically to fill the dock like the other editors do (otherwise @@ -205,10 +224,10 @@ void ConductorPropertiesEditorWidget::updateUi() @brief ConductorPropertiesEditorWidget::associatedUndo @return the edit as a QPropertyUndoCommand, or nullptr if unchanged. - Prototype note: applies only to the selected conductor. The modal dialog - additionally offers to propagate to every conductor on the same potential - (relatedPotentialConductors()); whether/how to expose that in the dock is - the open design decision for #500. + When "apply to all" is ticked, every conductor on the same potential is + updated in the same undo step (one undo reverts them all), exactly as the + modal dialog does (ConductorPropertiesDialog::PropertiesDialog). Otherwise + only the selected conductor is changed. */ QUndoCommand *ConductorPropertiesEditorWidget::associatedUndo() const { @@ -224,6 +243,26 @@ QUndoCommand *ConductorPropertiesEditorWidget::associatedUndo() const auto *undo = new QPropertyUndoCommand( m_conductor, "properties", old_value, new_value); undo->setText(tr("Modifier les propriétés d'un conducteur", "undo caption")); + + // Propagate to every conductor on the same potential, as the modal dialog + // does: each related conductor becomes a child command of the same undo + // step, set to the same target properties. + if (m_apply_all_cb && m_apply_all_cb->isChecked()) + { + const auto potential = m_conductor->relatedPotentialConductors(); + if (!potential.isEmpty()) + { + undo->setText(tr("Modifier les propriétés de plusieurs conducteurs", + "undo caption")); + for (Conductor *potential_conductor : potential) + { + QVariant old_v; + old_v.setValue(potential_conductor->properties()); + new QPropertyUndoCommand( + potential_conductor, "properties", old_v, new_value, undo); + } + } + } return undo; } diff --git a/sources/ui/conductorpropertieseditorwidget.h b/sources/ui/conductorpropertieseditorwidget.h index 42df3b93b..0479a6bee 100644 --- a/sources/ui/conductorpropertieseditorwidget.h +++ b/sources/ui/conductorpropertieseditorwidget.h @@ -26,14 +26,15 @@ class Conductor; class ConductorPropertiesWidget; +class QCheckBox; /** @brief The ConductorPropertiesEditorWidget class Hosts the existing ConductorPropertiesWidget in the dockable selection- properties panel, so a selected conductor can be edited in place like the other item types, instead of only through the modal dialog (issue #500). - Prototype: single-conductor editing; applying to the whole potential is the - open design question (the modal dialog offers it via a prompt). + A pinned "apply to all conductors of the potential" checkbox (persisted) + mirrors the modal dialog's option to propagate edits to the whole potential. */ class ConductorPropertiesEditorWidget : public PropertiesEditorWidget { @@ -59,6 +60,7 @@ class ConductorPropertiesEditorWidget : public PropertiesEditorWidget private: ConductorPropertiesWidget *m_cpw = nullptr; + QCheckBox *m_apply_all_cb = nullptr; Conductor *m_conductor = nullptr; ConductorProperties m_initial; QList m_live_connections; From 151b16ba761cc68cabfbc7a18c47035701928f64 Mon Sep 17 00:00:00 2001 From: Shane Ringrose Date: Thu, 18 Jun 2026 08:14:00 +1200 Subject: [PATCH 5/7] Conductor dock: English translations + align checkbox wording (#500) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add English translations (qet_en.ts) for the new conductor-panel strings so non-French users don't see untranslated source text: the panel title, the two undo captions, the apply-to-all checkbox, and the View-menu toggle + status tip. The apply-to-all checkbox now reuses the modal dialog's exact wording ("Appliquer les propriétés a l'ensemble des conducteurs de ce potentiel") for consistency and so it shares the existing translation. Co-Authored-By: Claude Opus 4.8 --- lang/qet_en.ts | 35 +++++++++++++++++++ .../ui/conductorpropertieseditorwidget.cpp | 5 ++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/lang/qet_en.ts b/lang/qet_en.ts index d78e8268f..1170c49b5 100644 --- a/lang/qet_en.ts +++ b/lang/qet_en.ts @@ -834,6 +834,31 @@ Note: these options DO NOT allow or block auto numberings, only their update pol Edit the properties of several conductors + + ConductorPropertiesEditorWidget + + + Appliquer les propriétés à l'ensemble des conducteurs de ce potentiel + Apply properties to all conductors of this potential + + + + Modifier les propriétés d'un conducteur + undo caption + Edit conductor properties + + + + Modifier les propriétés de plusieurs conducteurs + undo caption + Edit the properties of several conductors + + + + Conducteur + Conductor + + ConductorPropertiesWidget @@ -6068,6 +6093,16 @@ Available options: QETDiagramEditor + + + Propriétés du conducteur dans le panneau + Conductor properties in the panel + + + + Affiche ou non les propriétés d'un conducteur sélectionné dans le panneau de sélection + Show or hide the properties of a selected conductor in the selection panel + Afficha&ge diff --git a/sources/ui/conductorpropertieseditorwidget.cpp b/sources/ui/conductorpropertieseditorwidget.cpp index a2b6d91f2..5e4c15701 100644 --- a/sources/ui/conductorpropertieseditorwidget.cpp +++ b/sources/ui/conductorpropertieseditorwidget.cpp @@ -59,8 +59,11 @@ ConductorPropertiesEditorWidget::ConductorPropertiesEditorWidget( // off) sets it once. It is a child of this editor, not of m_cpw, so it is // deliberately outside the live-edit signal wiring in connectChangeSignals() // (toggling it must not push an edit, only change how the next edit applies). + // Reuse the modal dialog's exact wording for consistency (and so the + // existing translation applies). m_apply_all_cb = new QCheckBox( - tr("Appliquer à tous les conducteurs du potentiel"), this); + tr("Appliquer les propriétés à l'ensemble des conducteurs de ce potentiel"), + this); m_apply_all_cb->setChecked(QSettings().value( QStringLiteral("diagrameditor/conductor_apply_all"), true).toBool()); connect(m_apply_all_cb, &QCheckBox::toggled, this, [](bool on) { From 4e754cfac1e4468e2b0c89cfaa49855d4074e3ed Mon Sep 17 00:00:00 2001 From: ispyisail Date: Fri, 19 Jun 2026 07:43:27 +1200 Subject: [PATCH 6/7] Conductor dock: sync to external property changes (#500) The dock editor snapshotted the conductor once and never refreshed, so a change made via the modal Edit-conductor dialog left the dock holding stale values; on deselection apply() wrote that stale snapshot back, overwriting the dialog's change. Subscribe to Conductor::propertiesChange and refresh via updateUi() so the dock mirrors external edits and apply() becomes a no-op when nothing changed in the dock. --- sources/ui/conductorpropertieseditorwidget.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sources/ui/conductorpropertieseditorwidget.cpp b/sources/ui/conductorpropertieseditorwidget.cpp index 5e4c15701..384e43f11 100644 --- a/sources/ui/conductorpropertieseditorwidget.cpp +++ b/sources/ui/conductorpropertieseditorwidget.cpp @@ -100,7 +100,15 @@ ConductorPropertiesEditorWidget::~ConductorPropertiesEditorWidget() void ConductorPropertiesEditorWidget::setConductor(Conductor *conductor) { if (!conductor) return; + if (m_conductor && m_conductor != conductor) + disconnect(m_conductor, &Conductor::propertiesChange, + this, &ConductorPropertiesEditorWidget::updateUi); m_conductor = conductor; + //Keep the dock in sync when the conductor is edited elsewhere (e.g. the + //modal "Edit conductor" dialog); otherwise a stale snapshot would be + //written back on the next apply() and overwrite that change (issue #500). + connect(m_conductor, &Conductor::propertiesChange, + this, &ConductorPropertiesEditorWidget::updateUi, Qt::UniqueConnection); setEnabled(true); updateUi(); } From ff795258c481fb34537a4612c4c3eadacc6b2111 Mon Sep 17 00:00:00 2001 From: ispyisail Date: Sun, 27 Sep 2026 09:13:55 +1300 Subject: [PATCH 7/7] Conductor dock: turn it on in the preferences, off by default (#500) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Showing a selected conductor's properties in the selection-properties dock is now a preference, on the General page under Appearance: "Afficher les propriétés d'un conducteur sélectionné dans le panneau Propriétés de la sélection". It is off by default, so selecting a conductor does what it did before unless the user turns it on. This replaces the View-menu toggle, which defaulted to on; that entry is dropped in the merge with master. Same setting key (diagrameditor/conductor_properties_panel). Co-Authored-By: Claude Opus 5.5 --- sources/factory/propertieseditorfactory.cpp | 6 +++--- sources/ui/configpage/generalconfigurationpage.cpp | 2 ++ sources/ui/configpage/generalconfigurationpage.ui | 8 ++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/sources/factory/propertieseditorfactory.cpp b/sources/factory/propertieseditorfactory.cpp index 8098f995a..48a39738b 100644 --- a/sources/factory/propertieseditorfactory.cpp +++ b/sources/factory/propertieseditorfactory.cpp @@ -117,11 +117,11 @@ PropertiesEditorWidget *PropertiesEditorFactory::propertiesEditor( { case Conductor::Type: //1001 { - //Feature toggle (#500): when disabled in the View menu, selecting a - //conductor brings up nothing in the dock. Default enabled. + //Off unless enabled in the preferences (General page): selecting + //a conductor then brings up nothing in the dock, as before. if (!QSettings().value( QStringLiteral("diagrameditor/conductor_properties_panel"), - true).toBool()) { + false).toBool()) { return nullptr; } //Prototype (#500): single-conductor editing in the dock. diff --git a/sources/ui/configpage/generalconfigurationpage.cpp b/sources/ui/configpage/generalconfigurationpage.cpp index 06816e113..93bc8d0b8 100644 --- a/sources/ui/configpage/generalconfigurationpage.cpp +++ b/sources/ui/configpage/generalconfigurationpage.cpp @@ -97,6 +97,7 @@ GeneralConfigurationPage::GeneralConfigurationPage(QWidget *parent) : else ui->m_use_windows_mode_rb->setChecked(true); ui->m_zoom_out_beyond_folio->setChecked(settings.value("diagrameditor/zoom-out-beyond-of-folio", false).toBool()); + ui->m_conductor_properties_panel->setChecked(settings.value("diagrameditor/conductor_properties_panel", false).toBool()); ui->m_use_gesture_trackpad->setChecked(settings.value("diagramview/gestures", false).toBool()); ui->m_save_label_paste->setChecked(settings.value("diagramcommands/erase-label-on-copy", true).toBool()); ui->m_enable_scripting->setChecked(QetSettings::scriptingEnabled()); @@ -290,6 +291,7 @@ void GeneralConfigurationPage::applyConf() settings.setValue("diagrameditor/viewmode", view_mode) ; settings.setValue("diagrameditor/highlight-integrated-elements", ui->m_highlight_integrated_elements->isChecked()); settings.setValue("diagrameditor/zoom-out-beyond-of-folio", ui->m_zoom_out_beyond_folio->isChecked()); + settings.setValue("diagrameditor/conductor_properties_panel", ui->m_conductor_properties_panel->isChecked()); settings.setValue("diagrameditor/autosave-interval", ui->m_autosave_sb->value()); settings.setValue("diagrameditor/grid_display_startup", ui->grid_startup_cb->isChecked()); diff --git a/sources/ui/configpage/generalconfigurationpage.ui b/sources/ui/configpage/generalconfigurationpage.ui index 3bdd12356..9b85aa896 100644 --- a/sources/ui/configpage/generalconfigurationpage.ui +++ b/sources/ui/configpage/generalconfigurationpage.ui @@ -63,6 +63,13 @@ + + + + Afficher les propriétés d'un conducteur sélectionné dans le panneau Propriétés de la sélection + + + @@ -1175,6 +1182,7 @@ Vous pouvez spécifier ici la valeur par défaut de ce champ pour les éléments m_use_system_color_cb m_use_gesture_trackpad m_zoom_out_beyond_folio + m_conductor_properties_panel m_use_windows_mode_rb m_use_tab_mode_rb m_save_label_paste