From 367d168c6fe6881b17aa90c0542f9740dc9b1d37 Mon Sep 17 00:00:00 2001 From: ispyisail Date: Thu, 1 Oct 2026 08:17:38 +1300 Subject: [PATCH] Fix #1177: Space rotated the selection, not the part being added In the symbol editor, Space is the shortcut of the Rotate action, which rotates the selected parts. The action is enabled whenever something is selected, and a window shortcut is handled before the key reaches the scene, so while a terminal or arc was being placed with something already selected, Space rotated the selection and never reached ESEventAddTerminal / ESEventAddArc. With nothing selected the action was disabled and the key fell through, which is why it only happened with a selection. The scene now emits behaviorChanged() when it enters or leaves AddPart, and updateAction() keeps the selection actions (rotate, fine rotate, flip, mirror, cut, delete, depth) disabled while a part is being added. They come back when the tool ends. The selection itself is left alone. ESEventInterface::init() also gives the view keyboard focus: a selection made in the parts list left the focus there, so Space still never reached the tool. ~ElementScene blocks its signals before deleting the event interface, whose destructor resets the behavior while the editor is being destroyed. Co-Authored-By: Claude Opus 5.5 --- sources/editor/elementscene.cpp | 6 ++++++ sources/editor/elementscene.h | 2 ++ sources/editor/esevent/eseventinterface.cpp | 3 +++ sources/editor/ui/qetelementeditor.cpp | 7 +++++-- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/sources/editor/elementscene.cpp b/sources/editor/elementscene.cpp index 1ae830123..d5f0c6fa2 100644 --- a/sources/editor/elementscene.cpp +++ b/sources/editor/elementscene.cpp @@ -148,6 +148,9 @@ ElementScene::~ElementScene() disconnect(&m_undo_stack, &QUndoStack::indexChanged, this, &ElementScene::managePrimitivesGroups); delete m_decorator_lock; + //Deleting the event interface resets the behavior; the editor + //is already being destroyed, so it must not hear about it. + blockSignals(true); if (m_event_interface) delete m_event_interface; @@ -417,7 +420,10 @@ void ElementScene::clearEventInterface() */ void ElementScene::setBehavior(ElementScene::Behavior b) { + if (b == m_behavior) + return; m_behavior = b; + emit behaviorChanged(); } ElementScene::Behavior ElementScene::behavior() const diff --git a/sources/editor/elementscene.h b/sources/editor/elementscene.h index e4f086078..ee275703f 100644 --- a/sources/editor/elementscene.h +++ b/sources/editor/elementscene.h @@ -198,6 +198,8 @@ class ElementScene : public QGraphicsScene void elementTypeChanged(); /// Signal emitted with the current cursor position (scene coordinates) on every mouse move void mouseMoved(const QPointF &pos); + /// Signal emitted when the behavior changes, e.g. a part starts or stops being added + void behaviorChanged(); }; Q_DECLARE_OPERATORS_FOR_FLAGS(ElementScene::ItemOptions) diff --git a/sources/editor/esevent/eseventinterface.cpp b/sources/editor/esevent/eseventinterface.cpp index 6463d5e7b..b3a4aea55 100644 --- a/sources/editor/esevent/eseventinterface.cpp +++ b/sources/editor/esevent/eseventinterface.cpp @@ -42,6 +42,9 @@ void ESEventInterface::init() { m_scene->setBehavior(ElementScene::Behavior::AddPart); m_editor->elementView()->setDragMode(QGraphicsView::NoDrag); + //Keys such as Space must reach the part being added, even when + //the focus was left in the parts list (#1177) + m_editor->elementView()->setFocus(); } /** diff --git a/sources/editor/ui/qetelementeditor.cpp b/sources/editor/ui/qetelementeditor.cpp index d6346d3f7..dfb81b1ec 100644 --- a/sources/editor/ui/qetelementeditor.cpp +++ b/sources/editor/ui/qetelementeditor.cpp @@ -1253,7 +1253,8 @@ void QETElementEditor::updateAction() ui->m_select_all_act->setEnabled(true); ui->m_revert_selection_action->setEnabled(true); - //Action enabled if a primitive is selected + //Action enabled if a primitive is selected, and no part is being + //added: Space rotates the part being added, not the selection (#1177) auto select_list = m_depth_action_group->actions(); select_list << ui->m_cut_action << ui->m_delete_action @@ -1262,7 +1263,8 @@ void QETElementEditor::updateAction() << ui->m_flip_action << ui->m_mirror_action; const bool has_selection = m_elmt_scene->selectedItems().count() > 0; - auto items_selected = !m_read_only && has_selection; + const bool adding_part = m_elmt_scene->behavior() == ElementScene::AddPart; + auto items_selected = !m_read_only && has_selection && !adding_part; for (auto action : std::as_const(select_list)) { action->setEnabled(items_selected); } @@ -1297,6 +1299,7 @@ void QETElementEditor::setupConnection() connect(m_elmt_scene, &ElementScene::partsZValueChanged, this, &QETElementEditor::fillPartsList); connect(m_parts_list, &QListWidget::itemSelectionChanged, this, &QETElementEditor::updateSelectionFromPartsList); connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &QETElementEditor::updateAction); + connect(m_elmt_scene, &ElementScene::behaviorChanged, this, &QETElementEditor::updateAction); connect(m_elmt_scene, &ElementScene::selectionChanged, [this]() { this->updateInformations();