MythTV  0.26-pre
mythterminal.cpp
Go to the documentation of this file.
00001 /*
00002  *  Class MythTerminal
00003  *
00004  *  Copyright (C) Daniel Kristjansson 2008
00005  *
00006  *   This program is free software; you can redistribute it and/or modify
00007  *   it under the terms of the GNU General Public License as published by
00008  *   the Free Software Foundation; either version 2 of the License, or
00009  *   (at your option) any later version.
00010  *
00011  *   This program is distributed in the hope that it will be useful,
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *   GNU General Public License for more details.
00015  *
00016  *   You should have received a copy of the GNU General Public License
00017  *   along with this program; if not, write to the Free Software
00018  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 #include <inttypes.h>
00022 
00023 // MythTV headers
00024 #include "mythterminal.h"
00025 
00026 MythTerminal::MythTerminal(QString _program, QStringList _arguments) :
00027     lock(QMutex::Recursive), running(false),
00028     process(new QProcess()), program(_program), arguments(_arguments),
00029     curLabel(""), curValue(0), filter(new MythTerminalKeyFilter())
00030 {
00031     addSelection(curLabel, QString::number(curValue));
00032 
00033     process->setProcessChannelMode(QProcess::MergedChannels);
00034     connect(process, SIGNAL(readyRead()),
00035             this,    SLOT(  ProcessHasText()));
00036 
00037     connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
00038             this,    SLOT(  ProcessFinished(int, QProcess::ExitStatus)));
00039 
00040     connect(filter,  SIGNAL(KeyPressd(QKeyEvent*)),
00041             this,    SLOT(  ProcessSendKeyPress(QKeyEvent*)));
00042     SetEventFilter(filter);
00043 }
00044 
00045 void MythTerminal::TeardownAll(void)
00046 {
00047     if (process)
00048     {
00049         QMutexLocker locker(&lock);
00050         if (running)
00051             Kill();
00052         process->disconnect();
00053     }
00054 
00055     if (filter)
00056     {
00057         filter->disconnect();
00058     }
00059 
00060     if (process)
00061     {
00062         process->deleteLater();
00063         process = NULL;
00064     }
00065 
00066     if (filter)
00067     {
00068         filter->deleteLater();
00069         filter = NULL;
00070     }
00071 }
00072 
00073 void MythTerminal::AddText(const QString &_str)
00074 {
00075     QMutexLocker locker(&lock);
00076     QString str = _str;
00077     while (str.length())
00078     {
00079         int nlf = str.indexOf("\r\n");
00080         nlf = (nlf < 0) ? str.indexOf("\r") : nlf;
00081         nlf = (nlf < 0) ? str.indexOf("\n") : nlf;
00082 
00083         QString curStr = (nlf >= 0) ? str.left(nlf) : str;
00084         if (curStr.length())
00085         {
00086             curLabel += curStr;
00087             ReplaceLabel(curLabel, QString::number(curValue));
00088         }
00089 
00090         if (nlf >= 0)
00091         {
00092             addSelection(curLabel = "", QString::number(++curValue));
00093             str = str.mid(nlf + 1);
00094         }
00095         else
00096         {
00097             str = "";
00098         }
00099     }
00100     if (lbwidget)
00101     {
00102         lbwidget->setEnabled(true);
00103         lbwidget->setFocus();
00104         lbwidget->setCurrentRow(lbwidget->count() - 1);
00105     }
00106 }
00107 
00108 void MythTerminal::Start(void)
00109 {
00110     QMutexLocker locker(&lock);
00111     process->start(program, arguments);
00112     running = true;
00113 }
00114 
00115 void MythTerminal::Kill(void)
00116 {
00117     QMutexLocker locker(&lock);
00118     process->kill();
00119     running = false;
00120 }
00121 
00122 bool MythTerminal::IsDone(void) const
00123 {
00124     QMutexLocker locker(&lock);
00125     return QProcess::NotRunning == process->state();
00126 }
00127 
00128 void MythTerminal::ProcessHasText(void)
00129 {
00130     QMutexLocker locker(&lock);
00131     int64_t len = process->bytesAvailable();
00132 
00133     if (len <= 0)
00134         return;
00135 
00136     QByteArray buf = process->read(len);
00137     AddText(QString(buf));
00138 }
00139 
00140 void MythTerminal::ProcessSendKeyPress(QKeyEvent *e)
00141 {
00142     QMutexLocker locker(&lock);
00143     if (running && process && e->text().length())
00144     {
00145         QByteArray text = e->text().toLocal8Bit();
00146         AddText(text.constData());
00147         if (e->text()=="\n" || e->text()=="\r")
00148             process->write("\r\n");
00149         else
00150             process->write(text.constData());
00151     }
00152 }
00153 
00154 void MythTerminal::ProcessFinished(
00155     int exitCode, QProcess::ExitStatus exitStatus)
00156 {
00157     QMutexLocker locker(&lock);
00158     AddText(tr("*** Exited with status: %1 ***").arg(exitCode));
00159     setEnabled(false);
00160     running = false;
00161 }
00162 
00164 
00165 bool MythTerminalKeyFilter::eventFilter(QObject *obj, QEvent *event)
00166 {
00167     if (event->type() == QEvent::KeyPress)
00168     {
00169         QKeyEvent *e = (QKeyEvent*)(event);
00170         QStringList actions;
00171         bool handled = GetMythMainWindow()->TranslateKeyPress("qt", e, actions,
00172                                                               false);
00173         if (!handled && !actions.isEmpty())
00174         {
00175             if (actions.contains("LEFT") || actions.contains("RIGHT") ||
00176                 actions.contains("UP") || actions.contains("DOWN") ||
00177                 actions.contains("ESCAPE"))
00178             {
00179                 return QObject::eventFilter(obj, event);
00180             }
00181             else
00182             {
00183                 emit KeyPressd(e);
00184                 e->accept();
00185                 return true;
00186             }
00187         }
00188         else
00189         {
00190             emit KeyPressd(e);
00191             e->accept();
00192             return true;
00193         }
00194     }
00195     else
00196     {
00197         return QObject::eventFilter(obj, event);
00198     }
00199 }
00200 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends