File indexing completed on 2024-05-05 04:40:53
0001 /* 0002 SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-only 0005 */ 0006 0007 #ifndef PROJECT_FILE_QUICKOPEN 0008 #define PROJECT_FILE_QUICKOPEN 0009 0010 #include <language/interfaces/quickopendataprovider.h> 0011 #include <language/interfaces/quickopenfilter.h> 0012 #include <serialization/indexedstring.h> 0013 0014 #include <util/path.h> 0015 0016 #include <utility> 0017 0018 namespace KDevelop { 0019 class IProject; 0020 class ProjectFileItem; 0021 } 0022 0023 /** 0024 * Internal data class for the BaseFileDataProvider and ProjectFileData. 0025 */ 0026 struct ProjectFile 0027 { 0028 ProjectFile() = default; 0029 explicit ProjectFile(const KDevelop::ProjectFileItem*); 0030 0031 KDevelop::Path path; 0032 // project root folder url 0033 KDevelop::Path projectPath; 0034 // indexed url - only set for project files 0035 // currently open documents don't use this! 0036 KDevelop::IndexedString indexedPath; 0037 // true for files which reside outside of the project root 0038 // this happens e.g. for generated files in out-of-source build folders 0039 bool outsideOfProject = false; 0040 }; 0041 0042 inline void swap(ProjectFile& a, ProjectFile& b) noexcept 0043 { 0044 using std::swap; 0045 swap(a.path, b.path); 0046 swap(a.projectPath, b.projectPath); 0047 swap(a.indexedPath, b.indexedPath); 0048 swap(a.outsideOfProject, b.outsideOfProject); 0049 } 0050 0051 inline bool operator<(const ProjectFile& left, const ProjectFile& right) 0052 { 0053 if (left.outsideOfProject != right.outsideOfProject) { 0054 // place the less interesting generated files at the end 0055 return !left.outsideOfProject; 0056 } 0057 const int comparison = left.path.compare(right.path, Qt::CaseInsensitive); 0058 if (comparison != 0) { 0059 return comparison < 0; 0060 } 0061 // Only paths that are completely, case-sensitively equal are considered 0062 // duplicates. Comparing indexed paths here when the paths are 0063 // case-insensitively equal ensures that: 0064 // * the duplicates are adjacent and thus detected by std::unique; 0065 // * binary search algorithms find only case-sensitively equal elements. 0066 // OpenFilesDataProvider default-initializes all its indexed paths making 0067 // them all equal to each other. This is fine because OpenFilesDataProvider 0068 // doesn't use std::unique or binary search algorithms. 0069 return left.indexedPath < right.indexedPath; 0070 } 0071 0072 Q_DECLARE_TYPEINFO(ProjectFile, Q_MOVABLE_TYPE); 0073 0074 /** 0075 * The shared data class that is used by the quick open model. 0076 */ 0077 class ProjectFileData 0078 : public KDevelop::QuickOpenDataBase 0079 { 0080 public: 0081 explicit ProjectFileData(const ProjectFile& file); 0082 0083 QString text() const override; 0084 QString htmlDescription() const override; 0085 0086 bool execute(QString& filterText) override; 0087 0088 bool isExpandable() const override; 0089 QWidget* expandingWidget() const override; 0090 0091 QIcon icon() const override; 0092 0093 QList<QVariant> highlighting() const override; 0094 0095 QString project() const; 0096 0097 KDevelop::Path projectPath() const; 0098 0099 private: 0100 const ProjectFile m_file; 0101 }; 0102 0103 class BaseFileDataProvider 0104 : public KDevelop::QuickOpenDataProviderBase 0105 , public KDevelop::PathFilter<ProjectFile, BaseFileDataProvider> 0106 , public KDevelop::QuickOpenFileSetInterface 0107 { 0108 Q_OBJECT 0109 Q_INTERFACES(KDevelop::QuickOpenFileSetInterface) 0110 0111 public: 0112 BaseFileDataProvider(); 0113 void setFilterText(const QString& text) override; 0114 uint itemCount() const override; 0115 uint unfilteredItemCount() const override; 0116 KDevelop::QuickOpenDataPointer data(uint row) const override; 0117 0118 inline KDevelop::Path itemPath(const ProjectFile& data) const 0119 { 0120 return data.path; 0121 } 0122 0123 inline KDevelop::Path itemPrefixPath(const ProjectFile& data) const 0124 { 0125 return data.projectPath; 0126 } 0127 }; 0128 0129 /** 0130 * QuickOpen data provider for file-completion using project-files. 0131 * 0132 * It provides all files from all open projects except currently opened ones. 0133 */ 0134 class ProjectFileDataProvider 0135 : public BaseFileDataProvider 0136 { 0137 Q_OBJECT 0138 public: 0139 ProjectFileDataProvider(); 0140 void reset() override; 0141 QSet<KDevelop::IndexedString> files() const override; 0142 private Q_SLOTS: 0143 void projectClosing(KDevelop::IProject*); 0144 void projectOpened(KDevelop::IProject*); 0145 void fileAddedToSet(KDevelop::ProjectFileItem*); 0146 void fileRemovedFromSet(KDevelop::ProjectFileItem*); 0147 private: 0148 // project files sorted by their url 0149 // this is done so we can limit ourselves to a relatively fast 0150 // filtering without any expensive sorting in reset(). 0151 QVector<ProjectFile> m_projectFiles; 0152 }; 0153 0154 /** 0155 * Quick open data provider for currently opened documents. 0156 */ 0157 class OpenFilesDataProvider 0158 : public BaseFileDataProvider 0159 { 0160 Q_OBJECT 0161 public: 0162 void reset() override; 0163 QSet<KDevelop::IndexedString> files() const override; 0164 }; 0165 0166 #endif 0167