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
26 #include "libmythui/mythuibutton.h"
29 
30 #include "mythterminal.h"
31 
32 MythTerminal::MythTerminal(MythScreenStack *parent, QString _program,
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 
59 void 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 
105 bool 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;
138  m_enterButton->SetEnabled(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 
158  BuildFocusList();
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 }
MythUIButton::Clicked
void Clicked()
error
static void error(const char *str,...)
Definition: vbi.cpp:36
MythTerminal::TeardownAll
void TeardownAll(void)
Definition: mythterminal.cpp:46
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:386
MythTerminal::m_lock
QRecursiveMutex m_lock
Definition: mythterminal.h:47
MythScreenStack
Definition: mythscreenstack.h:16
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
MythUITextEdit::GetText
QString GetText(void) const
Definition: mythuitextedit.h:50
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:123
MythTerminal::IsDone
bool IsDone(void) const
Definition: mythterminal.cpp:105
MythTerminal::Kill
void Kill(void)
Definition: mythterminal.cpp:98
MythTerminal::ProcessHasText
void ProcessHasText(void)
Definition: mythterminal.cpp:111
mythuibuttonlist.h
MythTerminal::ProcessFinished
void ProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
Definition: mythterminal.cpp:128
close
#define close
Definition: compat.h:43
MythUIButtonListItem::SetText
void SetText(const QString &text, const QString &name="", const QString &state="")
Definition: mythuibuttonlist.cpp:3264
MythUIButtonListItem
Definition: mythuibuttonlist.h:41
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:91
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:206
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:59
MythUIType::SetEnabled
void SetEnabled(bool enable)
Definition: mythuitype.cpp:1131
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:3311
MythTerminal::m_process
QProcess * m_process
Definition: mythterminal.h:49
MythTerminal::Create
bool Create(void) override
Definition: mythterminal.cpp:142
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:687
std
Definition: mythchrono.h:23
MythTerminal::m_textEdit
MythUITextEdit * m_textEdit
Definition: mythterminal.h:54
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1554
mythterminal.h
mythuibutton.h
MythTerminal::MythTerminal
MythTerminal(MythScreenStack *parent, QString program, QStringList arguments)
Definition: mythterminal.cpp:32