From af181533dcd1b03194e8cf69fbbac56cc2d3816a Mon Sep 17 00:00:00 2001 From: Matthias Kuehlewein Date: Mon, 23 Jun 2025 12:57:48 +0200 Subject: [PATCH] MapEditorController: Paste at original location The current paste tool inserts objects at the map's viewport center. Add a new tool that pastes objects at their original (map coordinates) location. --- src/gui/map/map_editor.cpp | 43 ++++++++++++++++++++++++-------------- src/gui/map/map_editor.h | 5 +++-- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/gui/map/map_editor.cpp b/src/gui/map/map_editor.cpp index 2a60bfccd..86d7664de 100644 --- a/src/gui/map/map_editor.cpp +++ b/src/gui/map/map_editor.cpp @@ -988,8 +988,14 @@ void MapEditorController::createActions() cut_act->setMenuRole(QAction::TextHeuristicRole); copy_act = newAction("copy", tr("C&opy"), this, SLOT(copy()), "copy.png", QString{}, "edit_menu.html"); copy_act->setMenuRole(QAction::TextHeuristicRole); - paste_act = newAction("paste", tr("&Paste"), this, SLOT(paste()), "paste", QString{}, "edit_menu.html"); + auto* paste_act_mapper = new QSignalMapper(this); + connect(paste_act_mapper, QOverload::of(&QSignalMapper::mapped), this, QOverload::of(&MapEditorController::paste)); + paste_act = newAction("paste", tr("&Paste"), paste_act_mapper, SLOT(map()), "paste", QString{}, "edit_menu.html"); paste_act->setMenuRole(QAction::TextHeuristicRole); + paste_act_mapper->setMapping(paste_act, 1); + paste_original_act = newAction("paste-original", tr("Paste at original location"), paste_act_mapper, SLOT(map()), nullptr, QString{}, "edit_menu.html"); + paste_original_act->setMenuRole(QAction::TextHeuristicRole); + paste_act_mapper->setMapping(paste_original_act, 0); delete_act = newAction("delete", tr("Delete"), this, SLOT(deleteClicked()), "delete.png", QString{}, "toolbars.html#delete"); select_all_act = newAction("select-all", tr("Select all"), this, SLOT(selectAll()), nullptr, QString{}, "edit_menu.html"); select_nothing_act = newAction("select-nothing", tr("Select nothing"), this, SLOT(selectNothing()), nullptr, QString{}, "edit_menu.html"); @@ -1170,6 +1176,7 @@ void MapEditorController::createMenuAndToolbars() edit_menu->addAction(cut_act); edit_menu->addAction(copy_act); edit_menu->addAction(paste_act); + edit_menu->addAction(paste_original_act); edit_menu->addAction(delete_act); edit_menu->addSeparator(); edit_menu->addAction(select_all_act); @@ -1957,7 +1964,7 @@ void MapEditorController::copy() } -void MapEditorController::paste() +void MapEditorController::paste(int paste_at_center) { if (editing_in_progress) return; @@ -1980,14 +1987,17 @@ void MapEditorController::paste() return; } - // Move objects in paste_map so their bounding box center is at this map's viewport center. - // This makes the pasted objects appear at the center of the viewport. - QRectF paste_extent = paste_map.calculateExtent(true, false, nullptr); - auto offset = main_view->center() - paste_extent.center(); - - MapPart* part = paste_map.getCurrentPart(); - for (int i = 0; i < part->getNumObjects(); ++i) - part->getObject(i)->move(offset); + if (paste_at_center) + { + // Move objects in paste_map so their bounding box center is at this map's viewport center. + // This makes the pasted objects appear at the center of the viewport. + QRectF paste_extent = paste_map.calculateExtent(true, false, nullptr); + auto offset = main_view->center() - paste_extent.center(); + + MapPart* part = paste_map.getCurrentPart(); + for (int i = 0; i < part->getNumObjects(); ++i) + part->getObject(i)->move(offset); + } // Import pasted map. Do not blindly import all colors. importMap(paste_map, Map::MinimalObjectImport, window); @@ -2704,13 +2714,14 @@ void MapEditorController::clipboardChanged(QClipboard::Mode mode) void MapEditorController::updatePasteAvailability() { + const bool paste_available = QApplication::clipboard()->mimeData() + && QApplication::clipboard()->mimeData()->hasFormat(MimeType::OpenOrienteeringObjects()) + && !editing_in_progress; + if (paste_act) - { - paste_act->setEnabled( - QApplication::clipboard()->mimeData() - && QApplication::clipboard()->mimeData()->hasFormat(MimeType::OpenOrienteeringObjects()) - && !editing_in_progress); - } + paste_act->setEnabled(paste_available); + if (paste_original_act) + paste_original_act->setEnabled(paste_available); } void MapEditorController::showWholeMap() diff --git a/src/gui/map/map_editor.h b/src/gui/map/map_editor.h index b8ed5c200..142caecc2 100644 --- a/src/gui/map/map_editor.h +++ b/src/gui/map/map_editor.h @@ -1,6 +1,6 @@ /* * Copyright 2012, 2013, 2014 Thomas Schöps - * Copyright 2013-2024 Kai Pastor + * Copyright 2013-2025 Kai Pastor * * This file is part of OpenOrienteering. * @@ -289,7 +289,7 @@ public slots: /** Copies the selected object(s). */ void copy(); /** Pastes the object(s) from the clipboard. */ - void paste(); + void paste(int paste_at_center); /** Empties the undo / redo history to save space. */ void clearUndoRedoHistory(); @@ -715,6 +715,7 @@ protected slots: QAction* cut_act = {}; QAction* copy_act = {}; QAction* paste_act = {}; + QAction* paste_original_act = {}; QAction* delete_act = {}; QAction* select_all_act = {}; QAction* select_nothing_act = {};