# HG changeset patch # User Jacob Dawid # Date 1313742613 -7200 # Node ID 04931210aac046e48f8b94e8435c488030fe03ae # Parent f187d679607221279df4dc8663b37f1e9d64a0e6 Arrow keys work. Removed two more classes. diff -r f187d6796072 -r 04931210aac0 gui/octave-gui.pro --- a/gui/octave-gui.pro Fri Aug 19 03:37:49 2011 +0200 +++ b/gui/octave-gui.pro Fri Aug 19 10:30:13 2011 +0200 @@ -63,8 +63,6 @@ src/terminal/kptyprocess.cpp \ src/terminal/kprocess.cpp \ src/terminal/kptydevice.cpp \ - src/terminal/Session.cpp \ - src/terminal/ShellCommand.cpp \ src/MainWindow.cpp \ src/OctaveTerminal.cpp \ src/VariablesDockWidget.cpp \ @@ -93,8 +91,6 @@ src/terminal/kprocess.h \ src/terminal/kprocess_p.h \ src/terminal/kptydevice.h \ - src/terminal/Session.h \ - src/terminal/ShellCommand.h \ src/MainWindow.h \ src/OctaveTerminal.h \ src/VariablesDockWidget.h \ diff -r f187d6796072 -r 04931210aac0 gui/src/OctaveTerminal.cpp --- a/gui/src/OctaveTerminal.cpp Fri Aug 19 03:37:49 2011 +0200 +++ b/gui/src/OctaveTerminal.cpp Fri Aug 19 10:30:13 2011 +0200 @@ -48,16 +48,6 @@ void OctaveTerminal::openTerminal () { - m_session = new Session (); - m_session->setTitle (Session::NameRole, "QTerminalWidget"); - m_session->setProgram ("/bin/bash"); - m_session->setArguments (QStringList ()); - m_session->setAutoClose (true); - m_session->setFlowControlEnabled (true); - m_session->setDarkBackground (true); - - connect (m_session, SIGNAL(receivedData(QByteArray)), this, SLOT(handleReceivedData(QByteArray))); - int fdm, fds; if (openpty (&fdm, &fds, 0, 0, 0) < 0) { @@ -67,7 +57,9 @@ dup2 (fds, 1); dup2 (fds, 2); - m_session->openTeletype (fdm); + m_shellProcess = new Pty (fdm); + connect (m_shellProcess, SIGNAL(receivedData(QByteArray)), + this, SLOT(handleReceivedData(QByteArray))); } void @@ -75,20 +67,33 @@ { switch (keyEvent->key ()) { - case Qt::Key_PageUp: + case Qt::Key_PageUp: if (verticalScrollBar ()) verticalScrollBar ()->setValue (verticalScrollBar ()->value () - 10); - break; - case Qt::Key_PageDown: + return; + case Qt::Key_PageDown: if (verticalScrollBar ()) verticalScrollBar ()->setValue (verticalScrollBar ()->value () + 10); + return; + + case Qt::Key_Up: + m_shellProcess->sendData ("\EOA"); + break; + + case Qt::Key_Down: + m_shellProcess->sendData ("\EOB"); + break; + + case Qt::Key_Right: + m_shellProcess->sendData ("\EOC"); + break; + + case Qt::Key_Left: + m_shellProcess->sendData ("\EOF"); break; } - //QByteArray textToSend; - - //textToSend += QString::fromUtf8()); - m_session->sendText (keyEvent->text ()); + m_shellProcess->sendData (keyEvent->text ().toLocal8Bit ()); /* bool emitKeyPressSignal = true; @@ -207,7 +212,7 @@ // Decode data into cursor actions. foreach(QChar character, data) { - unsigned short unicode = character.toAscii(); + unsigned short unicode = character.unicode (); switch (unicode) { case 0: // Null (NUL) diff -r f187d6796072 -r 04931210aac0 gui/src/OctaveTerminal.h --- a/gui/src/OctaveTerminal.h Fri Aug 19 03:37:49 2011 +0200 +++ b/gui/src/OctaveTerminal.h Fri Aug 19 10:30:13 2011 +0200 @@ -19,7 +19,7 @@ #ifndef OCTAVETERMINAL_H #define OCTAVETERMINAL_H #include -#include "Session.h" +#include "Pty.h" class OctaveTerminal:public QPlainTextEdit { @@ -28,7 +28,7 @@ OctaveTerminal (QWidget * parent = 0); ~OctaveTerminal (); - void sendText (QString text) { m_session->sendText (text); } + void sendText (QString text) { m_shellProcess->sendData (text.toLocal8Bit ()); } void openTerminal (); signals: @@ -42,6 +42,6 @@ private: void construct (); - Session *m_session; + Pty *m_shellProcess; }; #endif // OCTAVETERMINAL_H diff -r f187d6796072 -r 04931210aac0 gui/src/terminal/Pty.cpp --- a/gui/src/terminal/Pty.cpp Fri Aug 19 03:37:49 2011 +0200 +++ b/gui/src/terminal/Pty.cpp Fri Aug 19 10:30:13 2011 +0200 @@ -202,18 +202,17 @@ } void -Pty::sendData (const char *data, int length) +Pty::sendData (const QByteArray& data) { - if (!length) + if (!data.length ()) return; - pty ()->write (data, length); + pty ()->write (data); } void Pty::dataReceived () { - QByteArray data = pty ()->readAll (); - emit receivedData (data.constData (), data.count ()); + emit receivedData (pty ()->readAll ()); } void diff -r f187d6796072 -r 04931210aac0 gui/src/terminal/Pty.h --- a/gui/src/terminal/Pty.h Fri Aug 19 03:37:49 2011 +0200 +++ b/gui/src/terminal/Pty.h Fri Aug 19 10:30:13 2011 +0200 @@ -123,20 +123,16 @@ * Sends data to the process currently controlling the * teletype ( whose id is returned by foregroundProcessGroup() ) * - * @param buffer Pointer to the data to send. - * @param length Length of @p buffer. */ - void sendData (const char *buffer, int length); + void sendData (const QByteArray& data); signals: /** * Emitted when a new block of data is received from * the teletype. * - * @param buffer Pointer to the data received. - * @param length Length of @p buffer */ - void receivedData (const char *buffer, int length); + void receivedData (const QByteArray& data); protected: void setupChildProcess (); diff -r f187d6796072 -r 04931210aac0 gui/src/terminal/Session.cpp --- a/gui/src/terminal/Session.cpp Fri Aug 19 03:37:49 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,744 +0,0 @@ -/* - This file is part of Konsole - - Copyright 2006-2008 by Robert Knight - Copyright 1997,1998 by Lars Doelle - Copyright 2009 by Thomas Dreibholz - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. -*/ - -// Own -#include "Session.h" - -// Standard -#include -#include -#include - -// Qt -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "kprocess.h" -#include "kptydevice.h" - -#include "Pty.h" -#include "ShellCommand.h" - -int - Session::lastSessionId = 0; - -// HACK This is copied out of QUuid::createUuid with reseeding forced. -// Required because color schemes repeatedly seed the RNG... -// ...with a constant. -QUuid -createUuid () -{ - static const int - intbits = sizeof (int) * 8; - static int - randbits = 0; - if (!randbits) - { - int - max = RAND_MAX; - do - { - ++randbits; - } - while ((max = max >> 1)); - } - - qsrand (uint (QDateTime::currentDateTime ().toTime_t ())); - qrand (); // Skip first - - QUuid - result; - uint * - data = &(result.data1); - int - chunks = 16 / sizeof (uint); - while (chunks--) - { - uint - randNumber = 0; - for (int filled = 0; filled < intbits; filled += randbits) - randNumber |= qrand () << filled; - *(data + chunks) = randNumber; - } - - result.data4[0] = (result.data4[0] & 0x3F) | 0x80; // UV_DCE - result.data3 = (result.data3 & 0x0FFF) | 0x4000; // UV_Random - - return result; -} - -Session::Session (QObject * parent): -QObject (parent), _shellProcess (0),/* _emulation (0),*/ _monitorActivity (false), -_monitorSilence (false), _notifiedActivity (false), _autoClose (true), -_wantedClose (false), _silenceSeconds (10), -_flowControl (true), _fullScripting (false), _sessionId (0), -_hasDarkBackground (false) -{ - _uniqueIdentifier = createUuid (); - - //prepare DBus communication - //new SessionAdaptor(this); - _sessionId = ++lastSessionId; - - // JPS: commented out for lack of DBUS support by default on OSX - //QDBusConnection::sessionBus().registerObject(QLatin1String("/Sessions/")+QString::number(_sessionId), this); - - //create emulation backend - //_emulation = new Vt102Emulation (); - /* - connect (_emulation, SIGNAL (titleChanged (int, const QString &)), - this, SLOT (setUserTitle (int, const QString &))); - connect (_emulation, SIGNAL (stateSet (int)), - this, SLOT (activityStateSet (int))); - connect (_emulation, SIGNAL (changeTabTextColorRequest (int)), - this, SIGNAL (changeTabTextColorRequest (int))); - connect (_emulation, - SIGNAL (profileChangeCommandReceived (const QString &)), this, - SIGNAL (profileChangeCommandReceived (const QString &))); - connect (_emulation, SIGNAL (flowControlKeyPressed (bool)), this, - SLOT (updateFlowControlState (bool))); -*/ - //create new teletype for I/O with shell process - openTeletype (-1); - - //setup timer for monitoring session activity - _monitorTimer = new QTimer (this); - _monitorTimer->setSingleShot (true); - connect (_monitorTimer, SIGNAL (timeout ()), this, - SLOT (monitorTimerDone ())); -} - -void -Session::openTeletype (int fd) -{ - delete _shellProcess; - - if (fd < 0) - _shellProcess = new Pty (); - else - _shellProcess = new Pty (fd); - - connect (_shellProcess, SIGNAL (receivedData (const char *, int)), this, - SLOT (onReceiveBlock (const char *, int))); - connect (_shellProcess, SIGNAL (finished (int, QProcess::ExitStatus)), this, - SLOT (done (int))); -} - -void -Session::setDarkBackground (bool darkBackground) -{ - _hasDarkBackground = darkBackground; -} - -bool -Session::hasDarkBackground () const -{ - return _hasDarkBackground; -} - -bool -Session::isRunning () const -{ - return _shellProcess->state () == QProcess::Running; -} - -void -Session::setProgram (const QString & program) -{ - _program = ShellCommand::expand (program); -} - -void -Session::setInitialWorkingDirectory (const QString & dir) -{ - //_initialWorkingDir = KShell::tildeExpand(ShellCommand::expand(dir)); - _initialWorkingDir = ShellCommand::expand (dir); -} - -void -Session::setArguments (const QStringList & arguments) -{ - _arguments = ShellCommand::expand (arguments); -} - -QString -Session::checkProgram (const QString & program) const -{ - // Upon a KPty error, there is no description on what that error was... - // Check to see if the given program is executable. - QString exec = QFile::encodeName (program); - - if (exec.isEmpty ()) - return QString (); - - // if 'exec' is not specified, fall back to default shell. if that - // is not set then fall back to /bin/sh - if (exec.isEmpty ()) - exec = qgetenv ("SHELL"); - if (exec.isEmpty ()) - exec = "/bin/sh"; - return program; -} - -void -Session::run () -{ - if (_uniqueIdentifier.isNull ()) - { - _uniqueIdentifier = createUuid (); - } - - const int CHOICE_COUNT = 3; - QString programs[CHOICE_COUNT] = { _program, qgetenv ("SHELL"), "/bin/sh" }; - QString exec; - int choice = 0; - while (choice < CHOICE_COUNT) - { - exec = checkProgram (programs[choice]); - if (exec.isEmpty ()) - choice++; - else - break; - } - - // if no arguments are specified, fall back to program name - QStringList arguments = _arguments.join (QChar (' ')).isEmpty ()? - QStringList () << exec : _arguments; - - if (!_initialWorkingDir.isEmpty ()) - _shellProcess->setWorkingDirectory (_initialWorkingDir); - else - _shellProcess->setWorkingDirectory (QDir::homePath ()); - - _shellProcess->setFlowControlEnabled (_flowControl); - //_shellProcess->setErase (_emulation->eraseChar ()); - - // this is not strictly accurate use of the COLORFGBG variable. This does not - // tell the terminal exactly which colors are being used, but instead approximates - // the color scheme as "black on white" or "white on black" depending on whether - // the background color is deemed dark or not - QString backgroundColorHint = - _hasDarkBackground ? "COLORFGBG=15;0" : "COLORFGBG=0;15"; - _environment << backgroundColorHint; - - _shellProcess->start (exec, arguments); - _shellProcess->setWriteable (false); - emit started (); -} - -void -Session::setUserTitle (int what, const QString & caption) -{ - //set to true if anything is actually changed (eg. old _nameTitle != new _nameTitle ) - bool modified = false; - - if ((what == IconNameAndWindowTitle) || (what == WindowTitle)) - { - if (_userTitle != caption) - { - _userTitle = caption; - modified = true; - } - } - - if ((what == IconNameAndWindowTitle) || (what == IconName)) - { - if (_iconText != caption) - { - _iconText = caption; - modified = true; - } - } - - if (what == TextColor || what == BackgroundColor) - { - QString colorString = caption.section (';', 0, 0); - QColor color = QColor (colorString); - if (color.isValid ()) - { - if (what == TextColor) - emit changeForegroundColorRequest (color); - else - emit changeBackgroundColorRequest (color); - } - } - - if (what == SessionName) - { - if (_nameTitle != caption) - { - setTitle (Session::NameRole, caption); - return; - } - } - - if (what == 31) - { - QString cwd = caption; - cwd = cwd.replace (QRegExp ("^~"), QDir::homePath ()); - //emit openUrlRequest (cwd); - } - - // change icon via \033]32;Icon\007 - if (what == 32) - { - if (_iconName != caption) - { - _iconName = caption; - - modified = true; - } - } - - if (what == ProfileChange) - { - emit profileChangeCommandReceived (caption); - return; - } - - if (modified) - emit titleChanged (); -} - -QString -Session::userTitle () const -{ - return _userTitle; -} - -void -Session::monitorTimerDone () -{ - //FIXME: The idea here is that the notification popup will appear to tell the user than output from - //the terminal has stopped and the popup will disappear when the user activates the session. - // - //This breaks with the addition of multiple views of a session. The popup should disappear - //when any of the views of the session becomes active - - - //FIXME: Make message text for this notification and the activity notification more descriptive. - if (_monitorSilence) - { - //KNotification::event("Silence", i18n("Silence in session '%1'", _nameTitle)propagateSize, QPixmap(), - // QApplication::activeWindow(), - // KNotification::CloseWhenWidgetActivated); - //emit stateChanged (NOTIFYSILENCE); - } - else - { - //emit stateChanged (NOTIFYNORMAL); - } - - _notifiedActivity = false; -} - -void -Session::updateFlowControlState (bool suspended) -{ - /* - if (suspended) - { - if (flowControlEnabled ()) - { - foreach (TerminalDisplay * display, _views) - { - if (display->flowControlWarningEnabled ()) - display->outputSuspended (true); - } - } - } - else - { - foreach (TerminalDisplay * display, _views) - display->outputSuspended (false); - }*/ -} - -void -Session::activityStateSet (int state) -{/* - if (state == NOTIFYBELL) - { - // empty - } - else if (state == NOTIFYACTIVITY) - { - if (_monitorSilence) - { - _monitorTimer->start (_silenceSeconds * 1000); - } - - if (_monitorActivity) - { - //FIXME: See comments in Session::monitorTimerDone() - if (!_notifiedActivity) - { - //KNotification::event("Activity", i18n("Activity in session '%1'", _nameTitle), QPixmap(), - // QApplication::activeWindow(), - //KNotification::CloseWhenWidgetActivated); - _notifiedActivity = true; - } - } - } - - if (state == NOTIFYACTIVITY && !_monitorActivity) - state = NOTIFYNORMAL; - if (state == NOTIFYSILENCE && !_monitorSilence) - state = NOTIFYNORMAL; - - emit stateChanged (state); - */ -} - -void -Session::refresh () -{ - const QSize existingSize = _shellProcess->windowSize (); - _shellProcess->setWindowSize (existingSize.height (), - existingSize.width () + 1); - _shellProcess->setWindowSize (existingSize.height (), - existingSize.width ()); -} - -bool -Session::kill (int signal) -{ - int result =::kill (_shellProcess->pid (), signal); - - if (result == 0) - { - _shellProcess->waitForFinished (); - return true; - } - else - return false; -} - -void -Session::close () -{ - _autoClose = true; - _wantedClose = true; - - if (!isRunning () || !kill (SIGHUP)) - { - if (isRunning ()) - { - _shellProcess->pty ()->close (); - if (_shellProcess->waitForFinished (3000)) - return; - } - QTimer::singleShot (1, this, SIGNAL (finished ())); - } -} - -void -Session::sendText (const QString & text) const -{ - _shellProcess->sendData (text.toStdString().c_str(), text.length ()); -} - -void -Session::sendMouseEvent (int buttons, int column, int line, int eventType) -{ - //_emulation->sendMouseEvent (buttons, column, line, eventType); -} - -Session::~Session () -{ - delete _shellProcess; -} - -void -Session::done (int exitStatus) -{ - if (!_autoClose) - { - _userTitle = QString ("@info:shell This session is done"); - emit titleChanged (); - return; - } - - QString message; - QTextStream msgStream (&message); - if (!_wantedClose || exitStatus != 0) - { - if (_shellProcess->exitStatus () == QProcess::NormalExit) - { - msgStream << "Program '" << _program << "' exited with status " << - exitStatus << "."; - } - else - { - msgStream << "Program '" << _program << "' crashed."; - } - } - emit finished (); -} - -QStringList -Session::environment () const -{ - return _environment; -} - -void -Session::setEnvironment (const QStringList & environment) -{ - _environment = environment; -} - -void -Session::setTitle (TitleRole role, const QString & newTitle) -{ - if (title (role) != newTitle) - { - if (role == NameRole) - _nameTitle = newTitle; - else if (role == DisplayedTitleRole) - _displayTitle = newTitle; - - emit titleChanged (); - } -} - -QString -Session::title (TitleRole role) const -{ - if (role == NameRole) - return _nameTitle; - else if (role == DisplayedTitleRole) - return _displayTitle; - else - return QString (); -} - -void -Session::setIconName (const QString & iconName) -{ - if (iconName != _iconName) - { - _iconName = iconName; - emit titleChanged (); - } -} - -void -Session::setIconText (const QString & iconText) -{ - _iconText = iconText; -} - -QString -Session::iconName () const -{ - return _iconName; -} - -QString -Session::iconText () const -{ - return _iconText; -} - -QStringList -Session::arguments () const -{ - return _arguments; -} - -QString -Session::program () const -{ - return _program; -} - -void -Session::setFlowControlEnabled (bool enabled) -{ - _flowControl = enabled; - - if (_shellProcess) - _shellProcess->setFlowControlEnabled (_flowControl); - emit flowControlEnabledChanged (enabled); -} - -bool -Session::flowControlEnabled () const -{ - if (_shellProcess) - return _shellProcess->flowControlEnabled (); - else - return _flowControl; -} - -void -Session::onReceiveBlock (const char *buf, int len) -{ - emit receivedData (QByteArray (buf, len)); -} - -void -Session::setTitle (int role, const QString & title) -{ - switch (role) - { - case (0): - this->setTitle (Session::NameRole, title); - break; - case (1): - this->setTitle (Session::DisplayedTitleRole, title); - break; - } -} - -QString -Session::title (int role) const -{ - switch (role) - { - case (0): - return this->title (Session::NameRole); - case (1): - return this->title (Session::DisplayedTitleRole); - default: - return QString (); - } -} - -SessionGroup::SessionGroup (QObject * parent):QObject (parent), _masterMode (0) -{ -} - -SessionGroup::~SessionGroup () -{ -} - -int -SessionGroup::masterMode () const -{ - return _masterMode; -} - -QList < Session * >SessionGroup::sessions () const -{ - return _sessions.keys (); -} - -bool -SessionGroup::masterStatus (Session * session) const -{ - return _sessions[session]; -} - -void -SessionGroup::addSession (Session * session) -{ - connect (session, SIGNAL (finished ()), this, SLOT (sessionFinished ())); - _sessions.insert (session, false); -} - -void -SessionGroup::removeSession (Session * session) -{ - disconnect (session, SIGNAL (finished ()), this, SLOT (sessionFinished ())); - setMasterStatus (session, false); - _sessions.remove (session); -} - -void -SessionGroup::sessionFinished () -{ - Session *session = qobject_cast < Session * >(sender ()); - Q_ASSERT (session); - removeSession (session); -} - -void -SessionGroup::setMasterMode (int mode) -{ - _masterMode = mode; -} - -QList < Session * >SessionGroup::masters () const -{ - return _sessions.keys (true); -} - -void -SessionGroup::setMasterStatus (Session * session, bool master) -{ - const bool wasMaster = _sessions[session]; - - if (wasMaster == master) - { - // No status change -> nothing to do. - return; - } - _sessions[session] = master; - - if (master) - { - //connect (session->emulation (), SIGNAL (sendData (const char *, int)), - // this, SLOT (forwardData (const char *, int))); - } - else - { - //disconnect (session->emulation (), - // SIGNAL (sendData (const char *, int)), this, - // SLOT (forwardData (const char *, int))); - } -} - -void -SessionGroup::forwardData (const char *data, int size) -{ - static bool _inForwardData = false; - if (_inForwardData) - { // Avoid recursive calls among session groups! - // A recursive call happens when a master in group A calls forwardData() - // in group B. If one of the destination sessions in group B is also a - // master of a group including the master session of group A, this would - // again call forwardData() in group A, and so on. - return; - } - - _inForwardData = true; - QListIterator < Session * >iter (_sessions.keys ()); - while (iter.hasNext ()) - { - Session *other = iter.next (); - if (!_sessions[other]) - { - //other->emulation ()->sendString (data, size); - } - } - _inForwardData = false; -} diff -r f187d6796072 -r 04931210aac0 gui/src/terminal/Session.h --- a/gui/src/terminal/Session.h Fri Aug 19 03:37:49 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,520 +0,0 @@ -/* - This file is part of Konsole, an X terminal. - - Copyright 2007-2008 by Robert Knight - Copyright 1997,1998 by Lars Doelle - Copyright 2009 by Thomas Dreibholz - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. -*/ - -#ifndef SESSION_H -#define SESSION_H - -// Qt -#include -#include -#include -#include -#include -#include -#include - -class KProcess; -class Pty; - -/** - * Represents a terminal session consisting of a pseudo-teletype and a terminal emulation. - * The pseudo-teletype (or PTY) handles I/O between the terminal process and Konsole. - * The terminal emulation ( Emulation and subclasses ) processes the output stream from the - * PTY and produces a character image which is then shown on views connected to the session. - * - * Each Session can be connected to one or more views by using the addView() method. - * The attached views can then display output from the program running in the terminal - * or send input to the program in the terminal in the form of keypresses and mouse - * activity. - */ -class Session:public QObject -{ -Q_OBJECT -public: - /** - * Constructs a new session. - * - * To start the terminal process, call the run() method, - * after specifying the program and arguments - * using setProgram() and setArguments() - * - * If no program or arguments are specified explicitly, the Session - * falls back to using the program specified in the SHELL environment - * variable. - */ - explicit Session (QObject * parent = 0); - ~Session (); - - /** - * Connect to an existing terminal. When a new Session() is constructed it - * automatically searches for and opens a new teletype. If you want to - * use an existing teletype (given its file descriptor) call this after - * constructing the session. - * - * Calling openTeletype() while a session is running has no effect. - * - * @param masterFd The file descriptor of the pseudo-teletype master (See KPtyProcess::KPtyProcess()) - */ - void openTeletype (int masterFd); - - /** - * Returns true if the session is currently running. This will be true - * after run() has been called successfully. - */ - bool isRunning () const; - - /** - * Adds a new view for this session. - * - * The viewing widget will display the output from the terminal and - * input from the viewing widget (key presses, mouse activity etc.) - * will be sent to the terminal. - * - * Views can be removed using removeView(). The session is automatically - * closed when the last view is removed. - */ - //void addView (TerminalDisplay * widget); - /** - * Removes a view from this session. When the last view is removed, - * the session will be closed automatically. - * - * @p widget will no longer display output from or send input - * to the terminal - */ - //void removeView (TerminalDisplay * widget); - - /** - * Returns the views connected to this session - */ - // QList < TerminalDisplay * >views () const; - - /** - * Returns the terminal emulation instance being used to encode / decode - * characters to / from the process. - */ - //Emulation *emulation () const; - - /** Returns the arguments passed to the shell process when run() is called. */ - QStringList arguments () const; - /** Returns the program name of the shell process started when run() is called. */ - QString program () const; - - /** - * Sets the command line arguments which the session's program will be passed when - * run() is called. - */ - void setArguments (const QStringList & arguments); - /** Sets the program to be executed when run() is called. */ - void setProgram (const QString & program); - - /** Returns the session's current working directory. */ - QString initialWorkingDirectory () - { - return _initialWorkingDir; - } - - /** - * Sets the initial working directory for the session when it is run - * This has no effect once the session has been started. - */ - void setInitialWorkingDirectory (const QString & dir); - - - /** - * This enum describes the available title roles. - */ - enum TitleRole - { - /** The name of the session. */ - NameRole, - /** The title of the session which is displayed in tabs etc. */ - DisplayedTitleRole - }; - - /** - * Return the session title set by the user (ie. the program running - * in the terminal), or an empty string if the user has not set a custom title - */ - QString userTitle () const; - - /** Convenience method used to read the name property. Returns title(Session::NameRole). */ - QString nameTitle () const - { - return title (Session::NameRole); - } - - /** Sets the name of the icon associated with this session. */ - void setIconName (const QString & iconName); - /** Returns the name of the icon associated with this session. */ - QString iconName () const; - - - /** Sets the text of the icon associated with this session. */ - void setIconText (const QString & iconText); - /** Returns the text of the icon associated with this session. */ - QString iconText () const; - - /** Sets the session's title for the specified @p role to @p title. */ - void setTitle (TitleRole role, const QString & title); - - /** Returns the session's title for the specified @p role. */ - QString title (TitleRole role) const; - - /** - * Specifies whether to close the session automatically when the terminal - * process terminates. - */ - void setAutoClose (bool b) - { - _autoClose = b; - } - - /** Returns true if the user has started a program in the session. */ - bool isForegroundProcessActive (); - - /** Returns the terminal session's window size in lines and columns. */ - QSize size (); - /** - * Emits a request to resize the session to accommodate - * the specified window size. - * - * @param size The size in lines and columns to request. - */ - void setSize (const QSize & size); - - /** - * Sets whether the session has a dark background or not. The session - * uses this information to set the COLORFGBG variable in the process's - * environment, which allows the programs running in the terminal to determine - * whether the background is light or dark and use appropriate colors by default. - * - * This has no effect once the session is running. - */ - void setDarkBackground (bool darkBackground); - /** - * Returns true if the session has a dark background. - * See setDarkBackground() - */ - bool hasDarkBackground () const; - - /** - * Attempts to get the shell program to redraw the current display area. - * This can be used after clearing the screen, for example, to get the - * shell to redraw the prompt line. - */ - void refresh (); - - /** - * Possible values of the @p what parameter for setUserTitle() - * See "Operating System Controls" section on http://rtfm.etla.org/xterm/ctlseq.html - */ - enum UserTitleChange - { - IconNameAndWindowTitle = 0, - IconName = 1, - WindowTitle = 2, - TextColor = 10, - BackgroundColor = 11, - SessionName = 30, - ProfileChange = 50 // this clashes with Xterm's font change command - }; - - public slots: - /** - * Starts the terminal session. - * - * This creates the terminal process and connects the teletype to it. - */ - void run (); - - /** - * Returns the environment of this session as a list of strings like - * VARIABLE=VALUE - */ - QStringList environment () const; - - /** - * Sets the environment for this session. - * @p environment should be a list of strings like - * VARIABLE=VALUE - */ - void setEnvironment (const QStringList & environment); - - /** - * Closes the terminal session. This sends a hangup signal - * (SIGHUP) to the terminal process and causes the finished() - * signal to be emitted. If the process does not respond to the SIGHUP signal - * then the terminal connection (the pty) is closed and Konsole waits for the - * process to exit. - */ - void close (); - - /** - * Changes the session title or other customizable aspects of the terminal - * emulation display. For a list of what may be changed see the - * Emulation::titleChanged() signal. - * - * @param what The feature being changed. Value is one of UserTitleChange - * @param caption The text part of the terminal command - */ - void setUserTitle (int what, const QString & caption); - - /** - * Sets whether flow control is enabled for this terminal - * session. - */ - void setFlowControlEnabled (bool enabled); - - /** Returns whether flow control is enabled for this terminal session. */ - bool flowControlEnabled () const; - - /** - * Sends @p text to the current foreground terminal program. - */ - void sendText (const QString & text) const; - - /** - * Sends a mouse event of type @p eventType emitted by button - * @p buttons on @p column/@p line to the current foreground - * terminal program - */ - void sendMouseEvent (int buttons, int column, int line, - int eventType); - - /** Sets the session's title for the specified @p role to @p title. - * This is an overloaded member function for setTitle(TitleRole, QString) - * provided for convenience since enum data types may not be - * exported directly through DBus - */ - void setTitle (int role, const QString & title); - - /** Returns the session's title for the specified @p role. - * This is an overloaded member function for setTitle(TitleRole) - * provided for convenience since enum data types may not be - * exported directly through DBus - */ - QString title (int role) const; - -signals: - - /** Emitted when the terminal process starts. */ - void started (); - - /** - * Emitted when the terminal process exits. - */ - void finished (); - - /** - * Emitted when output is received from the terminal process. - */ - void receivedData (const QByteArray& data); - - /** Emitted when the session's title has changed. */ - void titleChanged (); - - /** - * Emitted when the activity state of this session changes. - * - * @param state The new state of the session. This may be one - * of NOTIFYNORMAL, NOTIFYSILENCE or NOTIFYACTIVITY - */ - void stateChanged (int state); - - /** - * Requests that the color the text for any tabs associated with - * this session should be changed; - * - * TODO: Document what the parameter does - */ - void changeTabTextColorRequest (int); - - /** - * Requests that the background color of views on this session - * should be changed. - */ - void changeBackgroundColorRequest (const QColor &); - /** - * Requests that the text color of views on this session should - * be changed to @p color. - */ - void changeForegroundColorRequest (const QColor &); - - /** - * Emitted when a profile change command is received from the terminal. - * - * @param text The text of the command. This is a string of the form - * "PropertyName=Value;PropertyName=Value ..." - */ - void profileChangeCommandReceived (const QString & text); - - /** - * Emitted when the flow control state changes. - * - * @param enabled True if flow control is enabled or false otherwise. - */ - void flowControlEnabledChanged (bool enabled); - -private slots: - void done (int); - - void onReceiveBlock (const char *buffer, int len); - void monitorTimerDone (); - - void activityStateSet (int); - - //automatically detach views from sessions when view is destroyed - //void viewDestroyed (QObject * view); - - void updateFlowControlState (bool suspended); -private: - - bool kill (int signal); - - // checks that the binary 'program' is available and can be executed - // returns the binary name if available or an empty string otherwise - QString checkProgram (const QString & program) const; - - QUuid _uniqueIdentifier; // SHELL_SESSION_ID - - Pty *_shellProcess; - //Emulation *_emulation; - - //QList < TerminalDisplay * >_views; - - bool _monitorActivity; - bool _monitorSilence; - bool _notifiedActivity; - bool _masterMode; - bool _autoClose; - bool _wantedClose; - QTimer *_monitorTimer; - - int _silenceSeconds; - - QString _nameTitle; - QString _displayTitle; - QString _userTitle; - - QString _localTabTitleFormat; - QString _remoteTabTitleFormat; - - QString _iconName; - QString _iconText; // as set by: echo -en '\033]1;IconText\007 - bool _flowControl; - bool _fullScripting; - - QString _program; - QStringList _arguments; - - QStringList _environment; - int _sessionId; - - QString _initialWorkingDir; - QString _currentWorkingDir; - - int _foregroundPid; - - QColor _modifiedBackground; // as set by: echo -en '\033]11;Color\007 - - QString _profileKey; - - bool _hasDarkBackground; - - static int lastSessionId; - -}; - -/** - * Provides a group of sessions which is divided into master and slave sessions. - * Activity in master sessions can be propagated to all sessions within the group. - * The type of activity which is propagated and method of propagation is controlled - * by the masterMode() flags. - */ -class SessionGroup:public QObject -{ -Q_OBJECT public: - /** Constructs an empty session group. */ - SessionGroup (QObject * parent); - /** Destroys the session group and removes all connections between master and slave sessions. */ - ~SessionGroup (); - - /** Adds a session to the group. */ - void addSession (Session * session); - /** Removes a session from the group. */ - void removeSession (Session * session); - - /** Returns the list of sessions currently in the group. */ - QList < Session * >sessions () const; - - /** - * Sets whether a particular session is a master within the group. - * Changes or activity in the group's master sessions may be propagated - * to all the sessions in the group, depending on the current masterMode() - * - * @param session The session whoose master status should be changed. - * @param master True to make this session a master or false otherwise - */ - void setMasterStatus (Session * session, bool master); - /** Returns the master status of a session. See setMasterStatus() */ - bool masterStatus (Session * session) const; - - /** - * This enum describes the options for propagating certain activity or - * changes in the group's master sessions to all sessions in the group. - */ - enum MasterMode - { - /** - * Any input key presses in the master sessions are sent to all - * sessions in the group. - */ - CopyInputToAll = 1 - }; - - /** - * Specifies which activity in the group's master sessions is propagated - * to all sessions in the group. - * - * @param mode A bitwise OR of MasterMode flags. - */ - void setMasterMode (int mode); - /** - * Returns a bitwise OR of the active MasterMode flags for this group. - * See setMasterMode() - */ - int masterMode () const; - - private slots:void sessionFinished (); - void forwardData (const char *data, int size); - -private: - QList < Session * >masters () const; - - // maps sessions to their master status - QHash < Session *, bool > _sessions; - - int _masterMode; -}; - -#endif diff -r f187d6796072 -r 04931210aac0 gui/src/terminal/ShellCommand.cpp --- a/gui/src/terminal/ShellCommand.cpp Fri Aug 19 03:37:49 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,187 +0,0 @@ -/* - Copyright (C) 2007 by Robert Knight - - Rewritten for QT4 by e_k , Copyright (C)2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. -*/ - -// Own -#include "ShellCommand.h" - -//some versions of gcc(4.3) require explicit include -#include - -// expands environment variables in 'text' -// function copied from kdelibs/kio/kio/kurlcompletion.cpp -static bool expandEnv (QString & text); - -ShellCommand::ShellCommand (const QString & fullCommand) -{ - bool inQuotes = false; - - QString builder; - - for (int i = 0; i < fullCommand.count (); i++) - { - QChar ch = fullCommand[i]; - - const bool isLastChar = (i == fullCommand.count () - 1); - const bool isQuote = (ch == '\'' || ch == '\"'); - - if (!isLastChar && isQuote) - inQuotes = !inQuotes; - else - { - if ((!ch.isSpace () || inQuotes) && !isQuote) - builder.append (ch); - - if ((ch.isSpace () && !inQuotes) || (i == fullCommand.count () - 1)) - { - _arguments << builder; - builder.clear (); - } - } - } -} - -ShellCommand::ShellCommand (const QString & command, - const QStringList & arguments) -{ - _arguments = arguments; - - if (!_arguments.isEmpty ()) - _arguments[0] == command; -} - -QString -ShellCommand::fullCommand () const -{ - return _arguments.join (QChar (' ')); -} - -QString -ShellCommand::command () const -{ - if (!_arguments.isEmpty ()) - return _arguments[0]; - else - return QString (); -} - -QStringList -ShellCommand::arguments () const -{ - return _arguments; -} - -bool -ShellCommand::isRootCommand () const -{ - Q_ASSERT (0); // not implemented yet - return false; -} - -bool -ShellCommand::isAvailable () const -{ - Q_ASSERT (0); // not implemented yet - return false; -} - -QStringList -ShellCommand::expand (const QStringList & items) -{ - QStringList result; - - foreach (QString item, items) result << expand (item); - - return result; -} - -QString -ShellCommand::expand (const QString & text) -{ - QString result = text; - expandEnv (result); - return result; -} - -/* - * expandEnv - * - * Expand environment variables in text. Escaped '$' characters are ignored. - * Return true if any variables were expanded - */ -static bool -expandEnv (QString & text) -{ - // Find all environment variables beginning with '$' - // - int pos = 0; - - bool expanded = false; - - while ((pos = text.indexOf (QLatin1Char ('$'), pos)) != -1) - { - - // Skip escaped '$' - // - if (pos > 0 && text.at (pos - 1) == QLatin1Char ('\\')) - { - pos++; - } - // Variable found => expand - // - else - { - // Find the end of the variable = next '/' or ' ' - // - int pos2 = text.indexOf (QLatin1Char (' '), pos + 1); - int pos_tmp = text.indexOf (QLatin1Char ('/'), pos + 1); - - if (pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2)) - pos2 = pos_tmp; - - if (pos2 == -1) - pos2 = text.length (); - - // Replace if the variable is terminated by '/' or ' ' - // and defined - // - if (pos2 >= 0) - { - int len = pos2 - pos; - QString key = text.mid (pos + 1, len - 1); - QString value = - QString::fromLocal8Bit (::getenv (key.toLocal8Bit ())); - - if (!value.isEmpty ()) - { - expanded = true; - text.replace (pos, len, value); - pos = pos + value.length (); - } - else - { - pos = pos2; - } - } - } - } - - return expanded; -} diff -r f187d6796072 -r 04931210aac0 gui/src/terminal/ShellCommand.h --- a/gui/src/terminal/ShellCommand.h Fri Aug 19 03:37:49 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - Copyright (C) 2007 by Robert Knight - - Rewritten for QT4 by e_k , Copyright (C)2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. -*/ - -#ifndef SHELLCOMMAND_H -#define SHELLCOMMAND_H - -// Qt -#include - -/** - * A class to parse and extract information about shell commands. - * - * ShellCommand can be used to: - * - *
    - *
  • Take a command-line (eg "/bin/sh -c /path/to/my/script") and split it - * into its component parts (eg. the command "/bin/sh" and the arguments - * "-c","/path/to/my/script") - *
  • - *
  • Take a command and a list of arguments and combine them to - * form a complete command line. - *
  • - *
  • Determine whether the binary specified by a command exists in the - * user's PATH. - *
  • - *
  • Determine whether a command-line specifies the execution of - * another command as the root user using su/sudo etc. - *
  • - *
- */ -class ShellCommand -{ -public: - /** - * Constructs a ShellCommand from a command line. - * - * @param fullCommand The command line to parse. - */ - ShellCommand (const QString & fullCommand); - /** - * Constructs a ShellCommand with the specified @p command and @p arguments. - */ - ShellCommand (const QString & command, const QStringList & arguments); - - /** Returns the command. */ - QString command () const; - /** Returns the arguments. */ - QStringList arguments () const; - - /** - * Returns the full command line. - */ - QString fullCommand () const; - - /** Returns true if this is a root command. */ - bool isRootCommand () const; - /** Returns true if the program specified by @p command() exists. */ - bool isAvailable () const; - - /** Expands environment variables in @p text .*/ - static QString expand (const QString & text); - - /** Expands environment variables in each string in @p list. */ - static QStringList expand (const QStringList & items); - -private: - QStringList _arguments; -}; -#endif // SHELLCOMMAND_H