File indexing completed on 2024-05-19 05:54:12

0001 // This file was part of the KDE libraries
0002 // SPDX-FileCopyrightText: 2022 Tao Guo <guotao945@gmail.com>
0003 // SPDX-License-Identifier: GPL-2.0-or-later
0004 
0005 #include "quickcommandsplugin.h"
0006 #include "konsoledebug.h"
0007 #include "quickcommandsmodel.h"
0008 #include "quickcommandswidget.h"
0009 
0010 #include <KActionCollection>
0011 #include <KCommandBar>
0012 #include <QMainWindow>
0013 #include <QSettings>
0014 
0015 #include "MainWindow.h"
0016 #include <KLocalizedString>
0017 #include <KMessageBox>
0018 
0019 #include <QDockWidget>
0020 #include <kcommandbar.h>
0021 
0022 K_PLUGIN_CLASS_WITH_JSON(QuickCommandsPlugin, "konsole_quickcommands.json")
0023 
0024 struct QuickCommandsPlugin::Private {
0025     QuickCommandsModel model;
0026     QAction *showQuickAccess = nullptr;
0027     QMap<Konsole::MainWindow *, QuickCommandsWidget *> widgetForWindow;
0028     QMap<Konsole::MainWindow *, QDockWidget *> dockForWindow;
0029 };
0030 
0031 QuickCommandsPlugin::QuickCommandsPlugin(QObject *object, const QVariantList &args)
0032     : Konsole::IKonsolePlugin(object, args)
0033     , priv(std::make_unique<Private>())
0034 {
0035     priv->showQuickAccess = new QAction();
0036     setName(QStringLiteral("QuickCommands"));
0037 }
0038 
0039 QuickCommandsPlugin::~QuickCommandsPlugin() = default;
0040 
0041 void QuickCommandsPlugin::createWidgetsForMainWindow(Konsole::MainWindow *mainWindow)
0042 {
0043     auto *qcDockWidget = new QDockWidget(mainWindow);
0044     auto *qcWidget = new QuickCommandsWidget(mainWindow);
0045     qcWidget->setModel(&priv->model);
0046     qcDockWidget->setWindowTitle(i18n("Quick Commands"));
0047     qcDockWidget->setWidget(qcWidget);
0048     qcDockWidget->setObjectName(QStringLiteral("QuickCommandsDock"));
0049     qcDockWidget->setVisible(false);
0050     qcDockWidget->setAllowedAreas(Qt::DockWidgetArea::LeftDockWidgetArea | Qt::DockWidgetArea::RightDockWidgetArea);
0051 
0052     mainWindow->addDockWidget(Qt::LeftDockWidgetArea, qcDockWidget);
0053     connect(qcWidget, &QuickCommandsWidget::quickAccessShortcutChanged, this, [this, mainWindow](QKeySequence s) {
0054         mainWindow->actionCollection()->setDefaultShortcut(priv->showQuickAccess, s);
0055 
0056         QString sequenceText = s.toString();
0057         QSettings settings;
0058         settings.beginGroup(QStringLiteral("plugins"));
0059         settings.beginGroup(QStringLiteral("quickcommands"));
0060         settings.setValue(QStringLiteral("shortcut"), sequenceText);
0061         settings.sync();
0062     });
0063 
0064     priv->widgetForWindow[mainWindow] = qcWidget;
0065     priv->dockForWindow[mainWindow] = qcDockWidget;
0066 }
0067 
0068 void QuickCommandsPlugin::activeViewChanged(Konsole::SessionController *controller, Konsole::MainWindow *mainWindow)
0069 {
0070     priv->showQuickAccess->deleteLater();
0071     priv->showQuickAccess = new QAction(i18n("Show Quick Access"));
0072 
0073     QSettings settings;
0074     settings.beginGroup(QStringLiteral("plugins"));
0075     settings.beginGroup(QStringLiteral("quickcommands"));
0076 
0077     const QKeySequence def(Qt::CTRL | Qt::ALT | Qt::Key_G);
0078     const QString defText = def.toString();
0079     const QString entry = settings.value(QStringLiteral("shortcut"), defText).toString();
0080     const QKeySequence shortcutEntry(entry);
0081 
0082     mainWindow->actionCollection()->setDefaultShortcut(priv->showQuickAccess, shortcutEntry);
0083 
0084     controller->view()->addAction(priv->showQuickAccess);
0085 
0086     Konsole::TerminalDisplay *terminalDisplay = controller->view();
0087     connect(priv->showQuickAccess, &QAction::triggered, this, [this, terminalDisplay, controller] {
0088         auto bar = new KCommandBar(terminalDisplay->topLevelWidget());
0089         QList<QAction *> actions;
0090         for (int i = 0; i < priv->model.rowCount(); i++) {
0091             QModelIndex folder = priv->model.index(i, 0);
0092             for (int e = 0; e < priv->model.rowCount(folder); e++) {
0093                 QModelIndex idx = priv->model.index(e, 0, folder);
0094                 QAction *act = new QAction(idx.data().toString());
0095                 connect(act, &QAction::triggered, this, [this, idx, controller] {
0096                     const auto item = priv->model.itemFromIndex(idx);
0097                     const auto data = item->data(QuickCommandsModel::QuickCommandRole).value<QuickCommandData>();
0098                     controller->session()->sendTextToTerminal(data.command, QLatin1Char('\r'));
0099                 });
0100                 actions.append(act);
0101             }
0102         }
0103 
0104         if (actions.isEmpty()) // no quick commands found, must give feedback to the user about that
0105         {
0106             const QString feedbackMessage = i18n("No quick commands found. You can add one on Plugins -> Quick Commands");
0107             const QString feedbackTitle = i18n("Plugins - Quick Commands");
0108             KMessageBox::error(terminalDisplay->topLevelWidget(), feedbackMessage, feedbackTitle);
0109             return;
0110         }
0111 
0112         QVector<KCommandBar::ActionGroup> groups;
0113         groups.push_back(KCommandBar::ActionGroup{i18n("Quick Commands"), actions});
0114         bar->setActions(groups);
0115         bar->show();
0116     });
0117 
0118     if (mainWindow) {
0119         priv->widgetForWindow[mainWindow]->setCurrentController(controller);
0120     }
0121 }
0122 
0123 QList<QAction *> QuickCommandsPlugin::menuBarActions(Konsole::MainWindow *mainWindow) const
0124 {
0125     QAction *toggleVisibilityAction = new QAction(i18n("Show Quick Commands"), mainWindow);
0126     toggleVisibilityAction->setCheckable(true);
0127     mainWindow->actionCollection()->setDefaultShortcut(toggleVisibilityAction, QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_F1));
0128     connect(toggleVisibilityAction, &QAction::triggered, priv->dockForWindow[mainWindow], &QDockWidget::setVisible);
0129     connect(priv->dockForWindow[mainWindow], &QDockWidget::visibilityChanged, toggleVisibilityAction, &QAction::setChecked);
0130 
0131     return {toggleVisibilityAction};
0132 }
0133 
0134 #include "moc_quickcommandsplugin.cpp"
0135 #include "quickcommandsplugin.moc"