1/* Description : Kate CTags plugin
2 *
3 * Copyright (C) 2008-2011 by Kare Sars <kare.sars@iki.fi>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) version 3, or any
9 * later version accepted by the membership of KDE e.V. (or its
10 * successor approved by the membership of KDE e.V.), which shall
11 * act as a proxy defined in Section 6 of version 3 of the license.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "kate_ctags_plugin.h"
23
24#include <QFileInfo>
25#include <KFileDialog>
26#include <QCheckBox>
27
28#include <kmenu.h>
29#include <kactioncollection.h>
30#include <kstringhandler.h>
31#include <kmessagebox.h>
32#include <kstandarddirs.h>
33
34#include <kpluginfactory.h>
35#include <kpluginloader.h>
36#include <kaboutdata.h>
37
38K_PLUGIN_FACTORY(KateCTagsPluginFactory, registerPlugin<KateCTagsPlugin>();)
39K_EXPORT_PLUGIN(KateCTagsPluginFactory(KAboutData("katectags", "kate-ctags-plugin",
40 ki18n("CTags Plugin"), "0.2",
41 ki18n( "CTags Plugin"))))
42
43/******************************************************************/
44KateCTagsPlugin::KateCTagsPlugin(QObject* parent, const QList<QVariant>&):
45Kate::Plugin ((Kate::Application*)parent), m_view(0)
46{
47 KGlobal::locale()->insertCatalog("kate-ctags-plugin");
48}
49
50/******************************************************************/
51Kate::PluginView *KateCTagsPlugin::createView(Kate::MainWindow *mainWindow)
52{
53 m_view = new KateCTagsView(mainWindow, KateCTagsPluginFactory::componentData());
54 return m_view;
55}
56
57
58/******************************************************************/
59Kate::PluginConfigPage *KateCTagsPlugin::configPage (uint number, QWidget *parent, const char *)
60{
61 if (number != 0) return 0;
62 return new KateCTagsConfigPage(parent, this);
63}
64
65/******************************************************************/
66QString KateCTagsPlugin::configPageName (uint number) const
67{
68 if (number != 0) return QString();
69 return i18n("CTags");
70}
71
72/******************************************************************/
73QString KateCTagsPlugin::configPageFullName (uint number) const
74{
75 if (number != 0) return QString();
76 return i18n("CTags Settings");
77}
78
79/******************************************************************/
80KIcon KateCTagsPlugin::configPageIcon (uint number) const
81{
82 if (number != 0) return KIcon();
83 return KIcon("text-x-csrc");
84}
85
86/******************************************************************/
87void KateCTagsPlugin::readConfig()
88{
89}
90
91
92
93
94/******************************************************************/
95KateCTagsConfigPage::KateCTagsConfigPage( QWidget* parent, KateCTagsPlugin *plugin )
96: Kate::PluginConfigPage( parent )
97, m_plugin( plugin )
98{
99 m_confUi.setupUi(this);
100 m_confUi.cmdEdit->setText(DEFAULT_CTAGS_CMD);
101
102 m_confUi.addButton->setToolTip(i18n("Add a directory to index."));
103 m_confUi.addButton->setIcon(KIcon("list-add"));
104
105 m_confUi.delButton->setToolTip(i18n("Remove a directory."));
106 m_confUi.delButton->setIcon(KIcon("list-remove"));
107
108 m_confUi.updateDB->setToolTip(i18n("(Re-)generate the common CTags database."));
109 m_confUi.updateDB->setIcon(KIcon("view-refresh"));
110
111 connect(m_confUi.updateDB, SIGNAL(clicked()), this, SLOT(updateGlobalDB()));
112 connect(m_confUi.addButton, SIGNAL(clicked()), this, SLOT(addGlobalTagTarget()));
113 connect(m_confUi.delButton, SIGNAL(clicked()), this, SLOT(delGlobalTagTarget()));
114
115 connect(&m_proc, SIGNAL(finished(int,QProcess::ExitStatus)),
116 this, SLOT(updateDone(int,QProcess::ExitStatus)));
117
118 reset();
119}
120
121/******************************************************************/
122void KateCTagsConfigPage::apply()
123{
124 KConfigGroup config(KGlobal::config(), "CTags");
125 config.writeEntry("GlobalCommand", m_confUi.cmdEdit->text());
126
127 config.writeEntry("GlobalNumTargets", m_confUi.targetList->count());
128
129 QString nr;
130 for (int i=0; i<m_confUi.targetList->count(); i++) {
131 nr = QString("%1").arg(i,3);
132 config.writeEntry("GlobalTarget_"+nr, m_confUi.targetList->item(i)->text());
133 }
134 config.sync();
135}
136
137/******************************************************************/
138void KateCTagsConfigPage::reset()
139{
140 KConfigGroup config(KGlobal::config(), "CTags");
141 m_confUi.cmdEdit->setText(config.readEntry("GlobalCommand", DEFAULT_CTAGS_CMD));
142
143 int numEntries = config.readEntry("GlobalNumTargets", 0);
144 QString nr;
145 QString target;
146 for (int i=0; i<numEntries; i++) {
147 nr = QString("%1").arg(i,3);
148 target = config.readEntry("GlobalTarget_"+nr, QString());
149 if (!listContains(target)) {
150 new QListWidgetItem(target, m_confUi.targetList);
151 }
152 }
153 config.sync();
154}
155
156
157/******************************************************************/
158void KateCTagsConfigPage::addGlobalTagTarget()
159{
160 KFileDialog dialog(KUrl(), QString(), 0, 0);
161 dialog.setMode(KFile::Directory | KFile::Files | KFile::ExistingOnly | KFile::LocalOnly);
162
163 // i18n("CTags Database Location"));
164 if (dialog.exec() != QDialog::Accepted) {
165 return;
166 }
167
168 QStringList urls = dialog.selectedFiles();
169
170 for (int i=0; i<urls.size(); i++) {
171 if (!listContains(urls[i])) {
172 new QListWidgetItem(urls[i], m_confUi.targetList);
173 }
174 }
175
176}
177
178
179/******************************************************************/
180void KateCTagsConfigPage::delGlobalTagTarget()
181{
182 delete m_confUi.targetList->currentItem ();
183}
184
185
186/******************************************************************/
187bool KateCTagsConfigPage::listContains(const QString &target)
188{
189 for (int i=0; i<m_confUi.targetList->count(); i++) {
190 if (m_confUi.targetList->item(i)->text() == target) {
191 return true;
192 }
193 }
194 return false;
195}
196
197/******************************************************************/
198void KateCTagsConfigPage::updateGlobalDB()
199{
200 if (m_proc.state() != QProcess::NotRunning) {
201 return;
202 }
203
204 QString targets;
205 QString target;
206 for (int i=0; i<m_confUi.targetList->count(); i++) {
207 target = m_confUi.targetList->item(i)->text();
208 if (target.endsWith('/') || target.endsWith('\\')) {
209 target = target.left(target.size() - 1);
210 }
211 targets += target + ' ';
212 }
213
214 QString file = KStandardDirs::locateLocal("appdata", "plugins/katectags/common_db", true);
215
216 if (targets.isEmpty()) {
217 QFile::remove(file);
218 return;
219 }
220
221 QString command = QString("%1 -f %2 %3").arg(m_confUi.cmdEdit->text()).arg(file).arg(targets) ;
222
223 m_proc.setShellCommand(command);
224 m_proc.setOutputChannelMode(KProcess::SeparateChannels);
225 m_proc.start();
226
227 if(!m_proc.waitForStarted(500)) {
228 KMessageBox::error(0, i18n("Failed to run \"%1\". exitStatus = %2", command, m_proc.exitStatus()));
229 return;
230 }
231 m_confUi.updateDB->setDisabled(true);
232 QApplication::setOverrideCursor(QCursor(Qt::BusyCursor));
233}
234
235/******************************************************************/
236void KateCTagsConfigPage::updateDone(int exitCode, QProcess::ExitStatus status)
237{
238 if (status == QProcess::CrashExit) {
239 KMessageBox::error(this, i18n("The CTags executable crashed."));
240 }
241 else if (exitCode != 0) {
242 KMessageBox::error(this, i18n("The CTags command exited with code %1", exitCode));
243 }
244
245 m_confUi.updateDB->setDisabled(false);
246 QApplication::restoreOverrideCursor();
247}
248
249
250