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 #ifndef TrenchBroom_MapDocument 21 #define TrenchBroom_MapDocument 22 23 #include "Notifier.h" 24 #include "TrenchBroom.h" 25 #include "VecMath.h" 26 #include "Assets/AssetTypes.h" 27 #include "Assets/EntityDefinitionFileSpec.h" 28 #include "IO/Path.h" 29 #include "Model/EntityColor.h" 30 #include "Model/MapFacade.h" 31 #include "Model/MapFormat.h" 32 #include "Model/ModelTypes.h" 33 #include "Model/NodeCollection.h" 34 #include "View/CachingLogger.h" 35 #include "View/UndoableCommand.h" 36 #include "View/ViewTypes.h" 37 38 class Color; 39 namespace TrenchBroom { 40 namespace Assets { 41 class EntityDefinitionManager; 42 class EntityModelManager; 43 class TextureManager; 44 } 45 46 namespace Model { 47 class BrushFaceAttributes; 48 class ChangeBrushFaceAttributesRequest; 49 class EditorContext; 50 class Group; 51 class PickResult; 52 class PointFile; 53 } 54 55 namespace View { 56 class Command; 57 class Grid; 58 class MapViewConfig; 59 class Selection; 60 class UndoableCommand; 61 class VertexHandleManager; 62 class ViewEffectsService; 63 64 class MapDocument : public Model::MapFacade, public CachingLogger { 65 public: 66 static const BBox3 DefaultWorldBounds; 67 static const String DefaultDocumentName; 68 protected: 69 BBox3 m_worldBounds; 70 Model::GamePtr m_game; 71 Model::World* m_world; 72 Model::Layer* m_currentLayer; 73 Model::PointFile* m_pointFile; 74 Model::EditorContext* m_editorContext; 75 76 Assets::EntityDefinitionManager* m_entityDefinitionManager; 77 Assets::EntityModelManager* m_entityModelManager; 78 Assets::TextureManager* m_textureManager; 79 80 MapViewConfig* m_mapViewConfig; 81 Grid* m_grid; 82 83 IO::Path m_path; 84 size_t m_lastSaveModificationCount; 85 size_t m_modificationCount; 86 87 Model::NodeCollection m_partiallySelectedNodes; 88 Model::NodeCollection m_selectedNodes; 89 Model::BrushFaceList m_selectedBrushFaces; 90 91 String m_currentTextureName; 92 BBox3 m_lastSelectionBounds; 93 mutable BBox3 m_selectionBounds; 94 mutable bool m_selectionBoundsValid; 95 96 ViewEffectsService* m_viewEffectsService; 97 public: // notification 98 Notifier1<Command::Ptr> commandDoNotifier; 99 Notifier1<Command::Ptr> commandDoneNotifier; 100 Notifier1<Command::Ptr> commandDoFailedNotifier; 101 Notifier1<UndoableCommand::Ptr> commandUndoNotifier; 102 Notifier1<UndoableCommand::Ptr> commandUndoneNotifier; 103 Notifier1<UndoableCommand::Ptr> commandUndoFailedNotifier; 104 105 Notifier1<MapDocument*> documentWillBeClearedNotifier; 106 Notifier1<MapDocument*> documentWasClearedNotifier; 107 Notifier1<MapDocument*> documentWasNewedNotifier; 108 Notifier1<MapDocument*> documentWasLoadedNotifier; 109 Notifier1<MapDocument*> documentWasSavedNotifier; 110 Notifier0 documentModificationStateDidChangeNotifier; 111 112 Notifier0 editorContextDidChangeNotifier; 113 Notifier0 mapViewConfigDidChangeNotifier; 114 Notifier0 currentLayerDidChangeNotifier; 115 116 Notifier0 selectionWillChangeNotifier; 117 Notifier1<const Selection&> selectionDidChangeNotifier; 118 119 Notifier1<const Model::NodeList&> nodesWereAddedNotifier; 120 Notifier1<const Model::NodeList&> nodesWillBeRemovedNotifier; 121 Notifier1<const Model::NodeList&> nodesWereRemovedNotifier; 122 Notifier1<const Model::NodeList&> nodesWillChangeNotifier; 123 Notifier1<const Model::NodeList&> nodesDidChangeNotifier; 124 125 Notifier1<const Model::NodeList&> nodeVisibilityDidChangeNotifier; 126 Notifier1<const Model::NodeList&> nodeLockingDidChangeNotifier; 127 128 Notifier1<Model::Group*> groupWasOpenedNotifier; 129 Notifier1<Model::Group*> groupWasClosedNotifier; 130 131 Notifier1<const Model::BrushFaceList&> brushFacesDidChangeNotifier; 132 133 Notifier0 textureCollectionsDidChangeNotifier; 134 Notifier0 entityDefinitionsDidChangeNotifier; 135 Notifier0 modsDidChangeNotifier; 136 137 Notifier0 pointFileWasLoadedNotifier; 138 Notifier0 pointFileWasUnloadedNotifier; 139 protected: 140 MapDocument(); 141 public: 142 virtual ~MapDocument(); 143 public: // accessors and such 144 Model::GamePtr game() const; 145 const BBox3& worldBounds() const; 146 Model::World* world() const; 147 148 bool isGamePathPreference(const IO::Path& path) const; 149 150 Model::Layer* currentLayer() const; 151 void setCurrentLayer(Model::Layer* currentLayer); 152 153 Model::Group* currentGroup() const; 154 Model::Node* currentParent() const; 155 156 Model::EditorContext& editorContext() const; 157 bool textureLock(); 158 void setTextureLock(bool textureLock); 159 160 Assets::EntityDefinitionManager& entityDefinitionManager(); 161 Assets::EntityModelManager& entityModelManager(); 162 Assets::TextureManager& textureManager(); 163 164 MapViewConfig& mapViewConfig() const; 165 Grid& grid() const; 166 167 Model::PointFile* pointFile() const; 168 169 void setViewEffectsService(ViewEffectsService* viewEffectsService); 170 public: // new, load, save document 171 void newDocument(Model::MapFormat::Type mapFormat, const BBox3& worldBounds, Model::GamePtr game); 172 void loadDocument(Model::MapFormat::Type mapFormat, const BBox3& worldBounds, Model::GamePtr game, const IO::Path& path); 173 void saveDocument(); 174 void saveDocumentAs(const IO::Path& path); 175 void saveDocumentTo(const IO::Path& path); 176 private: 177 void doSaveDocument(const IO::Path& path); 178 void clearDocument(); 179 public: // copy and paste 180 String serializeSelectedNodes(); 181 String serializeSelectedBrushFaces(); 182 183 PasteType paste(const String& str); 184 private: 185 bool pasteNodes(const Model::NodeList& nodes); 186 bool pasteBrushFaces(const Model::BrushFaceList& faces); 187 public: // point file management 188 bool canLoadPointFile() const; 189 void loadPointFile(); 190 bool isPointFileLoaded() const; 191 void unloadPointFile(); 192 public: // selection 193 bool hasSelection() const; 194 bool hasSelectedNodes() const; 195 bool hasSelectedBrushFaces() const; 196 197 const Model::AttributableNodeList allSelectedAttributableNodes() const; 198 const Model::NodeCollection& selectedNodes() const; 199 const Model::BrushFaceList allSelectedBrushFaces() const; 200 const Model::BrushFaceList& selectedBrushFaces() const; 201 202 const BBox3& referenceBounds() const; 203 const BBox3& lastSelectionBounds() const; 204 const BBox3& selectionBounds() const; 205 const String& currentTextureName() const; 206 207 void selectAllNodes(); 208 void selectSiblings(); 209 void selectTouching(bool del); 210 void selectInside(bool del); 211 void selectNodesWithFilePosition(const std::vector<size_t>& positions); 212 void select(const Model::NodeList& nodes); 213 void select(Model::Node* node); 214 void select(const Model::BrushFaceList& faces); 215 void select(Model::BrushFace* face); 216 void convertToFaceSelection(); 217 218 void deselectAll(); 219 void deselect(Model::Node* node); 220 void deselect(const Model::NodeList& nodes); 221 void deselect(Model::BrushFace* face); 222 protected: 223 void updateLastSelectionBounds(); 224 void invalidateSelectionBounds(); 225 private: 226 void validateSelectionBounds() const; 227 void clearSelection(); 228 public: // adding, removing, reparenting, and duplicating nodes, declared in MapFacade interface 229 void addNode(Model::Node* node, Model::Node* parent); 230 void removeNode(Model::Node* node); 231 232 Model::NodeList addNodes(const Model::ParentChildrenMap& nodes); 233 Model::NodeList addNodes(const Model::NodeList& nodes, Model::Node* parent); 234 void removeNodes(const Model::NodeList& nodes); 235 236 void reparentNodes(Model::Node* newParent, const Model::NodeList& children); 237 void reparentNodes(const Model::ParentChildrenMap& nodes); 238 bool deleteObjects(); 239 bool duplicateObjects(); 240 public: // group management 241 void groupSelection(const String& name); 242 void ungroupSelection(); 243 void renameGroups(const String& name); 244 245 void openGroup(Model::Group* group); 246 void closeGroup(); 247 public: // modifying transient node attributes, declared in MapFacade interface 248 void isolate(const Model::NodeList& nodes); 249 void hide(const Model::NodeList nodes); // Don't take the nodes by reference! 250 void hideSelection(); 251 void show(const Model::NodeList& nodes); 252 void showAll(); 253 void ensureVisible(const Model::NodeList& nodes); 254 void resetVisibility(const Model::NodeList& nodes); 255 256 void lock(const Model::NodeList& nodes); 257 void unlock(const Model::NodeList& nodes); 258 void resetLock(const Model::NodeList& nodes); 259 public: // modifying objects, declared in MapFacade interface 260 bool translateObjects(const Vec3& delta); 261 bool rotateObjects(const Vec3& center, const Vec3& axis, FloatType angle); 262 bool flipObjects(const Vec3& center, Math::Axis::Type axis); 263 public: 264 bool createBrush(const Vec3::List& points); 265 bool csgConvexMerge(); 266 bool csgSubtract(); 267 bool csgIntersect(); 268 public: // modifying entity attributes, declared in MapFacade interface 269 bool setAttribute(const Model::AttributeName& name, const Model::AttributeValue& value); 270 bool renameAttribute(const Model::AttributeName& oldName, const Model::AttributeName& newName); 271 bool removeAttribute(const Model::AttributeName& name); 272 273 bool convertEntityColorRange(const Model::AttributeName& name, Assets::ColorRange::Type range); 274 public: // brush resizing, declared in MapFacade interface 275 bool resizeBrushes(const Model::BrushFaceList& faces, const Vec3& delta); 276 public: // modifying face attributes, declared in MapFacade interface 277 bool setTexture(Assets::Texture* texture); 278 bool setFaceAttributes(const Model::BrushFaceAttributes& attributes); 279 bool setFaceAttributes(const Model::ChangeBrushFaceAttributesRequest& request); 280 bool moveTextures(const Vec3f& cameraUp, const Vec3f& cameraRight, const Vec2f& delta); 281 bool rotateTextures(float angle); 282 bool shearTextures(const Vec2f& factors); 283 public: // modifying vertices, declared in MapFacade interface 284 void rebuildBrushGeometry(const Model::BrushList& brushes); 285 286 using MapFacade::snapVertices; 287 bool snapVertices(const Model::VertexToBrushesMap& vertices, size_t snapTo); 288 bool findPlanePoints(); 289 290 MoveVerticesResult moveVertices(const Model::VertexToBrushesMap& vertices, const Vec3& delta); 291 bool moveEdges(const Model::VertexToEdgesMap& edges, const Vec3& delta); 292 bool moveFaces(const Model::VertexToFacesMap& faces, const Vec3& delta); 293 bool splitEdges(const Model::VertexToEdgesMap& edges, const Vec3& delta); 294 bool splitFaces(const Model::VertexToFacesMap& faces, const Vec3& delta); 295 private: // subclassing interface for certain operations which are available from this class, but can only be implemented in a subclass 296 virtual void performRebuildBrushGeometry(const Model::BrushList& brushes) = 0; 297 public: // debug commands 298 void printVertices(); 299 public: // command processing 300 bool canUndoLastCommand() const; 301 bool canRedoNextCommand() const; 302 const String& lastCommandName() const; 303 const String& nextCommandName() const; 304 void undoLastCommand(); 305 void redoNextCommand(); 306 bool repeatLastCommands(); 307 void clearRepeatableCommands(); 308 public: // transactions 309 void beginTransaction(const String& name = ""); 310 void rollbackTransaction(); 311 void commitTransaction(); 312 void cancelTransaction(); 313 private: 314 bool submit(UndoableCommand::Ptr command); 315 private: // subclassing interface for command processing 316 virtual bool doCanUndoLastCommand() const = 0; 317 virtual bool doCanRedoNextCommand() const = 0; 318 virtual const String& doGetLastCommandName() const = 0; 319 virtual const String& doGetNextCommandName() const = 0; 320 virtual void doUndoLastCommand() = 0; 321 virtual void doRedoNextCommand() = 0; 322 virtual bool doRepeatLastCommands() = 0; 323 virtual void doClearRepeatableCommands() = 0; 324 325 virtual void doBeginTransaction(const String& name) = 0; 326 virtual void doEndTransaction() = 0; 327 virtual void doRollbackTransaction() = 0; 328 329 virtual bool doSubmit(UndoableCommand::Ptr command) = 0; 330 public: // asset state management 331 void commitPendingAssets(); 332 public: // picking 333 void pick(const Ray3& pickRay, Model::PickResult& pickResult) const; 334 Model::NodeList findNodesContaining(const Vec3& point) const; 335 private: // world management 336 void createWorld(Model::MapFormat::Type mapFormat, const BBox3& worldBounds, Model::GamePtr game); 337 void loadWorld(Model::MapFormat::Type mapFormat, const BBox3& worldBounds, Model::GamePtr game, const IO::Path& path); 338 void clearWorld(); 339 void initializeWorld(const BBox3& worldBounds); 340 public: // asset management 341 Assets::EntityDefinitionFileSpec entityDefinitionFile() const; 342 Assets::EntityDefinitionFileSpec::List allEntityDefinitionFiles() const; 343 void setEntityDefinitionFile(const Assets::EntityDefinitionFileSpec& spec); 344 345 const StringList externalTextureCollectionNames() const; 346 void addTextureCollection(const String& name); 347 void moveTextureCollectionUp(const String& name); 348 void moveTextureCollectionDown(const String& name); 349 void removeTextureCollections(const StringList& names); 350 private: 351 void loadAssets(); 352 void unloadAssets(); 353 354 void loadEntityDefinitions(); 355 void unloadEntityDefinitions(); 356 357 void loadEntityModels(); 358 void unloadEntityModels(); 359 360 void loadTextures(); 361 void loadBuiltinTextures(); 362 void loadExternalTextures(); 363 void unloadTextures(); 364 void reloadTextures(); 365 protected: 366 void addExternalTextureCollections(const StringList& names); 367 void updateExternalTextureCollectionProperty(); 368 369 void setEntityDefinitions(); 370 void setEntityDefinitions(const Model::NodeList& nodes); 371 void unsetEntityDefinitions(); 372 void unsetEntityDefinitions(const Model::NodeList& nodes); 373 void reloadEntityDefinitions(); 374 375 void setEntityModels(); 376 void setEntityModels(const Model::NodeList& nodes); 377 void clearEntityModels(); 378 void unsetEntityModels(); 379 380 void setTextures(); 381 void setTextures(const Model::NodeList& nodes); 382 void setTextures(const Model::BrushFaceList& faces); 383 384 void unsetTextures(); 385 void unsetTextures(const Model::NodeList& nodes); 386 protected: // search paths and mods 387 IO::Path::List externalSearchPaths() const; 388 void updateGameSearchPaths(); 389 public: 390 StringList mods() const; 391 void setMods(const StringList& mods); 392 private: // issue management 393 void registerIssueGenerators(); 394 public: 395 void setIssueHidden(Model::Issue* issue, bool hidden); 396 private: 397 virtual void doSetIssueHidden(Model::Issue* issue, bool hidden) = 0; 398 public: // document path 399 const String filename() const; 400 const IO::Path& path() const; 401 private: 402 void setPath(const IO::Path& path); 403 public: // modification count 404 bool modified() const; 405 size_t modificationCount() const; 406 private: 407 void setLastSaveModificationCount(); 408 void clearModificationCount(); 409 private: // observers 410 void bindObservers(); 411 void unbindObservers(); 412 void preferenceDidChange(const IO::Path& path); 413 void commandDone(Command::Ptr command); 414 void commandUndone(UndoableCommand::Ptr command); 415 }; 416 417 class Transaction { 418 private: 419 MapDocument* m_document; 420 bool m_cancelled; 421 public: 422 Transaction(MapDocumentWPtr document, const String& name = ""); 423 Transaction(MapDocumentSPtr document, const String& name = ""); 424 Transaction(MapDocument* document, const String& name = ""); 425 ~Transaction(); 426 427 void rollback(); 428 void cancel(); 429 private: 430 void begin(const String& name); 431 void commit(); 432 }; 433 } 434 } 435 436 #endif /* defined(TrenchBroom_MapDocument) */ 437