Changeset View
Changeset View
Standalone View
Standalone View
plugins/cgit/cgitplugin.cpp
- This file was added.
1 | /* This file is part of KDevelop | ||||
---|---|---|---|---|---|
2 | Copyright 2017 Friedrich W. H. Kossebau <kossebau@kde.org> | ||||
3 | | ||||
4 | This library is free software; you can redistribute it and/or | ||||
5 | modify it under the terms of the GNU Library General Public | ||||
6 | License as published by the Free Software Foundation; either | ||||
7 | version 2 of the License, or (at your option) any later version. | ||||
8 | | ||||
9 | This library is distributed in the hope that it will be useful, | ||||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
12 | Library General Public License for more details. | ||||
13 | | ||||
14 | You should have received a copy of the GNU Library General Public License | ||||
15 | along with this library; see the file COPYING.LIB. If not, write to | ||||
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||
17 | Boston, MA 02110-1301, USA. | ||||
18 | */ | ||||
19 | | ||||
20 | #include "cgitplugin.h" | ||||
21 | | ||||
22 | #include "cgithookupconfiguration.h" | ||||
23 | #include "cgithookupconfigpage.h" | ||||
24 | | ||||
25 | #include <interfaces/iproject.h> | ||||
26 | #include <util/path.h> | ||||
27 | #include <vcs/vcsrevision.h> | ||||
28 | | ||||
29 | #include <KTextEditor/Cursor> | ||||
30 | #include <KConfigGroup> | ||||
31 | #include <KPluginFactory> | ||||
32 | | ||||
33 | #include <QIcon> | ||||
34 | | ||||
35 | using namespace KDevelop; | ||||
36 | | ||||
37 | K_PLUGIN_FACTORY_WITH_JSON(CgitPluginFactory, "cgitplugin.json", registerPlugin<CgitPlugin>();) | ||||
38 | | ||||
39 | | ||||
40 | namespace { | ||||
41 | | ||||
42 | namespace Strings { | ||||
43 | inline QString cgitGroupKey() { return QStringLiteral("cgit Settings"); } | ||||
44 | inline QString nameKey() { return QStringLiteral("Name"); } | ||||
45 | inline QString baseUrlKey() { return QStringLiteral("BaseUrl"); } | ||||
46 | } | ||||
47 | | ||||
48 | } | ||||
49 | | ||||
50 | | ||||
51 | CgitPlugin::CgitPlugin(QObject *parent, const QVariantList& args) | ||||
52 | : KDevelop::IPlugin(QStringLiteral("kdevcgit"), parent) | ||||
53 | { | ||||
54 | Q_UNUSED(args); | ||||
55 | | ||||
56 | } | ||||
57 | | ||||
58 | CgitPlugin::~CgitPlugin() = default; | ||||
59 | | ||||
60 | | ||||
61 | QString CgitPlugin::projectServiceId() const | ||||
62 | { | ||||
63 | return QStringLiteral("cgit"); | ||||
64 | } | ||||
65 | | ||||
66 | QString CgitPlugin::projectServiceDisplayName() const | ||||
67 | { | ||||
68 | return QStringLiteral("cgit"); | ||||
69 | } | ||||
70 | | ||||
71 | QIcon CgitPlugin::projectServiceIcon() const | ||||
72 | { | ||||
73 | return QIcon::fromTheme(QStringLiteral("cgit")); | ||||
74 | } | ||||
75 | | ||||
76 | QList<IProjectServiceHookupConfiguration*> CgitPlugin::loadProjectServiceHookupConfigurations(IProject* project) const | ||||
77 | { | ||||
78 | QList<IProjectServiceHookupConfiguration*> result; | ||||
79 | | ||||
80 | KConfigGroup cfg(project->projectConfiguration(), Strings::cgitGroupKey()); | ||||
81 | | ||||
82 | for (const auto& groupName : cfg.groupList()) { | ||||
83 | KConfigGroup configurationGroup(&cfg, groupName); | ||||
84 | | ||||
85 | const QString name = configurationGroup.readEntry(Strings::nameKey(), QString()); | ||||
86 | auto cgitConfiguration = new CgitHookupConfiguration(groupName, name); | ||||
87 | const QUrl baseUrl = QUrl::fromUserInput(configurationGroup.readEntry(Strings::baseUrlKey(), QString())); | ||||
88 | cgitConfiguration->setBaseUrl(baseUrl); | ||||
89 | | ||||
90 | result << cgitConfiguration; | ||||
91 | } | ||||
92 | | ||||
93 | return result; | ||||
94 | } | ||||
95 | | ||||
96 | void CgitPlugin::saveProjectServiceHookupConfigurations(const QList<IProjectServiceHookupConfiguration*>& projectServiceHookupConfigurations, | ||||
97 | IProject* project) | ||||
98 | { | ||||
99 | QStringList configurationNames; | ||||
100 | for (auto configuration : projectServiceHookupConfigurations) { | ||||
101 | configurationNames.append(configuration->id()); | ||||
102 | } | ||||
103 | | ||||
104 | KConfigGroup cfg(project->projectConfiguration(), Strings::cgitGroupKey()); | ||||
105 | | ||||
106 | // clean up no longer existing configurations | ||||
107 | for (const auto& groupName : cfg.groupList()) { | ||||
108 | if (!configurationNames.contains(groupName)) { | ||||
109 | cfg.deleteGroup(groupName); | ||||
110 | } | ||||
111 | } | ||||
112 | | ||||
113 | // store current ones | ||||
114 | for (auto configuration : projectServiceHookupConfigurations) { | ||||
115 | auto cgitConfiguration = dynamic_cast<CgitHookupConfiguration*>(configuration); | ||||
116 | Q_ASSERT(cgitConfiguration); | ||||
117 | if (!cgitConfiguration) { | ||||
118 | continue; | ||||
119 | } | ||||
120 | KConfigGroup configurationGroup(&cfg, configuration->id()); | ||||
121 | configurationGroup.deleteGroup(); | ||||
122 | | ||||
123 | configurationGroup.writeEntry(Strings::nameKey(), cgitConfiguration->displayName()); | ||||
124 | configurationGroup.writeEntry(Strings::baseUrlKey(), cgitConfiguration->baseUrl().toString()); | ||||
125 | } | ||||
126 | | ||||
127 | cfg.sync(); | ||||
128 | } | ||||
129 | | ||||
130 | IProjectServiceHookupConfiguration* CgitPlugin::createProjectServiceHookupConfiguration(IProject* project) const | ||||
131 | { | ||||
132 | Q_UNUSED(project); | ||||
133 | return new CgitHookupConfiguration(projectServiceId(), projectServiceDisplayName()); | ||||
134 | } | ||||
135 | | ||||
136 | ProjectServiceHookupConfigPage* CgitPlugin::createProjectServiceHookupConfigPage(QWidget* parent) const | ||||
137 | { | ||||
138 | return new CgitHookupConfigPage(parent); | ||||
139 | } | ||||
140 | | ||||
141 | QVector<ProjectServiceUrlData> CgitPlugin::projectServiceUrlsFromTextSelection(const QUrl& url, const KTextEditor::Cursor& cursor, IProject* project) const | ||||
142 | { | ||||
143 | const QString relativeFilePath = project->path().relativePath(Path(url)); | ||||
144 | if (relativeFilePath.isEmpty() || relativeFilePath.startsWith(QLatin1String("../"))) { | ||||
145 | return {}; | ||||
146 | } | ||||
147 | | ||||
148 | QVector<ProjectServiceUrlData> result; | ||||
149 | const auto configurations = loadProjectServiceHookupConfigurations(project); | ||||
150 | for (auto configuration : configurations) { | ||||
151 | const auto cgitConfiguration = dynamic_cast<CgitHookupConfiguration*>(configuration); | ||||
152 | | ||||
153 | QUrl url = cgitConfiguration->baseUrl(); | ||||
154 | if (!url.isValid()) { | ||||
155 | continue; | ||||
156 | } | ||||
157 | | ||||
158 | // TODO: get the remote tracked branch of the matching remote repo here instead | ||||
159 | const QString branch = m_projectVcsTracker.currentBranchName(project); | ||||
160 | if (branch.isEmpty()) { | ||||
161 | continue; | ||||
162 | } | ||||
163 | | ||||
164 | // TODO: find out what url encoding branch and relativeFilePath need | ||||
165 | const QString path = url.path() + QLatin1String("/tree/") + relativeFilePath; | ||||
166 | const QString query = QLatin1String("h=") + branch; | ||||
167 | const QString fragment = QLatin1Char('n') + QString::number(cursor.line()+1); | ||||
168 | url.setPath(path); | ||||
169 | url.setQuery(query); | ||||
170 | url.setFragment(fragment); | ||||
171 | | ||||
172 | ProjectServiceUrlData data; | ||||
173 | data.url = url; | ||||
174 | data.name = cgitConfiguration->displayName(); | ||||
175 | data.icon = projectServiceIcon(); | ||||
176 | result << data; | ||||
177 | } | ||||
178 | | ||||
179 | return result; | ||||
180 | } | ||||
181 | | ||||
182 | IProjectServiceUrlMapper::ProjectServiceUrlMapperCapabilities CgitPlugin::projectServiceUrlMapperCapabilities() const | ||||
183 | { | ||||
184 | return TextSelectionProjectUrlMapping | VcsRevisionProjectUrlMapping | VcsRevisionFileUrlMapping; | ||||
185 | } | ||||
186 | | ||||
187 | QVector<ProjectServiceUrlData> CgitPlugin::projectServiceUrlsFromVcsRevision(const VcsRevision& revision, IProject* project) const | ||||
188 | { | ||||
189 | return urlsFromVcsRevision(QString(), revision, project); | ||||
190 | } | ||||
191 | | ||||
192 | QVector<ProjectServiceUrlData> CgitPlugin::projectServiceUrlsFromVcsRevision(const QUrl& url, const VcsRevision& revision, IProject* project) const | ||||
193 | { | ||||
194 | const QString relativeFilePath = project->path().relativePath(Path(url)); | ||||
195 | if (relativeFilePath.isEmpty() || relativeFilePath.startsWith(QLatin1String("../"))) { | ||||
196 | return {}; | ||||
197 | } | ||||
198 | | ||||
199 | return urlsFromVcsRevision(relativeFilePath, revision, project); | ||||
200 | } | ||||
201 | | ||||
202 | QVector<ProjectServiceUrlData> CgitPlugin::urlsFromVcsRevision(const QString& relativeFilePath, const VcsRevision& revision, IProject* project) const | ||||
203 | { | ||||
204 | QVector<ProjectServiceUrlData> result; | ||||
205 | const QString revisionHash = revision.revisionValue().toString(); | ||||
206 | if (revisionHash.isEmpty()) { | ||||
207 | return result; | ||||
208 | } | ||||
209 | | ||||
210 | const auto configurations = loadProjectServiceHookupConfigurations(project); | ||||
211 | for (auto configuration : configurations) { | ||||
212 | const auto cgitConfiguration = dynamic_cast<CgitHookupConfiguration*>(configuration); | ||||
213 | | ||||
214 | QUrl url = cgitConfiguration->baseUrl(); | ||||
215 | if (!url.isValid()) { | ||||
216 | continue; | ||||
217 | } | ||||
218 | | ||||
219 | // TODO: find out what url encoding branch and relativeFilePath need | ||||
220 | const QString path = url.path() + QLatin1String("/commit/") + relativeFilePath; | ||||
221 | const QString query = QLatin1String("id=") + revisionHash; | ||||
222 | url.setPath(path); | ||||
223 | url.setQuery(query); | ||||
224 | | ||||
225 | ProjectServiceUrlData data; | ||||
226 | data.url = url; | ||||
227 | data.name = cgitConfiguration->displayName(); | ||||
228 | data.icon = projectServiceIcon(); | ||||
229 | result << data; | ||||
230 | } | ||||
231 | | ||||
232 | return result; | ||||
233 | } | ||||
234 | | ||||
235 | // needed for QObject class created from K_PLUGIN_FACTORY_WITH_JSON | ||||
236 | #include "cgitplugin.moc" |