1 /* 2 Copyright (C) 2010-2014 Kristian Duske 3 4 This file is part of TrenchBroom. 5 6 TrenchBroom is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 TrenchBroom is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "SelectionCommand.h" 21 22 #include "Macros.h" 23 #include "Model/Brush.h" 24 #include "Model/EditorContext.h" 25 #include "Model/Entity.h" 26 #include "Model/Group.h" 27 #include "Model/NodeVisitor.h" 28 #include "Model/World.h" 29 #include "View/MapDocumentCommandFacade.h" 30 31 namespace TrenchBroom { 32 namespace View { 33 const Command::CommandType SelectionCommand::Type = Command::freeType(); 34 select(const Model::NodeList & nodes)35 SelectionCommand* SelectionCommand::select(const Model::NodeList& nodes) { 36 return new SelectionCommand(Action_SelectNodes, nodes, Model::EmptyBrushFaceList); 37 } 38 select(const Model::BrushFaceList & faces)39 SelectionCommand* SelectionCommand::select(const Model::BrushFaceList& faces) { 40 return new SelectionCommand(Action_SelectFaces, Model::EmptyNodeList, faces); 41 } 42 convertToFaces()43 SelectionCommand* SelectionCommand::convertToFaces() { 44 return new SelectionCommand(Action_ConvertToFaces, Model::EmptyNodeList, Model::EmptyBrushFaceList); 45 } 46 selectAllNodes()47 SelectionCommand* SelectionCommand::selectAllNodes() { 48 return new SelectionCommand(Action_SelectAllNodes, Model::EmptyNodeList, Model::EmptyBrushFaceList); 49 } 50 selectAllFaces()51 SelectionCommand* SelectionCommand::selectAllFaces() { 52 return new SelectionCommand(Action_SelectAllFaces, Model::EmptyNodeList, Model::EmptyBrushFaceList); 53 } 54 deselect(const Model::NodeList & nodes)55 SelectionCommand* SelectionCommand::deselect(const Model::NodeList& nodes) { 56 return new SelectionCommand(Action_DeselectNodes, nodes, Model::EmptyBrushFaceList); 57 } 58 deselect(const Model::BrushFaceList & faces)59 SelectionCommand* SelectionCommand::deselect(const Model::BrushFaceList& faces) { 60 return new SelectionCommand(Action_DeselectFaces, Model::EmptyNodeList, faces); 61 } 62 deselectAll()63 SelectionCommand* SelectionCommand::deselectAll() { 64 return new SelectionCommand(Action_DeselectAll, Model::EmptyNodeList, Model::EmptyBrushFaceList); 65 } 66 SelectionCommand(const Action action,const Model::NodeList & nodes,const Model::BrushFaceList & faces)67 SelectionCommand::SelectionCommand(const Action action, const Model::NodeList& nodes, const Model::BrushFaceList& faces) : 68 UndoableCommand(Type, makeName(action, nodes, faces)), 69 m_action(action), 70 m_nodes(nodes), 71 m_faces(faces) {} 72 makeName(const Action action,const Model::NodeList & nodes,const Model::BrushFaceList & faces)73 String SelectionCommand::makeName(const Action action, const Model::NodeList& nodes, const Model::BrushFaceList& faces) { 74 StringStream result; 75 switch (action) { 76 case Action_SelectNodes: 77 result << "Select " << nodes.size() << " " << StringUtils::safePlural(nodes.size(), "Object", "Objects"); 78 break; 79 case Action_SelectFaces: 80 result << "Select " << faces.size() << " " << StringUtils::safePlural(nodes.size(), "Brush Face", "Brush Faces"); 81 break; 82 case Action_SelectAllNodes: 83 result << "Select All Objects"; 84 break; 85 case Action_SelectAllFaces: 86 result << "Select All Brush Faces"; 87 break; 88 case Action_ConvertToFaces: 89 result << "Convert to Brush Face Selection"; 90 break; 91 case Action_DeselectNodes: 92 result << "Deselect " << nodes.size() << " " << StringUtils::safePlural(nodes.size(), "Object", "Objects"); 93 break; 94 case Action_DeselectFaces: 95 result << "Deselect " << faces.size() << " " << StringUtils::safePlural(nodes.size(), "Brush Face", "Brush Faces"); 96 break; 97 case Action_DeselectAll: 98 return "Select None"; 99 switchDefault() 100 } 101 return result.str(); 102 } 103 doPerformDo(MapDocumentCommandFacade * document)104 bool SelectionCommand::doPerformDo(MapDocumentCommandFacade* document) { 105 m_previouslySelectedNodes = document->selectedNodes().nodes(); 106 m_previouslySelectedFaces = document->selectedBrushFaces(); 107 108 switch (m_action) { 109 case Action_SelectNodes: 110 document->performSelect(m_nodes); 111 break; 112 case Action_SelectFaces: 113 document->performSelect(m_faces); 114 break; 115 case Action_SelectAllNodes: 116 document->performSelectAllNodes(); 117 break; 118 case Action_SelectAllFaces: 119 document->performSelectAllBrushFaces(); 120 break; 121 case Action_ConvertToFaces: 122 document->performConvertToBrushFaceSelection(); 123 break; 124 case Action_DeselectNodes: 125 document->performDeselect(m_nodes); 126 break; 127 case Action_DeselectFaces: 128 document->performDeselect(m_faces); 129 break; 130 case Action_DeselectAll: 131 document->performDeselectAll(); 132 break; 133 } 134 return true; 135 } 136 doPerformUndo(MapDocumentCommandFacade * document)137 bool SelectionCommand::doPerformUndo(MapDocumentCommandFacade* document) { 138 document->performDeselectAll(); 139 if (!m_previouslySelectedNodes.empty()) 140 document->performSelect(m_previouslySelectedNodes); 141 if (!m_previouslySelectedFaces.empty()) 142 document->performSelect(m_previouslySelectedFaces); 143 return true; 144 } 145 doIsRepeatDelimiter() const146 bool SelectionCommand::doIsRepeatDelimiter() const { 147 return true; 148 } 149 doIsRepeatable(MapDocumentCommandFacade * document) const150 bool SelectionCommand::doIsRepeatable(MapDocumentCommandFacade* document) const { 151 return false; 152 } 153 doCollateWith(UndoableCommand::Ptr command)154 bool SelectionCommand::doCollateWith(UndoableCommand::Ptr command) { 155 return false; 156 } 157 } 158 } 159