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 "FrameManager.h" 21 22 #include "Exceptions.h" 23 #include "Macros.h" 24 #include "View/MapDocument.h" 25 #include "View/MapDocumentCommandFacade.h" 26 #include "View/MapFrame.h" 27 28 #include <cassert> 29 30 #include <wx/display.h> 31 #include <wx/persist.h> 32 #include <wx/persist/toplevel.h> 33 34 namespace TrenchBroom { 35 namespace View { FrameManager(const bool singleFrame)36 FrameManager::FrameManager(const bool singleFrame) : 37 m_singleFrame(singleFrame), 38 m_topFrame(NULL) {} 39 ~FrameManager()40 FrameManager::~FrameManager() { 41 closeAllFrames(true); 42 } 43 newFrame()44 MapFrame* FrameManager::newFrame() { 45 return createOrReuseFrame(); 46 } 47 frames() const48 FrameList FrameManager::frames() const { 49 return m_frames; 50 } 51 closeAllFrames()52 bool FrameManager::closeAllFrames() { 53 return closeAllFrames(false); 54 } 55 allFramesClosed() const56 bool FrameManager::allFramesClosed() const { 57 return m_frames.empty(); 58 } 59 OnFrameActivate(wxActivateEvent & event)60 void FrameManager::OnFrameActivate(wxActivateEvent& event) { 61 if (event.GetActive()) 62 m_topFrame = static_cast<MapFrame*>(event.GetEventObject()); 63 event.Skip(); 64 } 65 createOrReuseFrame()66 MapFrame* FrameManager::createOrReuseFrame() { 67 assert(!m_singleFrame || m_frames.size() <= 1); 68 if (!m_singleFrame || m_frames.empty()) { 69 MapDocumentSPtr document = MapDocumentCommandFacade::newMapDocument(); 70 MapFrame* frame = createFrame(document); 71 m_frames.push_back(frame); 72 } 73 return m_frames.back(); 74 } 75 createFrame(MapDocumentSPtr document)76 MapFrame* FrameManager::createFrame(MapDocumentSPtr document) { 77 MapFrame* frame = new MapFrame(this, document); 78 frame->SetName("MapFrame"); 79 if (!wxPersistenceManager::Get().RegisterAndRestore(frame)) 80 frame->positionOnScreen(m_topFrame); 81 82 frame->Bind(wxEVT_ACTIVATE, &FrameManager::OnFrameActivate, this); 83 frame->Show(); 84 frame->Raise(); 85 return frame; 86 } 87 closeAllFrames(bool force)88 bool FrameManager::closeAllFrames(bool force) { 89 MapFrame* lastFrame = NULL; 90 unused(lastFrame); 91 while (!m_frames.empty()) { 92 MapFrame* frame = m_frames.front(); 93 assert(frame != lastFrame); 94 if (!frame->Close(force)) 95 return false; 96 } 97 assert(m_frames.empty()); 98 return true; 99 } 100 removeAndDestroyFrame(MapFrame * frame)101 void FrameManager::removeAndDestroyFrame(MapFrame* frame) { 102 FrameList::iterator it = std::find(m_frames.begin(), m_frames.end(), frame); 103 if (it != m_frames.end()) // On OS X, we sometimes get two close events for a frame when terminating the app from the dock. 104 m_frames.erase(it); 105 106 if (m_topFrame == frame) 107 m_topFrame = NULL; 108 109 frame->Unbind(wxEVT_ACTIVATE, &FrameManager::OnFrameActivate, this); 110 // wxPersistenceManager::Get().SaveAndUnregister(frame); 111 frame->Destroy(); 112 } 113 } 114 } 115