
/***************************************************************************
*   Copyright (C) 2006 by Andras Mantia                                   *
*   amantia@kde.org                                                       *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/


#ifndef BLOCKINGKPROCESS_H
#define BLOCKINGKPROCESS_H

#include <kprocess.h>

/**
 *  Blocking version of TDEProcess, which stores the stdout.
 *  Differences between start(TDEProcess::Block, TDEProcess::StdOut) and this
 *  class are:
 *  - the GUI update is not blocked why the external process is running
 *  - in case of problems there is a timeout (defaults to 60 seconds), after which the 
 *    process is terminated.
 *  - the stdout is caught - it the caller request it - and can be read by the caller
 * @author Andras Mantia <amantia@kde.org>
*/

class TQTimer;
class BlockingTDEProcess : public TDEProcess
{
  Q_OBJECT
  
  
public:
    BlockingTDEProcess(TQObject *parent, const char *name=0);
    BlockingTDEProcess();

    virtual ~BlockingTDEProcess();
    
    /**
     * Start the process. It waits until the process exits or the timeout is hit.
     * @param runmode @see TDEProcess, use TDEProcess::NotifyOnExit to get proper behaviour,
     * not TDEProcess::Block
     * @param comm if Stdout is passed, it catches the output. For the rest @see TDEProcess
     * @return true in case of success, false if there are problems to start the process
     *        or it was killed because of the timeout.
     */
    virtual bool start(RunMode runmode=NotifyOnExit, Communication comm=NoCommunication);
  
    /**
     * Get the output of the run process
     * @return the output
     */
    TQString stdOut() { return m_stdOut;}
    /**
     * Clear the internal stdout buffer. Useful in case the class is reused.
     */
    void clearStdOut() { m_stdOut = "";}
    /**
     * Get the error output of the run process
     * @return the output
     */
    TQString stdErr() { return m_stdErr;}
    /**
     * Clear the internal stderr buffer. Useful in case the class is reused.
     */
    void clearStdErr() { m_stdErr = "";}

    /**
     * Sets the timeout
     * @param timeout seconds after which the process is considered hung and killed. 0 disables the timeout.
     */
    void setTimeOut(int timeout) { m_timeoutValue = timeout; }
    
private slots:
    void slotReceivedStdOut(TDEProcess *proc, char *buffer, int buflen);
    void slotReceivedStdErr(TDEProcess *proc, char *buffer, int buflen);
    void slotProcessExited(TDEProcess *proc);
    void slotTimeOut();
            
private:
    void enter_loop();
        
    TQString m_stdOut;   
    TQString m_stdErr;   
    bool m_timeout;     
    int m_timeoutValue;
    TQTimer *m_timer;
};

#endif
