/***************************************************************************
                         myprocess.cpp  - Wrapper class for running shell processes
                             -------------------
    copyright            : (C) 2002 by Marc Britton
    email                : consume@optusnet.com.au
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
/* KDE INCLUDES */
#include <tdelocale.h>
#include <kprocess.h>
#include <tdelocale.h>

/* QT INCLUDES */
#include <tqapplication.h>
#include <tqobject.h>
#include <tqstring.h>

/* OTHER INCLUDES */
#include "myprocess.h"
#include "kommanderwidget.h"

MyProcess::MyProcess(const KommanderWidget *a_atw)
  : m_atw(a_atw), m_loopStarted(false), m_blocking(true), mProcess(0)
{
}

void tqt_enter_modal(TQWidget *widget);
void tqt_leave_modal(TQWidget *widget);

void MyProcess::setBlocking(bool blocking)
{
  m_blocking = blocking;
}

TQString MyProcess::output() const
{
  return m_output;  
}    
    
bool MyProcess::isBlocking() const
{
  return m_blocking;
}

  
void MyProcess::cancel()
{
  if (mProcess) {
    delete mProcess;
    mProcess = 0;
  }
}

TQString MyProcess::run(const TQString& a_command, const TQString& a_shell)
{
  TQString at = a_command.stripWhiteSpace();
  if (at.isEmpty())
  {
    emit processExited(0);
    return TQString();
  }

  TQString shellName = a_shell;
  if (shellName.isEmpty())
    shellName = "/bin/sh";

  // Look for shell
  if (at.startsWith("#!")) {
    int eol = at.find("\n");
    if (eol == -1)
      eol = at.length();
    shellName = at.mid(2, eol-1).stripWhiteSpace();
    at = at.mid(eol+1);
  }
  m_input = at.local8Bit();

  mProcess = new TDEProcess;
  (*mProcess) << shellName.latin1();

  connect(mProcess, TQ_SIGNAL(receivedStdout(TDEProcess*, char*, int)),
      TQ_SLOT(slotReceivedStdout(TDEProcess*, char*, int)));
  connect(mProcess, TQ_SIGNAL(processExited(TDEProcess*)), TQ_SLOT(slotProcessExited(TDEProcess*)));

  if(!mProcess->start(TDEProcess::NotifyOnExit, TDEProcess::All))
  {
    m_atw->printError(i18n("<qt>Failed to start shell process<br><b>%1</b></qt>").arg(shellName));
    return TQString();
  }
  mProcess->writeStdin(m_input, m_input.length());
  mProcess->closeStdin();

  if (!m_blocking)
    return TQString();
  else 
  {
    TQWidget dummy(0, 0, WType_Dialog | WShowModal);
    dummy.setFocusPolicy(TQWidget::NoFocus);
    m_loopStarted = true;
    tqt_enter_modal(&dummy);
    tqApp->enter_loop();
    tqt_leave_modal(&dummy);
  
    if (!m_output.isEmpty() && m_output[m_output.length()-1] == '\n')
      return m_output.left(m_output.length()-1);
    else
      return m_output;
  }
}

void MyProcess::slotReceivedStdout(TDEProcess*, char* a_buffer, int a_len)
{
  m_output += TQString::fromLocal8Bit(a_buffer, a_len);
  emit processReceivedStdout(this, a_buffer, a_len);
}

void MyProcess::slotProcessExited(TDEProcess* process)
{
  if (m_loopStarted)
  {
    tqApp->exit_loop();
    m_loopStarted = false;
  }
  delete process;
  if (!m_blocking)
    emit processExited(this);
  mProcess = 0;
}

#include "myprocess.moc"
