+class EntityFindSelected : public scene::Graph::Walker {
+public:
+ mutable const scene::Path *groupPath;
+ mutable scene::Instance *groupInstance;
+
+ EntityFindSelected() : groupPath(0), groupInstance(0)
+ {
+ }
+
+ bool pre(const scene::Path &path, scene::Instance &instance) const
+ {
+ return true;
+ }
+
+ void post(const scene::Path &path, scene::Instance &instance) const
+ {
+ Entity *entity = Node_getEntity(path.top());
+ if (entity != 0
+ && Instance_getSelectable(instance)->isSelected()
+ && node_is_group(path.top())
+ && !groupPath) {
+ groupPath = &path;
+ groupInstance = &instance;
+ }
+ }
+};
+
+class EntityGroupSelected : public scene::Graph::Walker {
+ NodeSmartReference group, worldspawn;
+//typedef std::pair<NodeSmartReference, NodeSmartReference> DeletionPair;
+//Stack<DeletionPair> deleteme;
+public:
+ EntityGroupSelected(const scene::Path &p) : group(p.top().get()), worldspawn(Map_FindOrInsertWorldspawn(g_map))
+ {
+ }
+
+ bool pre(const scene::Path &path, scene::Instance &instance) const
+ {
+ return true;
+ }
+
+ void post(const scene::Path &path, scene::Instance &instance) const
+ {
+ Selectable *selectable = Instance_getSelectable(instance);
+ if (selectable && selectable->isSelected()) {
+ Entity *entity = Node_getEntity(path.top());
+ if (entity == 0 && Node_isPrimitive(path.top())) {
+ NodeSmartReference child(path.top().get());
+ NodeSmartReference parent(path.parent().get());
+
+ if (path.size() >= 3 && parent != worldspawn) {
+ NodeSmartReference parentparent(path[path.size() - 3].get());
+
+ Node_getTraversable(parent)->erase(child);
+ Node_getTraversable(group)->insert(child);
+
+ if (Node_getTraversable(parent)->empty()) {
+ //deleteme.push(DeletionPair(parentparent, parent));
+ Node_getTraversable(parentparent)->erase(parent);
+ }
+ } else {
+ Node_getTraversable(parent)->erase(child);
+ Node_getTraversable(group)->insert(child);
+ }
+ }
+ }
+ }
+};
+
+void Entity_groupSelected()
+{
+ if (GlobalSelectionSystem().countSelected() < 1) {
+ return;
+ }
+
+ UndoableCommand undo("groupSelectedEntities");
+
+ scene::Path world_path(makeReference(GlobalSceneGraph().root()));
+ world_path.push(makeReference(Map_FindOrInsertWorldspawn(g_map)));
+
+ EntityFindSelected fse;
+ GlobalSceneGraph().traverse(fse);
+ if (fse.groupPath) {
+ GlobalSceneGraph().traverse(EntityGroupSelected(*fse.groupPath));
+ } else {
+ GlobalSceneGraph().traverse(EntityGroupSelected(world_path));
+ }
+}
+