00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <inttypes.h>
00022
00023
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