KExtProcess Documentation
When I started to write yesterday's blog I planned to add all kind of information about KExtProcess. It turned out that my blog became pretty big when I was only about halfway the stuff I planned, so I changed plans and promised some extra updates this week.
So here comes the first bonus chapter: documentation.
The main documentation source for KExtProcess, besides reading the code, are the API docs. I have the fortunate habit of adding small pieces of documentation to all methods I write using pseudo-apidox style syntax. Although I never tried to actually run Doxygen over them they turned out to be quite useful as a starting point. So when Adriaan de Groot started his 'ApiDox Crusade' I pointed out KExtProcess to him and he was kind enough to add it to his script that generates the docs.
Because Adriaan hosts the API docs on his personal ADSL line he asked me not to link directly to the English Breakfast Network and instead put the docs up on another server. You can find the docs here, thanks to Matt Douhan for offering me hosting and bandwidth on one of his servers. Both of you, be sure to ask me for a drink whenever we meet again, the service is much appreciated!
Besides the API docs there are the example programs. They are quite small and should therefore be relatively useful. What's missing is a porting guide from 'normal' KProcess to KExtProcess. I could go into all details of KProcess, but if you use it in the most common way within KDE your code probably looks like this:
KProcess *proc = new KProcess( this );
*proc << "tail";
*proc << "-f";
*proc << "/var/log/messages";
proc->start( KProcess::NotifyOnExit, KProcess::All );
connect( proc, SIGNAL( processExited( KProcess * ) ),
this, SLOT( slotProcessExited( KProcess * ) ) );
// And connect the other slots, etc.</code>
This should look pretty familiar, right? KExtProcess consists of more than one class and is therefore contained in a namespace. Taking this into account, porting to a local KExtProcess can be as easy as adding the right namespace and replacing 'KProcess' with 'KExtProcess':
KExtProcess::LocalProcess *proc = new KExtProcess::LocalProcess( this );
*proc << "tail";
*proc << "-f";
*proc << "/var/log/messages";
proc->start( KExtProcess::ExtProcess::NotifyOnExit, KExtProcess::ExtProcess::All );
connect( proc, SIGNAL( processExited( KExtProcess::ExtProcess * ) ),
this, SLOT( slotProcessExited( KExtProcess::ExtProcess * ) ) );
// And connect the other slots, etc.</code>
I don't think I'll be able to make porting easier than that, apart from ditching namespace, which I am not going to do for reasons which become more apparent if you start using the additional features that KExtProcess offers.
Take for example Profiles. If you want to give the user control over where and how to run the process, just add a combo box that shows all available profiles:
QStringList profiles = KExtProcess::Profile::profileList();
for ( QStringList::ConstIterator it = profiles.begin(); it != profiles.end(); ++it )
m_mainWin->m_profileList->insertItem( *it );
m_mainWin->m_profileList->setSelected( 0, true );
Once the user has selected a profile change the line that creates the LocalProcess above into the following four lines:
KExtProcess::Profile profile( 0L );
profile.load( m_mainWin->m_profileList->currentText() );
KExtProcess::ProcessFactory *factory = KExtProcess::ProcessFactory::self();
KExtProcess::ExtProcess *proc = factory->createProcess( &profile, this );</code>
Not very difficult. And I have some ideas to make this even simpler. Probably in KExtProcess 0.5 you can suffice with the following whopping two lines of code to instantly make your application work on remote systems:
KExtProcess::Profile profile( m_mainWin->m_profileList->currentText() );
KExtProcess::ExtProcess *proc = KExtProcess::ProcessFactory::createProcess( &profile, this );
This simplicity is why I consider KExtProcess so cool: existing code can be changed with incredible ease. As long as you have an actual use for remote process execution there is no reason for not trying KExtProcess. Which brings us nicely to one of the next episodes: possible uses for KExtProcess. Stay tuned :)