diff --git a/src/Part.cpp b/src/Part.cpp index d3ea1e5e..1ee505ca 100644 --- a/src/Part.cpp +++ b/src/Part.cpp @@ -1,389 +1,394 @@ /* Copyright 2007-2008 by Robert Knight 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 "Part.h" // Qt #include #include #include #include // KDE #include #include #include #include #include // Konsole #include "EditProfileDialog.h" #include "Emulation.h" #include "Session.h" #include "SessionController.h" #include "SessionManager.h" #include "ProfileManager.h" #include "TerminalDisplay.h" #include "ViewManager.h" #include "KonsoleSettings.h" #include "settings/PartInfo.h" #include "settings/ProfileSettings.h" using namespace Konsole; K_PLUGIN_FACTORY_WITH_JSON(KonsolePartFactory, "konsolepart.json", registerPlugin();) Part::Part(QWidget *parentWidget, QObject *parent, const QVariantList &) : KParts::ReadOnlyPart(parent), _viewManager(nullptr), _pluggedController(nullptr) { // create view widget _viewManager = new ViewManager(this, actionCollection()); _viewManager->setNavigationMethod(ViewManager::NoNavigation); connect(_viewManager, &Konsole::ViewManager::activeViewChanged, this, &Konsole::Part::activeViewChanged); connect(_viewManager, &Konsole::ViewManager::empty, this, &Konsole::Part::terminalExited); connect(_viewManager, static_cast(&Konsole::ViewManager::newViewRequest), this, &Konsole::Part::newTab); _viewManager->widget()->setParent(parentWidget); setWidget(_viewManager->widget()); actionCollection()->addAssociatedWidget(_viewManager->widget()); foreach (QAction *action, actionCollection()->actions()) { action->setShortcutContext(Qt::WidgetWithChildrenShortcut); } // Enable translucency support. _viewManager->widget()->setAttribute(Qt::WA_TranslucentBackground, true); // create basic session createSession(); } Part::~Part() { ProfileManager::instance()->saveSettings(); delete _viewManager; } bool Part::openFile() { return false; } void Part::terminalExited() { deleteLater(); } void Part::newTab() { createSession(); } Session *Part::activeSession() const { if (_viewManager->activeViewController() != nullptr) { Q_ASSERT(_viewManager->activeViewController()->session()); return _viewManager->activeViewController()->session(); } else { return nullptr; } } void Part::startProgram(const QString &program, const QStringList &arguments) { Q_ASSERT(activeSession()); // do nothing if the session has already started running if (activeSession()->isRunning()) { return; } if (!program.isEmpty() && !arguments.isEmpty()) { activeSession()->setProgram(program); activeSession()->setArguments(arguments); } activeSession()->run(); } void Part::openTeletype(int ptyMasterFd) { Q_ASSERT(activeSession()); activeSession()->openTeletype(ptyMasterFd); } void Part::showShellInDir(const QString &dir) { Q_ASSERT(activeSession()); // do nothing if the session has already started running if (activeSession()->isRunning()) { return; } // All other checking is done in setInitialWorkingDirectory() if (!dir.isEmpty()) { activeSession()->setInitialWorkingDirectory(dir); } activeSession()->run(); } void Part::sendInput(const QString &text) { Q_ASSERT(activeSession()); activeSession()->sendTextToTerminal(text); } int Part::terminalProcessId() { Q_ASSERT(activeSession()); return activeSession()->processId(); } int Part::foregroundProcessId() { Q_ASSERT(activeSession()); if (activeSession()->isForegroundProcessActive()) { return activeSession()->foregroundProcessId(); } else { return -1; } } QString Part::foregroundProcessName() { Q_ASSERT(activeSession()); if (activeSession()->isForegroundProcessActive()) { return activeSession()->foregroundProcessName(); } else { return QString(); } } QString Part::currentWorkingDirectory() const { Q_ASSERT(activeSession()); return activeSession()->currentWorkingDirectory(); } void Part::createSession(const QString &profileName, const QString &directory) { Profile::Ptr profile = ProfileManager::instance()->defaultProfile(); if (!profileName.isEmpty()) { profile = ProfileManager::instance()->loadProfile(profileName); } Q_ASSERT(profile); Session *session = SessionManager::instance()->createSession(profile); // override the default directory specified in the profile if (!directory.isEmpty() && profile->startInCurrentSessionDir()) { session->setInitialWorkingDirectory(directory); } _viewManager->createView(session); } void Part::activeViewChanged(SessionController *controller) { Q_ASSERT(controller); Q_ASSERT(controller->view()); // remove existing controller if (_pluggedController != nullptr) { removeChildClient(_pluggedController); disconnect(_pluggedController, &Konsole::SessionController::titleChanged, this, &Konsole::Part::activeViewTitleChanged); disconnect(_pluggedController, &Konsole::SessionController::currentDirectoryChanged, this, &Konsole::Part::currentDirectoryChanged); } // insert new controller insertChildClient(controller); connect(controller, &Konsole::SessionController::titleChanged, this, &Konsole::Part::activeViewTitleChanged); activeViewTitleChanged(controller); connect(controller, &Konsole::SessionController::currentDirectoryChanged, this, &Konsole::Part::currentDirectoryChanged); const char *displaySignal = SIGNAL(overrideShortcutCheck(QKeyEvent*,bool&)); const char *partSlot = SLOT(overrideTerminalShortcut(QKeyEvent*,bool&)); disconnect(controller->view(), displaySignal, this, partSlot); connect(controller->view(), displaySignal, this, partSlot); // set the current session's search bar controller->setSearchBar(_viewManager->searchBar()); _pluggedController = controller; } void Part::overrideTerminalShortcut(QKeyEvent *event, bool &override) { // Shift+Insert is commonly used as the alternate shortcut for // pasting in KDE apps(including konsole), so it deserves some // special treatment. if (((event->modifiers() & Qt::ShiftModifier) != 0u) && (event->key() == Qt::Key_Insert)) { override = false; return; } // override all shortcuts in the embedded terminal by default override = true; emit overrideShortcut(event, override); } void Part::activeViewTitleChanged(ViewProperties *properties) { emit setWindowCaption(properties->title()); } void Part::showManageProfilesDialog(QWidget *parent) { // Make sure this string is unique among all users of this part if (KConfigDialog::showDialog(QStringLiteral("konsolepartmanageprofiles"))) { return; } KConfigDialog *settingsDialog = new KConfigDialog(parent, QStringLiteral("konsolepartmanageprofiles"), KonsoleSettings::self()); settingsDialog->setFaceType(KPageDialog::Tabbed); auto profileSettings = new ProfileSettings(settingsDialog); settingsDialog->addPage(profileSettings, i18nc("@title Preferences page name", "Profiles"), QStringLiteral("configure")); auto partInfoSettings = new PartInfoSettings(settingsDialog); settingsDialog->addPage(partInfoSettings, i18nc("@title Preferences page name", "Part Info"), QStringLiteral("dialog-information")); settingsDialog->show(); } void Part::showEditCurrentProfileDialog(QWidget *parent) { Q_ASSERT(activeSession()); auto dialog = new EditProfileDialog(parent); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setProfile(SessionManager::instance()->sessionProfile(activeSession())); dialog->show(); } void Part::changeSessionSettings(const QString &text) { Q_ASSERT(activeSession()); // send a profile change command, the escape code format // is the same as the normal X-Term commands used to change the window title or icon, // but with a magic value of '50' for the parameter which specifies what to change QString command = QStringLiteral("\033]50;%1\a").arg(text); sendInput(command); } // Konqueror integration bool Part::openUrl(const QUrl &url) { if (KParts::ReadOnlyPart::url() == url) { emit completed(); return true; } setUrl(url); emit setWindowCaption(url.toDisplayString(QUrl::PreferLocalFile)); ////qDebug() << "Set Window Caption to " << url.pathOrUrl(); emit started(nullptr); if (url.isLocalFile()) { showShellInDir(url.path()); } else { showShellInDir(QDir::homePath()); } emit completed(); return true; } void Part::setMonitorSilenceEnabled(bool enabled) { Q_ASSERT(activeSession()); if (enabled) { activeSession()->setMonitorSilence(true); connect(activeSession(), &Konsole::Session::stateChanged, this, &Konsole::Part::sessionStateChanged, Qt::UniqueConnection); } else { activeSession()->setMonitorSilence(false); disconnect(activeSession(), &Konsole::Session::stateChanged, this, &Konsole::Part::sessionStateChanged); } } void Part::setMonitorActivityEnabled(bool enabled) { Q_ASSERT(activeSession()); if (enabled) { activeSession()->setMonitorActivity(true); connect(activeSession(), &Konsole::Session::stateChanged, this, &Konsole::Part::sessionStateChanged, Qt::UniqueConnection); } else { activeSession()->setMonitorActivity(false); disconnect(activeSession(), &Konsole::Session::stateChanged, this, &Konsole::Part::sessionStateChanged); } } +bool Part::isBlurEnabled() +{ + return ViewManager::profileHasBlurEnabled(SessionManager::instance()->sessionProfile(activeSession())); +} + void Part::sessionStateChanged(int state) { if (state == NOTIFYSILENCE) { emit silenceDetected(); } else if (state == NOTIFYACTIVITY) { emit activityDetected(); } } #include "Part.moc" diff --git a/src/Part.h b/src/Part.h index cf7bc4ca..72945321 100644 --- a/src/Part.h +++ b/src/Part.h @@ -1,194 +1,201 @@ /* Copyright 2007-2008 by Robert Knight 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 PART_H #define PART_H // KDE #include #include #include // Qt #include // Konsole #include "Profile.h" class QAction; class QStringList; class QKeyEvent; namespace Konsole { class Session; class SessionController; class ViewManager; class ViewProperties; /** * A re-usable terminal emulator component using the KParts framework which can * be used to embed terminal emulators into other applications. */ class Part : public KParts::ReadOnlyPart, public TerminalInterface { Q_OBJECT Q_INTERFACES(TerminalInterface) public: /** Constructs a new Konsole part with the specified parent. */ explicit Part(QWidget *parentWidget, QObject *parent, const QVariantList &); ~Part() Q_DECL_OVERRIDE; /** Reimplemented from TerminalInterface. */ void startProgram(const QString &program, const QStringList &arguments) Q_DECL_OVERRIDE; /** Reimplemented from TerminalInterface. */ void showShellInDir(const QString &dir) Q_DECL_OVERRIDE; /** Reimplemented from TerminalInterface. */ void sendInput(const QString &text) Q_DECL_OVERRIDE; /** Reimplemented from TerminalInterface. */ int terminalProcessId() Q_DECL_OVERRIDE; /** Reimplemented from TerminalInterface. */ int foregroundProcessId() Q_DECL_OVERRIDE; /** Reimplemented from TerminalInterface. */ QString foregroundProcessName() Q_DECL_OVERRIDE; /** Reimplemented from TerminalInterface. */ QString currentWorkingDirectory() const Q_DECL_OVERRIDE; public Q_SLOTS: /** * creates and run a session using the specified profile and directory * * @param profileName Specifies the name of the profile to create session * @param directory specifies The initial working directory of the created session * * This is highly experimental. Do not use it at the moment */ void createSession(const QString &profileName = QString(), const QString &directory = QString()); void showManageProfilesDialog(QWidget* parent); /** * Shows the dialog used to edit the profile used by the active session. The * dialog will be non-modal and will delete itself when it is closed. * * This is experimental API and not guaranteed to be present in later KDE 4 * releases. * * @param parent The parent widget of the new dialog. */ void showEditCurrentProfileDialog(QWidget *parent); /** * Sends a profile change command to the active session. This is equivalent to using * the konsoleprofile tool within the session to change its settings. The @p text string * is a semi-colon separated list of property=value pairs, eg. "colors=Linux Colors" * * See the documentation for konsoleprofile for information on the format of @p text * * This is experimental API and not guaranteed to be present in later KDE 4 releases. */ void changeSessionSettings(const QString &text); /** * Connects to an existing pseudo-teletype. See Session::openTeletype(). * This must be called before the session is started by startProgram(), * or showShellInDir() * * @param ptyMasterFd The file descriptor of the pseudo-teletype (pty) master */ void openTeletype(int ptyMasterFd); /** * Toggles monitoring for silence in the active session. If silence is detected, * the silenceDetected() signal is emitted. * * @param enabled Whether to enable or disable monitoring for silence. * */ void setMonitorSilenceEnabled(bool enabled); /** * Toggles monitoring for activity in the active session. If activity is detected, * the activityDetected() signal is emitted. * * @param enabled Whether to enable or disable monitoring for activity. * */ void setMonitorActivityEnabled(bool enabled); + /** + * Returns the status of the blur of the current profile. + * + * @return True if blur is enabled for the current active Konsole color profile. + * */ + bool isBlurEnabled(); + Q_SIGNALS: /** * Emitted when the key sequence for a shortcut, which is also a valid terminal key sequence, * is pressed while the terminal has focus. By responding to this signal, the * controlling application can choose whether to execute the action associated with * the shortcut or ignore the shortcut and send the key * sequence to the terminal application. * * In the embedded terminal, shortcuts are overridden and sent to the terminal by default. * Set @p override to false to prevent this happening and allow the shortcut to be triggered * normally. * * overrideShortcut() is not called for shortcuts which are not valid terminal key sequences, * eg. shortcuts with two or more modifiers. * * @param event Describes the keys that were pressed. * @param override Set this to false to prevent the terminal display from overriding the shortcut */ void overrideShortcut(QKeyEvent *event, bool &override); /** * Emitted when silence has been detected in the active session. Monitoring * for silence has to be enabled first using setMonitorSilenceEnabled(). */ void silenceDetected(); /** * Emitted when activity has been detected in the active session. Monitoring * for activity has to be enabled first using setMonitorActivityEnabled(). */ void activityDetected(); /** * Emitted when the current working directory of the active session has changed. */ void currentDirectoryChanged(const QString &dir); protected: /** Reimplemented from KParts::PartBase. */ bool openFile() Q_DECL_OVERRIDE; bool openUrl(const QUrl &url) Q_DECL_OVERRIDE; private Q_SLOTS: void activeViewChanged(SessionController *controller); void activeViewTitleChanged(ViewProperties *properties); void terminalExited(); void newTab(); void overrideTerminalShortcut(QKeyEvent *, bool &override); void sessionStateChanged(int state); private: Session *activeSession() const; private: ViewManager *_viewManager; SessionController *_pluggedController; }; } #endif // PART_H