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

KDE's Doxygen guidelines are available online.