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