00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
00013
00014 #include "wx/wxprec.h"
00015
00016 #ifdef __BORLANDC__
00017 #pragma hdrstop
00018 #endif
00019
00020 #ifndef WX_PRECOMP
00021 #include "wx/wx.h"
00022 #endif
00023
00024 #include <wx/txtstrm.h>
00025 #include <wx/notebook.h>
00026 #include "guipm/extcmdprogresspanel.h"
00027
00028
00029
00030
00031
00032
00033 IMPLEMENT_DYNAMIC_CLASS( wxExtCmdProgressPanel, wxPanel )
00034 DEFINE_EVENT_TYPE(wxEVT_COMMAND_PROGRESS_FAILED)
00035 DEFINE_EVENT_TYPE(wxEVT_COMMAND_PROGRESS_END)
00036 BEGIN_EVENT_TABLE( wxExtCmdProgressPanel, wxPanel )
00037 EVT_IDLE( wxExtCmdProgressPanel::OnIdle )
00038 EVT_END_PROCESS( ID_EXTCMD_PROCESS, wxExtCmdProgressPanel::OnProcessTerminate )
00039 EVT_UPDATE_UI( wxID_ANY, wxExtCmdProgressPanel::OnUpdateUI )
00040 END_EVENT_TABLE()
00041
00042
00043 wxExtCmdProgressPanel::wxExtCmdProgressPanel( )
00044 {
00045 }
00046
00047 wxExtCmdProgressPanel::wxExtCmdProgressPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString &name )
00048 {
00049 Create(parent, id, pos, size, style, name);
00050 }
00051
00052 bool wxExtCmdProgressPanel::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString &name )
00053 {
00054 m_currProcess = NULL;
00055 m_pCommandList = NULL;
00056 m_pOutput = NULL;
00057 m_pGauge = NULL;
00058 m_stage = wxPBSS_INVALID;
00059 m_pid = 0;
00060
00061 wxPanel::Create( parent, id, pos, size, style, name );
00062
00063 CreateControls();
00064 GetSizer()->Fit(this);
00065 GetSizer()->SetSizeHints(this);
00066 Centre();
00067
00068 return true;
00069 }
00070
00071 void wxExtCmdProgressPanel::CreateControls()
00072 {
00073
00075 wxExtCmdProgressPanel* itemProgressPanel1 = this;
00076
00077 wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
00078 itemProgressPanel1->SetSizer(itemBoxSizer2);
00079
00080 wxStaticText* itemStaticText3 = new wxStaticText( itemProgressPanel1, wxID_STATIC, _("Commands:"), wxDefaultPosition, wxDefaultSize, 0 );
00081 itemBoxSizer2->Add(itemStaticText3, 0, wxALIGN_LEFT|wxALL|wxADJUST_MINSIZE, 5);
00082
00083 wxString* m_pCommandListStrings = NULL;
00084 m_pCommandList = new wxListBox( itemProgressPanel1, ID_EXTCMD_COMMANDS, wxDefaultPosition, wxDefaultSize, 0, m_pCommandListStrings, wxLB_SINGLE );
00085 itemBoxSizer2->Add(m_pCommandList, 2, wxGROW|wxALL, 5);
00086
00087 wxStaticText* itemStaticText5 = new wxStaticText( itemProgressPanel1, wxID_STATIC, _("Output:"), wxDefaultPosition, wxDefaultSize, 0 );
00088 itemBoxSizer2->Add(itemStaticText5, 0, wxALIGN_LEFT|wxALL|wxADJUST_MINSIZE, 5);
00089
00090 m_pGauge = new wxGauge( itemProgressPanel1, ID_EXTCMD_GAUGE, 100, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL );
00091 m_pGauge->SetValue(0);
00092 itemBoxSizer2->Add(m_pGauge, 0, wxGROW|wxALL, 5);
00093
00094 wxNotebook* itemNotebook7 = new wxNotebook( itemProgressPanel1, ID_EXTCMD_NOTEBOOK, wxDefaultPosition, wxDefaultSize, wxNB_TOP );
00095
00096 wxPanel* itemPanel8 = new wxPanel( itemNotebook7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
00097 wxBoxSizer* itemBoxSizer9 = new wxBoxSizer(wxVERTICAL);
00098 itemPanel8->SetSizer(itemBoxSizer9);
00099
00100 m_pOutput = new wxTextCtrl( itemPanel8, ID_EXTCMD_OUTPUT, _T(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
00101 itemBoxSizer9->Add(m_pOutput, 1, wxGROW|wxALL, 5);
00102
00103 itemNotebook7->AddPage(itemPanel8, _("Output"));
00104
00105 wxPanel* itemPanel11 = new wxPanel( itemNotebook7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
00106 wxBoxSizer* itemBoxSizer12 = new wxBoxSizer(wxVERTICAL);
00107 itemPanel11->SetSizer(itemBoxSizer12);
00108
00109 m_pOutputErr = new wxTextCtrl( itemPanel11, ID_EXTCMD_OUTPUTERR, _T(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
00110 itemBoxSizer12->Add(m_pOutputErr, 1, wxGROW|wxALL, 5);
00111
00112 itemNotebook7->AddPage(itemPanel11, _("Errors/Warnings"));
00113
00114 itemBoxSizer2->Add(itemNotebook7, 5, wxGROW|wxALL, 5);
00115
00117 }
00118
00119 void wxExtCmdProgressPanel::SelectCurrProcess()
00120 {
00121 wxASSERT(m_nCurrProcess >= 0);
00122
00123
00124 m_pCommandList->SetString(m_nCurrProcess,
00125 ID_EXTCMD_CURRPROCESS_PREFIX +
00126 m_pCommandList->GetString(m_nCurrProcess));
00127
00128 m_pCommandList->SetSelection(m_nCurrProcess);
00129 }
00130
00131 void wxExtCmdProgressPanel::DeselectCurrProcess()
00132 {
00133 wxASSERT(m_nCurrProcess >= 0);
00134
00135
00136 wxString str = m_pCommandList->GetString(m_nCurrProcess);
00137 wxASSERT(str.StartsWith(ID_EXTCMD_CURRPROCESS_PREFIX));
00138 m_pCommandList->SetString(m_nCurrProcess,
00139 str.Right(str.Len() - wxString(ID_EXTCMD_CURRPROCESS_PREFIX).Len()));
00140 }
00141
00142 void wxExtCmdProgressPanel::OnProcessStart()
00143 {
00144 SelectCurrProcess();
00145
00146 m_pGauge->SetValue((m_nCurrProcess+1) * 100 / m_cmd.GetCount());
00147 }
00148
00149 wxString wxExtCmdProgressPanel::GetLogData() const
00150 {
00151 wxString ret;
00152
00153 if (m_stage == wxPBSS_INVALID)
00154 return wxEmptyString;
00155
00156 ret = wxString::Format(
00157 wxT(" ===== %s LOG FOR %s - %s ===== \n\n"),
00158 wxPackageBuildSystemStage2String(m_stage).MakeUpper().c_str(),
00159 m_pkg.GetName().c_str(),
00160 m_start.Format().c_str());
00161
00162 for (size_t i=0; i< m_cmd.GetCount(); i++)
00163 ret += GetCmdString(i) + wxString(wxT(' '), 15) +
00164 wxT(" [in path: ") + GetCmdPath(i) + wxT("]\n");
00165
00166 ret += wxT("\n\n ===> Output:\n");
00167 ret += m_pOutput->GetValue();
00168 ret += wxT("\n\n ===> Errors:\n");
00169 ret += m_pOutputErr->GetValue();
00170
00171 return ret;
00172 }
00173 wxString wxExtCmdProgressPanel::GetLogLabel() const
00174 {
00175 return wxString::Format(wxT("Log for %s of %s %s"),
00176 wxPackageBuildSystemStage2String(m_stage).MakeUpper().c_str(),
00177 m_pkg.GetName().c_str(),
00178 m_pkg.GetVersion().GetAsString().c_str());
00179 }
00180
00181 void wxExtCmdProgressPanel::Start()
00182 {
00183 wxASSERT(!m_timerIdleWakeUp.IsRunning());
00184
00185 m_pOutput->Clear();
00186 m_pOutputErr->Clear();
00187 m_nCurrProcess = -1;
00188 m_timerIdleWakeUp.Start(100);
00189 m_start = wxDateTime::Now();
00190 }
00191
00192 void wxExtCmdProgressPanel::Stop()
00193 {
00194
00195 m_timerIdleWakeUp.Stop();
00196
00197
00198 if (m_pid != 0)
00199 m_currProcess->Kill(m_pid, wxSIGTERM);
00200 }
00201
00202 void wxExtCmdProgressPanel::ClearControls()
00203 {
00204
00205 m_pCommandList->Clear();
00206 m_pOutput->Clear();
00207 m_pOutputErr->Clear();
00208 }
00209
00210 void wxExtCmdProgressPanel::SetPackage(const wxPackage &pkg)
00211 {
00212 m_pkg=pkg;
00213
00214
00215 UpdateCachedCommands();
00216
00217
00218 m_pCommandList->Clear();
00219 for (size_t i=0; i<m_cmd.GetCount(); i++)
00220 m_pCommandList->Append(m_cmd[i]);
00221 }
00222
00223 void wxExtCmdProgressPanel::UpdateCachedCommands()
00224 {
00225 m_cmd = m_pkg.GetSubstCmdForStage(m_stage, wxPKGCMD_ONLY_CHANGED);
00226
00227
00228 m_cmd = m_cmd.GetValidCommandsFor(m_pkg);
00229 }
00230
00231 wxString wxExtCmdProgressPanel::GetCmdString(size_t n) const
00232 {
00233 const wxPackageCommand &cmd = m_cmd[n];
00234 return cmd.GetProgram() + wxT(" ") + cmd.GetProgramArguments();
00235 }
00236
00237 wxString wxExtCmdProgressPanel::GetCmdPath(size_t n) const
00238 {
00239
00240 wxFileName path = wxFileName::DirName(m_cmd[n].GetWorkingPath(), wxPATH_UNIX);
00241
00242 wxString workDir(m_pkg.GetDecompressionPath());
00243 if (!path.MakeAbsolute(workDir) || !path.DirExists())
00244 path = wxFileName::DirName(workDir);
00245
00246 return path.GetPath();
00247 }
00248
00249
00250
00251
00252
00253
00254
00255 void wxExtCmdProgressPanel::OnTimer(wxTimerEvent& WXUNUSED(event))
00256 {
00257
00258 wxWakeUpIdle();
00259 }
00260
00261 void wxExtCmdProgressPanel::OnIdle(wxIdleEvent &ev)
00262 {
00263 if (!m_timerIdleWakeUp.IsRunning())
00264 return;
00265
00266 if (m_currProcess)
00267 {
00268 wxInputStream *stream = NULL;
00269 wxTextCtrl *output = NULL;
00270
00271
00272 if (m_currProcess->IsInputAvailable())
00273 {
00274 stream = m_currProcess->GetInputStream();
00275 output = m_pOutput;
00276 }
00277 else if (m_currProcess->IsErrorAvailable())
00278 {
00279 stream = m_currProcess->GetErrorStream();
00280 output = m_pOutputErr;
00281 }
00282
00283 if (stream)
00284 {
00285 ev.RequestMore();
00286 wxTextInputStream tis(*stream);
00287
00288 #if 0
00289
00290 wxString msg = tis.ReadLine() + wxT("\n");
00291 #else
00292 static char buffer[4096];
00293 buffer[stream->Read(buffer, WXSIZEOF(buffer) - 1).LastRead()] = _T('\0');
00294 wxString msg(buffer, wxConvUTF8);
00295 msg = msg.BeforeLast(wxT('\n'));
00296 #endif
00297
00298 output->AppendText(msg);
00299 }
00300 }
00301 else if (++m_nCurrProcess >= (int)m_cmd.GetCount())
00302 {
00303
00304 wxCommandEvent ev(wxEVT_COMMAND_PROGRESS_END, GetId());
00305 ev.SetInt(m_stage);
00306 ev.SetExtraLong(IsSuccessful());
00307 ev.SetString(m_pkg.GetName());
00308
00309 GetEventHandler()->AddPendingEvent(ev);
00310 }
00311 else
00312 {
00313
00314
00315
00316 const wxPackageCommand &cmd = m_cmd[m_nCurrProcess];
00317
00318
00319 OnProcessStart();
00320
00321
00322
00323 m_pkg.GetCompilerSettings().UpdateEnvVars();
00324
00325
00326 wxString path = GetCmdPath(m_nCurrProcess);
00327 if (!wxSetWorkingDirectory(path))
00328 {
00329 wxLogError(_T("Cannot set the current working directory to '%s'."),
00330 path.c_str());
00331 return;
00332 }
00333
00334 m_currProcess = new wxProcess(this, ID_EXTCMD_PROCESS);
00335 m_currProcess->Redirect();
00336
00337 wxString tolaunch = cmd.GetProgram();
00338 if (!tolaunch.IsEmpty())
00339 {
00340 wxString final = GetCmdString(m_nCurrProcess);
00341 wxLogDebug(wxT("Launching command '%s' in dir '%s'"),
00342 final.c_str(), wxGetCwd().c_str());
00343
00344
00345 m_pid = wxExecute(final, wxEXEC_ASYNC|wxEXEC_MAKE_GROUP_LEADER, m_currProcess);
00346 if ( m_pid == 0 )
00347 {
00348 wxLogError(_T("Execution of '%s' failed."), cmd.GetCommand().c_str());
00349 wxDELETE(m_currProcess);
00350 DeselectCurrProcess();
00351 }
00352 }
00353 else
00354 {
00355 wxArrayString arr(m_pkg.GetCompilerSettings().GetCompilerPaths(wxPCPT_BIN));
00356 if (arr.GetCount() > 0)
00357 {
00358 wxString err;
00359 err.Printf(_("Cannot find the '%s' program in the compiler paths currently in use:\n\n"),
00360 cmd.GetProgram().c_str());
00361 for (size_t i=0; i < arr.GetCount(); i++)
00362 err += wxT(" => ") + arr[i] + wxT("\n");
00363 err += _("\n\nPlease configure appropriately the compiler paths in the 'Settings' dialog.");
00364
00365 wxLogError(err);
00366 }
00367 else
00368 {
00369 wxLogError(_("The compiler paths for the '%s' format are empty! Cannot find the '%s' program.\nPlease configure appropriately the compiler paths in the 'Settings' dialog."),
00370 wxPackageCompilerFormat2String(m_pkg.GetCompilerSettings().GetSelFormat()).c_str(),
00371 cmd.GetProgram().c_str());
00372 }
00373
00374 wxDELETE(m_currProcess);
00375 DeselectCurrProcess();
00376 }
00377 }
00378 }
00379
00380 void wxExtCmdProgressPanel::OnProcessTerminate(wxProcessEvent &ev)
00381 {
00382 wxIdleEvent fake;
00383 while (m_currProcess->IsInputAvailable() ||
00384 m_currProcess->IsErrorAvailable())
00385 OnIdle(fake);
00386
00387
00388 m_nExitCode = ev.GetExitCode();
00389 wxDELETE(m_currProcess);
00390 DeselectCurrProcess();
00391
00392
00393 if (m_nCurrProcess == (int)m_cmd.GetCount() - 1)
00394 m_pGauge->SetValue(0);
00395 }
00396
00397 void wxExtCmdProgressPanel::OnUpdateUI(wxUpdateUIEvent &WXUNUSED(ev))
00398 {
00399 if (!IsProcessing())
00400 m_pGauge->SetValue(0);
00401 }
00402