void cloneSelected(const cmd::ArgumentList& args) { // Check for the correct editing mode (don't clone components) if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) { return; } UndoableCommand undo("cloneSelected"); // Create the list that will take the cloned instances SelectionCloner::Map cloned; SelectionCloner cloner; GlobalSceneGraph().root()->traverse(cloner); // Create a new namespace and move all cloned nodes into it INamespacePtr clonedNamespace = GlobalNamespaceFactory().createNamespace(); assert(clonedNamespace != NULL); // Move items into the temporary namespace, this will setup the links clonedNamespace->connect(cloner.getCloneRoot()); // Get the namespace of the current map scene::IMapRootNodePtr mapRoot = GlobalMapModule().getRoot(); if (mapRoot == NULL) return; // not map root (this can happen) INamespacePtr nspace = mapRoot->getNamespace(); if (nspace) { // Prepare the nodes for import nspace->ensureNoConflicts(cloner.getCloneRoot()); // Now move all nodes into the target namespace nspace->connect(cloner.getCloneRoot()); } // Unselect the current selection GlobalSelectionSystem().setSelectedAll(false); // Finally, move the cloned nodes to their destination and select them cloner.moveClonedNodes(true); if (registry::getValue<int>(RKEY_OFFSET_CLONED_OBJECTS) == 1) { // Move the current selection by one grid unit to the "right" and "downwards" nudgeSelected(eNudgeDown); nudgeSelected(eNudgeRight); } }
bool Map::import(const std::string& filename) { ui::ScreenUpdateBlocker blocker(_("Importing..."), filename); bool success = false; { IMapResourcePtr resource = GlobalMapResourceManager().capture(filename); if (resource->load()) { // load() returned TRUE, this means that the resource node // is not the NULL node scene::INodePtr otherRoot = resource->getNode(); // Adjust all new names to fit into the existing map namespace, // this routine will be changing a lot of names in the importNamespace INamespacePtr nspace = getRoot()->getNamespace(); if (nspace) { // Prepare our namespace for import nspace->ensureNoConflicts(otherRoot); // Now add the imported names to the local namespace nspace->connect(otherRoot); } MergeMap(otherRoot); success = true; } } SceneChangeNotify(); return success; }
void Map::importSelected(std::istream& in) { BasicContainerPtr root(new BasicContainer); // Instantiate the default import filter class MapImportFilter : public IMapImportFilter { private: scene::INodePtr _root; public: MapImportFilter(const scene::INodePtr& root) : _root(root) {} bool addEntity(const scene::INodePtr& entityNode) { _root->addChildNode(entityNode); return true; } bool addPrimitiveToEntity(const scene::INodePtr& primitive, const scene::INodePtr& entity) { if (Node_getEntity(entity)->isContainer()) { entity->addChildNode(primitive); return true; } else { return false; } } } importFilter(root); MapFormatPtr format = getFormat(); IMapReaderPtr reader = format->getMapReader(importFilter); try { // Start parsing reader->readFromStream(in); // Prepare child primitives addOriginToChildPrimitives(root); // Adjust all new names to fit into the existing map namespace, // this routine will be changing a lot of names in the importNamespace INamespacePtr nspace = getRoot()->getNamespace(); if (nspace) { // Prepare all names, but do not import them into the namesace. This // will happen during the MergeMap call. nspace->ensureNoConflicts(root); } MergeMap(root); } catch (IMapReader::FailureException& e) { gtkutil::MessageBox::ShowError( (boost::format(_("Failure reading map from clipboard:\n%s")) % e.what()).str(), GlobalMainFrame().getTopLevelWindow()); // Clear out the root node, otherwise we end up with half a map scene::NodeRemover remover; root->traverse(remover); } }