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#include <QtCore5Compat/QTextCodec>
29
30#include <QDir>
31#include <QDebug>
32
33// Konsole
34#include "KeyboardTranslator.h"
35#include "HistorySearch.h"
36
37
38KSession::KSession(QObject *parent) : QObject(parent)
39 ,m_session(createSession(QString()))
40{
41 connect(m_session.get(), &Konsole::Session::started, this, &KSession::started);
42 connect(m_session.get(), &Konsole::Session::finished, this, &KSession::sessionFinished);
44 connect(m_session.get(), &Konsole::Session::stateChanged, [this](int state)
45 {
46 qDebug() << m_session->iconText() << m_session->iconName() << m_session->isMonitorSilence() << m_session->program() << state;
47
48 Q_EMIT hasActiveProcessChanged();
49
50 if(m_processName != m_session->foregroundProcessName())
51 {
52 m_processName = m_session->foregroundProcessName();
53 Q_EMIT foregroundProcessNameChanged();
54 }
55 });
56
57 // m_session->setMonitorSilence(true);
58 m_session->setMonitorSilenceSeconds(30);
59
60 connect(m_session.get(), &Konsole::Session::bellRequest, [this](QString message)
61 {
62 Q_EMIT bellRequest(message);
63 });
64
65 connect(m_session.get(), &Konsole::Session::changeTabTextColorRequest, [this](int state)
66 {
67 qDebug() << "changeTabTextColorRequest" << state;
68 });
69
70 connect(m_session.get(), &Konsole::Session::changeTabTextColorRequest, [this](int state)
71 {
72 qDebug() << "changeTabTextColorRequest" << state;
73 });
74
76 {
77 qDebug() << "changeBackgroundColorRequest" << state;
78 });
79
80 connect(m_session.get(), &Konsole::Session::openUrlRequest, [this](QString state)
81 {
82 qDebug() << "openUrlRequest" << state;
83 });
84
85 connect(m_session.get(), &Konsole::Session::activity, [this]()
86 {
87 qDebug() << "activity";
88 Q_EMIT processHasSilent(false);
89 });
90
91 connect(m_session.get(), &Konsole::Session::silence, [this]()
92 {
93 qDebug() << "silence";
94 Q_EMIT processHasSilent(true);
95 });
96}
97
98KSession::~KSession()
99{
100 if (m_session)
101 {
102 m_session->close();
103 m_session->disconnect();
104 }
105}
106
108{
109 if(m_session->isMonitorSilence() == value)
110 return;
111
112 m_session->setMonitorSilence(value);
114}
115
117{
118 return m_session->isMonitorSilence();
119}
120
122{
123 m_session->setTitle(Session::NameRole, name);
124}
125
126std::unique_ptr<Session> KSession::createSession(QString name)
127{
128 auto session = std::make_unique<Session>();
129
130 session->setTitle(Session::NameRole, name);
131
132 /* Thats a freaking bad idea!!!!
133 * /bin/bash is not there on every system
134 * better set it to the current $SHELL
135 * Maybe you can also make a list available and then let the widget-owner decide what to use.
136 * By setting it to $SHELL right away we actually make the first filecheck obsolete.
137 * But as iam not sure if you want to do anything else ill just let both checks in and set this to $SHELL anyway.
138 */
139
140 //cool-old-term: There is another check in the code. Not sure if useful.
141
142 QString envshell = getenv("SHELL");
143 QString shellProg = !envshell.isNull() ? envshell : QStringLiteral("/bin/bash");
144 session->setProgram(shellProg);
145
146 setenv("TERM", "xterm-256color", 1);
147
148 //session->setProgram();
149
151 session->setArguments(args);
152 session->setAutoClose(true);
153
154 session->setCodec(QTextCodec::codecForName("UTF-8"));
155
156 session->setFlowControlEnabled(true);
157 session->setHistoryType(HistoryTypeBuffer(1000));
158
159 session->setDarkBackground(true);
160
161 session->setKeyBindings(QString());
162
163 return session;
164}
165
166/////////////////////////////////////////////////////////////////////////////////////
167/////////////////////////////////////////////////////////////////////////////////////
168
169
170int KSession::getRandomSeed()
171{
172 return m_session->sessionId() * 31;
173}
174
176{
177 m_session->setView(display);
178}
179
181{
182 m_session->removeView(display);
183}
184
185void KSession::sessionFinished()
186{
188}
189
190void KSession::selectionChanged(bool textSelected)
191{
192 Q_UNUSED(textSelected)
193}
194
196{
197 if (m_session->isRunning())
198 {
199 return;
200 }
201
202 m_session->run();
203}
204
205bool KSession::sendSignal(int signal)
206{
207 if (!m_session->isRunning())
208 {
209 return false;
210 }
211
212 return m_session->sendSignal(signal);
213}
214
216{
217 return m_session->processId();
218}
219
221{
222 if(currentDir() == dir)
223 return;
224 /*
225 this is a very hackish way of trying to determine if the shell is in
226 the foreground before attempting to change the directory. It may not
227 be portable to anything other than Linux.
228 */
229 QString strCmd;
230 strCmd.setNum(getShellPID());
231 strCmd.prepend(u"ps -j ");
232 strCmd.append(u" | tail -1 | awk '{ print $5 }' | grep -q \\+");
233 int retval = system(strCmd.toStdString().c_str());
234
235 if (!retval)
236 {
237 // Send prior Ctrl-E, Ctrl-U to ensure the line is empty. This is
238 // mandatory, otherwise sending a 'cd x\n' to a prompt with 'rm -rf *'
239 // would result in data loss.
240 sendText(QStringLiteral("\x05\x15"));
241
242 sendText(u"cd " + KShell::quoteArg(dir) + '\r');
244 }
245}
246
247void KSession::setEnvironment(const QStringList &environment)
248{
249 m_session->setEnvironment(environment);
250}
251
253{
254 if(m_session->program() == progname)
255 return;
256
257 m_session->setProgram(progname);
259}
260
262{
263 return m_session->program();
264}
265
267{
268 if(_initialWorkingDirectory != dir)
269 {
270 _initialWorkingDirectory = dir;
271 m_session->setInitialWorkingDirectory(dir);
274 }
275}
276
277QString KSession::getInitialWorkingDirectory()
278{
279 return _initialWorkingDirectory;
280}
281
283{
284 if(m_session->arguments() == args)
285 return;
286
287 m_session->setArguments(args);
289}
290
291void KSession::setTextCodec(QTextCodec *codec)
292{
293 m_session->setCodec(codec);
294}
295
297{
298 if(historySize() != lines )
299 {
300 if (lines < 0)
301 m_session->setHistoryType(HistoryTypeFile());
302 else
303 m_session->setHistoryType(HistoryTypeBuffer(lines));
304
306 }
307}
308
309int KSession::historySize() const
310{
311 if(m_session->historyType().isUnlimited())
312 {
313 return -1;
314 } else {
315 return m_session->historyType().maximumLineCount();
316 }
317}
318
319QString KSession::getHistory() const
320{
322 QTextStream historyStream(&history);
323 PlainTextDecoder historyDecoder;
324
325 historyDecoder.begin(&historyStream);
326 m_session->emulation()->writeToStream(&historyDecoder);
327 historyDecoder.end();
328
329 return history;
330}
331
333{
334 m_session->sendText(text);
335}
336
337void KSession::sendKey(int rep, int key, int mod) const
338{
339 Q_UNUSED(rep);
340 Q_UNUSED(key);
341 Q_UNUSED(mod);
342
343 //TODO implement or remove this function.
344 // Qt::KeyboardModifier kbm = Qt::KeyboardModifier(mod);
345
346 // QKeyEvent qkey(QEvent::KeyPress, key, kbm);
347
348 // while (rep > 0){
349 // m_session->sendKey(&qkey);
350 // --rep;
351 // }
352}
353
355{
356 m_session->emulation()->clearEntireScreen();
357}
358
359void KSession::search(const QString &regexp, int startLine, int startColumn, bool forwards)
360{
361 HistorySearch *history = new HistorySearch(QPointer<Emulation>(m_session->emulation()), QRegExp(regexp), forwards, startColumn, startLine, this);
362 connect(history, &HistorySearch::matchFound, this, &KSession::matchFound);
363 connect(history, &HistorySearch::noMatchFound, this, &KSession::noMatchFound);
364 history->search();
365}
366
368{
369 m_session->setFlowControlEnabled(enabled);
370}
371
373{
374 return m_session->flowControlEnabled();
375}
376
378{
379 m_session->setKeyBindings(kb);
381}
382
383QString KSession::getKeyBindings()
384{
385 return m_session->keyBindings();
386}
387
392
394{
395 return m_session->keyBindings();
396}
397
398QString KSession::getTitle()
399{
400 // if (m_session->currentDir() == QDir::homePath()) {
401 // return m_session->currentDir();
402 // }
403 //
404 // if (m_session->currentDir() == "/")
405 // return m_session->currentDir();
406 //
407 // return QDir(m_session->currentDir()).dirName();
408
409 return m_session->userTitle();
410}
411
413{
414 return m_session->processId() != m_session->foregroundProcessId();
415}
416
418{
419 return m_session->foregroundProcessName();
420}
421
423{
424 return m_session->currentDir();
425}
426
428{
429 return m_session->arguments();
430}
QString history
The commands history.
Definition ksession.h:69
void clearScreen()
clearScreen
Definition ksession.cpp:354
void titleChanged()
titleChanged
void removeView(TerminalDisplay *display)
removeView
Definition ksession.cpp:180
void startShellProgram()
startShellProgram
Definition ksession.cpp:195
void addView(TerminalDisplay *display)
addView
Definition ksession.cpp:175
void search(const QString &regexp, int startLine=0, int startColumn=0, bool forwards=true)
Search history.
Definition ksession.cpp:359
bool sendSignal(int signal)
sendSignal
Definition ksession.cpp:205
void noMatchFound()
noMatchFound
void initialWorkingDirectoryChanged()
initialWorkingDirectoryChanged
QString keyBindings()
Return current key bindings.
Definition ksession.cpp:393
QString currentDir
The current directory of the session.
Definition ksession.h:84
void setTitle(QString name)
setTitle
Definition ksession.cpp:121
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:266
void changeDir(const QString &dir)
changeDir
Definition ksession.cpp:220
void setArgs(const QStringList &args)
Shell program args, default is none.
Definition ksession.cpp:282
void setShellProgram(const QString &progname)
Shell program, default is /bin/bash
Definition ksession.cpp:252
void monitorSilenceChanged()
monitorSilenceChanged
void sendKey(int rep, int key, int mod) const
Emulate a key press.
Definition ksession.cpp:337
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:247
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:377
QStringList args() const
args
Definition ksession.cpp:427
int getShellPID()
getShellPID
Definition ksession.cpp:215
void currentDirChanged()
currentDirChanged
void setHistorySize(int lines)
History size for scrolling.
Definition ksession.cpp:296
void setMonitorSilence(bool value)
setMonitorSilence
Definition ksession.cpp:107
void finished()
finished
void setFlowControlEnabled(bool enabled)
Sets whether flow control is enabled.
Definition ksession.cpp:367
void started()
started
bool flowControlEnabled(void)
Returns whether flow control is enabled.
Definition ksession.cpp:372
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:388
void argsChanged()
argsChanged
void setTextCodec(QTextCodec *codec)
Text codec, default is UTF-8.
Definition ksession.cpp:291
void historySizeChanged()
historySizeChanged
void sendText(QString text)
Send some text to terminal.
Definition ksession.cpp:332
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 Oct 11 2024 12:16:29 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.