| 268 | }; |
| 269 | |
| 270 | void cloneSelected(const cmd::ArgumentList& args) |
| 271 | { |
| 272 | // Check for the correct editing mode (don't clone components) |
| 273 | if (GlobalSelectionSystem().getSelectionMode() == SelectionMode::Component || |
| 274 | GlobalMapModule().getEditMode() != IMap::EditMode::Normal) |
| 275 | { |
| 276 | return; |
| 277 | } |
| 278 | |
| 279 | // Get the namespace of the current map |
| 280 | auto mapRoot = GlobalMapModule().getRoot(); |
| 281 | if (!mapRoot) return; // not map root (this can happen) |
| 282 | |
| 283 | UndoableCommand undo("cloneSelected"); |
| 284 | |
| 285 | SelectionCloner cloner; |
| 286 | GlobalSceneGraph().root()->traverse(cloner); |
| 287 | |
| 288 | // Create a new namespace and move all cloned nodes into it |
| 289 | INamespacePtr clonedNamespace = GlobalNamespaceFactory().createNamespace(); |
| 290 | assert(clonedNamespace); |
| 291 | |
| 292 | // Move items into the temporary namespace, this will setup the links |
| 293 | clonedNamespace->connect(cloner.getCloneRoot()); |
| 294 | |
| 295 | // Adjust all new names to fit into the existing map namespace |
| 296 | map::algorithm::prepareNamesForImport(mapRoot, cloner.getCloneRoot()); |
| 297 | |
| 298 | // Unselect the current selection |
| 299 | GlobalSelectionSystem().setSelectedAll(false); |
| 300 | |
| 301 | // Finally, move the cloned nodes to their destination and select them |
| 302 | cloner.moveClonedNodes(true); |
| 303 | |
| 304 | if (registry::getValue<int>(RKEY_OFFSET_CLONED_OBJECTS) == 1) |
| 305 | { |
| 306 | // Move the current selection by one grid unit to the "right" and "downwards" |
| 307 | nudgeSelected(eNudgeDown); |
| 308 | nudgeSelected(eNudgeRight); |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | struct AxisBase |
| 313 | { |
nothing calls this directly
no test coverage detected