1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3  * http://www.gnu.org/licenses/lgpl-3.0.html
4  *
5  * $Revision: 11797 $
6  * $Id: manager.cpp 11797 2019-07-21 16:56:22Z fuscated $
7  * $HeadURL: svn://svn.code.sf.net/p/codeblocks/code/branches/release-20.xx/src/sdk/manager.cpp $
8  */
9 
10 #include "sdk_precomp.h"
11 
12 #ifndef CB_PRECOMP
13     #include <wx/xrc/xmlres.h>
14     #include <wx/fs_zip.h>
15     #include <wx/menu.h>
16 
17     #include "manager.h" // class's header file
18     #include "sdk_events.h"
19     #include "cbexception.h"
20     #include "projectmanager.h"
21     #include "editormanager.h"
22     #include "logmanager.h"
23     #include "pluginmanager.h"
24     #include "toolsmanager.h"
25     #include "macrosmanager.h"
26     #include "configmanager.h"
27     #include "scriptingmanager.h"
28     #include "templatemanager.h"
29     #include "personalitymanager.h"
30     #include "uservarmanager.h"
31     #include "filemanager.h"
32     #include "globals.h"
33     #include "xtra_res.h" // our new ToolBarAddOn handler
34 #endif
35 
36 #include <wx/app.h>    // wxTheApp
37 #include <wx/toolbar.h>
38 #include <wx/fs_mem.h>
39 
40 
41 #ifdef PPRCESS_EVENT_PERFORMANCE_MEASURE
42     // this preprocessor directive can be defined in cbfunctor.h to enable performance measure
43     #include <cxxabi.h>  // demangle C++ names
44     #include <cstdlib>   // free the memory created by abi::__cxa_demangle
45 #endif // PPRCESS_EVENT_PERFORMANCE_MEASURE
46 
47 #include "cbcolourmanager.h"
48 #include "ccmanager.h"
49 #include "debuggermanager.h"
50 
51 static Manager* s_ManagerInstance = nullptr;
52 
53 
54 #ifdef PPRCESS_EVENT_PERFORMANCE_MEASURE
GetCodeblocksEventName(wxEventType type)55 static wxString GetCodeblocksEventName(wxEventType type)
56 {
57     wxString name;
58     if      (type==cbEVT_APP_STARTUP_DONE) name = _T("cbEVT_APP_STARTUP_DONE");
59     else if (type==cbEVT_APP_START_SHUTDOWN) name = _T("cbEVT_APP_START_SHUTDOWN");
60     else if (type==cbEVT_APP_ACTIVATED) name = _T("cbEVT_APP_ACTIVATED");
61     else if (type==cbEVT_APP_DEACTIVATED) name = _T("cbEVT_APP_DEACTIVATED");
62     else if (type==cbEVT_PLUGIN_ATTACHED) name = _T("cbEVT_PLUGIN_ATTACHED");
63     else if (type==cbEVT_PLUGIN_RELEASED) name = _T("cbEVT_PLUGIN_RELEASED");
64     else if (type==cbEVT_PLUGIN_INSTALLED) name = _T("cbEVT_PLUGIN_INSTALLED");
65     else if (type==cbEVT_PLUGIN_UNINSTALLED) name = _T("cbEVT_PLUGIN_UNINSTALLED");
66     else if (type==cbEVT_PLUGIN_LOADING_COMPLETE) name = _T("cbEVT_PLUGIN_LOADING_COMPLETE");
67     else if (type==cbEVT_EDITOR_CLOSE) name = _T("cbEVT_EDITOR_CLOSE");
68     else if (type==cbEVT_EDITOR_OPEN) name = _T("cbEVT_EDITOR_OPEN");
69     else if (type==cbEVT_EDITOR_SWITCHED) name = _T("cbEVT_EDITOR_SWITCHED");
70     else if (type==cbEVT_EDITOR_ACTIVATED) name = _T("cbEVT_EDITOR_ACTIVATED");
71     else if (type==cbEVT_EDITOR_DEACTIVATED) name = _T("cbEVT_EDITOR_DEACTIVATED");
72     else if (type==cbEVT_EDITOR_BEFORE_SAVE) name = _T("cbEVT_EDITOR_BEFORE_SAVE");
73     else if (type==cbEVT_EDITOR_SAVE) name = _T("cbEVT_EDITOR_SAVE");
74     else if (type==cbEVT_EDITOR_MODIFIED) name = _T("cbEVT_EDITOR_MODIFIED");
75     else if (type==cbEVT_EDITOR_TOOLTIP) name = _T("cbEVT_EDITOR_TOOLTIP");
76     else if (type==cbEVT_EDITOR_TOOLTIP_CANCEL) name = _T("cbEVT_EDITOR_TOOLTIP_CANCEL");
77     else if (type==cbEVT_EDITOR_SPLIT) name = _T("cbEVT_EDITOR_SPLIT");
78     else if (type==cbEVT_EDITOR_UNSPLIT) name = _T("cbEVT_EDITOR_UNSPLIT");
79     else if (type==cbEVT_EDITOR_UPDATE_UI) name = _T("cbEVT_EDITOR_UPDATE_UI");
80     else if (type==cbEVT_PROJECT_NEW) name = _T("cbEVT_PROJECT_NEW");
81     else if (type==cbEVT_PROJECT_CLOSE) name = _T("cbEVT_PROJECT_CLOSE");
82     else if (type==cbEVT_PROJECT_OPEN) name = _T("cbEVT_PROJECT_OPEN");
83     else if (type==cbEVT_PROJECT_SAVE) name = _T("cbEVT_PROJECT_SAVE");
84     else if (type==cbEVT_PROJECT_ACTIVATE) name = _T("cbEVT_PROJECT_ACTIVATE");
85     else if (type==cbEVT_PROJECT_BEGIN_ADD_FILES) name = _T("cbEVT_PROJECT_BEGIN_ADD_FILES");
86     else if (type==cbEVT_PROJECT_END_ADD_FILES) name = _T("cbEVT_PROJECT_END_ADD_FILES");
87     else if (type==cbEVT_PROJECT_BEGIN_REMOVE_FILES) name = _T("cbEVT_PROJECT_BEGIN_REMOVE_FILES");
88     else if (type==cbEVT_PROJECT_END_REMOVE_FILES) name = _T("cbEVT_PROJECT_END_REMOVE_FILES");
89     else if (type==cbEVT_PROJECT_FILE_ADDED) name = _T("cbEVT_PROJECT_FILE_ADDED");
90     else if (type==cbEVT_PROJECT_FILE_REMOVED) name = _T("cbEVT_PROJECT_FILE_REMOVED");
91     else if (type==cbEVT_PROJECT_POPUP_MENU) name = _T("cbEVT_PROJECT_POPUP_MENU");
92     else if (type==cbEVT_PROJECT_TARGETS_MODIFIED) name = _T("cbEVT_PROJECT_TARGETS_MODIFIED");
93     else if (type==cbEVT_PROJECT_RENAMED) name = _T("cbEVT_PROJECT_RENAMED");
94     else if (type==cbEVT_WORKSPACE_CHANGED) name = _T("cbEVT_WORKSPACE_CHANGED");
95     else if (type==cbEVT_BUILDTARGET_ADDED) name = _T("cbEVT_BUILDTARGET_ADDED");
96     else if (type==cbEVT_BUILDTARGET_REMOVED) name = _T("cbEVT_BUILDTARGET_REMOVED");
97     else if (type==cbEVT_BUILDTARGET_RENAMED) name = _T("cbEVT_BUILDTARGET_RENAMED");
98     else if (type==cbEVT_BUILDTARGET_SELECTED) name = _T("cbEVT_BUILDTARGET_SELECTED");
99     else if (type==cbEVT_PIPEDPROCESS_STDOUT) name = _T("cbEVT_PIPEDPROCESS_STDOUT");
100     else if (type==cbEVT_PIPEDPROCESS_STDERR) name = _T("cbEVT_PIPEDPROCESS_STDERR");
101     else if (type==cbEVT_PIPEDPROCESS_TERMINATED) name = _T("cbEVT_PIPEDPROCESS_TERMINATED");
102     else if (type==cbEVT_THREADTASK_STARTED) name = _T("cbEVT_THREADTASK_STARTED");
103     else if (type==cbEVT_THREADTASK_ENDED) name = _T("cbEVT_THREADTASK_ENDED");
104     else if (type==cbEVT_THREADTASK_ALLDONE) name = _T("cbEVT_THREADTASK_ALLDONE");
105     else if (type==cbEVT_MENUBAR_CREATE_BEGIN) name = _T("cbEVT_MENUBAR_CREATE_BEGIN");
106     else if (type==cbEVT_MENUBAR_CREATE_END) name = _T("cbEVT_MENUBAR_CREATE_END");
107     else if (type==cbEVT_COMPILER_STARTED) name = _T("cbEVT_COMPILER_STARTED");
108     else if (type==cbEVT_COMPILER_FINISHED) name = _T("cbEVT_COMPILER_FINISHED");
109     else if (type==cbEVT_COMPILER_SET_BUILD_OPTIONS) name = _T("cbEVT_COMPILER_SET_BUILD_OPTIONS");
110     else if (type==cbEVT_CLEAN_PROJECT_STARTED) name = _T("cbEVT_CLEAN_PROJECT_STARTED");
111     else if (type==cbEVT_CLEAN_WORKSPACE_STARTED) name = _T("cbEVT_CLEAN_WORKSPACE_STARTED");
112     else if (type==cbEVT_DEBUGGER_STARTED) name = _T("cbEVT_DEBUGGER_STARTED");
113     else if (type==cbEVT_DEBUGGER_PAUSED) name = _T("cbEVT_DEBUGGER_PAUSED");
114     else if (type==cbEVT_DEBUGGER_CONTINUED) name = _T("cbEVT_DEBUGGER_CONTINUED");
115     else if (type==cbEVT_DEBUGGER_FINISHED) name = _T("cbEVT_DEBUGGER_FINISHED");
116     else if (type==cbEVT_DEBUGGER_CURSOR_CHANGED) name = _T("cbEVT_DEBUGGER_CURSOR_CHANGED");
117     else if (type==cbEVT_DEBUGGER_UPDATED) name = _T("cbEVT_DEBUGGER_UPDATED");
118     else name = _("unknown CodeBlocksEvent");
119 
120     return name;
121 }
122 #endif // PPRCESS_EVENT_PERFORMANCE_MEASURE
123 
Manager()124 Manager::Manager() :
125     m_pAppWindow(nullptr),
126     m_SearchResultLog(nullptr)
127 {
128     for (int &size : m_ImageSizes)
129         size = 0;
130     for (double &factor : m_UIScaleFactor)
131         factor = 0;
132 }
133 
~Manager()134 Manager::~Manager()
135 {
136     // remove all event sinks
137     for (EventSinksMap::iterator mit = m_EventSinks.begin(); mit != m_EventSinks.end(); ++mit)
138     {
139         while (mit->second.size())
140         {
141             delete (*(mit->second.begin()));
142             mit->second.erase(mit->second.begin());
143         }
144     }
145 
146     for (DockEventSinksMap::iterator mit = m_DockEventSinks.begin(); mit != m_DockEventSinks.end(); ++mit)
147     {
148         while (mit->second.size())
149         {
150             delete (*(mit->second.begin()));
151             mit->second.erase(mit->second.begin());
152         }
153     }
154 
155     for (LayoutEventSinksMap::iterator mit = m_LayoutEventSinks.begin(); mit != m_LayoutEventSinks.end(); ++mit)
156     {
157         while (mit->second.size())
158         {
159             delete (*(mit->second.begin()));
160             mit->second.erase(mit->second.begin());
161         }
162     }
163 
164     for (LogEventSinksMap::iterator mit = m_LogEventSinks.begin(); mit != m_LogEventSinks.end(); ++mit)
165     {
166         while (mit->second.size())
167         {
168             delete (*(mit->second.begin()));
169             mit->second.erase(mit->second.begin());
170         }
171     }
172 }
173 
174 
Get(wxFrame * appWindow)175 Manager* Manager::Get(wxFrame *appWindow)
176 {
177     if (appWindow)
178     {
179         if (Get()->m_pAppWindow)
180             cbThrow(_T("Illegal argument to Manager::Get()"));
181         else
182         {
183             Get()->m_pAppWindow = appWindow;
184             LoadResource(_T("manager_resources.zip"));
185             Get()->GetLogManager()->Log(_("Manager initialized"));
186         }
187     }
188     return Get();
189 }
190 
Get()191 Manager* Manager::Get()
192 {
193     if (!s_ManagerInstance)
194         s_ManagerInstance = new Manager;
195     return s_ManagerInstance;
196 }
197 
Free()198 void Manager::Free()
199 {
200     delete s_ManagerInstance;
201     s_ManagerInstance = nullptr;
202 }
203 
SetAppStartedUp(bool app_started_up)204 void Manager::SetAppStartedUp(bool app_started_up)
205 {
206     m_AppStartedUp = app_started_up;
207 }
208 
SetAppShuttingDown(bool app_shutting_down)209 void Manager::SetAppShuttingDown(bool app_shutting_down)
210 {
211     m_AppShuttingDown = app_shutting_down;
212 }
213 
SetBatchBuild(bool is_batch)214 void Manager::SetBatchBuild(bool is_batch)
215 {
216     m_IsBatch = is_batch;
217 }
218 
BlockYields(bool block)219 void Manager::BlockYields(bool block)
220 {
221     m_BlockYields = block;
222 }
223 
ProcessPendingEvents()224 void Manager::ProcessPendingEvents()
225 {
226     if (!m_BlockYields && !m_AppShuttingDown)
227         wxTheApp->ProcessPendingEvents();
228 }
229 
Yield()230 void Manager::Yield()
231 {
232     if (!m_BlockYields && !m_AppShuttingDown)
233         wxTheApp->Yield(true);
234 }
235 
Shutdown()236 void Manager::Shutdown()
237 {
238     m_AppShuttingDown = true;
239 
240     ToolsManager::Free();
241     TemplateManager::Free();
242     CCManager::Free();
243     PluginManager::Free();
244     DebuggerManager::Free();
245     ScriptingManager::Free();
246     ProjectManager::Free();
247     EditorManager::Free();
248     PersonalityManager::Free();
249     MacrosManager::Free();
250     UserVariableManager::Free();
251     LogManager::Free();
252     CfgMgrBldr::Free();
253 }
254 
ProcessEvent(CodeBlocksEvent & event)255 bool Manager::ProcessEvent(CodeBlocksEvent& event)
256 {
257     if (IsAppShuttingDown())
258         return false;
259 
260     EventSinksMap::iterator mit = m_EventSinks.find(event.GetEventType());
261     if (mit != m_EventSinks.end())
262     {
263         for (EventSinksArray::iterator it = mit->second.begin(); it != mit->second.end(); ++it)
264         {
265 #ifdef PPRCESS_EVENT_PERFORMANCE_MEASURE
266             wxStopWatch sw;
267 #endif // PPRCESS_EVENT_PERFORMANCE_MEASURE
268 
269             (*it)->Call(event);
270 
271 #ifdef PPRCESS_EVENT_PERFORMANCE_MEASURE
272             if(sw.Time() > 10) // only print a handler run longer than 10 ms
273             {
274                 // get a mangled C++ name of the function
275                 const char *p = (*it)->GetTypeName();
276                 int   status;
277                 char *realname;
278                 realname = abi::__cxa_demangle(p, 0, 0, &status);
279                 wxString msg;
280 
281                 // if the demangled C++ function name success, then realname is not NULL
282                 if (realname != 0)
283                 {
284                     msg = wxString::FromUTF8(realname);
285                     free(realname);
286                 }
287                 else
288                     msg = wxString::FromUTF8(p);
289 
290                 wxEventType type=event.GetEventType();
291                 msg << GetCodeblocksEventName(type);
292                 Manager::Get()->GetLogManager()->DebugLog(F(_("%s take %ld ms"), msg.wx_str(), sw.Time()));
293             }
294 #endif // PPRCESS_EVENT_PERFORMANCE_MEASURE
295         }
296     }
297     return true;
298 }
299 
ProcessEvent(CodeBlocksDockEvent & event)300 bool Manager::ProcessEvent(CodeBlocksDockEvent& event)
301 {
302     if (IsAppShuttingDown())
303         return false;
304 
305     DockEventSinksMap::iterator mit = m_DockEventSinks.find(event.GetEventType());
306     if (mit != m_DockEventSinks.end())
307     {
308         for (DockEventSinksArray::iterator it = mit->second.begin(); it != mit->second.end(); ++it)
309             (*it)->Call(event);
310     }
311     return true;
312 }
313 
ProcessEvent(CodeBlocksLayoutEvent & event)314 bool Manager::ProcessEvent(CodeBlocksLayoutEvent& event)
315 {
316     if (IsAppShuttingDown())
317         return false;
318 
319     LayoutEventSinksMap::iterator mit = m_LayoutEventSinks.find(event.GetEventType());
320     if (mit != m_LayoutEventSinks.end())
321     {
322         for (LayoutEventSinksArray::iterator it = mit->second.begin(); it != mit->second.end(); ++it)
323             (*it)->Call(event);
324     }
325     return true;
326 }
327 
ProcessEvent(CodeBlocksLogEvent & event)328 bool Manager::ProcessEvent(CodeBlocksLogEvent& event)
329 {
330     if (IsAppShuttingDown())
331         return false;
332 
333     LogEventSinksMap::iterator mit = m_LogEventSinks.find(event.GetEventType());
334     if (mit != m_LogEventSinks.end())
335     {
336         for (LogEventSinksArray::iterator it = mit->second.begin(); it != mit->second.end(); ++it)
337             (*it)->Call(event);
338     }
339     return true;
340 }
341 
IsAppShuttingDown()342 bool Manager::IsAppShuttingDown()
343 {
344     return m_AppShuttingDown;
345 }
346 
IsAppStartedUp()347 bool Manager::IsAppStartedUp()
348 {
349     return m_AppStartedUp;
350 }
351 
LoadXRC(wxString relpath)352 void Manager::LoadXRC(wxString relpath)
353 {
354     LoadResource(relpath);
355 }
356 
LoadMenuBar(wxString resid,bool createonfailure)357 wxMenuBar *Manager::LoadMenuBar(wxString resid,bool createonfailure)
358 {
359     wxMenuBar *m = wxXmlResource::Get()->LoadMenuBar(resid);
360     if (!m && createonfailure) m = new wxMenuBar();
361     return m;
362 }
363 
LoadMenu(wxString menu_id,bool createonfailure)364 wxMenu *Manager::LoadMenu(wxString menu_id,bool createonfailure)
365 {
366     wxMenu *m = wxXmlResource::Get()->LoadMenu(menu_id);
367     if (!m && createonfailure) m = new wxMenu(_T(""));
368     return m;
369 }
370 
CreateEmptyToolbar()371 wxToolBar* Manager::CreateEmptyToolbar()
372 {
373     const wxSize size(m_ImageSizes[UIComponent::Toolbars], m_ImageSizes[UIComponent::Toolbars]);
374     wxWindow *appFrame = GetAppFrame();
375 
376 #ifdef __WXMSW__
377     const double scaleFactor = 1.0;
378 #else
379     const double scaleFactor = cbGetContentScaleFactor(*appFrame);
380 #endif // __WXMSW__
381     const wxSize scaledSize(size.x/scaleFactor, size.y/scaleFactor);
382 
383     wxToolBar* toolbar = new wxToolBar(appFrame, -1, wxDefaultPosition, scaledSize, wxTB_FLAT | wxTB_NODIVIDER);
384     toolbar->SetToolBitmapSize(scaledSize);
385 
386     return toolbar;
387 }
388 
AddonToolBar(wxToolBar * toolBar,wxString resid)389 void Manager::AddonToolBar(wxToolBar* toolBar,wxString resid)
390 {
391     if (!toolBar)
392         return;
393     if (m_ToolbarHandler)
394         m_ToolbarHandler->SetCurrentResourceID(resid);
395     wxXmlResource::Get()->LoadObject(toolBar,nullptr,resid,_T("wxToolBarAddOn"));
396     if (m_ToolbarHandler)
397         m_ToolbarHandler->SetCurrentResourceID(wxString());
398 }
399 
SetImageSize(int size,UIComponent component)400 void Manager::SetImageSize(int size, UIComponent component)
401 {
402     cbAssert(component>=0 && component < UIComponent::Last);
403     m_ImageSizes[component] = size;
404 
405     if (component == UIComponent::Toolbars)
406     {
407         cbAssert(m_ToolbarHandler);
408         m_ToolbarHandler->SetToolbarImageSize(size);
409     }
410 }
411 
GetImageSize(UIComponent component) const412 int Manager::GetImageSize(UIComponent component) const
413 {
414     cbAssert(component>=0 && component < UIComponent::Last);
415     cbAssert(m_ImageSizes[component] > 0);
416     return m_ImageSizes[component];
417 }
418 
SetUIScaleFactor(double scaleFactor,UIComponent component)419 void Manager::SetUIScaleFactor(double scaleFactor, UIComponent component)
420 {
421     cbAssert(component>=0 && component < UIComponent::Last);
422     m_UIScaleFactor[component] = scaleFactor;
423 }
424 
GetUIScaleFactor(UIComponent component) const425 double Manager::GetUIScaleFactor(UIComponent component) const
426 {
427     cbAssert(component>=0 && component < UIComponent::Last);
428     cbAssert(m_UIScaleFactor[component] >= 1.0);
429     return m_UIScaleFactor[component];
430 }
431 
SetToolbarHandler(wxToolBarAddOnXmlHandler * handler)432 void Manager::SetToolbarHandler(wxToolBarAddOnXmlHandler *handler)
433 {
434     m_ToolbarHandler = handler;
435 }
436 
GetAppFrame() const437 wxFrame* Manager::GetAppFrame() const
438 {
439     return m_pAppWindow;
440 }
441 
GetAppWindow() const442 wxWindow* Manager::GetAppWindow() const
443 {
444     return (wxWindow*)m_pAppWindow;
445 }
446 
GetProjectManager() const447 ProjectManager* Manager::GetProjectManager() const
448 {
449     return ProjectManager::Get();
450 }
451 
GetEditorManager() const452 EditorManager* Manager::GetEditorManager() const
453 {
454     return EditorManager::Get();
455 }
456 
GetLogManager() const457 LogManager* Manager::GetLogManager() const
458 {
459     return LogManager::Get();
460 }
461 
GetPluginManager() const462 PluginManager* Manager::GetPluginManager() const
463 {
464     return PluginManager::Get();
465 }
466 
GetToolsManager() const467 ToolsManager* Manager::GetToolsManager() const
468 {
469     return ToolsManager::Get();
470 }
471 
GetMacrosManager() const472 MacrosManager* Manager::GetMacrosManager() const
473 {
474     return MacrosManager::Get();
475 }
476 
GetPersonalityManager() const477 PersonalityManager* Manager::GetPersonalityManager() const
478 {
479     return PersonalityManager::Get();
480 }
481 
GetUserVariableManager() const482 UserVariableManager* Manager::GetUserVariableManager() const
483 {
484     return UserVariableManager::Get();
485 }
486 
GetScriptingManager() const487 ScriptingManager* Manager::GetScriptingManager() const
488 {
489     return ScriptingManager::Get();
490 }
491 
GetConfigManager(const wxString & name_space) const492 ConfigManager* Manager::GetConfigManager(const wxString& name_space) const
493 {
494     return CfgMgrBldr::GetConfigManager(name_space);
495 }
496 
GetFileManager() const497 FileManager* Manager::GetFileManager() const
498 {
499     return FileManager::Get();
500 }
501 
GetDebuggerManager() const502 DebuggerManager* Manager::GetDebuggerManager() const
503 {
504     return DebuggerManager::Get();
505 }
506 
GetColourManager() const507 ColourManager* Manager::GetColourManager() const
508 {
509     return ColourManager::Get();
510 }
511 
GetCCManager() const512 CCManager* Manager::GetCCManager() const
513 {
514     return CCManager::Get();
515 }
516 
LoadResource(const wxString & file)517 bool Manager::LoadResource(const wxString& file)
518 {
519     wxString resourceFile = ConfigManager::LocateDataFile(file, sdDataGlobal | sdDataUser);
520     wxString memoryFile = _T("memory:") + file;
521 
522     if (wxFile::Access(resourceFile, wxFile::read) == false)
523     {
524         Get()->GetLogManager()->LogError(_("Manager failed to access XRC resource '") + resourceFile + _("'."));
525         return false;
526     }
527 
528     // The code below forces a reload of the resource
529     // Currently unused...
530 
531 //    {
532 //        wxMemoryFSHandler::RemoveFile(file);
533 //    }
534 //#if wxABI_VERSION > 20601
535 //    // unload old resources with the same name
536 //    wxXmlResource::Get()->Unload(memoryFile);
537 //#endif
538 
539     wxFile f(resourceFile, wxFile::read);
540     char *buf = nullptr;
541 
542     try
543     {
544         size_t len = f.Length();
545         buf = new char[len];
546         f.Read(buf, len);
547         {
548             wxMemoryFSHandler::AddFile(file, buf, len);
549         }
550         if ( !wxXmlResource::Get()->Load(memoryFile) )
551             Get()->GetLogManager()->LogError(_("Manager failed to load XRC resource '") + resourceFile + _("'."));
552         delete[] buf;
553         return true;
554     }
555     catch (...)
556     {
557         delete[] buf;
558         Get()->GetLogManager()->LogError(_("Manager hardly failed to load XRC resource '") + resourceFile + _("'."));
559         return false;
560     }
561 }
562 
GetCmdLineParser()563 wxCmdLineParser* Manager::GetCmdLineParser()
564 {
565     return &m_CmdLineParser;
566 }
567 
RegisterEventSink(wxEventType eventType,IEventFunctorBase<CodeBlocksEvent> * functor)568 void Manager::RegisterEventSink(wxEventType eventType, IEventFunctorBase<CodeBlocksEvent>* functor)
569 {
570     m_EventSinks[eventType].push_back(functor);
571 }
572 
RegisterEventSink(wxEventType eventType,IEventFunctorBase<CodeBlocksDockEvent> * functor)573 void Manager::RegisterEventSink(wxEventType eventType, IEventFunctorBase<CodeBlocksDockEvent>* functor)
574 {
575     m_DockEventSinks[eventType].push_back(functor);
576 }
577 
RegisterEventSink(wxEventType eventType,IEventFunctorBase<CodeBlocksLayoutEvent> * functor)578 void Manager::RegisterEventSink(wxEventType eventType, IEventFunctorBase<CodeBlocksLayoutEvent>* functor)
579 {
580     m_LayoutEventSinks[eventType].push_back(functor);
581 }
582 
RegisterEventSink(wxEventType eventType,IEventFunctorBase<CodeBlocksLogEvent> * functor)583 void Manager::RegisterEventSink(wxEventType eventType, IEventFunctorBase<CodeBlocksLogEvent>* functor)
584 {
585     m_LogEventSinks[eventType].push_back(functor);
586 }
587 
RemoveAllEventSinksFor(void * owner)588 void Manager::RemoveAllEventSinksFor(void* owner)
589 {
590     for (EventSinksMap::iterator mit = m_EventSinks.begin(); mit != m_EventSinks.end(); ++mit)
591     {
592         EventSinksArray::iterator it = mit->second.begin();
593         bool endIsInvalid = false;
594         while (!endIsInvalid && it != mit->second.end())
595         {
596             if ((*it) && (*it)->GetThis() == owner)
597             {
598                 EventSinksArray::iterator it2 = it++;
599                 endIsInvalid = it == mit->second.end();
600                 delete (*it2);
601                 mit->second.erase(it2);
602             }
603             else
604                 ++it;
605         }
606     }
607 
608     for (DockEventSinksMap::iterator mit = m_DockEventSinks.begin(); mit != m_DockEventSinks.end(); ++mit)
609     {
610         DockEventSinksArray::iterator it = mit->second.begin();
611         bool endIsInvalid = false;
612         while (!endIsInvalid && it != mit->second.end())
613         {
614             if ((*it) && (*it)->GetThis() == owner)
615             {
616                 DockEventSinksArray::iterator it2 = it++;
617                 endIsInvalid = it == mit->second.end();
618                 delete (*it2);
619                 mit->second.erase(it2);
620             }
621             else
622                 ++it;
623         }
624     }
625 
626     for (LayoutEventSinksMap::iterator mit = m_LayoutEventSinks.begin(); mit != m_LayoutEventSinks.end(); ++mit)
627     {
628         LayoutEventSinksArray::iterator it = mit->second.begin();
629         bool endIsInvalid = false;
630         while (!endIsInvalid && it != mit->second.end())
631         {
632             if ((*it) && (*it)->GetThis() == owner)
633             {
634                 LayoutEventSinksArray::iterator it2 = it++;
635                 endIsInvalid = it == mit->second.end();
636                 delete (*it2);
637                 mit->second.erase(it2);
638             }
639             else
640                 ++it;
641         }
642     }
643 
644     for (LogEventSinksMap::iterator mit = m_LogEventSinks.begin(); mit != m_LogEventSinks.end(); ++mit)
645     {
646         LogEventSinksArray::iterator it = mit->second.begin();
647         bool endIsInvalid = false;
648         while (!endIsInvalid && it != mit->second.end())
649         {
650             if ((*it) && (*it)->GetThis() == owner)
651             {
652                 LogEventSinksArray::iterator it2 = it++;
653                 endIsInvalid = it == mit->second.end();
654                 delete (*it2);
655                 mit->second.erase(it2);
656             }
657             else
658                 ++it;
659         }
660     }
661 }
662 
663 bool            Manager::m_AppShuttingDown = false;
664 bool            Manager::m_AppStartedUp    = false;
665 bool            Manager::m_BlockYields     = false;
666 bool            Manager::m_IsBatch         = false;
667 wxCmdLineParser Manager::m_CmdLineParser;
668 wxToolBarAddOnXmlHandler* Manager::m_ToolbarHandler = nullptr;
669