MythTV master
mythterminal.cpp
Go to the documentation of this file.
1/*
2 * Class MythTerminal
3 *
4 * Copyright (C) Daniel Kristjansson 2008
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <cinttypes>
22#include <utility>
23
24// MythTV headers
29
30#include "mythterminal.h"
31
33 QStringList _arguments) :
34 MythScreenType(parent, "terminal"),
35 m_process(new QProcess()), m_program(std::move(_program)),
36 m_arguments(std::move(_arguments))
37{
38 m_process->setProcessChannelMode(QProcess::MergedChannels);
39 connect(m_process, &QIODevice::readyRead,
41
42 connect(m_process, qOverload<int,QProcess::ExitStatus>(&QProcess::finished),
44}
45
47{
48 QMutexLocker locker(&m_lock);
49 if (m_process)
50 {
51 if (m_running)
52 Kill();
53 m_process->disconnect();
54 m_process->deleteLater();
55 m_process = nullptr;
56 }
57}
58
59void MythTerminal::AddText(const QString &_str)
60{
61 QMutexLocker locker(&m_lock);
62 QString str = _str;
63 while (!str.isEmpty())
64 {
65 int nlf = str.indexOf("\r\n");
66 nlf = (nlf < 0) ? str.indexOf("\r") : nlf;
67 nlf = (nlf < 0) ? str.indexOf("\n") : nlf;
68
69 QString curStr = (nlf >= 0) ? str.left(nlf) : str;
70 if (!curStr.isEmpty())
71 {
72 if (!m_currentLine)
74 else
76 }
77
78 if (nlf >= 0)
79 {
82 str = str.mid(nlf + 1);
83 }
84 else
85 {
86 str = "";
87 }
88 }
89}
90
92{
93 QMutexLocker locker(&m_lock);
95 m_running = true;
96}
97
99{
100 QMutexLocker locker(&m_lock);
101 m_process->kill();
102 m_running = false;
103}
104
105bool MythTerminal::IsDone(void) const
106{
107 QMutexLocker locker(&m_lock);
108 return QProcess::NotRunning == m_process->state();
109}
110
112{
113 QMutexLocker locker(&m_lock);
114 int64_t len = m_process->bytesAvailable();
115
116 if (len <= 0)
117 return;
118
119 QByteArray buf = m_process->read(len);
120 AddText(QString(buf));
121}
122
124{
125 Start();
126}
127
129 int exitCode, QProcess::ExitStatus exitStatus)
130{
131 QMutexLocker locker(&m_lock);
132 if (exitStatus == QProcess::CrashExit) {
133 AddText(tr("*** Crashed with status: %1 ***").arg(exitCode));
134 } else {
135 AddText(tr("*** Exited with status: %1 ***").arg(exitCode));
136 }
137 m_running = false;
139 m_textEdit->SetEnabled(false);
140}
141
143{
144 if (!LoadWindowFromXML("standardsetting-ui.xml", "terminal", this))
145 return false;
146
147 bool error = false;
148 UIUtilE::Assign(this, m_output, "output", &error);
149 UIUtilE::Assign(this, m_textEdit, "textedit", &error);
150 UIUtilE::Assign(this, m_enterButton, "enter", &error);
151
152 if (error)
153 {
154 LOG(VB_GENERAL, LOG_ERR, "Theme elements missing.");
155 return false;
156 }
157
159
160 MythUIButton *close = nullptr;
161 UIUtilW::Assign(this, close, "close");
162 if (close)
164
166 this,
167 [this]()
168 {
169 QMutexLocker locker(&m_lock);
170 if (m_running) // NOLINT(clang-analyzer-core.NullDereference)
171 {
172 QString text = m_textEdit->GetText() + "\r\n";
173 AddText(text);
174
175 m_process->write(text.toLocal8Bit().constData());
176 }
177 });
178
179 return true;
180}
Screen in which all other widgets are contained and rendered.
void BuildFocusList(void)
virtual void Close()
bool IsDone(void) const
QString m_program
Definition: mythterminal.h:50
QRecursiveMutex m_lock
Definition: mythterminal.h:47
bool Create(void) override
QProcess * m_process
Definition: mythterminal.h:49
void AddText(const QString &_str)
MythUITextEdit * m_textEdit
Definition: mythterminal.h:54
void ProcessHasText(void)
void Kill(void)
void Start(void)
MythUIButton * m_enterButton
Definition: mythterminal.h:55
MythUIButtonList * m_output
Definition: mythterminal.h:53
MythTerminal(MythScreenStack *parent, QString program, QStringList arguments)
void Init(void) override
Used after calling Load() to assign data to widgets and other UI initilisation which is prohibited in...
void TeardownAll(void)
MythUIButtonListItem * m_currentLine
Definition: mythterminal.h:52
void ProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
QStringList m_arguments
Definition: mythterminal.h:51
QString GetText(const QString &name="") const
void SetText(const QString &text, const QString &name="", const QString &state="")
void SetItemCurrent(MythUIButtonListItem *item)
A single button widget.
Definition: mythuibutton.h:22
void Clicked()
QString GetText(void) const
void SetEnabled(bool enable)
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
#define close
Definition: compat.h:30
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
def error(message)
Definition: smolt.py:409
STL namespace.
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27