1
#include <wx/notebook.h>
2
#include <wx/textctrl.h>
4
#include "ShellCtrlBase.h"
7
// The global instance of the shell registry
8
ShellRegistry& GlobalShellRegistry()
10
static ShellRegistry* theRegistry = new ShellRegistry();
14
// Unique IDs for Timer and Shell Manager messages
15
long ID_SHELLPOLLTIMER = wxNewId();
16
long ID_SHELLMGR = wxNewId();
17
long ID_REMOVE_TERMINATED = wxNewId();
20
bool ShellRegistry::Register(const wxString &name, fnCreate create, fnFree free) //register/deregister are called by the plugin registrant instance
22
Manager::Get()->GetLogManager()->Log(wxString::Format(_("Tools Plus Plugin: Registering shell type %s"),name.c_str()));
23
std::map<wxString, ShellRegInfo>::iterator it;
24
if(m_reginfo.find(name)!=m_reginfo.end())
34
bool ShellRegistry::Deregister(const wxString &name)
36
std::map<wxString, ShellRegInfo>::iterator it
37
=m_reginfo.find(name);
38
if(it==m_reginfo.end())
45
ShellCtrlBase *ShellRegistry::CreateControl(const wxString &type,wxWindow* parent, int id, const wxString &windowname, ShellManager *shellmgr)
47
std::map<wxString, ShellRegInfo>::iterator it
48
=m_reginfo.find(type);
49
if(it==m_reginfo.end())
51
return it->second.create(parent, id, windowname, shellmgr);
55
void ShellRegistry::FreeControl(ShellCtrlBase */*sh*/) //TODO: Don't think this is necessary?
57
// std::map<wxString, ShellRegInfo>::iterator it
58
// =m_reginfo.find(type);
59
// if(it!=m_reginfo.end())
60
// it.second->free(); //TODO: Can't compile
64
//IMPLEMENT_DYNAMIC_CLASS(ShellCtrlBase, wxPanel)
66
ShellCtrlBase::ShellCtrlBase(wxWindow* parent, int id, const wxString &name, ShellManager *shellmgr)
76
////////////////////////////////////// ShellManager /////////////////////////////////////////////
78
BEGIN_EVENT_TABLE(ShellManager, wxPanel)
79
EVT_CHAR(ShellManager::OnUserInput)
80
EVT_TIMER(ID_SHELLPOLLTIMER, ShellManager::OnPollandSyncOutput)
81
EVT_AUINOTEBOOK_PAGE_CLOSE(ID_SHELLMGR, ShellManager::OnPageClosing)
82
EVT_AUINOTEBOOK_TAB_RIGHT_UP(ID_SHELLMGR, ShellManager::OnPageContextMenu)
83
EVT_MENU(ID_REMOVE_TERMINATED,ShellManager::OnRemoveTerminated)
87
void ShellManager::OnPageClosing(wxAuiNotebookEvent& event)
89
ShellCtrlBase* sh = GetPage(event.GetSelection());
90
// LOGSTREAM << wxString::Format(_T("OnPageClosing(): ed=%p, title=%s\n"), eb, eb ? eb->GetTitle().c_str() : _T(""));
93
// event.Skip(); // allow others to process it too
95
void ShellManager::OnPageContextMenu(wxAuiNotebookEvent& event)
97
if (event.GetSelection() == -1)
100
// select the notebook that sends the event
101
m_nb->SetSelection(event.GetSelection());
102
wxMenu* pop = new wxMenu;
103
pop->Append(ID_REMOVE_TERMINATED, _("Close Inactive Tool Pages"));
105
m_nb->PopupMenu(pop);
109
void ShellManager::OnRemoveTerminated(cb_unused wxCommandEvent &event)
114
bool ShellManager::QueryClose(ShellCtrlBase* sh)
120
wxString msg(_("Process \"")+sh->GetName()+_("\" is still running...\nDo you want to kill it?"));
121
switch (cbMessageBox(msg, _("Kill process?"), wxICON_QUESTION | wxYES_NO))
136
long ShellManager::LaunchProcess(const wxString &processcmd, const wxString &name, const wxString &type, const wxArrayString &options)
139
ShellCtrlBase *shell=GlobalShellRegistry().CreateControl(type,this,id,name,this);
142
cbMessageBox(wxString::Format(_("Console type %s not found in registry."),type.c_str()));
145
long procid=shell->LaunchProcess(processcmd,options);
148
if(!m_synctimer.IsRunning())
149
m_synctimer.Start(100);
153
cbMessageBox(_("process launch failed."));
154
delete shell; //TODO: GlobalShellRegistry.FreeControl() ???
157
m_nb->AddPage(shell,name);
158
m_nb->SetSelection(m_nb->GetPageCount()-1);
163
ShellCtrlBase *ShellManager::GetPage(size_t i)
165
return (ShellCtrlBase*)m_nb->GetPage(i);
168
ShellCtrlBase *ShellManager::GetPage(const wxString &name)
170
for(unsigned int i=0;i<m_nb->GetPageCount();i++)
172
ShellCtrlBase *sh=GetPage(i);
173
if(name==sh->GetName())
180
// Forecefully kill the process
181
void ShellManager::KillProcess(int /*id*/)
185
void ShellManager::KillWindow(int /*id*/)
189
void ShellManager::RemoveDeadPages()
192
while(i<m_nb->GetPageCount())
194
ShellCtrlBase *shell=GetPage(i);
203
size_t ShellManager::GetTermNum(ShellCtrlBase *term)
205
for(unsigned int i=0;i<m_nb->GetPageCount();i++)
207
ShellCtrlBase *shell=GetPage(i);
211
return m_nb->GetPageCount();
214
int ShellManager::NumAlive()
217
for(unsigned int i=0;i<m_nb->GetPageCount();i++)
218
count+=!GetPage(i)->IsDead();
223
void ShellManager::OnShellTerminate(ShellCtrlBase *term)
225
size_t i=GetTermNum(term);
226
m_nb->SetPageText(i,_("[DONE]")+m_nb->GetPageText(i));
232
void ShellManager::OnPollandSyncOutput(wxTimerEvent& /*te*/)
234
for(unsigned int i=0;i<m_nb->GetPageCount();i++)
236
GetPage(i)->SyncOutput();
240
void ShellManager::OnUserInput(wxKeyEvent& /*ke*/)
241
{ //TODO: This shouldn't be necessary as individual pages will have the focus
242
// ShellCtrlBase *sh=(ShellCtrlBase*)m_nb->GetCurrentPage();
243
// sh->OnUserInput(ke);
246
ShellManager::ShellManager(wxWindow* parent)
247
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL/* | wxCLIP_CHILDREN*/)
249
m_synctimer.SetOwner(this, ID_SHELLPOLLTIMER);
250
wxBoxSizer* bs = new wxBoxSizer(wxVERTICAL);
251
m_nb = new wxAuiNotebook(this, ID_SHELLMGR, wxDefaultPosition, wxDefaultSize, wxAUI_NB_SCROLL_BUTTONS|wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
252
bs->Add(m_nb, 1, wxEXPAND | wxALL);
257
ShellManager::~ShellManager()
260
//All of the subwindows owned by this panel will be destroyed automatically