1/* This file is part of the Kate project.
2 *
3 * Copyright (C) 2013 Dominik Haumann <dhaumann.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#include "kateprojecttreeviewcontextmenu.h"
22
23#include <KMimeType>
24#include <KMimeTypeTrader>
25#include <KStandardDirs>
26#include <QMenu>
27#include <QFileInfo>
28#include <QDir>
29#include <KRun>
30#include <KIcon>
31#include <QProcess>
32#include <QApplication>
33#include <QClipboard>
34
35KateProjectTreeViewContextMenu::KateProjectTreeViewContextMenu ()
36{
37}
38
39KateProjectTreeViewContextMenu::~KateProjectTreeViewContextMenu ()
40{
41}
42
43static bool isGit(const QString& filename)
44{
45 QFileInfo fi(filename);
46 QDir dir (fi.absoluteDir());
47 QProcess git;
48 git.setWorkingDirectory (dir.absolutePath());
49 QStringList args;
50 args << "ls-files" << fi.fileName();
51 git.start("git", args);
52 bool isGit = false;
53 if (git.waitForStarted() && git.waitForFinished()) {
54 QStringList files = QString::fromLocal8Bit (git.readAllStandardOutput ()).split (QRegExp("[\n\r]"), QString::SkipEmptyParts);
55 isGit = files.contains(fi.fileName());
56 }
57 return isGit;
58}
59
60static bool appExists(const QString& appname)
61{
62 return !KStandardDirs::findExe(appname).isEmpty();
63}
64
65static void launchApp(const QString &app, const QString& file)
66{
67 QFileInfo fi(file);
68 QDir dir (fi.absoluteDir());
69
70 QStringList args;
71 args << file;
72
73 QProcess::startDetached(app, QStringList(), dir.absolutePath());
74}
75
76void KateProjectTreeViewContextMenu::exec(const QString& filename, const QPoint& pos, QWidget* parent)
77{
78 /**
79 * create context menu
80 */
81 QMenu menu;
82
83 QAction *copyAction=menu.addAction(KIcon("edit-copy"),i18n("Copy Filename"));
84
85 /**
86 * handle "open with"
87 * find correct mimetype to query for possible applications
88 */
89 QMenu *openWithMenu = menu.addMenu(i18n("Open With"));
90 KMimeType::Ptr mimeType = KMimeType::findByPath(filename);
91 KService::List offers = KMimeTypeTrader::self()->query(mimeType->name(), "Application");
92
93 /**
94 * for each one, insert a menu item...
95 */
96 for(KService::List::Iterator it = offers.begin(); it != offers.end(); ++it)
97 {
98 KService::Ptr service = *it;
99 if (service->name() == "Kate") continue; // omit Kate
100 QAction *action = openWithMenu->addAction(KIcon(service->icon()), service->name());
101 action->setData(service->entryPath());
102 }
103
104 /**
105 * perhaps disable menu, if no entries!
106 */
107 openWithMenu->setEnabled (!openWithMenu->isEmpty());
108
109 QList<QAction*> appActions;
110 if (isGit(filename)) {
111 QMenu* git = menu.addMenu(i18n("Git Tools"));
112 if (appExists("gitk")) {
113 QAction* action = git->addAction(i18n("Launch gitk"));
114 action->setData("gitk");
115 appActions.append(action);
116 }
117 if (appExists("qgit")) {
118 QAction* action = git->addAction(i18n("Launch qgit"));
119 action->setData("qgit");
120 appActions.append(action);
121 }
122 if (appExists("git-cola")) {
123 QAction* action = git->addAction(i18n("Launch git-cola"));
124 action->setData("git-cola");
125 appActions.append(action);
126 }
127
128 if (appActions.size() == 0) {
129 delete git;
130 }
131 }
132
133 /**
134 * run menu and handle the triggered action
135 */
136 if (QAction *action = menu.exec (pos)) {
137
138 // handle apps
139 if (copyAction == action) {
140 QApplication::clipboard()->setText(filename);
141 } else if (appActions.contains(action)) {
142 launchApp(action->data().toString(), filename);
143 } else {
144 // handle "open with"
145 const QString openWith = action->data().toString();
146 if (KService::Ptr app = KService::serviceByDesktopPath(openWith)) {
147 QList<QUrl> list;
148 list << QUrl::fromLocalFile (filename);
149 KRun::run(*app, list, parent);
150 }
151 }
152 }
153}
154
155// kate: space-indent on; indent-width 2; replace-tabs on;
156