diff --git a/app/session.cpp b/app/session.cpp index 806f705..c8f2d50 100644 --- a/app/session.cpp +++ b/app/session.cpp @@ -1,654 +1,660 @@ /* Copyright (C) 2008-2014 by Eike Hein Copyright (C) 2009 by Juan Carlos Torres 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) version 3 or any later version accepted by the membership of KDE e.V. (or its successor appro- ved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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, see https://www.gnu.org/licenses/. */ #include "session.h" #include "terminal.h" int Session::m_availableSessionId = 0; -Session::Session(SessionType type, QWidget* parent) : QObject(parent) +Session::Session(const QString& workingDir, SessionType type, QWidget* parent) : QObject(parent) { + m_workingDir = workingDir; m_sessionId = m_availableSessionId; m_availableSessionId++; m_activeTerminalId = -1; m_closable = true; m_baseSplitter = new Splitter(Qt::Horizontal, parent); connect(m_baseSplitter, SIGNAL(destroyed()), this, SLOT(prepareShutdown())); setupSession(type); } Session::~Session() { if (m_baseSplitter) delete m_baseSplitter; emit destroyed(m_sessionId); } void Session::setupSession(SessionType type) { switch (type) { case Single: { Terminal* terminal = addTerminal(m_baseSplitter); setActiveTerminal(terminal->id()); break; } case TwoHorizontal: { int splitterWidth = m_baseSplitter->width(); Terminal* terminal = addTerminal(m_baseSplitter); addTerminal(m_baseSplitter); QList newSplitterSizes; newSplitterSizes << (splitterWidth / 2) << (splitterWidth / 2); m_baseSplitter->setSizes(newSplitterSizes); QWidget* terminalWidget = terminal->terminalWidget(); if (terminalWidget) { terminalWidget->setFocus(); setActiveTerminal(terminal->id()); } break; } case TwoVertical: { m_baseSplitter->setOrientation(Qt::Vertical); int splitterHeight = m_baseSplitter->height(); Terminal* terminal = addTerminal(m_baseSplitter); addTerminal(m_baseSplitter); QList newSplitterSizes; newSplitterSizes << (splitterHeight / 2) << (splitterHeight / 2); m_baseSplitter->setSizes(newSplitterSizes); QWidget* terminalWidget = terminal->terminalWidget(); if (terminalWidget) { terminalWidget->setFocus(); setActiveTerminal(terminal->id()); } break; } case Quad: { int splitterWidth = m_baseSplitter->width(); int splitterHeight = m_baseSplitter->height(); m_baseSplitter->setOrientation(Qt::Vertical); Splitter* upperSplitter = new Splitter(Qt::Horizontal, m_baseSplitter); connect(upperSplitter, SIGNAL(destroyed()), this, SLOT(cleanup())); Splitter* lowerSplitter = new Splitter(Qt::Horizontal, m_baseSplitter); connect(lowerSplitter, SIGNAL(destroyed()), this, SLOT(cleanup())); Terminal* terminal = addTerminal(upperSplitter); addTerminal(upperSplitter); addTerminal(lowerSplitter); addTerminal(lowerSplitter); QList newSplitterSizes; newSplitterSizes << (splitterHeight / 2) << (splitterHeight / 2); m_baseSplitter->setSizes(newSplitterSizes); newSplitterSizes.clear(); newSplitterSizes << (splitterWidth / 2) << (splitterWidth / 2); upperSplitter->setSizes(newSplitterSizes); lowerSplitter->setSizes(newSplitterSizes); QWidget* terminalWidget = terminal->terminalWidget(); if (terminalWidget) { terminalWidget->setFocus(); setActiveTerminal(terminal->id()); } break; } default: { addTerminal(m_baseSplitter); break; } } } -Terminal* Session::addTerminal(QWidget* parent) +Terminal* Session::addTerminal(QWidget* parent, QString workingDir) { - Terminal* terminal = new Terminal(parent); + if (workingDir.isEmpty()) { + // fallback to session's default working dir + workingDir = m_workingDir; + } + + Terminal* terminal = new Terminal(workingDir, parent); connect(terminal, SIGNAL(activated(int)), this, SLOT(setActiveTerminal(int))); connect(terminal, SIGNAL(manuallyActivated(Terminal*)), this, SIGNAL(terminalManuallyActivated(Terminal*))); connect(terminal, SIGNAL(titleChanged(int,QString)), this, SLOT(setTitle(int,QString))); connect(terminal, SIGNAL(keyboardInputBlocked(Terminal*)), this, SIGNAL(keyboardInputBlocked(Terminal*))); connect(terminal, SIGNAL(silenceDetected(Terminal*)), this, SIGNAL(silenceDetected(Terminal*))); connect(terminal, SIGNAL(destroyed(int)), this, SLOT(cleanup(int))); m_terminals.insert(terminal->id(), terminal); QWidget* terminalWidget = terminal->terminalWidget(); if (terminalWidget) terminalWidget->setFocus(); return terminal; } void Session::closeTerminal(int terminalId) { if (terminalId == -1) terminalId = m_activeTerminalId; if (terminalId == -1) return; if (!m_terminals.contains(terminalId)) return; m_terminals.value(terminalId)->deletePart(); } void Session::focusPreviousTerminal() { if (m_activeTerminalId == -1) return; if (!m_terminals.contains(m_activeTerminalId)) return; QMapIterator it(m_terminals); it.toBack(); while (it.hasPrevious()) { it.previous(); if (it.key() == m_activeTerminalId) { if (it.hasPrevious()) { QWidget* terminalWidget = it.peekPrevious().value()->terminalWidget(); if (terminalWidget) terminalWidget->setFocus(); } else { it.toBack(); QWidget* terminalWidget = it.peekPrevious().value()->terminalWidget(); if (terminalWidget) terminalWidget->setFocus(); } break; } } } void Session::focusNextTerminal() { if (m_activeTerminalId == -1) return; if (!m_terminals.contains(m_activeTerminalId)) return; QMapIterator it(m_terminals); while (it.hasNext()) { it.next(); if (it.key() == m_activeTerminalId) { if (it.hasNext()) { QWidget* terminalWidget = it.peekNext().value()->terminalWidget(); if (terminalWidget) terminalWidget->setFocus(); } else { it.toFront(); QWidget* terminalWidget = it.peekNext().value()->terminalWidget(); if (terminalWidget) terminalWidget->setFocus(); } break; } } } int Session::splitLeftRight(int terminalId) { if (terminalId == -1) terminalId = m_activeTerminalId; if (terminalId == -1) return -1; if (!m_terminals.contains(terminalId)) return -1; Terminal* terminal = m_terminals.value(terminalId); if (terminal) return split(terminal, Qt::Horizontal); else return -1; } int Session::splitTopBottom(int terminalId) { if (terminalId == -1) terminalId = m_activeTerminalId; if (terminalId == -1) return -1; if (!m_terminals.contains(terminalId)) return -1; Terminal* terminal = m_terminals.value(terminalId); if (terminal) return split(terminal, Qt::Vertical); else return -1; } int Session::split(Terminal* terminal, Qt::Orientation orientation) { Splitter* splitter = static_cast(terminal->splitter()); if (splitter->count() == 1) { int splitterWidth = splitter->width(); if (splitter->orientation() != orientation) splitter->setOrientation(orientation); - terminal = addTerminal(splitter); + terminal = addTerminal(splitter, terminal->currentWorkingDirectory()); QList newSplitterSizes; newSplitterSizes << (splitterWidth / 2) << (splitterWidth / 2); splitter->setSizes(newSplitterSizes); QWidget* partWidget = terminal->partWidget(); if (partWidget) partWidget->show(); m_activeTerminalId = terminal->id(); } else { QList splitterSizes = splitter->sizes(); Splitter* newSplitter = new Splitter(orientation, splitter); connect(newSplitter, SIGNAL(destroyed()), this, SLOT(cleanup())); if (splitter->indexOf(terminal->partWidget()) == 0) splitter->insertWidget(0, newSplitter); QWidget* partWidget = terminal->partWidget(); if (partWidget) partWidget->setParent(newSplitter); terminal->setSplitter(newSplitter); - terminal = addTerminal(newSplitter); + terminal = addTerminal(newSplitter, terminal->currentWorkingDirectory()); splitter->setSizes(splitterSizes); QList newSplitterSizes; newSplitterSizes << (splitterSizes[1] / 2) << (splitterSizes[1] / 2); newSplitter->setSizes(newSplitterSizes); newSplitter->show(); partWidget = terminal->partWidget(); if (partWidget) partWidget->show(); m_activeTerminalId = terminal->id(); } return m_activeTerminalId; } int Session::tryGrowTerminal(int terminalId, GrowthDirection direction, uint pixels) { Terminal* terminal = getTerminal(terminalId); Splitter* splitter = static_cast(terminal->splitter()); QWidget* child = terminal->partWidget(); while (splitter) { bool isHorizontal = (direction == Right || direction == Left); bool isForward = (direction == Down || direction == Right); // Detecting correct orientation. if ((splitter->orientation() == Qt::Horizontal && isHorizontal) || (splitter->orientation() == Qt::Vertical && !isHorizontal)) { int currentPos = splitter->indexOf(child); if (currentPos != -1 // Next/Prev movable element detection. && (currentPos != 0 || isForward) && (currentPos != splitter->count() - 1 || !isForward)) { QList currentSizes = splitter->sizes(); int oldSize = currentSizes[currentPos]; int affected = isForward ? currentPos + 1: currentPos -1; currentSizes[currentPos] += pixels; currentSizes[affected] -= pixels; splitter->setSizes(currentSizes); return splitter->sizes()[currentPos] - oldSize; } } // Try with a higher level. child = splitter; splitter = static_cast(splitter->parentWidget()); } return -1; } void Session::setActiveTerminal(int terminalId) { m_activeTerminalId = terminalId; setTitle(m_activeTerminalId, m_terminals.value(m_activeTerminalId)->title()); } void Session::setTitle(int terminalId, const QString& title) { if (terminalId == m_activeTerminalId) { m_title = title; emit titleChanged(m_title); emit titleChanged(m_sessionId, m_title); } } void Session::cleanup(int terminalId) { if (m_activeTerminalId == terminalId && m_terminals.count() > 1) focusPreviousTerminal(); m_terminals.remove(terminalId); cleanup(); } void Session::cleanup() { if (!m_baseSplitter) return; m_baseSplitter->recursiveCleanup(); if (m_terminals.isEmpty()) m_baseSplitter->deleteLater(); } void Session::prepareShutdown() { m_baseSplitter = NULL; deleteLater(); } const QString Session::terminalIdList() { QList keyList = m_terminals.uniqueKeys(); QStringList idList; QListIterator i(keyList); while (i.hasNext()) idList << QString::number(i.next()); return idList.join(QLatin1Char(',')); } bool Session::hasTerminal(int terminalId) { return m_terminals.contains(terminalId); } Terminal* Session::getTerminal(int terminalId) { if (!m_terminals.contains(terminalId)) return 0; return m_terminals.value(terminalId); } void Session::runCommand(const QString& command, int terminalId) { if (terminalId == -1) terminalId = m_activeTerminalId; if (terminalId == -1) return; if (!m_terminals.contains(terminalId)) return; m_terminals.value(terminalId)->runCommand(command); } void Session::manageProfiles() { if ( m_activeTerminalId == -1) return; if (!m_terminals.contains(m_activeTerminalId)) return; m_terminals.value(m_activeTerminalId)->manageProfiles(); } void Session::editProfile() { if ( m_activeTerminalId == -1) return; if (!m_terminals.contains(m_activeTerminalId)) return; m_terminals.value(m_activeTerminalId)->editProfile(); } bool Session::keyboardInputEnabled() { int keyboardInputEnabledCount = 0; QMapIterator i(m_terminals); while (i.hasNext()) if (i.next().value()->keyboardInputEnabled()) ++keyboardInputEnabledCount; return m_terminals.count() == keyboardInputEnabledCount; } void Session::setKeyboardInputEnabled(bool enabled) { QMapIterator i(m_terminals); while (i.hasNext()) setKeyboardInputEnabled(i.next().key(), enabled); } bool Session::keyboardInputEnabled(int terminalId) { if (!m_terminals.contains(terminalId)) return false; return m_terminals.value(terminalId)->keyboardInputEnabled(); } void Session::setKeyboardInputEnabled(int terminalId, bool enabled) { if (!m_terminals.contains(terminalId)) return; m_terminals.value(terminalId)->setKeyboardInputEnabled(enabled); } bool Session::hasTerminalsWithKeyboardInputEnabled() { QMapIterator i(m_terminals); while (i.hasNext()) if (i.next().value()->keyboardInputEnabled()) return true; return false; } bool Session::hasTerminalsWithKeyboardInputDisabled() { QMapIterator i(m_terminals); while (i.hasNext()) if (!i.next().value()->keyboardInputEnabled()) return true; return false; } bool Session::monitorActivityEnabled() { int monitorActivityEnabledCount = 0; QMapIterator i(m_terminals); while (i.hasNext()) if (i.next().value()->monitorActivityEnabled()) ++monitorActivityEnabledCount; return m_terminals.count() == monitorActivityEnabledCount; } void Session::setMonitorActivityEnabled(bool enabled) { QMapIterator i(m_terminals); while (i.hasNext()) setMonitorActivityEnabled(i.next().key(), enabled); } bool Session::monitorActivityEnabled(int terminalId) { if (!m_terminals.contains(terminalId)) return false; return m_terminals.value(terminalId)->monitorActivityEnabled(); } void Session::setMonitorActivityEnabled(int terminalId, bool enabled) { if (!m_terminals.contains(terminalId)) return; Terminal* terminal = m_terminals.value(terminalId); connect(terminal, SIGNAL(activityDetected(Terminal*)), this, SIGNAL(activityDetected(Terminal*)), Qt::UniqueConnection); terminal->setMonitorActivityEnabled(enabled); } bool Session::hasTerminalsWithMonitorActivityEnabled() { QMapIterator i(m_terminals); while (i.hasNext()) if (i.next().value()->monitorActivityEnabled()) return true; return false; } bool Session::hasTerminalsWithMonitorActivityDisabled() { QMapIterator i(m_terminals); while (i.hasNext()) if (!i.next().value()->monitorActivityEnabled()) return true; return false; } void Session::reconnectMonitorActivitySignals() { QMapIterator i(m_terminals); while (i.hasNext()) { i.next(); connect(i.value(), SIGNAL(activityDetected(Terminal*)), this, SIGNAL(activityDetected(Terminal*)), Qt::UniqueConnection); } } bool Session::monitorSilenceEnabled() { int monitorSilenceEnabledCount = 0; QMapIterator i(m_terminals); while (i.hasNext()) if (i.next().value()->monitorSilenceEnabled()) ++monitorSilenceEnabledCount; return m_terminals.count() == monitorSilenceEnabledCount; } void Session::setMonitorSilenceEnabled(bool enabled) { QMapIterator i(m_terminals); while (i.hasNext()) setMonitorSilenceEnabled(i.next().key(), enabled); } bool Session::monitorSilenceEnabled(int terminalId) { if (!m_terminals.contains(terminalId)) return false; return m_terminals.value(terminalId)->monitorSilenceEnabled(); } void Session::setMonitorSilenceEnabled(int terminalId, bool enabled) { if (!m_terminals.contains(terminalId)) return; m_terminals.value(terminalId)->setMonitorSilenceEnabled(enabled); } bool Session::hasTerminalsWithMonitorSilenceDisabled() { QMapIterator i(m_terminals); while (i.hasNext()) if (!i.next().value()->monitorSilenceEnabled()) return true; return false; } bool Session::hasTerminalsWithMonitorSilenceEnabled() { QMapIterator i(m_terminals); while (i.hasNext()) if (i.next().value()->monitorSilenceEnabled()) return true; return false; } diff --git a/app/session.h b/app/session.h index 797234b..71e4c85 100644 --- a/app/session.h +++ b/app/session.h @@ -1,139 +1,140 @@ /* Copyright (C) 2008-2009 by Eike Hein Copyright (C) 2009 by Juan Carlos Torres 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) version 3 or any later version accepted by the membership of KDE e.V. (or its successor appro- ved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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, see https://www.gnu.org/licenses/. */ #ifndef SESSION_H #define SESSION_H #include "splitter.h" #include #include class Terminal; class Session : public QObject { Q_OBJECT public: enum SessionType { Single, TwoHorizontal, TwoVertical, Quad }; enum GrowthDirection { Up, Right, Down, Left }; - explicit Session(SessionType type = Single, QWidget* parent = 0); + explicit Session(const QString& workingDir, SessionType type = Single, QWidget* parent = 0); ~Session(); int id() { return m_sessionId; } const QString title() { return m_title; } QWidget* widget() { return m_baseSplitter; } int activeTerminalId() { return m_activeTerminalId; } const QString terminalIdList(); int terminalCount() { return m_terminals.count(); } bool hasTerminal(int terminalId); Terminal* getTerminal(int terminalId); bool closable() { return m_closable; } void setClosable(bool closable) { m_closable = closable; } bool keyboardInputEnabled(); void setKeyboardInputEnabled(bool enabled); bool keyboardInputEnabled(int terminalId); void setKeyboardInputEnabled(int terminalId, bool enabled); bool hasTerminalsWithKeyboardInputEnabled(); bool hasTerminalsWithKeyboardInputDisabled(); bool monitorActivityEnabled(); void setMonitorActivityEnabled(bool enabled); bool monitorActivityEnabled(int terminalId); void setMonitorActivityEnabled(int terminalId, bool enabled); bool hasTerminalsWithMonitorActivityEnabled(); bool hasTerminalsWithMonitorActivityDisabled(); bool monitorSilenceEnabled(); void setMonitorSilenceEnabled(bool enabled); bool monitorSilenceEnabled(int terminalId); void setMonitorSilenceEnabled(int terminalId, bool enabled); bool hasTerminalsWithMonitorSilenceEnabled(); bool hasTerminalsWithMonitorSilenceDisabled(); public Q_SLOTS: void closeTerminal(int terminalId = -1); void focusNextTerminal(); void focusPreviousTerminal(); int splitLeftRight(int terminalId = -1); int splitTopBottom(int terminalId = -1); int tryGrowTerminal(int terminalId, GrowthDirection direction, uint pixels); void runCommand(const QString& command, int terminalId = -1); void manageProfiles(); void editProfile(); void reconnectMonitorActivitySignals(); Q_SIGNALS: void titleChanged(const QString& title); void titleChanged(int sessionId, const QString& title); void terminalManuallyActivated(Terminal* terminal); void keyboardInputBlocked(Terminal* terminal); void activityDetected(Terminal* terminal); void silenceDetected(Terminal* terminal); void destroyed(int sessionId); private Q_SLOTS: void setActiveTerminal(int terminalId); void setTitle(int terminalId, const QString& title); void cleanup(int terminalId); void cleanup(); void prepareShutdown(); private: void setupSession(SessionType type); - Terminal* addTerminal(QWidget* parent); + Terminal* addTerminal(QWidget* parent, QString workingDir = QString()); int split(Terminal* terminal, Qt::Orientation orientation); + QString m_workingDir; static int m_availableSessionId; int m_sessionId; Splitter* m_baseSplitter; int m_activeTerminalId; QMap m_terminals; QString m_title; bool m_closable; }; #endif diff --git a/app/sessionstack.cpp b/app/sessionstack.cpp index 0945d22..69f8780 100644 --- a/app/sessionstack.cpp +++ b/app/sessionstack.cpp @@ -1,671 +1,675 @@ /* Copyright (C) 2008-2014 by Eike Hein Copyright (C) 2009 by Juan Carlos Torres 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) version 3 or any later version accepted by the membership of KDE e.V. (or its successor appro- ved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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, see https://www.gnu.org/licenses/. */ #include "sessionstack.h" #include "settings.h" #include "terminal.h" #include "visualeventoverlay.h" #include #include #include #include #include static bool show_disallow_certain_dbus_methods_message = true; SessionStack::SessionStack(QWidget* parent) : QStackedWidget(parent) { QDBusConnection::sessionBus().registerObject(QStringLiteral("/yakuake/sessions"), this, QDBusConnection::ExportScriptableSlots); m_activeSessionId = -1; m_visualEventOverlay = new VisualEventOverlay(this); connect(this, SIGNAL(removeTerminalHighlight()), m_visualEventOverlay, SLOT(removeTerminalHighlight())); } SessionStack::~SessionStack() { } int SessionStack::addSessionImpl(Session::SessionType type) { - Session* session = new Session(type, this); + Session* currentSession = m_sessions.value(activeSessionId()); + Terminal* currentTerminal = currentSession ? currentSession->getTerminal(currentSession->activeTerminalId()) : NULL; + QString workingDir = currentTerminal ? currentTerminal->currentWorkingDirectory() : QString(); + + Session* session = new Session(workingDir, type, this); connect(session, SIGNAL(titleChanged(int,QString)), this, SIGNAL(titleChanged(int,QString))); connect(session, SIGNAL(terminalManuallyActivated(Terminal*)), this, SLOT(handleManualTerminalActivation(Terminal*))); connect(session, SIGNAL(keyboardInputBlocked(Terminal*)), m_visualEventOverlay, SLOT(indicateKeyboardInputBlocked(Terminal*))); connect(session, SIGNAL(activityDetected(Terminal*)), parentWidget(), SLOT(handleTerminalActivity(Terminal*))); connect(session, SIGNAL(silenceDetected(Terminal*)), parentWidget(), SLOT(handleTerminalSilence(Terminal*))); connect(parentWidget(), SIGNAL(windowClosed()), session, SLOT(reconnectMonitorActivitySignals())); connect(session, SIGNAL(destroyed(int)), this, SLOT(cleanup(int))); addWidget(session->widget()); m_sessions.insert(session->id(), session); if (Settings::dynamicTabTitles()) emit sessionAdded(session->id(), session->title()); else emit sessionAdded(session->id(), QString()); return session->id(); } int SessionStack::addSession() { return addSessionImpl(Session::Single); } int SessionStack::addSessionTwoHorizontal() { return addSessionImpl(Session::TwoHorizontal); } int SessionStack::addSessionTwoVertical() { return addSessionImpl(Session::TwoVertical); } int SessionStack::addSessionQuad() { return addSessionImpl(Session::Quad); } void SessionStack::raiseSession(int sessionId) { if (sessionId == -1 || !m_sessions.contains(sessionId)) return; Session* session = m_sessions.value(sessionId); if (!m_visualEventOverlay->isHidden()) m_visualEventOverlay->hide(); if (m_activeSessionId != -1 && m_sessions.contains(m_activeSessionId)) { Session* oldActiveSession = m_sessions.value(m_activeSessionId); disconnect(oldActiveSession, SLOT(closeTerminal())); disconnect(oldActiveSession, SLOT(focusPreviousTerminal())); disconnect(oldActiveSession, SLOT(focusNextTerminal())); disconnect(oldActiveSession, SLOT(manageProfiles())); disconnect(oldActiveSession, SIGNAL(titleChanged(QString)), this, SIGNAL(activeTitleChanged(QString))); oldActiveSession->reconnectMonitorActivitySignals(); } m_activeSessionId = sessionId; setCurrentWidget(session->widget()); if (session->widget()->focusWidget()) session->widget()->focusWidget()->setFocus(); if (session->hasTerminalsWithKeyboardInputDisabled()) m_visualEventOverlay->show(); connect(this, SIGNAL(closeTerminal()), session, SLOT(closeTerminal())); connect(this, SIGNAL(previousTerminal()), session, SLOT(focusPreviousTerminal())); connect(this, SIGNAL(nextTerminal()), session, SLOT(focusNextTerminal())); connect(this, SIGNAL(manageProfiles()), session, SLOT(manageProfiles())); connect(session, SIGNAL(titleChanged(QString)), this, SIGNAL(activeTitleChanged(QString))); emit sessionRaised(sessionId); emit activeTitleChanged(session->title()); } void SessionStack::removeSession(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return; if (!m_sessions.contains(sessionId)) return; if (queryClose(sessionId, QueryCloseSession)) m_sessions.value(sessionId)->deleteLater(); } void SessionStack::removeTerminal(int terminalId) { int sessionId = sessionIdForTerminalId(terminalId); if (terminalId == -1) { if (m_activeSessionId == -1) return; if (!m_sessions.contains(m_activeSessionId)) return; if (m_sessions.value(m_activeSessionId)->closable()) m_sessions.value(m_activeSessionId)->closeTerminal(); } else { if (m_sessions.value(sessionId)->closable()) m_sessions.value(sessionId)->closeTerminal(terminalId); } } void SessionStack::closeActiveTerminal(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return; if (!m_sessions.contains(sessionId)) return; if (queryClose(sessionId, QueryCloseTerminal)) m_sessions.value(sessionId)->closeTerminal(); } void SessionStack::cleanup(int sessionId) { if (sessionId == m_activeSessionId) m_activeSessionId = -1; m_sessions.remove(sessionId); emit sessionRemoved(sessionId); } int SessionStack::activeTerminalId() { if (!m_sessions.contains(m_activeSessionId)) return -1; return m_sessions.value(m_activeSessionId)->activeTerminalId(); } const QString SessionStack::sessionIdList() { QList keyList = m_sessions.uniqueKeys(); QStringList idList; QListIterator i(keyList); while (i.hasNext()) idList << QString::number(i.next()); return idList.join(QLatin1Char(',')); } const QString SessionStack::terminalIdList() { QStringList idList; QHashIterator it(m_sessions); while (it.hasNext()) { it.next(); idList << it.value()->terminalIdList(); } return idList.join(QLatin1Char(',')); } const QString SessionStack::terminalIdsForSessionId(int sessionId) { if (!m_sessions.contains(sessionId)) return QString::number(-1); return m_sessions.value(sessionId)->terminalIdList(); } int SessionStack::sessionIdForTerminalId(int terminalId) { int sessionId = -1; QHashIterator it(m_sessions); while (it.hasNext()) { it.next(); if (it.value()->hasTerminal(terminalId)) { sessionId = it.key(); break; } } return sessionId; } static void warnAboutDBus() { #if !defined(REMOVE_SENDTEXT_RUNCOMMAND_DBUS_METHODS) if (show_disallow_certain_dbus_methods_message) { KNotification::event(KNotification::Warning, QStringLiteral("Yakuake D-Bus Warning"), i18n("The D-Bus method runCommand was just used. There are security concerns about allowing these methods to be public. If desired, these methods can be changed to internal use only by re-compiling Yakuake.

This warning will only show once for this Yakuake instance.

")); show_disallow_certain_dbus_methods_message = false; } #endif } void SessionStack::runCommand(const QString& command) { warnAboutDBus(); if (m_activeSessionId == -1) return; if (!m_sessions.contains(m_activeSessionId)) return; m_sessions.value(m_activeSessionId)->runCommand(command); } void SessionStack::runCommandInTerminal(int terminalId, const QString& command) { warnAboutDBus(); QHashIterator it(m_sessions); while (it.hasNext()) { it.next(); it.value()->runCommand(command, terminalId); } } bool SessionStack::isSessionClosable(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->closable(); } void SessionStack::setSessionClosable(int sessionId, bool closable) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return; if (!m_sessions.contains(sessionId)) return; m_sessions.value(sessionId)->setClosable(closable); } bool SessionStack::hasUnclosableSessions() const { QHashIterator it(m_sessions); while (it.hasNext()) { it.next(); if (!it.value()->closable()) return true; } return false; } bool SessionStack::isSessionKeyboardInputEnabled(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->keyboardInputEnabled(); } void SessionStack::setSessionKeyboardInputEnabled(int sessionId, bool enabled) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return; if (!m_sessions.contains(sessionId)) return; m_sessions.value(sessionId)->setKeyboardInputEnabled(enabled); if (sessionId == m_activeSessionId) { if (enabled) m_visualEventOverlay->hide(); else m_visualEventOverlay->show(); } } bool SessionStack::isTerminalKeyboardInputEnabled(int terminalId) { int sessionId = sessionIdForTerminalId(terminalId); if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->keyboardInputEnabled(terminalId); } void SessionStack::setTerminalKeyboardInputEnabled(int terminalId, bool enabled) { int sessionId = sessionIdForTerminalId(terminalId); if (sessionId == -1) return; if (!m_sessions.contains(sessionId)) return; m_sessions.value(sessionId)->setKeyboardInputEnabled(terminalId, enabled); if (sessionId == m_activeSessionId) { if (enabled) m_visualEventOverlay->hide(); else m_visualEventOverlay->show(); } } bool SessionStack::hasTerminalsWithKeyboardInputEnabled(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->hasTerminalsWithKeyboardInputEnabled(); } bool SessionStack::hasTerminalsWithKeyboardInputDisabled(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->hasTerminalsWithKeyboardInputDisabled(); } bool SessionStack::isSessionMonitorActivityEnabled(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->monitorActivityEnabled(); } void SessionStack::setSessionMonitorActivityEnabled(int sessionId, bool enabled) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return; if (!m_sessions.contains(sessionId)) return; m_sessions.value(sessionId)->setMonitorActivityEnabled(enabled); } bool SessionStack::isTerminalMonitorActivityEnabled(int terminalId) { int sessionId = sessionIdForTerminalId(terminalId); if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->monitorActivityEnabled(terminalId); } void SessionStack::setTerminalMonitorActivityEnabled(int terminalId, bool enabled) { int sessionId = sessionIdForTerminalId(terminalId); if (sessionId == -1) return; if (!m_sessions.contains(sessionId)) return; m_sessions.value(sessionId)->setMonitorActivityEnabled(terminalId, enabled); } bool SessionStack::hasTerminalsWithMonitorActivityEnabled(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->hasTerminalsWithMonitorActivityEnabled(); } bool SessionStack::hasTerminalsWithMonitorActivityDisabled(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->hasTerminalsWithMonitorActivityDisabled(); } bool SessionStack::isSessionMonitorSilenceEnabled(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->monitorSilenceEnabled(); } void SessionStack::setSessionMonitorSilenceEnabled(int sessionId, bool enabled) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return; if (!m_sessions.contains(sessionId)) return; m_sessions.value(sessionId)->setMonitorSilenceEnabled(enabled); } bool SessionStack::isTerminalMonitorSilenceEnabled(int terminalId) { int sessionId = sessionIdForTerminalId(terminalId); if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->monitorSilenceEnabled(terminalId); } void SessionStack::setTerminalMonitorSilenceEnabled(int terminalId, bool enabled) { int sessionId = sessionIdForTerminalId(terminalId); if (sessionId == -1) return; if (!m_sessions.contains(sessionId)) return; m_sessions.value(sessionId)->setMonitorSilenceEnabled(terminalId, enabled); } bool SessionStack::hasTerminalsWithMonitorSilenceEnabled(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->hasTerminalsWithMonitorSilenceEnabled(); } bool SessionStack::hasTerminalsWithMonitorSilenceDisabled(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return false; if (!m_sessions.contains(sessionId)) return false; return m_sessions.value(sessionId)->hasTerminalsWithMonitorSilenceDisabled(); } void SessionStack::editProfile(int sessionId) { if (sessionId == -1) sessionId = m_activeSessionId; if (sessionId == -1) return; if (!m_sessions.contains(sessionId)) return; m_sessions.value(sessionId)->editProfile(); } int SessionStack::splitSessionLeftRight(int sessionId) { if (sessionId == -1) return -1; if (!m_sessions.contains(sessionId)) return -1; return m_sessions.value(sessionId)->splitLeftRight(); } int SessionStack::splitSessionTopBottom(int sessionId) { if (sessionId == -1) return -1; if (!m_sessions.contains(sessionId)) return -1; return m_sessions.value(sessionId)->splitTopBottom(); } int SessionStack::splitTerminalLeftRight(int terminalId) { int sessionId = sessionIdForTerminalId(terminalId); if (sessionId == -1) return -1; return m_sessions.value(sessionId)->splitLeftRight(terminalId); } int SessionStack::splitTerminalTopBottom(int terminalId) { int sessionId = sessionIdForTerminalId(terminalId); if (sessionId == -1) return -1; return m_sessions.value(sessionId)->splitTopBottom(terminalId); } int SessionStack::tryGrowTerminalRight(int terminalId, uint pixels) { int sessionId = sessionIdForTerminalId(terminalId); if (sessionId == -1) return -1; return m_sessions.value(sessionId)->tryGrowTerminal(terminalId, Session::Right, pixels); } int SessionStack::tryGrowTerminalLeft(int terminalId, uint pixels) { int sessionId = sessionIdForTerminalId(terminalId); if (sessionId == -1) return -1; return m_sessions.value(sessionId)->tryGrowTerminal(terminalId, Session::Left, pixels); } int SessionStack::tryGrowTerminalTop(int terminalId, uint pixels) { int sessionId = sessionIdForTerminalId(terminalId); if (sessionId == -1) return -1; return m_sessions.value(sessionId)->tryGrowTerminal(terminalId, Session::Up, pixels); } int SessionStack::tryGrowTerminalBottom(int terminalId, uint pixels) { int sessionId = sessionIdForTerminalId(terminalId); if (sessionId == -1) return -1; return m_sessions.value(sessionId)->tryGrowTerminal(terminalId, Session::Down, pixels); } void SessionStack::emitTitles() { QString title; QHashIterator it(m_sessions); while (it.hasNext()) { it.next(); title = it.value()->title(); if (!title.isEmpty()) emit titleChanged(it.value()->id(), title); } } bool SessionStack::requiresVisualEventOverlay() { if (m_activeSessionId == -1) return false; if (!m_sessions.contains(m_activeSessionId)) return false; return m_sessions.value(m_activeSessionId)->hasTerminalsWithKeyboardInputDisabled(); } void SessionStack::handleTerminalHighlightRequest(int terminalId) { Terminal* terminal = 0; QHashIterator it(m_sessions); while (it.hasNext()) { it.next(); terminal = it.value()->getTerminal(terminalId); if (terminal && it.value()->id() == m_activeSessionId) { m_visualEventOverlay->highlightTerminal(terminal, true); break; } } } void SessionStack::showEvent(QShowEvent *event) { Q_UNUSED(event) if (m_activeSessionId == -1) return; if (!m_sessions.contains(m_activeSessionId)) return; Terminal *terminal = m_sessions.value(m_activeSessionId)->getTerminal(activeTerminalId()); if (terminal) { QWidget* terminalWidget = terminal->terminalWidget(); if (terminalWidget) terminalWidget->setFocus(); } } void SessionStack::handleManualTerminalActivation(Terminal* terminal) { if (!Settings::terminalHighlightOnManualActivation()) return; Session* session = qobject_cast(QObject::sender()); if (session->terminalCount() > 1) m_visualEventOverlay->highlightTerminal(terminal, false); } bool SessionStack::queryClose(int sessionId, QueryCloseType type) { if (!m_sessions.contains(sessionId)) return false; if (!m_sessions.value(sessionId)->closable()) { QString closeQuestionIntro = xi18nc("@info", "You have locked this session to prevent accidental closing of terminals."); QString closeQuestion; if (type == QueryCloseSession) closeQuestion = xi18nc("@info", "Are you sure you want to close this session?"); else if (type == QueryCloseTerminal) closeQuestion = xi18nc("@info", "Are you sure you want to close this terminal?"); int result = KMessageBox::warningContinueCancel(this, closeQuestionIntro + QStringLiteral("

") + closeQuestion, xi18nc("@title:window", "Really Close?"), KStandardGuiItem::close(), KStandardGuiItem::cancel()); if (result != KMessageBox::Continue) return false; } return true; } diff --git a/app/terminal.cpp b/app/terminal.cpp index 9b1f0db..9ae1303 100644 --- a/app/terminal.cpp +++ b/app/terminal.cpp @@ -1,301 +1,311 @@ /* Copyright (C) 2008-2014 by Eike Hein 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) version 3 or any later version accepted by the membership of KDE e.V. (or its successor appro- ved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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, see https://www.gnu.org/licenses/. */ #include "terminal.h" #include "settings.h" #include #include #include #include #include #include #include #include #include #include #include #include #include int Terminal::m_availableTerminalId = 0; -Terminal::Terminal(QWidget* parent) : QObject(parent) +Terminal::Terminal(const QString& workingDir, QWidget* parent) : QObject(parent) { m_terminalId = m_availableTerminalId; m_availableTerminalId++; m_keyboardInputEnabled = true; m_monitorActivityEnabled = false; m_monitorSilenceEnabled = false; m_part = NULL; m_terminalInterface = NULL; m_partWidget = NULL; m_terminalWidget = NULL; m_parentSplitter = parent; KPluginFactory* factory = 0; KService::Ptr service = KService::serviceByDesktopName(QStringLiteral("konsolepart")); if( service ) { factory = KPluginLoader(service->library()).factory(); } m_part = factory ? (factory->create(parent)) : 0; if (m_part) { connect(m_part, SIGNAL(setWindowCaption(QString)), this, SLOT(setTitle(QString))); connect(m_part, SIGNAL(overrideShortcut(QKeyEvent*,bool&)), this, SLOT(overrideShortcut(QKeyEvent*,bool&))); connect(m_part, SIGNAL(destroyed()), this, SLOT(deleteLater())); m_partWidget = m_part->widget(); m_terminalWidget = m_part->widget()->focusWidget(); if (m_terminalWidget) { m_terminalWidget->setFocusPolicy(Qt::WheelFocus); m_terminalWidget->installEventFilter(this); } disableOffendingPartActions(); - m_terminalInterface = qobject_cast(m_part); + m_terminalInterface = qobject_cast(m_part); + + bool startInWorkingDir = m_terminalInterface->profileProperty(QStringLiteral("StartInCurrentSessionDir")).toBool(); + if (startInWorkingDir && !workingDir.isEmpty()) { + m_terminalInterface->showShellInDir(workingDir); + } } else displayKPartLoadError(); } Terminal::~Terminal() { emit destroyed(m_terminalId); } void Terminal::deletePart() { if (m_part) m_part->deleteLater(); else deleteLater(); } bool Terminal::eventFilter(QObject* /* watched */, QEvent* event) { if (event->type() == QEvent::FocusIn) { emit activated(m_terminalId); QFocusEvent* focusEvent = static_cast(event); if (focusEvent->reason() == Qt::MouseFocusReason || focusEvent->reason() == Qt::OtherFocusReason || focusEvent->reason() == Qt::BacktabFocusReason) emit manuallyActivated(this); } else if (event->type() == QEvent::MouseMove) { if (Settings::focusFollowsMouse() && m_terminalWidget && !m_terminalWidget->hasFocus()) m_terminalWidget->setFocus(); } if (!m_keyboardInputEnabled) { if (event->type() == QEvent::KeyPress) { QKeyEvent* keyEvent = static_cast(event); if (keyEvent->modifiers() == Qt::NoModifier) emit keyboardInputBlocked(this); return true; } else if (event->type() == QEvent::KeyRelease) return true; } return false; } void Terminal::displayKPartLoadError() { KColorScheme colorScheme(QPalette::Active); QColor warningColor = colorScheme.background(KColorScheme::NeutralBackground).color(); QColor warningColorLight = KColorScheme::shade(warningColor, KColorScheme::LightShade, 0.1); QString gradient = QStringLiteral("qlineargradient(x1:0, y1:0, x2:0, y2:1,stop: 0 %1, stop: 0.6 %1, stop: 1.0 %2)"); gradient = gradient.arg(warningColor.name()).arg(warningColorLight.name()); QString styleSheet = QStringLiteral("QLabel { background: %1; }"); QWidget* widget = new QWidget(m_parentSplitter); widget->setStyleSheet(styleSheet.arg(gradient)); m_partWidget = widget; m_terminalWidget = widget; m_terminalWidget->setFocusPolicy(Qt::WheelFocus); m_terminalWidget->installEventFilter(this); QLabel* label = new QLabel(widget); label->setContentsMargins(10, 10, 10, 10); label->setWordWrap(false); label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); label->setTextInteractionFlags(Qt::TextSelectableByMouse); label->setText(xi18nc("@info", "Yakuake was unable to load " "the Konsole component. " "A Konsole installation is " "required to use Yakuake.")); QLabel* icon = new QLabel(widget); icon->setContentsMargins(10, 10, 10, 10); icon->setPixmap(QIcon::fromTheme(QStringLiteral("dialog-warning")).pixmap(QSize(48, 48))); icon->setAlignment(Qt::AlignRight | Qt::AlignVCenter); QHBoxLayout* layout = new QHBoxLayout(widget); layout->addWidget(icon); layout->addWidget(label); layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); layout->setStretchFactor(icon, 1); layout->setStretchFactor(label,5); } void Terminal::disableOffendingPartActions() { // This is an unwelcome stop-gap that will be removed once we can // count on a Konsole version that doesn't pollute a KPart user's // shortcut "namespace". if (!m_part) return; KActionCollection* actionCollection = m_part->actionCollection(); if (actionCollection) { QAction* action = 0; action = actionCollection->action(QStringLiteral("next-view")); if (action) action->setEnabled(false); action = actionCollection->action(QStringLiteral("previous-view")); if (action) action->setEnabled(false); action = actionCollection->action(QStringLiteral("close-active-view")); if (action) action->setEnabled(false); action = actionCollection->action(QStringLiteral("split-view-left-right")); if (action) action->setEnabled(false); action = actionCollection->action(QStringLiteral("split-view-top-bottom")); if (action) action->setEnabled(false); action = actionCollection->action(QStringLiteral("rename-session")); if (action) action->setEnabled(false); action = actionCollection->action(QStringLiteral("enlarge-font")); if (action) action->setEnabled(false); action = actionCollection->action(QStringLiteral("shrink-font")); if (action) action->setEnabled(false); } } void Terminal::setTitle(const QString& title) { m_title = title; emit titleChanged(m_terminalId, m_title); } void Terminal::runCommand(const QString& command) { m_terminalInterface->sendInput(command + QStringLiteral("\n")); } void Terminal::manageProfiles() { QMetaObject::invokeMethod(m_part, "showManageProfilesDialog", Qt::QueuedConnection, Q_ARG(QWidget*, QApplication::activeWindow())); } void Terminal::editProfile() { QMetaObject::invokeMethod(m_part, "showEditCurrentProfileDialog", Qt::QueuedConnection, Q_ARG(QWidget*, QApplication::activeWindow())); } void Terminal::overrideShortcut(QKeyEvent* /* event */, bool& override) { override = false; } void Terminal::setMonitorActivityEnabled(bool enabled) { m_monitorActivityEnabled = enabled; if (enabled) { connect(m_part, SIGNAL(activityDetected()), this, SLOT(activityDetected()), Qt::UniqueConnection); QMetaObject::invokeMethod(m_part, "setMonitorActivityEnabled", Qt::QueuedConnection, Q_ARG(bool, true)); } else { disconnect(m_part, SIGNAL(activityDetected()), this, SLOT(activityDetected())); QMetaObject::invokeMethod(m_part, "setMonitorActivityEnabled", Qt::QueuedConnection, Q_ARG(bool, false)); } } void Terminal::setMonitorSilenceEnabled(bool enabled) { m_monitorSilenceEnabled = enabled; if (enabled) { connect(m_part, SIGNAL(silenceDetected()), this, SLOT(silenceDetected()), Qt::UniqueConnection); QMetaObject::invokeMethod(m_part, "setMonitorSilenceEnabled", Qt::QueuedConnection, Q_ARG(bool, true)); } else { disconnect(m_part, SIGNAL(silenceDetected()), this, SLOT(silenceDetected())); QMetaObject::invokeMethod(m_part, "setMonitorSilenceEnabled", Qt::QueuedConnection, Q_ARG(bool, false)); } } void Terminal::activityDetected() { emit activityDetected(this); } void Terminal::silenceDetected() { emit silenceDetected(this); } + +QString Terminal::currentWorkingDirectory() const +{ + return m_terminalInterface->currentWorkingDirectory(); +} diff --git a/app/terminal.h b/app/terminal.h index 874be29..44f3ba6 100644 --- a/app/terminal.h +++ b/app/terminal.h @@ -1,110 +1,113 @@ /* Copyright (C) 2008-2014 by Eike Hein 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) version 3 or any later version accepted by the membership of KDE e.V. (or its successor appro- ved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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, see https://www.gnu.org/licenses/. */ #ifndef TERMINAL_H #define TERMINAL_H #include #include class QKeyEvent; -class TerminalInterface; +// Requires V2 to access profileProperty(). +class TerminalInterfaceV2; class Terminal : public QObject { Q_OBJECT public: - explicit Terminal(QWidget* parent = 0); + explicit Terminal(const QString& workingDir, QWidget* parent = 0); ~Terminal(); bool eventFilter(QObject* watched, QEvent* event) override; int id() { return m_terminalId; } const QString title() { return m_title; } QWidget* partWidget() { return m_partWidget; } QWidget* terminalWidget() { return m_terminalWidget; } QWidget* splitter() { return m_parentSplitter; } void setSplitter(QWidget* splitter) { m_parentSplitter = splitter; } void runCommand(const QString& command); void manageProfiles(); void editProfile(); bool keyboardInputEnabled() { return m_keyboardInputEnabled; } void setKeyboardInputEnabled(bool enabled) { m_keyboardInputEnabled = enabled; } bool monitorActivityEnabled() { return m_monitorActivityEnabled; } void setMonitorActivityEnabled(bool enabled); bool monitorSilenceEnabled() { return m_monitorSilenceEnabled; } void setMonitorSilenceEnabled(bool enabled); + QString currentWorkingDirectory() const; + void deletePart(); Q_SIGNALS: void titleChanged(int terminalId, const QString& title); void activated(int terminalId); void manuallyActivated(Terminal* terminal); void keyboardInputBlocked(Terminal* terminal); void activityDetected(Terminal* terminal); void silenceDetected(Terminal* terminal); void destroyed(int terminalId); private Q_SLOTS: void setTitle(const QString& title); void overrideShortcut(QKeyEvent* event, bool& override); void silenceDetected(); void activityDetected(); private: void disableOffendingPartActions(); void displayKPartLoadError(); static int m_availableTerminalId; int m_terminalId; KParts::Part* m_part; - TerminalInterface* m_terminalInterface; + TerminalInterfaceV2* m_terminalInterface; QWidget* m_partWidget; QPointer m_terminalWidget; QWidget* m_parentSplitter; QString m_title; bool m_keyboardInputEnabled; bool m_monitorActivityEnabled; bool m_monitorSilenceEnabled; }; #endif