diff --git a/addons/externaltools/kateexternaltoolsview.cpp b/addons/externaltools/kateexternaltoolsview.cpp index 4401f442c..4f5df65ff 100644 --- a/addons/externaltools/kateexternaltoolsview.cpp +++ b/addons/externaltools/kateexternaltoolsview.cpp @@ -1,271 +1,275 @@ /* This file is part of the KDE project * * Copyright 2019 Dominik Haumann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kateexternaltoolsview.h" #include "externaltoolsplugin.h" #include "kateexternaltool.h" #include "ui_toolview.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // BEGIN KateExternalToolsMenuAction KateExternalToolsMenuAction::KateExternalToolsMenuAction(const QString &text, KActionCollection *collection, KateExternalToolsPlugin *plugin, KTextEditor::MainWindow *mw) : KActionMenu(text, mw) , m_plugin(plugin) , m_mainwindow(mw) , m_actionCollection(collection) { reload(); // track active view to adapt enabled tool actions connect(mw, &KTextEditor::MainWindow::viewChanged, this, &KateExternalToolsMenuAction::slotViewChanged); } KateExternalToolsMenuAction::~KateExternalToolsMenuAction() = default; void KateExternalToolsMenuAction::reload() { // clear action collection bool needs_readd = (m_actionCollection->takeAction(this) != nullptr); m_actionCollection->clear(); if (needs_readd) m_actionCollection->addAction(QStringLiteral("tools_external"), this); menu()->clear(); // create tool actions std::map categories; std::vector uncategorizedActions; // first add categorized actions, such that the submenus appear at the top for (auto tool : m_plugin->tools()) { if (tool->hasexec) { auto a = new QAction(tool->translatedName(), this); a->setIcon(QIcon::fromTheme(tool->icon)); a->setData(QVariant::fromValue(tool)); connect(a, &QAction::triggered, [this, a]() { m_plugin->runTool(*a->data().value(), m_mainwindow->activeView()); }); m_actionCollection->addAction(tool->actionName, a); if (!tool->category.isEmpty()) { auto categoryMenu = categories[tool->category]; if (!categoryMenu) { categoryMenu = new KActionMenu(tool->translatedCategory(), this); categories[tool->category] = categoryMenu; addAction(categoryMenu); } categoryMenu->addAction(a); } else { uncategorizedActions.push_back(a); } } } // now add uncategorized actions below for (auto uncategorizedAction : uncategorizedActions) { addAction(uncategorizedAction); } addSeparator(); auto cfgAction = new QAction(i18n("Configure..."), this); addAction(cfgAction); connect(cfgAction, &QAction::triggered, this, &KateExternalToolsMenuAction::showConfigPage, Qt::QueuedConnection); // load shortcuts KSharedConfig::Ptr pConfig = KSharedConfig::openConfig(QStringLiteral("externaltools"), KConfig::NoGlobals, QStandardPaths::ApplicationsLocation); KConfigGroup config(pConfig, "Global"); config = KConfigGroup(pConfig, "Shortcuts"); m_actionCollection->readSettings(&config); slotViewChanged(m_mainwindow->activeView()); } void KateExternalToolsMenuAction::slotViewChanged(KTextEditor::View *view) { // no active view, oh oh if (!view) { return; } // try to enable/disable to match current mime type const QString mimeType = view->document()->mimeType(); const auto actions = m_actionCollection->actions(); for (QAction *action : actions) { if (action && action->data().value()) { auto tool = action->data().value(); action->setEnabled(tool->matchesMimetype(mimeType)); } } } void KateExternalToolsMenuAction::showConfigPage() { m_mainwindow->showPluginConfigPage(m_plugin, 0); } // END KateExternalToolsMenuAction // BEGIN KateExternalToolsPluginView KateExternalToolsPluginView::KateExternalToolsPluginView(KTextEditor::MainWindow *mainWindow, KateExternalToolsPlugin *plugin) : QObject(mainWindow) , m_plugin(plugin) , m_mainWindow(mainWindow) , m_outputDoc(new QTextDocument(this)) , m_statusDoc(new QTextDocument(this)) { m_plugin->registerPluginView(this); KXMLGUIClient::setComponentName(QLatin1String("externaltools"), i18n("External Tools")); setXMLFile(QLatin1String("ui.rc")); if (KAuthorized::authorizeAction(QStringLiteral("shell_access"))) { m_externalToolsMenu = new KateExternalToolsMenuAction(i18n("External Tools"), actionCollection(), plugin, mainWindow); actionCollection()->addAction(QStringLiteral("tools_external"), m_externalToolsMenu); m_externalToolsMenu->setWhatsThis(i18n("Launch external helper applications")); } mainWindow->guiFactory()->addClient(this); // ESC should close & hide ToolView - connect(m_mainWindow, &KTextEditor::MainWindow::unhandledShortcutOverride, [this](QEvent *event) { - auto keyEvent = static_cast(event); - if (keyEvent->key() == Qt::Key_Escape && keyEvent->modifiers() == Qt::NoModifier) { - deleteToolView(); - } - }); + connect(m_mainWindow, &KTextEditor::MainWindow::unhandledShortcutOverride, this, &KateExternalToolsPluginView::handleEsc); } KateExternalToolsPluginView::~KateExternalToolsPluginView() { m_plugin->unregisterPluginView(this); m_mainWindow->guiFactory()->removeClient(this); deleteToolView(); delete m_externalToolsMenu; m_externalToolsMenu = nullptr; } void KateExternalToolsPluginView::rebuildMenu() { if (m_externalToolsMenu) { KXMLGUIFactory *f = factory(); f->removeClient(this); reloadXML(); m_externalToolsMenu->reload(); f->addClient(this); } } KTextEditor::MainWindow *KateExternalToolsPluginView::mainWindow() const { return m_mainWindow; } void KateExternalToolsPluginView::createToolView() { if (!m_toolView) { m_toolView = mainWindow()->createToolView(m_plugin, QStringLiteral("ktexteditor_plugin_externaltools"), KTextEditor::MainWindow::Bottom, QIcon::fromTheme(QStringLiteral("system-run")), i18n("External Tools")); m_ui = new Ui::ToolView(); m_ui->setupUi(m_toolView); // set the documents m_ui->teOutput->setDocument(m_outputDoc); m_ui->teStatus->setDocument(m_statusDoc); // use fixed font for displaying status and output text const auto fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); m_ui->teOutput->setFont(fixedFont); m_ui->teStatus->setFont(fixedFont); // close button to delete tool view auto btnClose = new QToolButton(); btnClose->setAutoRaise(true); btnClose->setIcon(QIcon::fromTheme(QStringLiteral("tab-close"))); connect(btnClose, &QToolButton::clicked, this, &KateExternalToolsPluginView::deleteToolView); m_ui->tabWidget->setCornerWidget(btnClose); } } void KateExternalToolsPluginView::showToolView(ToolViewFocus tab) { createToolView(); if (tab == ToolViewFocus::OutputTab) { m_ui->tabWidget->setCurrentWidget(m_ui->tabOutput); } else { m_ui->tabWidget->setCurrentWidget(m_ui->tabStatus); } mainWindow()->showToolView(m_toolView); } void KateExternalToolsPluginView::clearToolView() { m_outputDoc->clear(); m_statusDoc->clear(); } void KateExternalToolsPluginView::addToolStatus(const QString &message) { QTextCursor cursor(m_statusDoc); cursor.movePosition(QTextCursor::End); cursor.insertText(message); cursor.insertText(QStringLiteral("\n")); } void KateExternalToolsPluginView::setOutputData(const QString &data) { QTextCursor cursor(m_outputDoc); cursor.movePosition(QTextCursor::End); cursor.insertText(data); } void KateExternalToolsPluginView::deleteToolView() { if (m_toolView) { delete m_ui; m_ui = nullptr; delete m_toolView; m_toolView = nullptr; } } + +void KateExternalToolsPluginView::handleEsc(QEvent *event) +{ + auto keyEvent = dynamic_cast(event); + if (keyEvent && keyEvent->key() == Qt::Key_Escape && keyEvent->modifiers() == Qt::NoModifier) { + deleteToolView(); + } +} + // END KateExternalToolsPluginView // kate: space-indent on; indent-width 4; replace-tabs on; diff --git a/addons/externaltools/kateexternaltoolsview.h b/addons/externaltools/kateexternaltoolsview.h index b0f787373..9d6e49d3b 100644 --- a/addons/externaltools/kateexternaltoolsview.h +++ b/addons/externaltools/kateexternaltoolsview.h @@ -1,157 +1,162 @@ /* This file is part of the KDE project * * Copyright 2019 Dominik Haumann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KTEXTEDITOR_EXTERNALTOOLS_H #define KTEXTEDITOR_EXTERNALTOOLS_H namespace KTextEditor { class MainWindow; } namespace KTextEditor { class View; } #include #include #include class QTextDocument; class KActionCollection; class KateExternalToolsPlugin; class KateExternalTool; namespace Ui { class ToolView; } enum class ToolViewFocus { OutputTab = 0, StatusTab }; /** * Menu action that displays all KateExternalTool in a submenu. * Enables/disables the tool actions whenever the view changes, depending on the mimetype. */ class KateExternalToolsMenuAction : public KActionMenu { Q_OBJECT public: KateExternalToolsMenuAction(const QString &text, KActionCollection *collection, KateExternalToolsPlugin *plugin, class KTextEditor::MainWindow *mw = nullptr); virtual ~KateExternalToolsMenuAction(); /** * This will load all the configured services. */ void reload(); KActionCollection *actionCollection() const { return m_actionCollection; } private Q_SLOTS: /** * Called whenever the current view changed. * Required to enable/disable the tools that depend on specific mimetypes. */ void slotViewChanged(KTextEditor::View *view); /** * Triggered via Tools > External Tools > Configure... */ void showConfigPage(); private: KateExternalToolsPlugin *m_plugin; KTextEditor::MainWindow *m_mainwindow; // for the actions to access view/doc managers KActionCollection *m_actionCollection; }; class KateExternalToolsPluginView : public QObject, public KXMLGUIClient { Q_OBJECT public: /** * Constructor. */ KateExternalToolsPluginView(KTextEditor::MainWindow *mainWindow, KateExternalToolsPlugin *plugin); /** * Virtual destructor. */ ~KateExternalToolsPluginView(); /** * Returns the associated mainWindow */ KTextEditor::MainWindow *mainWindow() const; public Q_SLOTS: /** * Called by the plugin view to reload the menu */ void rebuildMenu(); /** * Creates the tool view. If already existing, does nothing. */ void createToolView(); /** * Shows the tool view. The toolview will be created, if not yet existing. */ void showToolView(ToolViewFocus tab); /** * Clears the toolview data. If no toolview is around, nothing happens. */ void clearToolView(); /** * Shows the External Tools toolview and points the error message along with * some more info about the tool. */ void addToolStatus(const QString &message); /** * Sets the output data to data; */ void setOutputData(const QString &data); /** * Deletes the tool view, if existing. */ void deleteToolView(); + /** + * On Escape, hide tool view. + */ + void handleEsc(QEvent *event); + private: KateExternalToolsPlugin *m_plugin; KTextEditor::MainWindow *m_mainWindow; KateExternalToolsMenuAction *m_externalToolsMenu = nullptr; QWidget *m_toolView = nullptr; Ui::ToolView *m_ui = nullptr; QTextDocument *m_outputDoc = nullptr; QTextDocument *m_statusDoc = nullptr; }; #endif // KTEXTEDITOR_EXTERNALTOOLS_H // kate: space-indent on; indent-width 4; replace-tabs on;