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 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-01 08:17:38 +13:00
parent 2a6155e0c9
commit 367d168c6f
4 changed files with 16 additions and 2 deletions
+6
View File
@@ -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
+2
View File
@@ -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)
@@ -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();
}
/**
+5 -2
View File
@@ -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();