1 /*  This file was part of the KDE libraries
2 
3     SPDX-FileCopyrightText: 2021 Tomaz Canabrava <tcanabrava@kde.org>
4 
5     SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #include "sshmanagerplugin.h"
9 
10 #include "sshmanagermodel.h"
11 #include "sshmanagerpluginwidget.h"
12 
13 #include "konsoledebug.h"
14 #include "session/SessionController.h"
15 
16 #include <QDockWidget>
17 #include <QListView>
18 #include <QMainWindow>
19 #include <QMenuBar>
20 #include <QTimer>
21 
22 #include <KActionCollection>
23 #include <KLocalizedString>
24 
25 #include "MainWindow.h"
26 
27 K_PLUGIN_CLASS_WITH_JSON(SSHManagerPlugin, "konsole_sshmanager.json")
28 
29 struct SSHManagerPluginPrivate {
30     SSHManagerModel model;
31 
32     QMap<Konsole::MainWindow *, SSHManagerTreeWidget *> widgetForWindow;
33     QMap<Konsole::MainWindow *, QDockWidget *> dockForWindow;
34 };
35 
SSHManagerPlugin(QObject * object,const QVariantList & args)36 SSHManagerPlugin::SSHManagerPlugin(QObject *object, const QVariantList &args)
37     : Konsole::IKonsolePlugin(object, args)
38     , d(std::make_unique<SSHManagerPluginPrivate>())
39 {
40     setName(QStringLiteral("SshManager"));
41 }
42 
43 SSHManagerPlugin::~SSHManagerPlugin() = default;
44 
createWidgetsForMainWindow(Konsole::MainWindow * mainWindow)45 void SSHManagerPlugin::createWidgetsForMainWindow(Konsole::MainWindow *mainWindow)
46 {
47     auto *sshDockWidget = new QDockWidget(mainWindow);
48     auto *managerWidget = new SSHManagerTreeWidget();
49     managerWidget->setModel(&d->model);
50     sshDockWidget->setWidget(managerWidget);
51     sshDockWidget->setWindowTitle(i18n("SSH Manager"));
52     sshDockWidget->setObjectName(QStringLiteral("SSHManagerDock"));
53     sshDockWidget->setVisible(false);
54 
55     mainWindow->addDockWidget(Qt::LeftDockWidgetArea, sshDockWidget);
56 
57     d->widgetForWindow[mainWindow] = managerWidget;
58     d->dockForWindow[mainWindow] = sshDockWidget;
59 
60     connect(managerWidget, &SSHManagerTreeWidget::requestNewTab, this, [mainWindow] {
61         mainWindow->newTab();
62     });
63 }
64 
menuBarActions(Konsole::MainWindow * mainWindow) const65 QList<QAction *> SSHManagerPlugin::menuBarActions(Konsole::MainWindow *mainWindow) const
66 {
67     Q_UNUSED(mainWindow);
68 
69     QAction *toggleVisibilityAction = new QAction(i18n("Show SSH Manager"), mainWindow);
70     toggleVisibilityAction->setCheckable(true);
71 
72     connect(toggleVisibilityAction, &QAction::triggered, d->dockForWindow[mainWindow], &QDockWidget::setVisible);
73     connect(d->dockForWindow[mainWindow], &QDockWidget::visibilityChanged, toggleVisibilityAction, &QAction::setChecked);
74 
75     return {toggleVisibilityAction};
76 }
77 
activeViewChanged(Konsole::SessionController * controller)78 void SSHManagerPlugin::activeViewChanged(Konsole::SessionController *controller)
79 {
80     activeViewChangedInternal(QPointer(controller));
81 }
82 
activeViewChangedInternal(QPointer<Konsole::SessionController> controller)83 void SSHManagerPlugin::activeViewChangedInternal(QPointer<Konsole::SessionController> controller)
84 {
85     if (!controller) {
86         qCWarning(KonsoleDebug) << "Active view changed, but no controller";
87         return;
88     }
89 
90     if (!controller->view()) {
91         qCWarning(KonsoleDebug) << controller << "does not have a view";
92         return;
93     }
94 
95     auto mainWindow = qobject_cast<Konsole::MainWindow *>(controller->view()->topLevelWidget());
96 
97     // HACK: if we don't get a mainwindow here this *might* be just opening, call it again
98     // later on.
99     // We really shouldn't use an arbitrary time delay, and we need to use a
100     // QPointer in case it gets deleted while the timer is running.
101     if (!mainWindow) {
102         QTimer::singleShot(500, this, [this, controller] {
103             activeViewChangedInternal(controller);
104         });
105         return;
106     }
107 
108     d->widgetForWindow[mainWindow]->setCurrentController(controller);
109 }
110 
111 #include "sshmanagerplugin.moc"
112