File indexing completed on 2024-04-28 04:37:21
0001 /* 0002 SPDX-FileCopyrightText: 2015 Laszlo Kis-Adam <laszlo.kis-adam@kdemail.net> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "problemstore.h" 0008 0009 #include <language/editor/documentrange.h> 0010 #include <shell/problem.h> 0011 #include <shell/watcheddocumentset.h> 0012 #include "problemstorenode.h" 0013 0014 namespace KDevelop 0015 { 0016 0017 class ProblemStorePrivate 0018 { 0019 public: 0020 ProblemStorePrivate() 0021 : m_severities(KDevelop::IProblem::Error | KDevelop::IProblem::Warning | KDevelop::IProblem::Hint) 0022 , m_rootNode(new KDevelop::ProblemStoreNode()) 0023 { 0024 } 0025 0026 /// Watched document set. Only problems that are in files in this set are stored. 0027 KDevelop::WatchedDocumentSet *m_documents = nullptr; 0028 0029 /// The severity filter setting 0030 KDevelop::IProblem::Severities m_severities; 0031 0032 /// The problems list 0033 KDevelop::ProblemStoreNode *m_rootNode; 0034 0035 /// Path of the currently open document 0036 KDevelop::IndexedString m_currentDocument; 0037 0038 /// Path for the DocumentsInPath scope 0039 QString m_pathForDocumentsInPathScope; 0040 0041 /// All stored problems 0042 QVector<KDevelop::IProblem::Ptr> m_allProblems; 0043 }; 0044 0045 0046 ProblemStore::ProblemStore(QObject *parent) 0047 : QObject(parent), 0048 d_ptr(new ProblemStorePrivate) 0049 { 0050 setScope(BypassScopeFilter); 0051 } 0052 0053 ProblemStore::~ProblemStore() 0054 { 0055 Q_D(ProblemStore); 0056 0057 clear(); 0058 0059 delete d->m_rootNode; 0060 } 0061 0062 void ProblemStore::addProblem(const IProblem::Ptr &problem) 0063 { 0064 Q_D(ProblemStore); 0065 0066 auto* node = new ProblemNode(d->m_rootNode); 0067 node->setProblem(problem); 0068 d->m_rootNode->addChild(node); 0069 0070 d->m_allProblems += problem; 0071 emit problemsChanged(); 0072 } 0073 0074 void ProblemStore::setProblems(const QVector<IProblem::Ptr> &problems) 0075 { 0076 Q_D(ProblemStore); 0077 0078 int oldSize = d->m_allProblems.size(); 0079 0080 // set signals block to prevent problemsChanged() emitting during clean 0081 { 0082 QSignalBlocker blocker(this); 0083 clear(); 0084 } 0085 0086 for (const IProblem::Ptr& problem : problems) { 0087 d->m_rootNode->addChild(new ProblemNode(d->m_rootNode, problem)); 0088 } 0089 0090 rebuild(); 0091 0092 if (d->m_allProblems.size() != oldSize || d->m_allProblems != problems) { 0093 d->m_allProblems = problems; 0094 emit problemsChanged(); 0095 } 0096 } 0097 0098 QVector<IProblem::Ptr> ProblemStore::problems(const KDevelop::IndexedString& document) const 0099 { 0100 Q_D(const ProblemStore); 0101 0102 QVector<IProblem::Ptr> documentProblems; 0103 0104 for (auto& problem : qAsConst(d->m_allProblems)) { 0105 if (problem->finalLocation().document == document) 0106 documentProblems += problem; 0107 } 0108 0109 return documentProblems; 0110 } 0111 0112 const ProblemStoreNode* ProblemStore::findNode(int row, ProblemStoreNode *parent) const 0113 { 0114 Q_D(const ProblemStore); 0115 0116 Q_UNUSED(parent); 0117 return d->m_rootNode->child(row); 0118 } 0119 0120 int ProblemStore::count(ProblemStoreNode *parent) const 0121 { 0122 Q_D(const ProblemStore); 0123 0124 if(parent) 0125 return parent->count(); 0126 else 0127 return d->m_rootNode->count(); 0128 } 0129 0130 void ProblemStore::clear() 0131 { 0132 Q_D(ProblemStore); 0133 0134 d->m_rootNode->clear(); 0135 0136 if (!d->m_allProblems.isEmpty()) { 0137 d->m_allProblems.clear(); 0138 emit problemsChanged(); 0139 } 0140 } 0141 0142 void ProblemStore::rebuild() 0143 { 0144 } 0145 0146 void ProblemStore::setSeverity(int severity) 0147 { 0148 switch (severity) 0149 { 0150 case KDevelop::IProblem::Error: 0151 setSeverities(KDevelop::IProblem::Error); 0152 break; 0153 case KDevelop::IProblem::Warning: 0154 setSeverities(KDevelop::IProblem::Error | KDevelop::IProblem::Warning); 0155 break; 0156 case KDevelop::IProblem::Hint: 0157 setSeverities(KDevelop::IProblem::Error | KDevelop::IProblem::Warning | KDevelop::IProblem::Hint); 0158 break; 0159 } 0160 } 0161 0162 void ProblemStore::setSeverities(KDevelop::IProblem::Severities severities) 0163 { 0164 Q_D(ProblemStore); 0165 0166 if(severities != d->m_severities) 0167 { 0168 d->m_severities = severities; 0169 rebuild(); 0170 emit changed(); 0171 } 0172 } 0173 0174 int ProblemStore::severity() const 0175 { 0176 Q_D(const ProblemStore); 0177 0178 if (d->m_severities.testFlag(KDevelop::IProblem::Hint)) 0179 return KDevelop::IProblem::Hint; 0180 if (d->m_severities.testFlag(KDevelop::IProblem::Warning)) 0181 return KDevelop::IProblem::Warning; 0182 if (d->m_severities.testFlag(KDevelop::IProblem::Error)) 0183 return KDevelop::IProblem::Error; 0184 return 0; 0185 } 0186 0187 KDevelop::IProblem::Severities ProblemStore::severities() const 0188 { 0189 Q_D(const ProblemStore); 0190 0191 return d->m_severities; 0192 } 0193 0194 WatchedDocumentSet* ProblemStore::documents() const 0195 { 0196 Q_D(const ProblemStore); 0197 0198 return d->m_documents; 0199 } 0200 0201 void ProblemStore::setScope(ProblemScope scope) 0202 { 0203 Q_D(ProblemStore); 0204 0205 bool showImports = false; 0206 0207 if (d->m_documents) { 0208 if (scope == d->m_documents->scope()) 0209 return; 0210 0211 showImports = d->m_documents->showImports(); 0212 delete d->m_documents; 0213 } 0214 0215 switch (scope) { 0216 case CurrentDocument: 0217 d->m_documents = new CurrentDocumentSet(d->m_currentDocument, this); 0218 break; 0219 case OpenDocuments: 0220 d->m_documents = new OpenDocumentSet(this); 0221 break; 0222 case CurrentProject: 0223 d->m_documents = new CurrentProjectSet(d->m_currentDocument, this); 0224 break; 0225 case AllProjects: 0226 d->m_documents = new AllProjectSet(this); 0227 break; 0228 case DocumentsInPath: 0229 d->m_documents = new DocumentsInPathSet(d->m_pathForDocumentsInPathScope, this); 0230 break; 0231 case DocumentsInCurrentPath: 0232 d->m_documents = new DocumentsInCurrentPathSet(d->m_currentDocument, this); 0233 break; 0234 case BypassScopeFilter: 0235 d->m_documents = new BypassSet(this); 0236 break; 0237 } 0238 0239 d->m_documents->setShowImports(showImports); 0240 0241 rebuild(); 0242 0243 connect(d->m_documents, &WatchedDocumentSet::changed, this, &ProblemStore::onDocumentSetChanged); 0244 0245 emit changed(); 0246 } 0247 0248 ProblemScope ProblemStore::scope() const 0249 { 0250 Q_D(const ProblemStore); 0251 0252 Q_ASSERT(d->m_documents); 0253 0254 return d->m_documents->scope(); 0255 } 0256 0257 void ProblemStore::setGrouping(int grouping) 0258 { 0259 Q_UNUSED(grouping); 0260 } 0261 0262 void ProblemStore::setShowImports(bool showImports) 0263 { 0264 Q_D(ProblemStore); 0265 0266 d->m_documents->setShowImports(showImports); 0267 } 0268 0269 int ProblemStore::showImports() const 0270 { 0271 Q_D(const ProblemStore); 0272 0273 return d->m_documents->showImports(); 0274 } 0275 0276 void ProblemStore::setCurrentDocument(const IndexedString &doc) 0277 { 0278 Q_D(ProblemStore); 0279 0280 d->m_currentDocument = doc; 0281 d->m_documents->setCurrentDocument(doc); 0282 } 0283 0284 0285 const KDevelop::IndexedString& ProblemStore::currentDocument() const 0286 { 0287 Q_D(const ProblemStore); 0288 0289 return d->m_currentDocument; 0290 } 0291 0292 void ProblemStore::setPathForDocumentsInPathScope(const QString& path) 0293 { 0294 Q_D(ProblemStore); 0295 0296 d->m_pathForDocumentsInPathScope = path; 0297 0298 if (d->m_documents->scope() == DocumentsInPath) { 0299 static_cast<DocumentsInPathSet*>(d->m_documents)->setPath(path); 0300 } 0301 } 0302 0303 QString ProblemStore::pathForDocumentsInPathScope() const 0304 { 0305 Q_D(const ProblemStore); 0306 0307 return d->m_pathForDocumentsInPathScope; 0308 } 0309 0310 void ProblemStore::onDocumentSetChanged() 0311 { 0312 rebuild(); 0313 0314 emit changed(); 0315 } 0316 0317 ProblemStoreNode* ProblemStore::rootNode() const 0318 { 0319 Q_D(const ProblemStore); 0320 0321 return d->m_rootNode; 0322 } 0323 0324 } 0325 0326 #include "moc_problemstore.cpp"