Ctrl+Shift+V pastes at the origin point, Ctrl+V keeps pasting under the cursor

Ctrl+V moves the pasted group under the pointer as before. The new
Ctrl+Shift+V ("Coller au point d'origine", diagrameditor.paste_origin)
leaves the group exactly where it was copied from and warps the OS
cursor to the group's grid-snapped origin, so the paste baseline and
the physical cursor agree and the group starts following the mouse from
its original place instead of jumping to the pointer.

The cursor warp is only trusted as the baseline when it verifiably
lands (QCursor::pos() agrees with the target): QCursor::setPos() needs
pointer focus and is a silent no-op on compositors without
wp_pointer_warp_v1. Otherwise m_baseline_captured stays false and
moveTo() re-baselines on the first real mouse move, so a refused warp
costs at most the first movement rather than flinging the group across
the folio. An origin outside the viewport is scrolled into view first,
since the compositor rejects warp targets outside the window.
This commit is contained in:
Kellermorph
2026-10-01 13:04:04 +02:00
parent 2a6155e0c9
commit 87bd172c44
4 changed files with 111 additions and 29 deletions
+16 -2
View File
@@ -359,14 +359,17 @@ void QETDiagramEditor::setUpActions()
m_cut = new QAction(QET::Icons::EditCut, tr("Co&uper"), this);
m_copy = new QAction(QET::Icons::EditCopy, tr("Cop&ier"), this);
m_paste = new QAction(QET::Icons::EditPaste, tr("C&oller"), this);
m_paste_origin = new QAction(QET::Icons::EditPaste, tr("Coller au point d'origine"), this);
ShortcutManager::instance().registerAction(m_cut, "diagrameditor.cut", tr("Éditeur de schémas"), QKeySequence::Cut);
ShortcutManager::instance().registerAction(m_copy, "diagrameditor.copy", tr("Éditeur de schémas"), QKeySequence::Copy);
ShortcutManager::instance().registerAction(m_paste, "diagrameditor.paste", tr("Éditeur de schémas"), QKeySequence::Paste);
ShortcutManager::instance().registerAction(m_paste_origin, "diagrameditor.paste_origin", tr("Éditeur de schémas"), QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_V));
m_cut -> setStatusTip(tr("Transfère les éléments sélectionnés dans le presse-papier", "status bar tip"));
m_copy -> setStatusTip(tr("Copie les éléments sélectionnés dans le presse-papier", "status bar tip"));
m_paste -> setStatusTip(tr("Place les éléments du presse-papier sur le folio", "status bar tip"));
m_paste_origin -> setStatusTip(tr("Place les éléments du presse-papier à leur position d'origine et déplace le curseur vers ce point", "status bar tip"));
connect(m_cut, &QAction::triggered, [this]() {
if (currentDiagramView())
@@ -376,7 +379,10 @@ void QETDiagramEditor::setUpActions()
if (currentDiagramView())
currentDiagramView()->copy();
});
connect(m_paste, &QAction::triggered, [this]() {
//Both paste shortcuts share one starter; they differ only in the
//placement mode handed to DiagramEventAddPaste.
const auto start_paste = [this](DiagramEventAddPaste::PastePlacement placement) {
auto *dv = currentDiagramView();
if (!dv || !dv->diagram()) return;
@@ -399,7 +405,13 @@ void QETDiagramEditor::setUpActions()
const QPointF start_pos = dv->mapToScene(view_pos);
dv->diagram()->setEventInterface(
new DiagramEventAddPaste(dv->diagram(), start_pos));
new DiagramEventAddPaste(dv->diagram(), start_pos, placement));
};
connect(m_paste, &QAction::triggered, [start_paste]() {
start_paste(DiagramEventAddPaste::UnderCursor);
});
connect(m_paste_origin, &QAction::triggered, [start_paste]() {
start_paste(DiagramEventAddPaste::AtOrigin);
});
//Duplicate: copy the selection and place it at a configured,
@@ -1239,6 +1251,7 @@ void QETDiagramEditor::setUpMenu()
menu_edition -> addAction(m_cut);
menu_edition -> addAction(m_copy);
menu_edition -> addAction(m_paste);
menu_edition -> addAction(m_paste_origin);
menu_edition -> addAction(m_duplicate);
menu_edition -> addAction(m_configure_duplicate);
menu_edition -> addAction(m_insert_last_element);
@@ -2566,6 +2579,7 @@ void QETDiagramEditor::slot_updatePasteAction()
// pour coller, il faut un schema ouvert et un schema dans le presse-papier
m_paste -> setEnabled(editable_diagram && Diagram::clipboardMayContainDiagram());
m_paste_origin -> setEnabled(editable_diagram && Diagram::clipboardMayContainDiagram());
}
/**