/////////////////////////////////////////////////////////////////////////////////
//      $Id: kpTerm.cpp,v 1.12 2002/09/26 20:43:58 leitner Exp $ 
//
// File  : pkgOptions.cpp
// Author: Toivo Pedaste
//

#include "../config.h"

#include <qvbox.h>

#include <kglobalsettings.h>
#include <kdebug.h>

#include <kpTerm.h>


//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

kpTerm::kpTerm(kpPty *pt, QWidget * parent,  const char * name ) :
  QMultiLineEdit(parent,name)
{
  pty = pt;
  setFont(KGlobalSettings::fixedFont());
  setMinimumWidth(fontMetrics().maxWidth()*80 +
        minimumSizeHint().width());
  setWordWrap(QMultiLineEdit::WidgetWidth);
  setReadOnly(TRUE);
}

void kpTerm::doConnect()
{
  connect(pty, SIGNAL(textIn(QString)), this,
	  SLOT(textIn(QString)));
  connect(pty,SIGNAL(result(QStringList &, int)),
	  this,SLOT(slotResult(QStringList &, int)));
  connect(this, SIGNAL(keyOut(char)), pty,
	  SLOT(keyOut(char)));
}

void kpTerm::doUnconnect()
{
  disconnect(pty, SIGNAL(textIn(QString)), this,
		   SLOT(textIn(QString)));
  disconnect(pty,SIGNAL(result(QStringList &, int)),
	  this,SLOT(slotResult(QStringList &, int)));
  disconnect(this, SIGNAL(keyOut(char)), pty,
		   SLOT(keyOut(char)));
}

bool kpTerm::run(QString cmd, QStringList &r) 
{
  setReadOnly(FALSE);
  setFocus();
  if (pty->start(TRUE)) {
    doConnect();

    r =  pty->run(cmd,FALSE);
    return TRUE;
  } else {
    return FALSE;
  }
}
 
void kpTerm::cancel() {
  emit keyOut('\03');
}

void kpTerm::done()
{
   clear();
   doUnconnect();
   setReadOnly(TRUE);
   clearFocus();
}

void kpTerm::keyPressEvent ( QKeyEvent * e ) 
{
  //  kdDebug() << "K=" << e->ascii() << "," << e->ascii() << "\n";
  if (e->ascii()) {
    emit keyOut(e->ascii());
  } else {
      QMultiLineEdit::keyPressEvent (e);
  }
  setCursorPosition(9999,9999);
}

void kpTerm::textIn(QString stext)
{
  QRegExp chrs("[\\010\\012\\015]");
  //QRegExp chrs("[ed]");
  QString del = "\010";
  //  kdDebug() << "Tin=[" << stext << "]\n";
  //  int x,y;
  if (stext.find(chrs) < 0) {
    insert( stext );
  } else {
    int p;
    int op = 0;

    while ((p = stext.find(chrs,op)) >= 0) {
      if (p != op)
	insert( stext.mid(op, p-op)); 
      if (stext[p] == '\b') {
	backspace();
      } else if (stext[p] == '\r') {
	home();
      }  else if (stext[p] == '\n') {
	end();
	newLine();
      }
      op = p + 1;
    }
    if ((signed int)stext.length() > op)
      insert( stext.right(stext.length()-op));
  }
  setCursorPosition(9999,9999);
}

void kpTerm::insert ( const QString & str, bool) {
  int x,y;
  getCursorPosition(&y,&x);

  if (str.length() > 0) {
    //    kdDebug() << "ins:"  << y << "," << x << str <<":" << str.length() << "\n";
    if (x == 0 && str != "\n") {
      killLine();
      getCursorPosition(&y,&x);
      //      kdDebug() << "k="  << y << "," << x <<"\n";
    }
    QMultiLineEdit::insert(str,(bool)FALSE);
  }
}

void kpTerm::slotResult(QStringList &rlist, int ret)
{
  emit result(rlist, ret);
  doUnconnect();
}


//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
kpRun::kpRun( QWidget *parent)
  :  KDialogBase(parent, "kpRun", true, QString::null,
		Cancel, Cancel, true )
{
  QVBox *page = makeVBoxMainWidget();
  title = new QLabel("", page);
  QFont f( KGlobalSettings::generalFont());
  f.setBold(true);
  f.setPointSize(f.pointSize()+4);
  title->setFont(f);

  term = new kpTerm(kpty,page);

  connect(term,SIGNAL(result(QStringList &, int)),
	  this,SLOT(slotResult(QStringList &, int)));
 
  hide();
}

bool kpRun::run(QString cmd, QString msg)
{
  QStringList r;

  title->setText(msg);
  if (!cmd.isEmpty()) {
    return term->run(cmd, r);
  } else {
    term->doConnect();
    term->setReadOnly(FALSE);
    term->setFocus();
    return true;
  }
}

void kpRun::addText(QStringList ret)
{
  for ( QStringList::Iterator it = ret.begin(); it != ret.end(); ++it ) {
    //    kdDebug() << "ks=" << *it << "\n";
    term->textIn(*it);
  }
}

void kpRun::slotResult(QStringList &, int ret)
{
  if (ret == 0 || ret == 666) {
    term->clear();
    if (ret == 0) 
      accept();
    else
      reject();
  }
}

void kpRun::slotCancel()
{
  term->clear();
  term->cancel();
  accept();
}

#include "kpTerm.moc"
