merged 2.2 branch
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@7748 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
		| @@ -86,6 +86,8 @@ public: | ||||
|     void OnAsyncExec(wxCommandEvent& event); | ||||
|     void OnShell(wxCommandEvent& event); | ||||
|     void OnExecWithRedirect(wxCommandEvent& event); | ||||
|     void OnExecWithPipe(wxCommandEvent& event); | ||||
|  | ||||
|     void OnDDEExec(wxCommandEvent& event); | ||||
|  | ||||
|     void OnAbout(wxCommandEvent& event); | ||||
| @@ -94,11 +96,14 @@ public: | ||||
|     void OnIdle(wxIdleEvent& event); | ||||
|  | ||||
|     // for MyPipedProcess | ||||
|     void OnProcessTerminated(MyPipedProcess *process) | ||||
|         { m_running.Remove(process); } | ||||
|     void OnProcessTerminated(MyPipedProcess *process); | ||||
|     wxListBox *GetLogListBox() const { return m_lbox; } | ||||
|  | ||||
| private: | ||||
|     void ShowOutput(const wxString& cmd, | ||||
|                     const wxArrayString& output, | ||||
|                     const wxString& title); | ||||
|  | ||||
|     wxString m_cmdLast; | ||||
|  | ||||
|     wxListBox *m_lbox; | ||||
| @@ -141,7 +146,23 @@ public: | ||||
|  | ||||
|     virtual void OnTerminate(int pid, int status); | ||||
|  | ||||
|     bool HasInput(); | ||||
|     virtual bool HasInput(); | ||||
| }; | ||||
|  | ||||
| // A version of MyPipedProcess which also sends input to the stdin of the | ||||
| // child process | ||||
| class MyPipedProcess2 : public MyPipedProcess | ||||
| { | ||||
| public: | ||||
|     MyPipedProcess2(MyFrame *parent, const wxString& cmd, const wxString& input) | ||||
|         : MyPipedProcess(parent, cmd), m_input(input) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|     virtual bool HasInput(); | ||||
|  | ||||
| private: | ||||
|     wxString m_input; | ||||
| }; | ||||
|  | ||||
| // ---------------------------------------------------------------------------- | ||||
| @@ -159,6 +180,7 @@ enum | ||||
|     Exec_Shell, | ||||
|     Exec_DDEExec, | ||||
|     Exec_Redirect, | ||||
|     Exec_Pipe, | ||||
|     Exec_About = 300 | ||||
| }; | ||||
|  | ||||
| @@ -179,6 +201,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) | ||||
|     EVT_MENU(Exec_AsyncExec, MyFrame::OnAsyncExec) | ||||
|     EVT_MENU(Exec_Shell, MyFrame::OnShell) | ||||
|     EVT_MENU(Exec_Redirect, MyFrame::OnExecWithRedirect) | ||||
|     EVT_MENU(Exec_Pipe, MyFrame::OnExecWithPipe) | ||||
|  | ||||
|     EVT_MENU(Exec_DDEExec, MyFrame::OnDDEExec) | ||||
|  | ||||
|     EVT_MENU(Exec_About, MyFrame::OnAbout) | ||||
| @@ -232,11 +256,6 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) | ||||
|     wxApp::s_macAboutMenuItemId = Exec_About; | ||||
| #endif | ||||
|  | ||||
|     // set the frame icon | ||||
| #ifndef __WXGTK__ | ||||
|     SetIcon(wxICON(mondrian)); | ||||
| #endif | ||||
|  | ||||
|     // create a menu bar | ||||
|     wxMenu *menuFile = new wxMenu(_T(""), wxMENU_TEAROFF); | ||||
|     menuFile->Append(Exec_ClearLog, _T("&Clear log\tCtrl-C"), | ||||
| @@ -251,8 +270,11 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) | ||||
|                      _T("Launch a program and return immediately")); | ||||
|     execMenu->Append(Exec_Shell, _T("Execute &shell command...\tCtrl-S"), | ||||
|                      _T("Launch a shell and execute a command in it")); | ||||
|     execMenu->AppendSeparator(); | ||||
|     execMenu->Append(Exec_Redirect, _T("Capture command &output...\tCtrl-O"), | ||||
|                      _T("Launch a program and capture its output")); | ||||
|     execMenu->Append(Exec_Pipe, _T("&Pipe through command...\tCtrl-P"), | ||||
|                      _T("Pipe a string through a filter")); | ||||
|  | ||||
| #ifdef __WINDOWS__ | ||||
|     execMenu->AppendSeparator(); | ||||
| @@ -387,21 +409,15 @@ void MyFrame::OnExecWithRedirect(wxCommandEvent& WXUNUSED(event)) | ||||
|  | ||||
|     if ( sync ) | ||||
|     { | ||||
|         wxArrayString output; | ||||
|         int code = wxExecute(cmd, output); | ||||
|         wxArrayString output, errors; | ||||
|         int code = wxExecute(cmd, output, errors); | ||||
|         wxLogStatus(_T("command '%s' terminated with exit code %d."), | ||||
|                     cmd.c_str(), code); | ||||
|  | ||||
|         if ( code != -1 ) | ||||
|         { | ||||
|             m_lbox->Append(wxString::Format(_T("--- Output of '%s' ---"), | ||||
|                                             cmd.c_str())); | ||||
|  | ||||
|             size_t count = output.GetCount(); | ||||
|             for ( size_t n = 0; n < count; n++ ) | ||||
|             { | ||||
|                 m_lbox->Append(output[n]); | ||||
|             } | ||||
|             ShowOutput(cmd, output, _T("Output")); | ||||
|             ShowOutput(cmd, errors, _T("Errors")); | ||||
|         } | ||||
|     } | ||||
|     else // async exec | ||||
| @@ -422,6 +438,42 @@ void MyFrame::OnExecWithRedirect(wxCommandEvent& WXUNUSED(event)) | ||||
|     m_cmdLast = cmd; | ||||
| } | ||||
|  | ||||
| void MyFrame::OnExecWithPipe(wxCommandEvent& WXUNUSED(event)) | ||||
| { | ||||
|     if ( !m_cmdLast ) | ||||
|         m_cmdLast = _T("tr [a-z] [A-Z]"); | ||||
|  | ||||
|     wxString cmd = wxGetTextFromUser(_T("Enter the command: "), | ||||
|                                      DIALOG_TITLE, | ||||
|                                      m_cmdLast); | ||||
|  | ||||
|     if ( !cmd ) | ||||
|         return; | ||||
|  | ||||
|     wxString input = wxGetTextFromUser(_T("Enter the string to send to it: "), | ||||
|                                        DIALOG_TITLE); | ||||
|     if ( !input ) | ||||
|         return; | ||||
|  | ||||
|     // always execute the filter asynchronously | ||||
|     MyPipedProcess2 *process = new MyPipedProcess2(this, cmd, input); | ||||
|     int pid = wxExecute(cmd, FALSE /* async */, process); | ||||
|     if ( pid ) | ||||
|     { | ||||
|         wxLogStatus(_T("Process %ld (%s) launched."), pid, cmd.c_str()); | ||||
|  | ||||
|         m_running.Add(process); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         wxLogError(_T("Execution of '%s' failed."), cmd.c_str()); | ||||
|  | ||||
|         delete process; | ||||
|     } | ||||
|  | ||||
|     m_cmdLast = cmd; | ||||
| } | ||||
|  | ||||
| void MyFrame::OnDDEExec(wxCommandEvent& WXUNUSED(event)) | ||||
| { | ||||
| #ifdef __WINDOWS__ | ||||
| @@ -477,6 +529,31 @@ void MyFrame::OnIdle(wxIdleEvent& event) | ||||
|     } | ||||
| } | ||||
|  | ||||
| void MyFrame::OnProcessTerminated(MyPipedProcess *process) | ||||
| { | ||||
|     m_running.Remove(process); | ||||
| } | ||||
|  | ||||
|  | ||||
| void MyFrame::ShowOutput(const wxString& cmd, | ||||
|                          const wxArrayString& output, | ||||
|                          const wxString& title) | ||||
| { | ||||
|     size_t count = output.GetCount(); | ||||
|     if ( !count ) | ||||
|         return; | ||||
|  | ||||
|     m_lbox->Append(wxString::Format(_T("--- %s of '%s' ---"), | ||||
|                                     title.c_str(), cmd.c_str())); | ||||
|  | ||||
|     for ( size_t n = 0; n < count; n++ ) | ||||
|     { | ||||
|         m_lbox->Append(output[n]); | ||||
|     } | ||||
|  | ||||
|     m_lbox->Append(_T("--- End of output ---")); | ||||
| } | ||||
|  | ||||
| // ---------------------------------------------------------------------------- | ||||
| // MyProcess | ||||
| // ---------------------------------------------------------------------------- | ||||
| @@ -496,6 +573,8 @@ void MyProcess::OnTerminate(int pid, int status) | ||||
|  | ||||
| bool MyPipedProcess::HasInput() | ||||
| { | ||||
|     bool hasInput = FALSE; | ||||
|  | ||||
|     wxInputStream& is = *GetInputStream(); | ||||
|     if ( !is.Eof() ) | ||||
|     { | ||||
| @@ -503,16 +582,28 @@ bool MyPipedProcess::HasInput() | ||||
|  | ||||
|         // this assumes that the output is always line buffered | ||||
|         wxString msg; | ||||
|         msg << m_cmd << _T(": ") << tis.ReadLine(); | ||||
|         msg << m_cmd << _T(" (stdout): ") << tis.ReadLine(); | ||||
|  | ||||
|         m_parent->GetLogListBox()->Append(msg); | ||||
|  | ||||
|         return TRUE; | ||||
|         hasInput = TRUE; | ||||
|     } | ||||
|     else | ||||
|  | ||||
|     wxInputStream& es = *GetErrorStream(); | ||||
|     if ( !es.Eof() ) | ||||
|     { | ||||
|         return FALSE; | ||||
|         wxTextInputStream tis(es); | ||||
|  | ||||
|         // this assumes that the output is always line buffered | ||||
|         wxString msg; | ||||
|         msg << m_cmd << _T(" (stderr): ") << tis.ReadLine(); | ||||
|  | ||||
|         m_parent->GetLogListBox()->Append(msg); | ||||
|  | ||||
|         hasInput = TRUE; | ||||
|     } | ||||
|  | ||||
|     return hasInput; | ||||
| } | ||||
|  | ||||
| void MyPipedProcess::OnTerminate(int pid, int status) | ||||
| @@ -525,3 +616,24 @@ void MyPipedProcess::OnTerminate(int pid, int status) | ||||
|  | ||||
|     MyProcess::OnTerminate(pid, status); | ||||
| } | ||||
|  | ||||
| // ---------------------------------------------------------------------------- | ||||
| // MyPipedProcess2 | ||||
| // ---------------------------------------------------------------------------- | ||||
|  | ||||
| bool MyPipedProcess2::HasInput() | ||||
| { | ||||
|     if ( !!m_input ) | ||||
|     { | ||||
|         wxTextOutputStream os(*GetOutputStream()); | ||||
|         os.WriteString(m_input); | ||||
|  | ||||
|         CloseOutput(); | ||||
|         m_input.clear(); | ||||
|  | ||||
|         // call us once again - may be we'll have output | ||||
|         return TRUE; | ||||
|     } | ||||
|  | ||||
|     return MyPipedProcess::HasInput(); | ||||
| } | ||||
|   | ||||
| @@ -6,5 +6,5 @@ WXDIR = ../.. | ||||
| TARGET=exec | ||||
| OBJECTS = $(TARGET).o | ||||
|  | ||||
| include $(WXDIR)\src\makeprog.g95 | ||||
| include $(WXDIR)/src/makeprog.g95 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user