/***************************************************************************
    begin                : Mon Sep 20 1999
    copyright            : (C) 1999 by John Birch
    email                : jbb@kdevelop.org
	
                          Adapted for ruby debugging
                          --------------------------
    begin                : Mon Nov 1 2004
    copyright            : (C) 2004 by Richard Dale
    email                : Richard_Dale@tipitina.demon.co.uk
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "dbgpsdlg.h"

#include <kbuttonbox.h>
#include <kdialog.h>
#include <tdeglobalsettings.h>
#include <tdelocale.h>
#include <kprocess.h>
#include <kstdguiitem.h>

#include <tqframe.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqlistbox.h>
#include <tqtoolbutton.h>
#include <tqpushbutton.h>

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

namespace RDBDebugger
{

/***************************************************************************/

// Display a list of processes for the user to select one
// only display processes that they can do something with so if the user
// is root then display all processes
// For use with the internal debugger, but this dialog doesn't know anything
// about why it's doing it.

Dbg_PS_Dialog::Dbg_PS_Dialog(TQWidget *parent, const char *name)
    : KDialog(parent, name, true),      // modal
      psProc_(0),
      pids_(new TQListBox(this)),
      heading_(new TQLabel(" ", this)),
      pidLines_(TQString())
{
    setCaption(i18n("Attach to Process"));

    TQBoxLayout *topLayout = new TQVBoxLayout(this, 5);

    heading_->setFont(TDEGlobalSettings::fixedFont());
    heading_->setFrameStyle(TQFrame::Panel|TQFrame::Sunken);
    heading_->setMaximumHeight(heading_->sizeHint().height());
//    heading_->setMinimumSize(heading_->sizeHint());
    topLayout->addWidget(heading_, 5);

    topLayout->addWidget(pids_, 5);
    pids_->setFont(TDEGlobalSettings::fixedFont());

    KButtonBox *buttonbox = new KButtonBox(this, TQt::Horizontal, 5);
    TQPushButton *ok       = buttonbox->addButton(KStdGuiItem::ok());
    buttonbox->addStretch();
    TQPushButton *cancel   = buttonbox->addButton(KStdGuiItem::cancel());
    buttonbox->layout();
    topLayout->addWidget(buttonbox);

    connect(ok,     TQ_SIGNAL(clicked()),  TQ_SLOT(accept()));
    connect(cancel, TQ_SIGNAL(clicked()),  TQ_SLOT(reject()));

    psProc_ = new KShellProcess("/bin/sh");
    #ifdef USE_SOLARIS
    *psProc_ << "ps";
    *psProc_ << "-opid";
    *psProc_ << "-otty";
    *psProc_ << "-os";
    *psProc_ << "-otime";
    *psProc_ << "-oargs";
    pidCmd_ = "ps -opid -otty -os -otime -oargs";

    if (getuid() == 0) {
        *psProc_ << "-e";
        pidCmd_ += " -e";
    }
    #else
    *psProc_ << "ps";
    *psProc_ << "x";
    pidCmd_ = "ps x";

    if (getuid() == 0) {
        *psProc_ << "a";
        pidCmd_ += " a";
    }
    #endif

    connect( psProc_, TQ_SIGNAL(processExited(TDEProcess *)),                TQ_SLOT(slotProcessExited()) );
    connect( psProc_, TQ_SIGNAL(receivedStdout(TDEProcess *, char *, int)),  TQ_SLOT(slotReceivedOutput(TDEProcess *, char *, int)) );
    psProc_->start(TDEProcess::NotifyOnExit, TDEProcess::Stdout);

    // Default display to 40 chars wide, default height is okay
    resize( ((TDEGlobalSettings::fixedFont()).pointSize())*40, height());
    topLayout->activate();
}

/***************************************************************************/

Dbg_PS_Dialog::~Dbg_PS_Dialog()
{
    delete psProc_;
}

/***************************************************************************/

int Dbg_PS_Dialog::pidSelected()
{
    TQString pidText = pids_->text(pids_->currentItem());
    if (!pidText.isEmpty())
        return atoi(pidText.latin1());

    return 0;
}

/***************************************************************************/

void Dbg_PS_Dialog::slotReceivedOutput(TDEProcess */*proc*/, char *buffer, int buflen)
{
    pidLines_ += TQString::fromLocal8Bit(buffer, buflen+1);
}

/***************************************************************************/

void Dbg_PS_Dialog::slotProcessExited()
{
    delete psProc_;
    psProc_ = 0;

    pidLines_ += '\n';

    int start = pidLines_.find('\n', 0);  // Skip the first line (header line)
    int pos;
    if (start != -1)
        heading_->setText(pidLines_.left(start));
    while ( (pos = pidLines_.find('\n', start)) != -1) {
        TQString item = pidLines_.mid(start, pos-start);
        if (!item.isEmpty()) {
            if (item.find(pidCmd_) == -1)
                pids_->insertItem(item);
        }

        start = pos+1;
    }
}

}

/***************************************************************************/
#include "dbgpsdlg.moc"
