File indexing completed on 2024-05-12 05:43:33
0001 /* 0002 Copyright (C) 2015 Volker Krause <vkrause@kde.org> 0003 0004 This program is free software; you can redistribute it and/or modify it 0005 under the terms of the GNU Library General Public License as published by 0006 the Free Software Foundation; either version 2 of the License, or (at your 0007 option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, but WITHOUT 0010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0012 License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program. If not, see <https://www.gnu.org/licenses/>. 0016 */ 0017 0018 #include "codenavigator.h" 0019 0020 #include <QAction> 0021 #include <QInputDialog> 0022 #include <QMenu> 0023 #include <QProcess> 0024 #include <QSettings> 0025 #include <QStandardPaths> 0026 #include <QUrl> 0027 0028 struct ide_settings_t { 0029 const char* const app; 0030 const char* const args; 0031 const char* const name; 0032 const char* const icon; 0033 }; 0034 0035 static const ide_settings_t ide_settings[] { 0036 { "kdevelop", "%f:%l", QT_TRANSLATE_NOOP("CodeNavigator", "KDevelop"), "kdevelop" }, 0037 { "kate", "%f --line %l", QT_TRANSLATE_NOOP("CodeNavigator", "Kate"), "kate" }, 0038 { "kwrite", "%f --line %l", QT_TRANSLATE_NOOP("CodeNavigator", "KWrite"), nullptr }, 0039 { "qtcreator", "%f", QT_TRANSLATE_NOOP("CodeNavigator", "Qt Creator"), nullptr } 0040 }; 0041 0042 static const int ide_settings_size = sizeof(ide_settings) / sizeof(ide_settings_t); 0043 0044 0045 bool CodeNavigator::isValid() 0046 { 0047 return true; // TODO 0048 } 0049 0050 void CodeNavigator::goTo(const QString& filePath, int line) 0051 { 0052 QSettings settings; 0053 settings.beginGroup(QStringLiteral("CodeNavigator")); 0054 const auto ideIdx = settings.value(QStringLiteral("IDE"), -1).toInt(); 0055 0056 QString command; 0057 if (ideIdx >= 0 && ideIdx < ide_settings_size) { 0058 command += ide_settings[ideIdx].app; 0059 command += ' '; 0060 command += ide_settings[ideIdx].args; 0061 } else { 0062 command = settings.value(QStringLiteral("CustomCommand")).toString(); 0063 } 0064 0065 command.replace(QLatin1String("%f"), filePath); 0066 command.replace(QLatin1String("%l"), QString::number(std::max(0, line))); 0067 0068 if (!command.isEmpty()) 0069 QProcess::startDetached(command); 0070 } 0071 0072 void CodeNavigator::goTo(const QUrl& url) 0073 { 0074 goTo(url.path(), url.fragment().toInt()); 0075 } 0076 0077 QAction* CodeNavigator::configMenu(QWidget *parent) 0078 { 0079 static QAction *configAction = nullptr; 0080 if (!configAction) { 0081 configAction = new QAction(QIcon::fromTheme(QStringLiteral("applications-development")), QObject::tr("Code Navigation"), parent); 0082 auto menu = new QMenu(parent); 0083 auto group = new QActionGroup(parent); 0084 group->setExclusive(true); 0085 0086 QSettings settings; 0087 settings.beginGroup(QStringLiteral("CodeNavigator")); 0088 const auto currentIdx = settings.value(QStringLiteral("IDE"), -1).toInt(); 0089 0090 for (int i = 0; i < ide_settings_size; ++i) { 0091 auto action = new QAction(menu); 0092 action->setText(QObject::tr(ide_settings[i].name)); 0093 if (ide_settings[i].icon) 0094 action->setIcon(QIcon::fromTheme(ide_settings[i].icon)); 0095 action->setCheckable(true); 0096 action->setChecked(currentIdx == i); 0097 action->setData(i); 0098 action->setEnabled(!QStandardPaths::findExecutable(ide_settings[i].app).isEmpty()); 0099 group->addAction(action); 0100 menu->addAction(action); 0101 } 0102 menu->addSeparator(); 0103 0104 auto action = new QAction(menu); 0105 action->setText(QObject::tr("Custom...")); 0106 action->setCheckable(true); 0107 action->setChecked(currentIdx == -1); 0108 group->addAction(action); 0109 menu->addAction(action); 0110 0111 QObject::connect(group, &QActionGroup::triggered, [parent](QAction *action) { 0112 QSettings settings; 0113 settings.beginGroup(QStringLiteral("CodeNavigator")); 0114 0115 if (!action->data().isValid()) { 0116 const auto customCmd = QInputDialog::getText( 0117 parent, QObject::tr("Custom Code Navigation"), 0118 QObject::tr("Specify command to use for code navigation, '%f' will be replaced by the file name, '%l' by the line number."), 0119 QLineEdit::Normal, settings.value(QStringLiteral("CustomCommand")).toString() 0120 ); 0121 if (!customCmd.isEmpty()) { 0122 settings.setValue(QStringLiteral("CustomCommand"), customCmd); 0123 settings.setValue(QStringLiteral("IDE"), -1); 0124 } 0125 return; 0126 } 0127 0128 const auto defaultIdx = action->data().toInt(); 0129 settings.setValue(QStringLiteral("IDE"), defaultIdx); 0130 }); 0131 0132 configAction->setMenu(menu); 0133 } 0134 0135 return configAction; 0136 }