[ptx] Can anyone work on wxExternalCmdExecDialog for autopano and enblend?

Ippei UKAI ippei_ukai at mac.com
Mon May 16 12:51:39 BST 2005


Hi,

Now, my exam is over :)
So, last night, I drafted the dialogbox for executing external  
command line tools.

Windows port does display the console using WindowsAPI while  
executing the command, but on Mac, there seems no easy way of doing  
this. On Mac, like other operating systems, not many people want to  
launch an application from command line while double-clickable  
application is available. I wonder why wxWidgets library does not  
provide such an important feature, but anyway, I made the following  
code using the "exec" sample comes with wxWidgets source. It's not  
even "buggy" yet; but at least displays a window and puts the  
standard out to the list box (I think better with multiline text  
control, but I have not changed this from the sample). I basically  
only striped off the sample and made it a dialogbox, but, well, not a  
bad start.

Being first year undergraduate Informatics student, I'm not  
experienced enough in C++ and GUI programming. So, could anyone work  
on this feature while I implement more Mac specific thigs? I'm  
thinking this feature would also be useful on UNIX port. (Otherwise,  
I will look for other cheap and easier way of running command line  
tool on a new window on Mac.)

Thanks,
Ippei



(I wrote this inside NonaStitcherPanel.cpp)
Before the implementation of NonaStitcherPanel:

//---------------------------------------------------------------------- 
-------
//Reference: wxWidgets "exec" sample

class wxExternalCmdExecDial;
class MyPipedProcess;

class wxExternalCmdExecDialog : public wxDialog
{
public:
     wxExternalCmdExecDialog(wxWindow* parent,
                             wxWindowID id,
                             const wxString& title = wxT("Command  
Line Progress"),
                             const wxPoint& pos = wxDefaultPosition,
                             const wxSize& size = wxDefaultSize,
                             long style = wxMINIMIZE_BOX,
                             const wxString& name = wxT 
("externalCmDialogBox"));

     int ShowModal(wxString &cmd);
     void OnCancel(wxCommandEvent& event);
     void OnTimer(wxTimerEvent& WXUNUSED(event));
     void OnIdle(wxIdleEvent& event);
     wxListBox *GetLogListBox() const { return m_lbox; }

private:
     wxListBox *m_lbox;
     wxTimer m_timerIdleWakeUp;
     MyPipedProcess *process;
     long processID;

DECLARE_EVENT_TABLE()
};

//--

class MyPipedProcess : public wxProcess
{
public:
     MyPipedProcess(wxExternalCmdExecDialog *parent, const wxString&  
cmd)
     : wxProcess(parent), m_cmd(cmd)
     {
         m_parent = parent;
         Redirect();
     }

     virtual void OnTerminate(int pid, int status);
     virtual bool HasInput();

protected:
     wxExternalCmdExecDialog *m_parent;
     wxString m_cmd;
};

//-----------

BEGIN_EVENT_TABLE(wxExternalCmdExecDialog, wxDialog)
EVT_IDLE(wxExternalCmdExecDialog::OnIdle)
EVT_TIMER(wxID_ANY, wxExternalCmdExecDialog::OnTimer)
END_EVENT_TABLE()

wxExternalCmdExecDialog::wxExternalCmdExecDialog(wxWindow* parent,
                                                  wxWindowID id,
                                                  const wxString&  
title = wxT("Command Line Progress"),
                                                  const wxPoint& pos  
= wxDefaultPosition,
                                                  const wxSize& size  
= wxDefaultSize,
                                                  long style =  
wxMINIMIZE_BOX,
                                                  const wxString&  
name = wxT("externalCmDialogBox"))
     : wxDialog(parent, id, , pos, size, style, name),
       m_timerIdleWakeUp(this)
{
     m_lbox = new wxListBox(this, wxID_ANY);
     wxSizer *theSizer = new wxBoxSizer(wxVERTICAL);
     theSizer->Add(m_lbox, 0, wxEXPAND | wxALL, 5);
     theSizer->Add( CreateStdDialogButtonSizer(wxCANCEL) , 0, wxALL, 3);
     this->SetSizer(theSizer);
     this->SetAutoLayout(true);
}


int wxExternalCmdExecDialog::ShowModal(wxString &cmd)
{
     process = new MyPipedProcess(this, cmd);

     processID = wxExecute(cmd, wxEXEC_ASYNC, process);
     if (!processID)
     {
         delete process;
         EndModal(-1);
     }
     else
     {
         m_timerIdleWakeUp.Start(200);
     }

     return wxDialog::ShowModal();
}

void wxExternalCmdExecDialog::OnCancel(wxCommandEvent& event)
{
     if(process && !processID) wxKill(processID);
     EndModal(-2);
}

void wxExternalCmdExecDialog::OnTimer(wxTimerEvent& WXUNUSED(event))
{
     wxWakeUpIdle();
}

void wxExternalCmdExecDialog::OnIdle(wxIdleEvent& event)
{
     if ( process->HasInput() )
     {
         event.RequestMore();
     }
}

//--

bool MyPipedProcess::HasInput()
{
     bool hasInput = false;

     if ( IsInputAvailable() )
     {
         wxTextInputStream tis(*GetInputStream());

         // this assumes that the output is always line buffered
         wxString msg;
         //msg << m_cmd << _T(" (stdout): ") << tis.ReadLine();
         msg << _T("(stdout): ") << tis.ReadLine();

         m_parent->GetLogListBox()->Append(msg);

         hasInput = true;
     }

     if ( IsErrorAvailable() )
     {
         wxTextInputStream tis(*GetErrorStream());

         // this assumes that the output is always line buffered
         wxString msg;
         //msg << m_cmd << _T(" (stderr): ") << tis.ReadLine();
         msg << _T("(stderr): ") << tis.ReadLine();

         m_parent->GetLogListBox()->Append(msg);

         hasInput = true;
     }

     return hasInput;
}

void MyPipedProcess::OnTerminate(int pid, int status)
{
     // show the rest of the output
     while ( HasInput() )
         ;

//    wxLogStatus(m_parent, _T("Process %u ('%s') terminated with  
exit code %d."),
//                pid, m_cmd.c_str(), status);

     m_parent->EndModal(-3);

     // we're not needed any more
     delete this;
}

//---------------------------------------------------------------------- 
--------


In NonaStitcherPanel::Stitch :

             wxExternalCmdExecDialog enblend_dlg(this, wxID_ANY);
             ret = enblend_dlg.ShowModal(cmdline);


-- 
  ->> 鵜飼 一平  (UKAI Ippei) ->>>>>>>>>>>>>>>>>>>>>>>>>
   My general MSN, AIM, and E-Mail: ippei_ukai at mac.com
   Homepage:  http://homepage.mac.com/ippei_ukai/




More information about the ptX mailing list