From cd2330c4fca46b8395eac0ad06f4ffce434ec156 Mon Sep 17 00:00:00 2001 From: Theodore Wang Date: Sun, 3 Dec 2023 23:37:18 +0800 Subject: [PATCH] Implemented DBus methods for copying input to other sessions Implemented methods which allow input to be copied to no other session and to all sessions. In addition, users can also select exactly which sessions to copy input to by passing a list of Session ids. Calling supporting method copyingSessions() on a session lists other sessions which are copying input from it. Calling supporting method feederSessions() on a session lists other sessions it is copying input from. BUG: 307089 --- src/session/Session.cpp | 83 +++++++++++++++++++++++++++++++ src/session/Session.h | 31 ++++++++++++ src/session/SessionController.cpp | 42 ++++++++++------ src/session/SessionController.h | 16 ++++-- 4 files changed, 155 insertions(+), 17 deletions(-) diff --git a/src/session/Session.cpp b/src/session/Session.cpp index 554c4a153..d8d254f76 100644 --- a/src/session/Session.cpp +++ b/src/session/Session.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #ifndef Q_OS_WIN #include @@ -46,6 +47,7 @@ #include "Pty.h" #include "SSHProcessInfo.h" #include "SessionController.h" +#include "SessionGroup.h" #include "SessionManager.h" #include "ShellCommand.h" #include "Vt102Emulation.h" @@ -1807,6 +1809,79 @@ void Session::setProfile(const QString &profileName) } } +bool Session::copyInputToAllSessions() +{ + if (auto c = controller()) { + c->copyInputActions()->setCurrentItem(SessionController::CopyInputToAllTabsMode); + c->copyInputToAllTabs(); + return true; + } + + return false; +} + +bool Session::copyInputToSessions(QList sessionIds) +{ + if (auto c = controller()) { + auto sessions = new QList(); + c->copyInputActions()->setCurrentItem(SessionController::CopyInputToSelectedTabsMode); + + for (auto sessionId : sessionIds) { + if (auto session = SessionManager::instance()->idToSession(sessionId)) + sessions->append(session); + else + return false; + } + + c->copyInputToSelectedTabs(sessions); + return true; + } + + return false; +} + +bool Session::copyInputToNone() +{ + if (auto c = controller()) { + c->copyInputActions()->setCurrentItem(SessionController::CopyInputToNoneMode); + c->copyInputToNone(); + return true; + } else + return false; +} + +QList Session::copyingSessions() +{ + if (auto c = controller()) { + if (auto copyToGroup = c->copyToGroup()) { + QList sessionIds; + + for (auto session : copyToGroup->sessions()) { + sessionIds.append(session->sessionId()); + } + + sessionIds.removeAll(sessionId()); + return sessionIds; + } + } + + return QList(); +} + +QList Session::feederSessions() +{ + QList feeders; + + for (auto session : SessionManager::instance()->sessions()) { + if (session->copyingSessions().contains(sessionId()) && !feeders.contains(session->sessionId())) { + feeders.append(session->sessionId()); + } + } + + feeders.removeAll(sessionId()); + return feeders; +} + int Session::foregroundProcessId() { int pid; @@ -1994,4 +2069,12 @@ QColor Session::color() const return _tabColor; } +SessionController *Session::controller() +{ + if (!_views.isEmpty()) + return _views.first()->sessionController(); + + return nullptr; +} + #include "moc_Session.cpp" diff --git a/src/session/Session.h b/src/session/Session.h index 03ab5a650..97031d9ee 100644 --- a/src/session/Session.h +++ b/src/session/Session.h @@ -38,6 +38,7 @@ class ProcessInfo; class TerminalDisplay; class ZModemDialog; class HistoryType; +class SessionController; /** * Represents a terminal session consisting of a pseudo-teletype and a terminal emulation. @@ -661,6 +662,35 @@ public Q_SLOTS: */ Q_SCRIPTABLE QString profile(); + /** + * Sets that input should be copied to all sessions in current window. + * Returns false if fail. + */ + Q_SCRIPTABLE bool copyInputToAllSessions(); + + /** + * Sets that input should be copied to sessions whose ids are described in the list. + * Returns false if fail. + */ + Q_SCRIPTABLE bool copyInputToSessions(QList sessions); + + /** + * Sets that input should not be copied to any other sessions. + * Returns false if fail. + */ + Q_SCRIPTABLE bool copyInputToNone(); + + /** + * Returns a list of ids of sessions which copy inputs from this session. + * Returns empty list if fail. + */ + Q_SCRIPTABLE QList copyingSessions(); + + /** + * Returns a list of ids of sessions which this sessions copies inputs from. + */ + Q_SCRIPTABLE QList feederSessions(); + Q_SIGNALS: /** Emitted when the terminal process starts. */ @@ -819,6 +849,7 @@ private: void updateSessionProcessInfo(); bool updateForegroundProcessInfo(); void updateWorkingDirectory(); + SessionController *controller(); QString validDirectory(const QString &dir) const; diff --git a/src/session/SessionController.cpp b/src/session/SessionController.cpp index 5c8ee2b2e..87be6fa2f 100644 --- a/src/session/SessionController.cpp +++ b/src/session/SessionController.cpp @@ -850,6 +850,7 @@ void SessionController::setupExtraActions() copyInputActions->addAction(copyInputToSelectedTabsAction); copyInputActions->addAction(copyInputToNoneAction); connect(copyInputActions, &KSelectAction::actionTriggered, this, &Konsole::SessionController::copyInputActionsTriggered); + _copyInputActions = copyInputActions; action = collection->addAction(QStringLiteral("zmodem-upload"), this, &SessionController::zmodemUpload); action->setText(i18n("&ZModem Upload...")); @@ -1314,7 +1315,7 @@ void SessionController::copyInputToAllTabs() Q_EMIT copyInputChanged(this); } -void SessionController::copyInputToSelectedTabs() +void SessionController::copyInputToSelectedTabs(QList *sessions) { if (_copyToGroup == nullptr) { _copyToGroup = new SessionGroup(this); @@ -1323,22 +1324,12 @@ void SessionController::copyInputToSelectedTabs() _copyToGroup->setMasterMode(SessionGroup::CopyInputToAll); } - auto *dialog = new CopyInputDialog(view()); - dialog->setAttribute(Qt::WA_DeleteOnClose); - dialog->setModal(true); - dialog->setMasterSession(session()); - const QList sessionsList = _copyToGroup->sessions(); QSet currentGroup(sessionsList.begin(), sessionsList.end()); currentGroup.remove(session()); - dialog->setChosenSessions(currentGroup); - - connect(dialog, &QDialog::accepted, this, [=]() { - QSet newGroup = dialog->chosenSessions(); - newGroup.remove(session()); - + auto update = [this](QSet newGroup, QSet currentGroup) { const QSet completeGroup = newGroup | currentGroup; for (Session *session : completeGroup) { if (newGroup.contains(session) && !currentGroup.contains(session)) { @@ -1352,9 +1343,27 @@ void SessionController::copyInputToSelectedTabs() _copyToGroup->setMasterMode(SessionGroup::CopyInputToAll); snapshot(); Q_EMIT copyInputChanged(this); - }); + }; - dialog->show(); + if (sessions != nullptr) { + QSet newGroup(sessions->begin(), sessions->end()); + newGroup.remove(session()); + update(newGroup, currentGroup); + } else { + auto *dialog = new CopyInputDialog(view()); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setModal(true); + dialog->setMasterSession(session()); + dialog->setChosenSessions(currentGroup); + + connect(dialog, &QDialog::accepted, this, [=]() { + QSet newGroup = dialog->chosenSessions(); + newGroup.remove(session()); + update(newGroup, currentGroup); + }); + + dialog->show(); + } } void SessionController::copyInputToNone() @@ -2131,4 +2140,9 @@ void SessionController::setVisible(QString name, bool visible) actionCollection()->action(name)->setVisible(visible); } +KSelectAction *SessionController::copyInputActions() +{ + return _copyInputActions; +} + #include "moc_SessionController.cpp" diff --git a/src/session/SessionController.h b/src/session/SessionController.h index 9924fdbd1..4857dd48c 100644 --- a/src/session/SessionController.h +++ b/src/session/SessionController.h @@ -35,6 +35,7 @@ class QUrl; class KCodecAction; class QAction; class KActionMenu; +class KSelectAction; namespace Konsole { @@ -157,6 +158,13 @@ public: return _monitorOnce; }; + const SessionGroup *copyToGroup() const + { + return _copyToGroup; + } + + KSelectAction *copyInputActions(); + Q_SIGNALS: /** * Emitted when the view associated with the controller is focused. @@ -240,6 +248,10 @@ public Q_SLOTS: /** Close the incremental search */ void searchClosed(); // called when the user clicks on the + void copyInputToAllTabs(); + void copyInputToSelectedTabs(QList *sessions = nullptr); + void copyInputToNone(); + private Q_SLOTS: // menu item handlers void openBrowser(); @@ -253,9 +265,6 @@ private Q_SLOTS: void selectLine(); void pasteFromX11Selection(); // shortcut only void copyInputActionsTriggered(QAction *action); - void copyInputToAllTabs(); - void copyInputToSelectedTabs(); - void copyInputToNone(); void editCurrentProfile(); void changeCodec(QTextCodec *codec); void enableSearchBar(bool showSearchBar); @@ -360,6 +369,7 @@ private: ColorFilter *_colorFilter; QAction *_copyInputToAllTabsAction; + KSelectAction *_copyInputActions; QAction *_findAction; QAction *_findNextAction;