Fix bugtracker #243: allow copying out of a read-only element

Opening an element you cannot write -- anything from the QET collection,
for instance -- disabled Copy along with everything else, so there was no
way to reuse a primitive from it. The workaround was to save the whole
element into your own collection first, just to take one shape out of it.

Two actions stood in the way, and neither of them modifies anything:

- Select All and Invert Selection were in the list disabled outright when
  read only, so nothing could be selected in the first place;
- Copy was enabled only when "!m_read_only && selectedItems().count()", so
  even a mouse selection left it greyed out.

Both now work on a read-only element. Copy is safe there:
ElementScene::copy() serialises the current selection to the clipboard and
touches neither the element nor the file.

Cut, Paste, Paste-in-area, Delete, Rotate, Flip, Mirror, the depth actions
and the add-primitive tools stay disabled exactly as before, so the element
is still protected -- this only stops the editor from refusing to read out
what it is already displaying.

Verified with a chmod 444 element: Select All then Copy now work, the
clipboard receives the expected <definition> with all three primitives,
Cut/Paste/Delete remain greyed out, Save stays disabled, and the file is
untouched (same permissions, same checksum).
This commit is contained in:
ispyisail
2026-08-13 11:28:51 +12:00
parent 10cc162c4e
commit 6f9f5f84c2
+17 -7
View File
@@ -1088,29 +1088,39 @@ void QETElementEditor::updateAction()
{
//Action disabled if read only
auto ro_list = m_add_part_action_grp->actions();
ro_list << ui->m_select_all_act
<< ui->m_revert_selection_action
<< ui->m_paste_from_file_action
ro_list << ui->m_paste_from_file_action
<< ui->m_paste_from_element_action;
for (auto action : std::as_const(ro_list)) {
action->setDisabled(m_read_only);
}
//Changing what is selected does not change the element, so these stay
//available when it is read only -- otherwise there is no way to pick
//out the primitive you want to copy out of it.
ui->m_select_all_act->setEnabled(true);
ui->m_revert_selection_action->setEnabled(true);
//Action enabled if a primitive is selected
auto select_list = m_depth_action_group->actions();
select_list << ui->m_deselect_all_action
<< ui->m_cut_action
<< ui->m_copy_action
select_list << ui->m_cut_action
<< ui->m_delete_action
<< ui->m_rotate_action
<< ui->m_rotateFine_action
<< ui->m_flip_action
<< ui->m_mirror_action;
auto items_selected = !m_read_only && m_elmt_scene->selectedItems().count();
const bool has_selection = m_elmt_scene->selectedItems().count() > 0;
auto items_selected = !m_read_only && has_selection;
for (auto action : std::as_const(select_list)) {
action->setEnabled(items_selected);
}
//Copying only reads the element -- ElementScene::copy() serialises the
//selection to the clipboard and touches nothing else -- so it is
//allowed on a read-only element too. Cut, paste and delete above stay
//disabled, so the element itself is still protected.
ui->m_copy_action->setEnabled(has_selection);
ui->m_deselect_all_action->setEnabled(has_selection);
//Action about clipboard
auto clipboard_contain_elmt = !m_read_only && ElementScene::clipboardMayContainElement();
ui->m_paste_action->setEnabled(clipboard_contain_elmt);