MauiKit Terminal

ksession.cpp
1/*
2 This file is part of Konsole QML plugin,
3 which is a terminal emulator from KDE.
4
5Copyright 2013 by Dmitry Zagnoyko <hiroshidi@gmail.com>
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301 USA.
21*/
22
23// Own
24#include "ksession.h"
25#include <KShell>
26
27// Qt
28#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
29#include <QTextCodec>
30#else
31#include <QtCore5Compat/QTextCodec>
32#endif
33
34#include <QDir>
35#include <QDebug>
36
37// Konsole
38#include "KeyboardTranslator.h"
39#include "HistorySearch.h"
40
41
42KSession::KSession(QObject *parent) : QObject(parent)
43 ,m_session(createSession(QString()))
44{
45 connect(m_session.get(), &Konsole::Session::started, this, &KSession::started);
46 connect(m_session.get(), &Konsole::Session::finished, this, &KSession::sessionFinished);
48 connect(m_session.get(), &Konsole::Session::stateChanged, [this](int state)
49 {
50 qDebug() << m_session->iconText() << m_session->iconName() << m_session->isMonitorSilence() << m_session->program() << state;
51
52 Q_EMIT hasActiveProcessChanged();
53
54 if(m_processName != m_session->foregroundProcessName())
55 {
56 m_processName = m_session->foregroundProcessName();
57 Q_EMIT foregroundProcessNameChanged();
58 }
59 });
60
61 // m_session->setMonitorSilence(true);
62 m_session->setMonitorSilenceSeconds(30);
63
64 connect(m_session.get(), &Konsole::Session::bellRequest, [this](QString message)
65 {
66 Q_EMIT bellRequest(message);
67 });
68
69 connect(m_session.get(), &Konsole::Session::changeTabTextColorRequest, [this](int state)
70 {
71 qDebug() << "changeTabTextColorRequest" << state;
72 });
73
74 connect(m_session.get(), &Konsole::Session::changeTabTextColorRequest, [this](int state)
75 {
76 qDebug() << "changeTabTextColorRequest" << state;
77 });
78
80 {
81 qDebug() << "changeBackgroundColorRequest" << state;
82 });
83
84 connect(m_session.get(), &Konsole::Session::openUrlRequest, [this](QString state)
85 {
86 qDebug() << "openUrlRequest" << state;
87 });
88
89 connect(m_session.get(), &Konsole::Session::activity, [this]()
90 {
91 qDebug() << "activity";
92 Q_EMIT processHasSilent(false);
93 });
94
95 connect(m_session.get(), &Konsole::Session::silence, [this]()
96 {
97 qDebug() << "silence";
98 Q_EMIT processHasSilent(true);
99 });
100}
101
102KSession::~KSession()
103{
104 if (m_session)
105 {
106 m_session->close();
107 m_session->disconnect();
108 }
109}
110
112{
113 if(m_session->isMonitorSilence() == value)
114 return;
115
116 m_session->setMonitorSilence(value);
118}
119
121{
122 return m_session->isMonitorSilence();
123}
124
126{
127 m_session->setTitle(Session::NameRole, name);
128}
129
130std::unique_ptr<Session> KSession::createSession(QString name)
131{
132 auto session = std::make_unique<Session>();
133
134 session->setTitle(Session::NameRole, name);
135
136 /* Thats a freaking bad idea!!!!
137 * /bin/bash is not there on every system
138 * better set it to the current $SHELL
139 * Maybe you can also make a list available and then let the widget-owner decide what to use.
140 * By setting it to $SHELL right away we actually make the first filecheck obsolete.
141 * But as iam not sure if you want to do anything else ill just let both checks in and set this to $SHELL anyway.
142 */
143
144 //cool-old-term: There is another check in the code. Not sure if useful.
145
146 QString envshell = getenv("SHELL");
147 QString shellProg = !envshell.isNull() ? envshell : QStringLiteral("/bin/bash");
148 session->setProgram(shellProg);
149
150 setenv("TERM", "xterm-256color", 1);
151
152 //session->setProgram();
153
155 session->setArguments(args);
156 session->setAutoClose(true);
157
158 session->setCodec(QTextCodec::codecForName("UTF-8"));
159
160 session->setFlowControlEnabled(true);
161 session->setHistoryType(HistoryTypeBuffer(1000));
162
163 session->setDarkBackground(true);
164
165 session->setKeyBindings(QString());
166
167 return session;
168}
169
170/////////////////////////////////////////////////////////////////////////////////////
171/////////////////////////////////////////////////////////////////////////////////////
172
173
174int KSession::getRandomSeed()
175{
176 return m_session->sessionId() * 31;
177}
178
180{
181 m_session->setView(display);
182}
183
185{
186 m_session->removeView(display);
187}
188
189void KSession::sessionFinished()
190{
192}
193
194void KSession::selectionChanged(bool textSelected)
195{
196 Q_UNUSED(textSelected)
197}
198
200{
201 if (m_session->isRunning())
202 {
203 return;
204 }
205
206 m_session->run();
207}
208
209bool KSession::sendSignal(int signal)
210{
211 if (!m_session->isRunning())
212 {
213 return false;
214 }
215
216 return m_session->sendSignal(signal);
217}
218
220{
221 return m_session->processId();
222}
223
225{
226 /*
227 this is a very hackish way of trying to determine if the shell is in
228 the foreground before attempting to change the directory. It may not
229 be portable to anything other than Linux.
230 */
231 QString strCmd;
232 strCmd.setNum(getShellPID());
233 strCmd.prepend(u"ps -j ");
234 strCmd.append(u" | tail -1 | awk '{ print $5 }' | grep -q \\+");
235 int retval = system(strCmd.toStdString().c_str());
236
237 if (!retval)
238 {
239 // Send prior Ctrl-E, Ctrl-U to ensure the line is empty. This is
240 // mandatory, otherwise sending a 'cd x\n' to a prompt with 'rm -rf *'
241 // would result in data loss.
242 sendText(QStringLiteral("\x05\x15"));
243
244 sendText(u"cd " + KShell::quoteArg(dir) + '\r');
246 }
247}
248
249void KSession::setEnvironment(const QStringList &environment)
250{
251 m_session->setEnvironment(environment);
252}
253
255{
256 if(m_session->program() == progname)
257 return;
258
259 m_session->setProgram(progname);
261}
262
264{
265 return m_session->program();
266}
267
269{
270 if(_initialWorkingDirectory != dir)
271 {
272 _initialWorkingDirectory = dir;
273 m_session->setInitialWorkingDirectory(dir);
276 }
277}
278
279QString KSession::getInitialWorkingDirectory()
280{
281 return _initialWorkingDirectory;
282}
283
285{
286 if(m_session->arguments() == args)
287 return;
288
289 m_session->setArguments(args);
291}
292
293void KSession::setTextCodec(QTextCodec *codec)
294{
295 m_session->setCodec(codec);
296}
297
299{
300 if(historySize() != lines )
301 {
302 if (lines < 0)
303 m_session->setHistoryType(HistoryTypeFile());
304 else
305 m_session->setHistoryType(HistoryTypeBuffer(lines));
306
308 }
309}
310
311int KSession::historySize() const
312{
313 if(m_session->historyType().isUnlimited())
314 {
315 return -1;
316 } else {
317 return m_session->historyType().maximumLineCount();
318 }
319}
320
321QString KSession::getHistory() const
322{
324 QTextStream historyStream(&history);
325 PlainTextDecoder historyDecoder;
326
327 historyDecoder.begin(&historyStream);
328 m_session->emulation()->writeToStream(&historyDecoder);
329 historyDecoder.end();
330
331 return history;
332}
333
335{
336 m_session->sendText(text);
337}
338
339void KSession::sendKey(int rep, int key, int mod) const
340{
341 Q_UNUSED(rep);
342 Q_UNUSED(key);
343 Q_UNUSED(mod);
344
345 //TODO implement or remove this function.
346 // Qt::KeyboardModifier kbm = Qt::KeyboardModifier(mod);
347
348 // QKeyEvent qkey(QEvent::KeyPress, key, kbm);
349
350 // while (rep > 0){
351 // m_session->sendKey(&qkey);
352 // --rep;
353 // }
354}
355
357{
358 m_session->emulation()->clearEntireScreen();
359}
360
361void KSession::search(const QString &regexp, int startLine, int startColumn, bool forwards)
362{
363 HistorySearch *history = new HistorySearch(QPointer<Emulation>(m_session->emulation()), QRegExp(regexp), forwards, startColumn, startLine, this);
364 connect(history, &HistorySearch::matchFound, this, &KSession::matchFound);
365 connect(history, &HistorySearch::noMatchFound, this, &KSession::noMatchFound);
366 history->search();
367}
368
370{
371 m_session->setFlowControlEnabled(enabled);
372}
373
375{
376 return m_session->flowControlEnabled();
377}
378
380{
381 m_session->setKeyBindings(kb);
383}
384
385QString KSession::getKeyBindings()
386{
387 return m_session->keyBindings();
388}
389
394
396{
397 return m_session->keyBindings();
398}
399
400QString KSession::getTitle()
401{
402 // if (m_session->currentDir() == QDir::homePath()) {
403 // return m_session->currentDir();
404 // }
405 //
406 // if (m_session->currentDir() == "/")
407 // return m_session->currentDir();
408 //
409 // return QDir(m_session->currentDir()).dirName();
410
411 return m_session->userTitle();
412}
413
415{
416 return m_session->processId() != m_session->foregroundProcessId();
417}
418
420{
421 return m_session->foregroundProcessName();
422}
423
425{
426 return m_session->currentDir();
427}
429{
430 return m_session->arguments();
431}
QString history
The commands history.
Definition ksession.h:69
void clearScreen()
clearScreen
Definition ksession.cpp:356
void titleChanged()
titleChanged
void removeView(TerminalDisplay *display)
removeView
Definition ksession.cpp:184
void startShellProgram()
startShellProgram
Definition ksession.cpp:199
void addView(TerminalDisplay *display)
addView
Definition ksession.cpp:179
void search(const QString &regexp, int startLine=0, int startColumn=0, bool forwards=true)
Search history.
Definition ksession.cpp:361
bool sendSignal(int signal)
sendSignal
Definition ksession.cpp:209
void noMatchFound()
noMatchFound
void initialWorkingDirectoryChanged()
initialWorkingDirectoryChanged
QString keyBindings()
Return current key bindings.
Definition ksession.cpp:395
QString currentDir
The current directory of the session.
Definition ksession.h:84
void setTitle(QString name)
setTitle
Definition ksession.cpp:125
void changedKeyBindings(QString kb)
changedKeyBindings
QString foregroundProcessName
The name of the current process running.
Definition ksession.h:79
void setInitialWorkingDirectory(const QString &dir)
Initial working directory.
Definition ksession.cpp:268
void changeDir(const QString &dir)
changeDir
Definition ksession.cpp:224
void setArgs(const QStringList &args)
Shell program args, default is none.
Definition ksession.cpp:284
void setShellProgram(const QString &progname)
Shell program, default is /bin/bash
Definition ksession.cpp:254
void monitorSilenceChanged()
monitorSilenceChanged
void sendKey(int rep, int key, int mod) const
Emulate a key press.
Definition ksession.cpp:339
bool hasActiveProcess
Whether the session has an active process running.
Definition ksession.h:74
int historySize
Allows to set the amount of lines to store in the history.
Definition ksession.h:89
void setEnvironment(const QStringList &environment)
Set the custom enviroment variables.
Definition ksession.cpp:249
void matchFound(int startColumn, int startLine, int endColumn, int endLine)
matchFound
void shellProgramChanged()
shellProgramChanged
void setKeyBindings(const QString &kb)
Set named key binding for the session.
Definition ksession.cpp:379
QStringList args() const
args
Definition ksession.cpp:428
int getShellPID()
getShellPID
Definition ksession.cpp:219
void currentDirChanged()
currentDirChanged
void setHistorySize(int lines)
History size for scrolling.
Definition ksession.cpp:298
void setMonitorSilence(bool value)
setMonitorSilence
Definition ksession.cpp:111
void finished()
finished
void setFlowControlEnabled(bool enabled)
Sets whether flow control is enabled.
Definition ksession.cpp:369
void started()
started
bool flowControlEnabled(void)
Returns whether flow control is enabled.
Definition ksession.cpp:374
static QStringList availableKeyBindings()
Sets whether the flow control warning box should be shown when the flow control stop key (Ctrl+S) is ...
Definition ksession.cpp:390
void argsChanged()
argsChanged
void setTextCodec(QTextCodec *codec)
Text codec, default is UTF-8.
Definition ksession.cpp:293
void historySizeChanged()
historySizeChanged
void sendText(QString text)
Send some text to terminal.
Definition ksession.cpp:334
QString shellProgram
Allows to change the default shell program, by default bash is used.
Definition ksession.h:59
bool monitorSilence
Whether to monitor when the session has gone silent.
Definition ksession.h:94
QList< QString > allTranslators()
Returns a list of the names of available keyboard translators.
static KeyboardTranslatorManager * instance()
Returns the global KeyboardTranslatorManager instance.
A terminal character decoder which produces plain text, ignoring colours and other appearance-related...
void end() override
End decoding.
void begin(QTextStream *output) override
Begin decoding characters.
void started()
Emitted when the terminal process starts.
void finished()
Emitted when the terminal process exits.
void titleChanged()
Emitted when the session's title has changed.
void openUrlRequest(const QString &url)
TODO: Document me.
void changeTabTextColorRequest(int)
Requests that the color the text for any tabs associated with this session should be changed;.
void stateChanged(int state)
Emitted when the activity state of this session changes.
void changeBackgroundColorRequest(const QColor &)
Requests that the background color of views on this session should be changed.
void bellRequest(const QString &message)
Emitted when a bell event occurs in the session.
A widget which displays output from a terminal emulation and sends input keypresses and mouse activit...
KCOREADDONS_EXPORT QString quoteArg(const QString &arg)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString & append(QChar ch)
bool isNull() const const
QString & prepend(QChar ch)
QString & setNum(double n, char format, int precision)
std::string toStdString() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 26 2024 11:57:30 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.