kateprojecttreeviewcontextmenu.cpp 4.62 KB
Newer Older
1
2
/*  This file is part of the Kate project.
 *
3
 *  SPDX-FileCopyrightText: 2013 Dominik Haumann <dhaumann.org>
4
 *
5
 *  SPDX-License-Identifier: LGPL-2.0-or-later
6
7
8
 */

#include "kateprojecttreeviewcontextmenu.h"
9
#include "git/gitutils.h"
Waqar Ahmed's avatar
Waqar Ahmed committed
10
#include "kateprojectviewtree.h"
11

Christoph Cullmann's avatar
Christoph Cullmann committed
12
#include <KApplicationTrader>
Ahmad Samir's avatar
Ahmad Samir committed
13
14
#include <KIO/ApplicationLauncherJob>
#include <KIO/JobUiDelegate>
15
#include <KIO/OpenFileManagerWindowJob>
Christoph Cullmann's avatar
Christoph Cullmann committed
16
#include <KLocalizedString>
17
18
#include <KNS3/KMoreTools>
#include <KNS3/KMoreToolsMenuFactory>
19
#include <KPropertiesDialog>
Christoph Cullmann's avatar
Christoph Cullmann committed
20

21
22
#include <QApplication>
#include <QClipboard>
23
24
25
#include <QFileInfo>
#include <QIcon>
#include <QMenu>
Dominik Haumann's avatar
Dominik Haumann committed
26
#include <QMimeDatabase>
27
28
#include <QMimeType>
#include <QStandardPaths>
29

Waqar Ahmed's avatar
Waqar Ahmed committed
30
void KateProjectTreeViewContextMenu::exec(const QString &filename, const QModelIndex &index, const QPoint &pos, KateProjectViewTree *parent)
31
{
32
    /**
33
     * Create context menu
34
35
36
     */
    QMenu menu;

37
38
39
    /**
     * Copy Path
     */
40
    QAction *copyAction = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-copy")), i18n("Copy File Path"));
41

42
    /**
43
     * Handle "open with",
44
45
46
47
     * find correct mimetype to query for possible applications
     */
    QMenu *openWithMenu = menu.addMenu(i18n("Open With"));
    QMimeType mimeType = QMimeDatabase().mimeTypeForFile(filename);
Nicolas Fella's avatar
Nicolas Fella committed
48
    const KService::List offers = KApplicationTrader::queryByMimeType(mimeType.name());
49
    // For each one, insert a menu item...
50
    for (const auto &service : offers) {
51
        if (service->name() == QLatin1String("Kate")) {
52
            continue; // omit Kate
53
54
55
        }
        QAction *action = openWithMenu->addAction(QIcon::fromTheme(service->icon()), service->name());
        action->setData(service->entryPath());
56
    }
57
58
    // Perhaps disable menu, if no entries
    openWithMenu->setEnabled(!openWithMenu->isEmpty());
59

60
    /**
61
     * Open Containing folder
62
     */
63
    auto openContaingFolderAction = menu.addAction(QIcon::fromTheme(QStringLiteral("document-open-folder")), i18n("&Open Containing Folder"));
64

65
66
67
68
69
    /**
     * File Properties Dialog
     */
    auto filePropertiesAction = menu.addAction(QIcon::fromTheme(QStringLiteral("dialog-object-properties")), i18n("Properties"));

70
    QAction *fileHistory = nullptr;
71
72
73
    /**
     * Git menu
     */
Laurent Montel's avatar
Laurent Montel committed
74
    KMoreToolsMenuFactory menuFactory(QStringLiteral("kate/addons/project/git-tools"));
Gregor Mi's avatar
Gregor Mi committed
75
    QMenu gitMenu; // must live as long as the maybe filled menu items should live
76
77
78
    if (GitUtils::isGitRepo(QFileInfo(filename).absolutePath())) {
        fileHistory = menu.addAction(i18n("Show File History"));

79
        menuFactory.fillMenuFromGroupingNames(&gitMenu, {QLatin1String("git-clients-and-actions")}, QUrl::fromLocalFile(filename));
80
        menu.addSection(i18n("Git:"));
81
82
        const auto gitActions = gitMenu.actions();
        for (auto action : gitActions) {
83
            menu.addAction(action);
84
        }
85
    }
86

Ahmad Samir's avatar
Ahmad Samir committed
87
88
89
90
91
92
93
94
95
    auto handleOpenWith = [parent](QAction *action, const QString &filename) {
        KService::Ptr app = KService::serviceByDesktopPath(action->data().toString());
        // If app is null, ApplicationLauncherJob will invoke the open-with dialog
        auto *job = new KIO::ApplicationLauncherJob(app);
        job->setUrls({QUrl::fromLocalFile(filename)});
        job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, parent));
        job->start();
    };

96
97
98
99
100
    // we can ATM only handle file renames
    QAction *rename = nullptr;
    if (index.data(KateProjectItem::TypeRole).toInt() == KateProjectItem::File) {
        rename = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-rename")), i18n("&Rename"));
    }
101

102
103
104
    /**
     * run menu and handle the triggered action
     */
105
    if (QAction *const action = menu.exec(pos)) {
106
        if (action == copyAction) {
107
            QApplication::clipboard()->setText(filename);
108
        } else if (action->parentWidget() == openWithMenu) {
109
            // handle "open with"
Ahmad Samir's avatar
Ahmad Samir committed
110
            handleOpenWith(action, filename);
111
112
113
        } else if (action == openContaingFolderAction) {
            KIO::highlightInFileManager({QUrl::fromLocalFile(filename)});
        } else if (action == filePropertiesAction) {
114
115
            // code copied and adapted from frameworks/kio/src/filewidgets/knewfilemenu.cpp
            KFileItem fileItem(QUrl::fromLocalFile(filename));
116
            QDialog *dlg = new KPropertiesDialog(fileItem);
117
118
            dlg->setAttribute(Qt::WA_DeleteOnClose);
            dlg->show();
119
        } else if (rename && action == rename) {
Waqar Ahmed's avatar
Waqar Ahmed committed
120
            parent->edit(index);
121
        } else if (action == fileHistory) {
122
            showFileHistory(index.data(Qt::UserRole).toString());
123
        } else {
124
125
            // One of the git actions was triggered
        }
126
127
    }
}