/*
* 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 <mandrav@codeblocks.org>
* 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 <wx/intl.h>
#include <wx/process.h>
#include <wx/menu.h>
#include <wx/mdi.h>
#include <wx/msgdlg.h>
#include "toolsmanager.h"
#include "manager.h"
#include "macrosmanager.h"
#include "configmanager.h"
#include "messagemanager.h"
#include "configuretoolsdlg.h"
#include "managerproxy.h"
#include <wx/listimpl.cpp>
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);
}
syntax highlighted by Code2HTML, v. 0.9.1