Commit 978533f4 authored by Mario Aichinger's avatar Mario Aichinger Committed by Christoph Cullmann
Browse files

add open-with entry to the context menu of the filebrowser

parent 0b61ede2
......@@ -22,6 +22,7 @@ target_sources(
katefilebrowserconfig.cpp
katefilebrowser.cpp
katebookmarkhandler.cpp
katefilebrowseropenwithmenu.cpp
)
kcoreaddons_desktop_to_json(katefilebrowserplugin katefilebrowserplugin.desktop)
......
......@@ -34,6 +34,19 @@
#include <QLineEdit>
#include <QStyle>
#include <QVBoxLayout>
#include <QMenu>
#include <kio_version.h>
#if KIO_VERSION < QT_VERSION_CHECK(5, 71, 0)
# include <KOpenWithDialog>
# include <KRun>
#else
# include <KIO/ApplicationLauncherJob>
# include <KIO/JobUiDelegate>
#endif
#include <KApplicationTrader>
#include "katefilebrowseropenwithmenu.h"
// END Includes
......@@ -106,6 +119,8 @@ KateFileBrowser::KateFileBrowser(KTextEditor::MainWindow *mainWindow, QWidget *p
connect(m_dirOperator, &KDirOperator::fileSelected, this, &KateFileBrowser::fileSelected);
connect(m_mainWindow, &KTextEditor::MainWindow::viewChanged, this, &KateFileBrowser::autoSyncFolder);
connect(m_dirOperator, &KDirOperator::contextMenuAboutToShow, this, &KateFileBrowser::contextMenuAboutToShow);
}
KateFileBrowser::~KateFileBrowser()
......@@ -212,6 +227,74 @@ void KateFileBrowser::setDir(const QUrl &u)
m_dirOperator->setUrl(newurl, true);
}
void KateFileBrowser::contextMenuAboutToShow(const KFileItem &item, QMenu *menu)
{
if(m_openWithMenu == nullptr) {
m_openWithMenu = new KateFileBrowserOpenWithMenu(i18nc("@action:inmenu", "Open With"), this);
menu->insertMenu(menu->actions().at(1), m_openWithMenu);
menu->insertSeparator(menu->actions().at(2));
connect(m_openWithMenu, &QMenu::aboutToShow, this, &KateFileBrowser::fixOpenWithMenu);
connect(m_openWithMenu, &QMenu::triggered, this, &KateFileBrowser::openWithMenuAction);
}
m_openWithMenu->setItem(item);
}
void KateFileBrowser::fixOpenWithMenu()
{
KateFileBrowserOpenWithMenu *menu = static_cast<KateFileBrowserOpenWithMenu *>(sender());
menu->clear();
// get a list of appropriate services.
QMimeType mime = menu->item().determineMimeType();
QAction *a = nullptr;
const KService::List offers = KApplicationTrader::queryByMimeType(mime.name());
// for each one, insert a menu item...
for (const auto &service : offers) {
if (service->name() == QLatin1String("Kate")) {
continue;
}
a = menu->addAction(QIcon::fromTheme(service->icon()), service->name());
a->setData(QVariant(QList<QString>({service->entryPath(), menu->item().url().toString()})));
}
// append "Other..." to call the KDE "open with" dialog.
a = menu->addAction(i18n("&Other..."));
a->setData(QVariant(QList<QString>({QString(), menu->item().url().toString()})));
}
void KateFileBrowser::openWithMenuAction(QAction *a)
{
const QString application = a->data().toStringList().first();
const QString fileName = a->data().toStringList().last();
const QList<QUrl> list({QUrl(fileName)});
#if KIO_VERSION < QT_VERSION_CHECK(5, 71, 0)
if (application.isEmpty()) {
// display "open with" dialog
KOpenWithDialog dlg(list);
if (dlg.exec()) {
KRun::runService(*dlg.service(), list, this);
}
return;
}
KService::Ptr app = KService::serviceByDesktopPath(application);
if (app) {
KRun::runService(*app, list, this);
} else {
KMessageBox::error(this, i18n("Application '%1' not found.", application), i18n("Application not found"));
}
#else
KService::Ptr app = KService::serviceByDesktopPath(application);
// If app is null, ApplicationLauncherJob will invoke the open-with dialog
auto *job = new KIO::ApplicationLauncherJob(app);
job->setUrls(list);
job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
job->start();
#endif
}
// END Public Slots
// BEGIN Private Slots
......
......@@ -17,6 +17,9 @@
#include <QUrl>
#include <QWidget>
#include <QMenu>
#include "katefilebrowseropenwithmenu.h"
class KateBookmarkHandler;
class KActionCollection;
......@@ -76,6 +79,10 @@ private Q_SLOTS:
void updateUrlNavigator(const QUrl &u);
void setActiveDocumentDir();
void autoSyncFolder();
void contextMenuAboutToShow(const KFileItem &item, QMenu *menu);
void fixOpenWithMenu();
void openWithMenuAction(QAction *a);
protected:
QUrl activeDocumentUrl();
......@@ -96,6 +103,7 @@ private:
KDirOperator *m_dirOperator;
KHistoryComboBox *m_filter;
QAction *m_autoSyncFolder = nullptr;
KateFileBrowserOpenWithMenu *m_openWithMenu = nullptr;
KTextEditor::MainWindow *m_mainWindow;
};
......
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2020 Mario Aichinger <aichingm@gmail.com>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
// BEGIN Includes
#include "katefilebrowseropenwithmenu.h"
// END Includes
// BEGIN KateFileBrowserOpenWithMenu
KateFileBrowserOpenWithMenu::KateFileBrowserOpenWithMenu(const QString &title, QWidget *parent) : QMenu(title, parent)
{
}
KateFileBrowserOpenWithMenu::~KateFileBrowserOpenWithMenu()
{
}
// END Constructor/Destructor
// kate: space-indent on; indent-width 2; replace-tabs on;
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2020 Mario Aichinger <aichingm@gmail.com>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef KATE_FILEBROWSEROPENWITHMENU_H
#define KATE_FILEBROWSEROPENWITHMENU_H
#include <QMenu>
#include <KFileItem>
/*
The KateFileBrowserOpenWithMenu extends a QMenu with a KFileItem property, used to
pass data of the selected file to the creation of the submenu.
*/
class KateFileBrowserOpenWithMenu : public QMenu
{
Q_OBJECT
Q_PROPERTY(KFileItem item READ item WRITE setItem)
public:
explicit KateFileBrowserOpenWithMenu(const QString &title, QWidget *parent = nullptr);
~KateFileBrowserOpenWithMenu();
void setItem(KFileItem item)
{
m_item = item;
}
KFileItem item()
{
return m_item;
}
public Q_SLOTS:
private Q_SLOTS:
protected:
private:
KFileItem m_item;
};
#endif // KATE_FILEBROWSEROPENWITHMENU_H
// kate: space-indent on; indent-width 2; replace-tabs on;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment