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 | |
38 | K_PLUGIN_FACTORY(KateCTagsPluginFactory, registerPlugin<KateCTagsPlugin>();) |
39 | K_EXPORT_PLUGIN(KateCTagsPluginFactory(KAboutData("katectags" , "kate-ctags-plugin" , |
40 | ki18n("CTags Plugin" ), "0.2" , |
41 | ki18n( "CTags Plugin" )))) |
42 | |
43 | /******************************************************************/ |
44 | KateCTagsPlugin::KateCTagsPlugin(QObject* parent, const QList<QVariant>&): |
45 | Kate::Plugin ((Kate::Application*)parent), m_view(0) |
46 | { |
47 | KGlobal::locale()->insertCatalog("kate-ctags-plugin" ); |
48 | } |
49 | |
50 | /******************************************************************/ |
51 | Kate::PluginView *KateCTagsPlugin::createView(Kate::MainWindow *mainWindow) |
52 | { |
53 | m_view = new KateCTagsView(mainWindow, KateCTagsPluginFactory::componentData()); |
54 | return m_view; |
55 | } |
56 | |
57 | |
58 | /******************************************************************/ |
59 | Kate::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 | /******************************************************************/ |
66 | QString KateCTagsPlugin::configPageName (uint number) const |
67 | { |
68 | if (number != 0) return QString(); |
69 | return i18n("CTags" ); |
70 | } |
71 | |
72 | /******************************************************************/ |
73 | QString KateCTagsPlugin::configPageFullName (uint number) const |
74 | { |
75 | if (number != 0) return QString(); |
76 | return i18n("CTags Settings" ); |
77 | } |
78 | |
79 | /******************************************************************/ |
80 | KIcon KateCTagsPlugin::configPageIcon (uint number) const |
81 | { |
82 | if (number != 0) return KIcon(); |
83 | return KIcon("text-x-csrc" ); |
84 | } |
85 | |
86 | /******************************************************************/ |
87 | void KateCTagsPlugin::readConfig() |
88 | { |
89 | } |
90 | |
91 | |
92 | |
93 | |
94 | /******************************************************************/ |
95 | KateCTagsConfigPage::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 | /******************************************************************/ |
122 | void 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 | /******************************************************************/ |
138 | void 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 | /******************************************************************/ |
158 | void 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 | /******************************************************************/ |
180 | void KateCTagsConfigPage::delGlobalTagTarget() |
181 | { |
182 | delete m_confUi.targetList->currentItem (); |
183 | } |
184 | |
185 | |
186 | /******************************************************************/ |
187 | bool 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 | /******************************************************************/ |
198 | void 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 | /******************************************************************/ |
236 | void 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 | |