File indexing completed on 2024-05-05 05:51:37
0001 /* Description : Kate CTags plugin 0002 * 0003 * SPDX-FileCopyrightText: 2008-2011 Kare Sars <kare.sars@iki.fi> 0004 * 0005 * This program is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2.1 of the License, or (at your option) version 3, or any 0009 * later version accepted by the membership of KDE e.V. (or its 0010 * successor approved by the membership of KDE e.V.), which shall 0011 * act as a proxy defined in Section 6 of version 3 of the license. 0012 * 0013 * This program is distributed in the hope that it will be useful, 0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 * General Public License for more details. 0017 * 0018 * You should have received a copy of the GNU General Public 0019 * License along with this program. If not, see <http://www.gnu.org/licenses/>. 0020 */ 0021 0022 #include "kate_ctags_plugin.h" 0023 0024 #include "hostprocess.h" 0025 0026 #include <QCheckBox> 0027 #include <QFileDialog> 0028 0029 #include <KConfigGroup> 0030 #include <KSharedConfig> 0031 0032 #include <KLocalizedString> 0033 #include <KMessageBox> 0034 #include <ktexteditor/editor.h> 0035 0036 #include <KPluginFactory> 0037 0038 K_PLUGIN_FACTORY_WITH_JSON(KateCTagsPluginFactory, "katectagsplugin.json", registerPlugin<KateCTagsPlugin>();) 0039 0040 /******************************************************************/ 0041 KateCTagsPlugin::KateCTagsPlugin(QObject *parent, const QVariantList &) 0042 : KTextEditor::Plugin(parent) 0043 { 0044 // FIXME KF5 0045 // KGlobal::locale()->insertCatalog("kate-ctags-plugin"); 0046 } 0047 0048 /******************************************************************/ 0049 QObject *KateCTagsPlugin::createView(KTextEditor::MainWindow *mainWindow) 0050 { 0051 m_view = new KateCTagsView(this, mainWindow); 0052 return m_view; 0053 } 0054 0055 /******************************************************************/ 0056 KTextEditor::ConfigPage *KateCTagsPlugin::configPage(int number, QWidget *parent) 0057 { 0058 if (number != 0) { 0059 return nullptr; 0060 } 0061 return new KateCTagsConfigPage(parent); 0062 } 0063 0064 /******************************************************************/ 0065 void KateCTagsPlugin::readConfig() 0066 { 0067 } 0068 0069 /******************************************************************/ 0070 KateCTagsConfigPage::KateCTagsConfigPage(QWidget *parent) 0071 : KTextEditor::ConfigPage(parent) 0072 { 0073 m_confUi.setupUi(this); 0074 m_confUi.cmdEdit->setText(DEFAULT_CTAGS_CMD); 0075 connect(m_confUi.cmdEdit, &QLineEdit::textEdited, this, &KateCTagsConfigPage::changed); 0076 0077 m_confUi.addButton->setToolTip(i18n("Add a directory to index.")); 0078 m_confUi.addButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); 0079 0080 m_confUi.delButton->setToolTip(i18n("Remove a directory.")); 0081 m_confUi.delButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); 0082 0083 m_confUi.updateDB->setToolTip(i18n("(Re-)generate the common CTags database.")); 0084 m_confUi.updateDB->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh"))); 0085 0086 connect(m_confUi.updateDB, &QPushButton::clicked, this, &KateCTagsConfigPage::updateGlobalDB); 0087 connect(m_confUi.addButton, &QPushButton::clicked, this, &KateCTagsConfigPage::addGlobalTagTarget); 0088 connect(m_confUi.delButton, &QPushButton::clicked, this, &KateCTagsConfigPage::delGlobalTagTarget); 0089 0090 connect(&m_proc, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &KateCTagsConfigPage::updateDone); 0091 connect(&m_proc, &QProcess::readyReadStandardError, this, [this]() { 0092 QString error = QString::fromLocal8Bit(m_proc.readAllStandardError()); 0093 KMessageBox::error(nullptr, error); 0094 }); 0095 reset(); 0096 } 0097 0098 /******************************************************************/ 0099 QString KateCTagsConfigPage::name() const 0100 { 0101 return i18n("CTags"); 0102 } 0103 0104 /******************************************************************/ 0105 QString KateCTagsConfigPage::fullName() const 0106 { 0107 return i18n("CTags Settings"); 0108 } 0109 0110 /******************************************************************/ 0111 QIcon KateCTagsConfigPage::icon() const 0112 { 0113 return QIcon::fromTheme(QStringLiteral("text-x-csrc")); 0114 } 0115 0116 /******************************************************************/ 0117 void KateCTagsConfigPage::apply() 0118 { 0119 KConfigGroup config(KSharedConfig::openConfig(), QStringLiteral("CTags")); 0120 config.writeEntry("GlobalCommand", m_confUi.cmdEdit->text()); 0121 0122 config.writeEntry("GlobalNumTargets", m_confUi.targetList->count()); 0123 0124 QString nr; 0125 for (int i = 0; i < m_confUi.targetList->count(); i++) { 0126 nr = QStringLiteral("%1").arg(i, 3); 0127 config.writeEntry(QStringLiteral("GlobalTarget_") + nr, m_confUi.targetList->item(i)->text()); 0128 } 0129 config.sync(); 0130 } 0131 0132 /******************************************************************/ 0133 void KateCTagsConfigPage::reset() 0134 { 0135 KConfigGroup config(KSharedConfig::openConfig(), QStringLiteral("CTags")); 0136 m_confUi.cmdEdit->setText(config.readEntry(QStringLiteral("GlobalCommand"), DEFAULT_CTAGS_CMD)); 0137 0138 int numEntries = config.readEntry(QStringLiteral("GlobalNumTargets"), 0); 0139 QString nr; 0140 QString target; 0141 for (int i = 0; i < numEntries; i++) { 0142 nr = QStringLiteral("%1").arg(i, 3); 0143 target = config.readEntry(QLatin1String("GlobalTarget_") + nr, QString()); 0144 if (!listContains(target)) { 0145 new QListWidgetItem(target, m_confUi.targetList); 0146 } 0147 } 0148 config.sync(); 0149 } 0150 0151 /******************************************************************/ 0152 void KateCTagsConfigPage::addGlobalTagTarget() 0153 { 0154 QFileDialog dialog; 0155 dialog.setFileMode(QFileDialog::Directory); 0156 // dialog.setMode(KFile::Directory | KFile::Files | KFile::ExistingOnly | KFile::LocalOnly); 0157 0158 QString dir; 0159 if (m_confUi.targetList->currentItem()) { 0160 dir = m_confUi.targetList->currentItem()->text(); 0161 } else if (m_confUi.targetList->item(0)) { 0162 dir = m_confUi.targetList->item(0)->text(); 0163 } 0164 dialog.setDirectory(dir); 0165 0166 // i18n("CTags Database Location")); 0167 if (dialog.exec() != QDialog::Accepted) { 0168 return; 0169 } 0170 0171 QStringList urls = dialog.selectedFiles(); 0172 0173 for (int i = 0; i < urls.size(); i++) { 0174 if (!listContains(urls[i])) { 0175 new QListWidgetItem(urls[i], m_confUi.targetList); 0176 Q_EMIT changed(); 0177 } 0178 } 0179 } 0180 0181 /******************************************************************/ 0182 void KateCTagsConfigPage::delGlobalTagTarget() 0183 { 0184 delete m_confUi.targetList->currentItem(); 0185 Q_EMIT changed(); 0186 } 0187 0188 /******************************************************************/ 0189 bool KateCTagsConfigPage::listContains(const QString &target) 0190 { 0191 for (int i = 0; i < m_confUi.targetList->count(); i++) { 0192 if (m_confUi.targetList->item(i)->text() == target) { 0193 return true; 0194 } 0195 } 0196 return false; 0197 } 0198 0199 /******************************************************************/ 0200 void KateCTagsConfigPage::updateGlobalDB() 0201 { 0202 if (m_proc.state() != QProcess::NotRunning) { 0203 return; 0204 } 0205 0206 QStringList targets; 0207 for (int i = 0; i < m_confUi.targetList->count(); i++) { 0208 auto target = m_confUi.targetList->item(i)->text(); 0209 if (target.endsWith(QLatin1Char('/')) || target.endsWith(QLatin1Char('\\'))) { 0210 target = target.left(target.size() - 1); 0211 } 0212 targets << target; 0213 } 0214 0215 QString file = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QLatin1String("/katectags"); 0216 QDir().mkpath(file); 0217 file += QLatin1String("/common_db"); 0218 0219 if (targets.isEmpty()) { 0220 QFile::remove(file); 0221 return; 0222 } 0223 0224 QStringList arguments = m_proc.splitCommand(m_confUi.cmdEdit->text()); 0225 const QString command = arguments.takeFirst(); 0226 arguments << QStringLiteral("-f") << file << targets; 0227 startHostProcess(m_proc, command, arguments); 0228 0229 if (!m_proc.waitForStarted(500)) { 0230 KMessageBox::error(nullptr, i18n("Failed to run. Error: %1, exit code: %2", m_proc.errorString(), m_proc.exitCode())); 0231 return; 0232 } 0233 m_confUi.updateDB->setDisabled(true); 0234 QApplication::setOverrideCursor(QCursor(Qt::BusyCursor)); 0235 } 0236 0237 /******************************************************************/ 0238 void KateCTagsConfigPage::updateDone(int exitCode, QProcess::ExitStatus status) 0239 { 0240 if (status == QProcess::CrashExit) { 0241 KMessageBox::error(this, i18n("The CTags executable crashed.")); 0242 } else if (exitCode != 0) { 0243 KMessageBox::error(this, i18n("The CTags command exited with code %1", exitCode)); 0244 } 0245 0246 m_confUi.updateDB->setDisabled(false); 0247 QApplication::restoreOverrideCursor(); 0248 } 0249 0250 #include "kate_ctags_plugin.moc" 0251 #include "moc_kate_ctags_plugin.cpp"