Warning, file /kdevelop/kdevelop/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectincludepathsmanager.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2014 Sergey Kalinichev <kalinichev.so.0@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "noprojectincludepathsmanager.h" 0008 0009 #include <QFile> 0010 #include <QDir> 0011 #include <QFileInfo> 0012 0013 #include <KLocalizedString> 0014 0015 #include <interfaces/icore.h> 0016 #include <interfaces/ilanguagecontroller.h> 0017 #include <language/backgroundparser/backgroundparser.h> 0018 #include <serialization/indexedstring.h> 0019 0020 #include "noprojectcustomincludepaths.h" 0021 0022 namespace 0023 { 0024 inline QString includePathsFile() { return QStringLiteral(".kdev_include_paths"); } 0025 0026 0027 bool removeSettings(const QString& storageDirectory) 0028 { 0029 const QString file = storageDirectory + QDir::separator() + includePathsFile(); 0030 return QFile::remove(file); 0031 } 0032 0033 QStringList pathListToStringList(const Path::List& paths) 0034 { 0035 QStringList sl; 0036 sl.reserve(paths.size()); 0037 for (const auto& p : paths) { 0038 sl << p.path(); 0039 } 0040 return sl; 0041 } 0042 } 0043 0044 QString NoProjectIncludePathsManager::findConfigurationFile(const QString& path) 0045 { 0046 QDir dir(path); 0047 while (dir.exists()) { 0048 QFileInfo customIncludePathsFile(dir, includePathsFile()); 0049 if (customIncludePathsFile.exists()) { 0050 return customIncludePathsFile.absoluteFilePath(); 0051 } 0052 0053 if (!dir.cdUp()) { 0054 break; 0055 } 0056 } 0057 return {}; 0058 } 0059 0060 std::pair<Path::List, QHash<QString, QString>> 0061 NoProjectIncludePathsManager::includesAndDefines(const QString& path) 0062 { 0063 QFileInfo fi(path); 0064 0065 auto pathToFile = findConfigurationFile(fi.absoluteDir().absolutePath()); 0066 if (pathToFile.isEmpty()) { 0067 return {}; 0068 } 0069 Path::List includes; 0070 QHash<QString, QString> defines; 0071 0072 QFile f(pathToFile); 0073 if (f.open(QIODevice::ReadOnly | QIODevice::Text)) { 0074 const QString fileContent = QString::fromLocal8Bit(f.readAll()); 0075 const auto lines = fileContent.splitRef(QLatin1Char('\n'), Qt::SkipEmptyParts); 0076 QFileInfo dir(pathToFile); 0077 const QChar dirSeparator = QDir::separator(); 0078 for (const auto& line : lines) { 0079 const auto textLine = line.trimmed().toString(); 0080 if (textLine.startsWith(QLatin1String("#define "))) { 0081 QStringList items = textLine.split(QLatin1Char(' ')); 0082 if (items.length() > 1) 0083 { 0084 defines[items[1]] = QStringList(items.mid(2)).join(QLatin1Char(' ')); 0085 }else{ 0086 qWarning() << i18n("Bad #define directive in %1: %2", pathToFile, textLine); 0087 } 0088 continue; 0089 } 0090 if (!textLine.isEmpty()) { 0091 QFileInfo pathInfo(textLine); 0092 if (pathInfo.isRelative()) { 0093 includes << Path(dir.canonicalPath() + dirSeparator + textLine); 0094 } else { 0095 includes << Path(textLine); 0096 } 0097 } 0098 } 0099 f.close(); 0100 } 0101 return std::make_pair(includes, defines); 0102 } 0103 0104 bool NoProjectIncludePathsManager::writeIncludePaths(const QString& storageDirectory, const QStringList& includePaths) 0105 { 0106 QDir dir(storageDirectory); 0107 QFileInfo customIncludePaths(dir, includePathsFile()); 0108 QFile f(customIncludePaths.filePath()); 0109 if (f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { 0110 QTextStream out(&f); 0111 for (const auto& customPath : includePaths) { 0112 out << customPath << QLatin1Char('\n'); 0113 } 0114 if (includePaths.isEmpty()) { 0115 removeSettings(storageDirectory); 0116 } 0117 return true; 0118 } else { 0119 return false; 0120 } 0121 } 0122 0123 void NoProjectIncludePathsManager::openConfigurationDialog(const QString& path) 0124 { 0125 auto cip = new NoProjectCustomIncludePaths; 0126 cip->setAttribute(Qt::WA_DeleteOnClose); 0127 cip->setModal(true); 0128 0129 QFileInfo fi(path); 0130 auto dir = fi.absoluteDir().absolutePath(); 0131 cip->setStorageDirectory(dir); 0132 0133 auto paths = includesAndDefines(path).first; 0134 0135 cip->setCustomIncludePaths(pathListToStringList(paths)); 0136 0137 QObject::connect(cip, &QDialog::accepted, cip, [this, cip, &path]() { 0138 if (!writeIncludePaths(cip->storageDirectory(), cip->customIncludePaths())) { 0139 qWarning() << i18n("Failed to save custom include paths in directory: %1", cip->storageDirectory()); 0140 } 0141 KDevelop::ICore::self()->languageController()->backgroundParser()->addDocument(KDevelop::IndexedString(path)); 0142 }); 0143 }