File indexing completed on 2024-05-05 16:45:14
0001 /* 0002 SPDX-FileCopyrightText: 2017 Anton Anikin <anton.anikin@htower.ru> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "problemmodel.h" 0008 0009 #include "plugin.h" 0010 #include "utils.h" 0011 0012 #include <interfaces/icore.h> 0013 #include <interfaces/ilanguagecontroller.h> 0014 #include <interfaces/iproject.h> 0015 #include <language/editor/documentrange.h> 0016 #include <shell/problemmodelset.h> 0017 0018 #include <KLocalizedString> 0019 0020 namespace cppcheck 0021 { 0022 0023 inline KDevelop::ProblemModelSet* problemModelSet() 0024 { 0025 return KDevelop::ICore::self()->languageController()->problemModelSet(); 0026 } 0027 0028 namespace Strings { 0029 QString problemModelId() { return QStringLiteral("Cppcheck"); } 0030 } 0031 0032 ProblemModel::ProblemModel(Plugin* plugin) 0033 : KDevelop::ProblemModel(plugin) 0034 , m_plugin(plugin) 0035 , m_project(nullptr) 0036 , m_pathLocation(KDevelop::DocumentRange::invalid()) 0037 { 0038 setFeatures(CanDoFullUpdate | ScopeFilter | SeverityFilter | Grouping | CanByPassScopeFilter); 0039 reset(); 0040 problemModelSet()->addModel(Strings::problemModelId(), i18n("Cppcheck"), this); 0041 } 0042 0043 ProblemModel::~ProblemModel() 0044 { 0045 problemModelSet()->removeModel(Strings::problemModelId()); 0046 } 0047 0048 KDevelop::IProject* ProblemModel::project() const 0049 { 0050 return m_project; 0051 } 0052 0053 void ProblemModel::fixProblemFinalLocation(KDevelop::IProblem::Ptr problem) 0054 { 0055 // Fix problems with incorrect range, which produced by cppcheck's errors 0056 // without <location> element. In this case location automatically gets "/". 0057 // To avoid this we set current analysis path as problem location. 0058 0059 if (problem->finalLocation().document.isEmpty()) { 0060 problem->setFinalLocation(m_pathLocation); 0061 } 0062 0063 const auto& diagnostics = problem->diagnostics(); 0064 for (auto& diagnostic : diagnostics) { 0065 fixProblemFinalLocation(diagnostic); 0066 } 0067 } 0068 0069 bool ProblemModel::problemExists(KDevelop::IProblem::Ptr newProblem) 0070 { 0071 for (auto problem : qAsConst(m_problems)) { 0072 if (newProblem->source() == problem->source() && 0073 newProblem->severity() == problem->severity() && 0074 newProblem->finalLocation() == problem->finalLocation() && 0075 newProblem->description() == problem->description() && 0076 newProblem->explanation() == problem->explanation()) 0077 return true; 0078 } 0079 0080 return false; 0081 } 0082 0083 void ProblemModel::setMessage(const QString& message) 0084 { 0085 setPlaceholderText(message, m_pathLocation, i18n("Cppcheck")); 0086 } 0087 0088 void ProblemModel::addProblems(const QVector<KDevelop::IProblem::Ptr>& problems) 0089 { 0090 static int maxLength = 0; 0091 0092 if (m_problems.isEmpty()) { 0093 maxLength = 0; 0094 } 0095 0096 for (auto problem : problems) { 0097 fixProblemFinalLocation(problem); 0098 0099 if (problemExists(problem)) { 0100 continue; 0101 } 0102 0103 m_problems.append(problem); 0104 addProblem(problem); 0105 0106 // This performs adjusting of columns width in the ProblemsView 0107 if (maxLength < problem->description().length()) { 0108 maxLength = problem->description().length(); 0109 setProblems(m_problems); 0110 } 0111 } 0112 } 0113 0114 void ProblemModel::setProblems() 0115 { 0116 setMessage(i18n("Analysis completed, no problems detected.")); 0117 setProblems(m_problems); 0118 } 0119 0120 void ProblemModel::reset() 0121 { 0122 reset(nullptr, QString()); 0123 } 0124 0125 void ProblemModel::reset(KDevelop::IProject* project, const QString& path) 0126 { 0127 m_project = project; 0128 0129 m_path = path; 0130 m_pathLocation.document = KDevelop::IndexedString(m_path); 0131 0132 clearProblems(); 0133 m_problems.clear(); 0134 0135 QString tooltip; 0136 if (m_project) { 0137 setMessage(i18n("Analysis started...")); 0138 tooltip = i18nc("@info:tooltip %1 is the path of the file", "Re-run last Cppcheck analysis (%1)", prettyPathName(m_path)); 0139 } else { 0140 tooltip = i18nc("@info:tooltip", "Re-run last Cppcheck analysis"); 0141 } 0142 0143 setFullUpdateTooltip(tooltip); 0144 } 0145 0146 void ProblemModel::show() 0147 { 0148 problemModelSet()->showModel(Strings::problemModelId()); 0149 } 0150 0151 void ProblemModel::forceFullUpdate() 0152 { 0153 if (m_project && !m_plugin->isRunning()) { 0154 m_plugin->runCppcheck(m_project, m_path); 0155 } 0156 } 0157 0158 } 0159 0160 #include "moc_problemmodel.cpp"