~efargaspro/+junk/codeblocks-16.01-release

« back to all changes in this revision

Viewing changes to src/plugins/contrib/ToolsPlus/ShellCtrlBase.cpp

  • Committer: damienlmoore at gmail
  • Date: 2016-02-02 02:43:22 UTC
  • Revision ID: damienlmoore@gmail.com-20160202024322-yql5qmtbwdyamdwd
Code::BlocksĀ 16.01

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <wx/notebook.h>
 
2
#include <wx/textctrl.h>
 
3
#include <wx/regex.h>
 
4
#include "ShellCtrlBase.h"
 
5
#include <globals.h>
 
6
 
 
7
// The global instance of the shell registry
 
8
ShellRegistry& GlobalShellRegistry()
 
9
{
 
10
   static ShellRegistry* theRegistry = new ShellRegistry();
 
11
   return *theRegistry;
 
12
}
 
13
 
 
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();
 
18
 
 
19
 
 
20
bool ShellRegistry::Register(const wxString &name, fnCreate create, fnFree free) //register/deregister are called by the plugin registrant instance
 
21
{
 
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())
 
25
        return false;
 
26
    ShellRegInfo sri;
 
27
    sri.create=create;
 
28
    sri.free=free;
 
29
    m_reginfo[name]=sri;
 
30
    return true;
 
31
}
 
32
 
 
33
 
 
34
bool ShellRegistry::Deregister(const wxString &name)
 
35
{
 
36
    std::map<wxString, ShellRegInfo>::iterator it
 
37
        =m_reginfo.find(name);
 
38
    if(it==m_reginfo.end())
 
39
        return false;
 
40
    m_reginfo.erase(it);
 
41
    return true;
 
42
}
 
43
 
 
44
 
 
45
ShellCtrlBase *ShellRegistry::CreateControl(const wxString &type,wxWindow* parent, int id, const wxString &windowname, ShellManager *shellmgr)
 
46
{
 
47
    std::map<wxString, ShellRegInfo>::iterator it
 
48
        =m_reginfo.find(type);
 
49
    if(it==m_reginfo.end())
 
50
        return NULL;
 
51
    return it->second.create(parent, id, windowname, shellmgr);
 
52
}
 
53
 
 
54
 
 
55
void ShellRegistry::FreeControl(ShellCtrlBase */*sh*/) //TODO: Don't think this is necessary?
 
56
{
 
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
 
61
}
 
62
 
 
63
 
 
64
//IMPLEMENT_DYNAMIC_CLASS(ShellCtrlBase, wxPanel)
 
65
 
 
66
ShellCtrlBase::ShellCtrlBase(wxWindow* parent, int id, const wxString &name, ShellManager *shellmgr)
 
67
                : wxPanel(parent, id)
 
68
{
 
69
    m_parent=parent;
 
70
    m_name=name;
 
71
    m_id=id;
 
72
    m_shellmgr=shellmgr;
 
73
}
 
74
 
 
75
 
 
76
////////////////////////////////////// ShellManager /////////////////////////////////////////////
 
77
 
 
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)
 
84
END_EVENT_TABLE()
 
85
 
 
86
 
 
87
void ShellManager::OnPageClosing(wxAuiNotebookEvent& event)
 
88
{
 
89
    ShellCtrlBase* sh = GetPage(event.GetSelection());
 
90
    //    LOGSTREAM << wxString::Format(_T("OnPageClosing(): ed=%p, title=%s\n"), eb, eb ? eb->GetTitle().c_str() : _T(""));
 
91
    if (!QueryClose(sh))
 
92
        event.Veto();
 
93
//    event.Skip(); // allow others to process it too
 
94
}
 
95
void ShellManager::OnPageContextMenu(wxAuiNotebookEvent& event)
 
96
{
 
97
    if (event.GetSelection() == -1)
 
98
        return;
 
99
 
 
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"));
 
104
 
 
105
    m_nb->PopupMenu(pop);
 
106
    delete pop;
 
107
}
 
108
 
 
109
void ShellManager::OnRemoveTerminated(cb_unused wxCommandEvent &event)
 
110
{
 
111
    RemoveDeadPages();
 
112
}
 
113
 
 
114
bool ShellManager::QueryClose(ShellCtrlBase* sh)
 
115
{
 
116
    if(!sh)
 
117
        return true;
 
118
    if(!sh->IsDead())
 
119
    {
 
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))
 
122
        {
 
123
        case wxID_YES:
 
124
            sh->KillProcess();
 
125
            return false;
 
126
        case wxID_NO:
 
127
            return false;
 
128
        default:
 
129
            break;
 
130
        }
 
131
    }
 
132
    return true;
 
133
}
 
134
 
 
135
 
 
136
long ShellManager::LaunchProcess(const wxString &processcmd, const wxString &name, const wxString &type, const wxArrayString &options)
 
137
{
 
138
    int id=wxNewId();
 
139
    ShellCtrlBase *shell=GlobalShellRegistry().CreateControl(type,this,id,name,this);
 
140
    if(!shell)
 
141
    {
 
142
        cbMessageBox(wxString::Format(_("Console type %s not found in registry."),type.c_str()));
 
143
        return -1;
 
144
    }
 
145
    long procid=shell->LaunchProcess(processcmd,options);
 
146
    if(procid>0)
 
147
    {
 
148
        if(!m_synctimer.IsRunning())
 
149
            m_synctimer.Start(100);
 
150
    }
 
151
    else
 
152
    {
 
153
        cbMessageBox(_("process launch failed."));
 
154
        delete shell; //TODO: GlobalShellRegistry.FreeControl() ???
 
155
        return -1;
 
156
    }
 
157
    m_nb->AddPage(shell,name);
 
158
    m_nb->SetSelection(m_nb->GetPageCount()-1);
 
159
//    shell->Show();
 
160
    return procid;
 
161
}
 
162
 
 
163
ShellCtrlBase *ShellManager::GetPage(size_t i)
 
164
{
 
165
    return (ShellCtrlBase*)m_nb->GetPage(i);
 
166
}
 
167
 
 
168
ShellCtrlBase *ShellManager::GetPage(const wxString &name)
 
169
{
 
170
    for(unsigned int i=0;i<m_nb->GetPageCount();i++)
 
171
    {
 
172
        ShellCtrlBase *sh=GetPage(i);
 
173
        if(name==sh->GetName())
 
174
            return sh;
 
175
    }
 
176
    return NULL;
 
177
}
 
178
 
 
179
 
 
180
// Forecefully kill the process
 
181
void ShellManager::KillProcess(int /*id*/)
 
182
{
 
183
}
 
184
 
 
185
void ShellManager::KillWindow(int /*id*/)
 
186
{
 
187
}
 
188
 
 
189
void ShellManager::RemoveDeadPages()
 
190
{
 
191
    unsigned int i=0;
 
192
    while(i<m_nb->GetPageCount())
 
193
    {
 
194
        ShellCtrlBase *shell=GetPage(i);
 
195
        if(shell->IsDead())
 
196
            m_nb->DeletePage(i);
 
197
        else
 
198
            i++;
 
199
    }
 
200
}
 
201
 
 
202
 
 
203
size_t ShellManager::GetTermNum(ShellCtrlBase *term)
 
204
{
 
205
    for(unsigned int i=0;i<m_nb->GetPageCount();i++)
 
206
    {
 
207
        ShellCtrlBase *shell=GetPage(i);
 
208
        if(shell==term)
 
209
            return i;
 
210
    }
 
211
    return m_nb->GetPageCount();
 
212
}
 
213
 
 
214
int ShellManager::NumAlive()
 
215
{
 
216
    int count=0;
 
217
    for(unsigned int i=0;i<m_nb->GetPageCount();i++)
 
218
        count+=!GetPage(i)->IsDead();
 
219
    return count;
 
220
}
 
221
 
 
222
 
 
223
void ShellManager::OnShellTerminate(ShellCtrlBase *term)
 
224
{
 
225
    size_t i=GetTermNum(term);
 
226
    m_nb->SetPageText(i,_("[DONE]")+m_nb->GetPageText(i));
 
227
    if(NumAlive()==0)
 
228
        m_synctimer.Stop();
 
229
}
 
230
 
 
231
 
 
232
void ShellManager::OnPollandSyncOutput(wxTimerEvent& /*te*/)
 
233
{
 
234
    for(unsigned int i=0;i<m_nb->GetPageCount();i++)
 
235
    {
 
236
        GetPage(i)->SyncOutput();
 
237
    }
 
238
}
 
239
 
 
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);
 
244
}
 
245
 
 
246
ShellManager::ShellManager(wxWindow* parent)
 
247
    : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL/* | wxCLIP_CHILDREN*/)
 
248
{
 
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);
 
253
    SetAutoLayout(TRUE);
 
254
    SetSizer(bs);
 
255
}
 
256
 
 
257
ShellManager::~ShellManager()
 
258
{
 
259
    //dtor
 
260
    //All of the subwindows owned by this panel will be destroyed automatically
 
261
}
 
262