/* * This file is part of Code::Blocks Studio, an open-source cross-platform IDE * Copyright (C) 2003 Yiannis An. Mandravellos * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact e-mail: Yiannis An. Mandravellos * Program URL : http://www.codeblocks.org * * $Id: toolsmanager.cpp,v 1.10.2.1 2005/10/25 07:59:03 mandrav Exp $ * $Date: 2005/10/25 07:59:03 $ */ #include "sdk_precomp.h" #include #include #include #include #include #include "toolsmanager.h" #include "manager.h" #include "macrosmanager.h" #include "configmanager.h" #include "messagemanager.h" #include "configuretoolsdlg.h" #include "managerproxy.h" #include WX_DEFINE_LIST(ToolsList); ToolsManager* ToolsManager::Get() { if(Manager::isappShuttingDown()) // The mother of all sanity checks ToolsManager::Free(); else if (!ToolsManagerProxy::Get()) { ToolsManagerProxy::Set( new ToolsManager() ); Manager::Get()->GetMessageManager()->Log(_("ToolsManager initialized")); } return ToolsManagerProxy::Get(); } void ToolsManager::Free() { if (ToolsManagerProxy::Get()) { delete ToolsManagerProxy::Get(); ToolsManagerProxy::Set( 0L ); } } int idToolsConfigure = wxNewId(); BEGIN_EVENT_TABLE(ToolsManager, wxEvtHandler) EVT_MENU(idToolsConfigure, ToolsManager::OnConfigure) END_EVENT_TABLE() ToolsManager::ToolsManager() : m_Menu(0L) { SC_CONSTRUCTOR_BEGIN LoadTools(); ConfigManager::AddConfiguration(_("Tools"), _T("/tools")); Manager::Get()->GetAppWindow()->PushEventHandler(this); } ToolsManager::~ToolsManager() { SC_DESTRUCTOR_BEGIN // this is a core manager, so it is removed when the app is shutting down. // in this case, the app has already un-hooked us, so no need to do it ourselves... // Manager::Get()->GetAppWindow()->RemoveEventHandler(this); m_ItemsManager.Clear( m_Menu ); // free-up any memory used for tools m_Tools.DeleteContents(true); m_Tools.Clear(); SC_DESTRUCTOR_END } void ToolsManager::CreateMenu(wxMenuBar* menuBar) { SANITY_CHECK(); } void ToolsManager::ReleaseMenu(wxMenuBar* menuBar) { SANITY_CHECK(); } bool ToolsManager::Execute(Tool* tool) { SANITY_CHECK(false); if (!tool) return false; wxString cmdline; wxString cmd = tool->command; wxString params = tool->params; wxString dir = tool->workingDir; Manager::Get()->GetMacrosManager()->ReplaceMacros(cmd); Manager::Get()->GetMacrosManager()->ReplaceMacros(params); Manager::Get()->GetMacrosManager()->ReplaceMacros(dir); cmdline << cmd << _T(" ") << params; SANITY_CHECK(false); if(!(Manager::Get()->GetMacrosManager())) return false; // We cannot afford the Macros Manager to fail here! // What if it failed already? wxSetWorkingDirectory(dir); wxProcess* process = new wxProcess(); return wxExecute(cmdline, wxEXEC_ASYNC, process); } void ToolsManager::AddTool(const wxString& name, const wxString& command, const wxString& params, const wxString& workingDir, bool save) { SANITY_CHECK(); Tool tool; tool.name = name; tool.command = command; tool.params = params; tool.workingDir = workingDir; InsertTool(m_Tools.GetCount(), &tool, save); } void ToolsManager::AddTool(Tool* tool, bool save) { SANITY_CHECK(); if (tool) InsertTool(m_Tools.GetCount(), tool, save); } void ToolsManager::InsertTool(int position, Tool* tool, bool save) { SANITY_CHECK(); //Manager::Get()->GetMessageManager()->DebugLog("Creating tool: %s", tool->name.c_str()); m_Tools.Insert(position, new Tool(*tool)); if (save) SaveTools(); } void ToolsManager::RemoveToolByIndex(int index) { SANITY_CHECK(); int idx = 0; for (ToolsList::Node* node = m_Tools.GetFirst(); node; node = node->GetNext()) { if (idx == index) { DoRemoveTool(node); return; } ++idx; } } void ToolsManager::RemoveToolByName(const wxString& name) { SANITY_CHECK(); for (ToolsList::Node* node = m_Tools.GetFirst(); node; node = node->GetNext()) { Tool* tool = node->GetData(); if (name.Matches(tool->name)) { DoRemoveTool(node); return; } } } void ToolsManager::DoRemoveTool(ToolsList::Node* node) { SANITY_CHECK(); if (node) { if (node->GetData()->menuId != -1) m_Menu->Delete(node->GetData()->menuId); m_Tools.DeleteNode(node); SaveTools(); } } Tool* ToolsManager::GetToolById(int id) { SANITY_CHECK(0L); for (ToolsList::Node* node = m_Tools.GetFirst(); node; node = node->GetNext()) { Tool* tool = node->GetData(); if (tool->menuId == id) return tool; } return 0L; } Tool* ToolsManager::GetToolByIndex(int index) { SANITY_CHECK(0L); int idx = 0; for (ToolsList::Node* node = m_Tools.GetFirst(); node; node = node->GetNext()) { Tool* tool = node->GetData(); if (idx == index) return tool; ++idx; } return 0L; } void ToolsManager::LoadTools() { SANITY_CHECK(); wxString str; long cookie; ConfigManager::Get()->SetPath(_T("/tools")); bool cont = ConfigManager::Get()->GetFirstGroup(str, cookie); while (cont) { Tool tool; ConfigManager::Get()->Read(_T("/tools/") + str + _T("/command"), &tool.command); ConfigManager::Get()->Read(_T("/tools/") + str + _T("/params"), &tool.params); ConfigManager::Get()->Read(_T("/tools/") + str + _T("/workingDir"), &tool.workingDir); // remove ordering number if (str.GetChar(2) == ' ' && str.Left(2).IsNumber()) str.Remove(0, 3); tool.name = str; AddTool(&tool, false); cont = ConfigManager::Get()->GetNextGroup(str, cookie); } ConfigManager::Get()->SetPath(_T("/")); Manager::Get()->GetMessageManager()->Log(_("Configured %d tools"), m_Tools.GetCount()); } void ToolsManager::SaveTools() { SANITY_CHECK(); int count = 0; ConfigManager::Get()->DeleteGroup(_T("/tools")); for (ToolsList::Node* node = m_Tools.GetFirst(); node; node = node->GetNext()) { Tool* tool = node->GetData(); wxString elem; // prepend a 0-padded 2-digit number to keep ordering wxString tmp; tmp.Printf(_("%2.2d"), count++); elem << _T("/tools/") << tmp << _T(" ") << tool->name << _T("/"); ConfigManager::Get()->Write(elem + _T("command"), tool->command); ConfigManager::Get()->Write(elem + _T("params"), tool->params); ConfigManager::Get()->Write(elem + _T("workingDir"), tool->workingDir); } } void ToolsManager::BuildToolsMenu(wxMenu* menu) { SANITY_CHECK(); // clear previously added menu items m_ItemsManager.Clear(menu); // add menu items for tools m_Menu = menu; if (m_Menu->GetMenuItemCount() > 0) { m_ItemsManager.Add(menu, wxID_SEPARATOR, _T(""), _T("")); } for (ToolsList::Node* node = m_Tools.GetFirst(); node; node = node->GetNext()) { Tool* tool = node->GetData(); if (tool->menuId == -1) tool->menuId = wxNewId(); m_ItemsManager.Add(menu, tool->menuId, tool->name, tool->name); Connect(tool->menuId, -1, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &ToolsManager::OnToolClick); } if (m_Tools.GetCount() > 0) { m_ItemsManager.Add(menu, wxID_SEPARATOR, _T(""), _T("")); } m_ItemsManager.Add(menu, idToolsConfigure, _("&Configure tools..."), _("Add/remove user-defined tools")); } int ToolsManager::Configure() { SANITY_CHECK(0); ConfigureToolsDlg dlg(Manager::Get()->GetAppWindow()); dlg.ShowModal(); SaveTools(); BuildToolsMenu(m_Menu); return 0; } // events void ToolsManager::OnConfigure(wxCommandEvent& event) { SANITY_CHECK(); Configure(); } void ToolsManager::OnToolClick(wxCommandEvent& event) { SANITY_CHECK(); Tool* tool = GetToolById(event.GetId()); if (!Execute(tool)) wxMessageBox(_("Could not execute ") + tool->name); }