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
25 #include "mythlogging.h"
26 #include "mythterminal.h"
27 #include "mythuibutton.h"
28 #include "mythuibuttonlist.h"
29 #include "mythuitextedit.h"
30 
31 MythTerminal::MythTerminal(MythScreenStack *parent, QString _program,
32  QStringList _arguments) :
33  MythScreenType(parent, "terminal"),
34  m_process(new QProcess()), m_program(std::move(_program)),
35  m_arguments(std::move(_arguments))
36 {
37  m_process->setProcessChannelMode(QProcess::MergedChannels);
38  connect(m_process, &QIODevice::readyRead,
40 
41  connect(m_process, qOverload<int,QProcess::ExitStatus>(&QProcess::finished),
43 }
44 
46 {
47  QMutexLocker locker(&m_lock);
48  if (m_process)
49  {
50  if (m_running)
51  Kill();
52  m_process->disconnect();
53  m_process->deleteLater();
54  m_process = nullptr;
55  }
56 }
57 
58 void MythTerminal::AddText(const QString &_str)
59 {
60  QMutexLocker locker(&m_lock);
61  QString str = _str;
62  while (!str.isEmpty())
63  {
64  int nlf = str.indexOf("\r\n");
65  nlf = (nlf < 0) ? str.indexOf("\r") : nlf;
66  nlf = (nlf < 0) ? str.indexOf("\n") : nlf;
67 
68  QString curStr = (nlf >= 0) ? str.left(nlf) : str;
69  if (!curStr.isEmpty())
70  {
71  if (!m_currentLine)
73  else
75  }
76 
77  if (nlf >= 0)
78  {
81  str = str.mid(nlf + 1);
82  }
83  else
84  {
85  str = "";
86  }
87  }
88 }
89 
91 {
92  QMutexLocker locker(&m_lock);
94  m_running = true;
95 }
96 
98 {
99  QMutexLocker locker(&m_lock);
100  m_process->kill();
101  m_running = false;
102 }
103 
104 bool MythTerminal::IsDone(void) const
105 {
106  QMutexLocker locker(&m_lock);
107  return QProcess::NotRunning == m_process->state();
108 }
109 
111 {
112  QMutexLocker locker(&m_lock);
113  int64_t len = m_process->bytesAvailable();
114 
115  if (len <= 0)
116  return;
117 
118  QByteArray buf = m_process->read(len);
119  AddText(QString(buf));
120 }
121 
123 {
124  Start();
125 }
126 
128  int exitCode, QProcess::ExitStatus exitStatus)
129 {
130  QMutexLocker locker(&m_lock);
131  if (exitStatus == QProcess::CrashExit) {
132  AddText(tr("*** Crashed with status: %1 ***").arg(exitCode));
133  } else {
134  AddText(tr("*** Exited with status: %1 ***").arg(exitCode));
135  }
136  m_running = false;
137  m_enterButton->SetEnabled(false);
138  m_textEdit->SetEnabled(false);
139 }
140 
142 {
143  if (!LoadWindowFromXML("standardsetting-ui.xml", "terminal", this))
144  return false;
145 
146  bool error = false;
147  UIUtilE::Assign(this, m_output, "output", &error);
148  UIUtilE::Assign(this, m_textEdit, "textedit", &error);
149  UIUtilE::Assign(this, m_enterButton, "enter", &error);
150 
151  if (error)
152  {
153  LOG(VB_GENERAL, LOG_ERR, "Theme elements missing.");
154  return false;
155  }
156 
157  BuildFocusList();
158 
159  MythUIButton *close = nullptr;
160  UIUtilW::Assign(this, close, "close");
161  if (close)
163 
165  this,
166  [this]()
167  {
168  QMutexLocker locker(&m_lock);
169  if (m_running) // NOLINT(clang-analyzer-core.NullDereference)
170  {
171  QString text = m_textEdit->GetText() + "\r\n";
172  AddText(text);
173 
174  m_process->write(text.toLocal8Bit().constData());
175  }
176  });
177 
178  return true;
179 }
MythUIButton::Clicked
void Clicked()
error
static void error(const char *str,...)
Definition: vbi.cpp:42
MythTerminal::TeardownAll
void TeardownAll(void)
Definition: mythterminal.cpp:45
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:402
MythTerminal::m_lock
QMutex m_lock
Definition: mythterminal.h:47
MythScreenStack
Definition: mythscreenstack.h:15
arg
arg(title).arg(filename).arg(doDelete))
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:44
MythUITextEdit::GetText
QString GetText(void) const
Definition: mythuitextedit.h:47
MythTerminal::Init
void Init(void) override
Used after calling Load() to assign data to widgets and other UI initilisation which is prohibited in...
Definition: mythterminal.cpp:122
MythTerminal::IsDone
bool IsDone(void) const
Definition: mythterminal.cpp:104
MythTerminal::Kill
void Kill(void)
Definition: mythterminal.cpp:97
MythTerminal::ProcessHasText
void ProcessHasText(void)
Definition: mythterminal.cpp:110
mythuibuttonlist.h
MythTerminal::ProcessFinished
void ProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
Definition: mythterminal.cpp:127
close
#define close
Definition: compat.h:17
MythUIButtonListItem::SetText
void SetText(const QString &text, const QString &name="", const QString &state="")
Definition: mythuibuttonlist.cpp:3264
MythUIButtonListItem
Definition: mythuibuttonlist.h:27
MythTerminal::m_arguments
QStringList m_arguments
Definition: mythterminal.h:51
MythTerminal::m_currentLine
MythUIButtonListItem * m_currentLine
Definition: mythterminal.h:52
mythlogging.h
MythTerminal::Start
void Start(void)
Definition: mythterminal.cpp:90
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:222
MythUIButton
A single button widget.
Definition: mythuibutton.h:21
MythTerminal::m_running
bool m_running
Definition: mythterminal.h:48
MythTerminal::AddText
void AddText(const QString &_str)
Definition: mythterminal.cpp:58
MythUIType::SetEnabled
void SetEnabled(bool enable)
Definition: mythuitype.cpp:1109
MythTerminal::m_program
QString m_program
Definition: mythterminal.h:50
MythTerminal::m_output
MythUIButtonList * m_output
Definition: mythterminal.h:53
UIUtilDisp::Assign
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
MythUIButtonListItem::GetText
QString GetText(const QString &name="") const
Definition: mythuibuttonlist.cpp:3305
MythTerminal::m_process
QProcess * m_process
Definition: mythterminal.h:49
MythTerminal::Create
bool Create(void) override
Definition: mythterminal.cpp:141
MythTerminal::m_enterButton
MythUIButton * m_enterButton
Definition: mythterminal.h:55
mythuitextedit.h
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:692
MythTerminal::m_textEdit
MythUITextEdit * m_textEdit
Definition: mythterminal.h:54
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1557
mythterminal.h
mythuibutton.h
MythTerminal::MythTerminal
MythTerminal(MythScreenStack *parent, QString program, QStringList arguments)
Definition: mythterminal.cpp:31