File indexing completed on 2024-04-28 04:37:05
0001 /* 0002 SPDX-FileCopyrightText: 2005 Roberto Raggi <roberto@kdevelop.org> 0003 SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de> 0004 SPDX-FileCopyrightText: 2007 Aleix Pol <aleixpol@gmail.com> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #ifndef KDEVPLATFORM_PROJECTMODEL_H 0010 #define KDEVPLATFORM_PROJECTMODEL_H 0011 0012 #include <QAbstractItemModel> 0013 #include <QUrl> 0014 0015 #include "projectexport.h" 0016 0017 template<typename T1,typename T2> struct QPair; 0018 template<typename T> class QList; 0019 0020 namespace KDevelop 0021 { 0022 0023 class IProject; 0024 class ProjectFolderItem; 0025 class ProjectBuildFolderItem; 0026 class ProjectFileItem; 0027 class ProjectTargetItem; 0028 class ProjectExecutableTargetItem; 0029 class ProjectLibraryTargetItem; 0030 class ProjectModel; 0031 class IndexedString; 0032 class Path; 0033 class ProjectModelPrivate; 0034 0035 /** 0036 * Base class to implement the visitor pattern for the project item tree. 0037 * 0038 * Feel free to subclass it and add overloads for the methods corresponding 0039 * to the items you are interested in. 0040 * 0041 * Start visiting using one of the visit methods. 0042 */ 0043 class KDEVPLATFORMPROJECT_EXPORT ProjectVisitor 0044 { 0045 public: 0046 ProjectVisitor(); 0047 virtual ~ProjectVisitor(); 0048 /** 0049 * Visit the whole project model tree. 0050 */ 0051 virtual void visit( ProjectModel* ); 0052 /** 0053 * Visit the tree starting from the project root item. 0054 */ 0055 virtual void visit( IProject* ); 0056 /** 0057 * Visit the folder and anything it contains. 0058 */ 0059 virtual void visit( ProjectFolderItem* ); 0060 /** 0061 * Visit the file. 0062 */ 0063 virtual void visit( ProjectFileItem* ); 0064 /** 0065 * Visit the build folder and anything it contains. 0066 */ 0067 virtual void visit( ProjectBuildFolderItem* ); 0068 /** 0069 * Visit the target and all children it may contain. 0070 */ 0071 virtual void visit( ProjectExecutableTargetItem* ); 0072 /** 0073 * Visit the target and all children it may contain. 0074 */ 0075 virtual void visit( ProjectLibraryTargetItem* ); 0076 }; 0077 0078 /** 0079 * Interface that allows a developer to implement the three basic types of 0080 * items you would see in a multi-project 0081 * \li Folder 0082 * \li Project 0083 * \li Custom Target 0084 * \li Library Target 0085 * \li Executable Target 0086 * \li File 0087 */ 0088 class KDEVPLATFORMPROJECT_EXPORT ProjectBaseItem 0089 { 0090 public: 0091 ProjectBaseItem( IProject*, const QString &name, ProjectBaseItem *parent = nullptr ); 0092 virtual ~ProjectBaseItem(); 0093 0094 0095 enum ProjectItemType 0096 { 0097 BaseItem = 0 /** item is a base item */, 0098 BuildFolder = 1 /** item is a buildable folder */, 0099 Folder = 2 /** item is a folder */, 0100 ExecutableTarget = 3 /** item is an executable target */, 0101 LibraryTarget = 4 /** item is a library target */, 0102 Target = 5 /** item is a target */, 0103 File = 6 /** item is a file */, 0104 CustomProjectItemType = 100 /** type which should be used as base for custom types */ 0105 }; 0106 0107 enum RenameStatus 0108 { 0109 RenameOk = 0, 0110 ExistingItemSameName = 1, 0111 ProjectManagerRenameFailed = 2, 0112 InvalidNewName = 3 0113 }; 0114 0115 /** @returns Returns the project that the item belongs to. */ 0116 IProject* project() const; 0117 0118 /** @returns If this item is a folder, it returns a pointer to the folder, otherwise returns a 0 pointer. */ 0119 virtual ProjectFolderItem *folder() const; 0120 0121 /** @returns If this item is a target, it returns a pointer to the target, otherwise returns a 0 pointer. */ 0122 virtual ProjectTargetItem *target() const; 0123 0124 /** @returns If this item is a file, it returns a pointer to the file, otherwise returns a 0 pointer. */ 0125 virtual ProjectFileItem *file() const; 0126 0127 /** @returns If this item is a file, it returns a pointer to the file, otherwise returns a 0 pointer. */ 0128 virtual ProjectExecutableTargetItem *executable() const; 0129 0130 /** @returns Returns a list of the folders that have this object as the parent. */ 0131 QList<ProjectFolderItem*> folderList() const; 0132 0133 /** @returns Returns a list of the targets that have this object as the parent. */ 0134 QList<ProjectTargetItem*> targetList() const; 0135 0136 /** @returns Returns a list of the files that have this object as the parent. */ 0137 QList<ProjectFileItem*> fileList() const; 0138 0139 virtual bool lessThan( const KDevelop::ProjectBaseItem* ) const; 0140 static bool pathLessThan(KDevelop::ProjectBaseItem* item1, KDevelop::ProjectBaseItem* item2); 0141 0142 /** @returns the @p row item in the list of children of this item or 0 if there is no such child. */ 0143 ProjectBaseItem* child( int row ) const; 0144 /** @returns the list of children of this item. */ 0145 QList<ProjectBaseItem*> children() const; 0146 /** @returns a valid QModelIndex for usage with the model API for this item. */ 0147 QModelIndex index() const; 0148 /** @returns The parent item if this item has one, else it return 0. */ 0149 virtual ProjectBaseItem* parent() const; 0150 /** @returns the displayed text of this item. */ 0151 QString text() const; 0152 /** @returns the row in the list of children of this items parent, or -1. */ 0153 int row() const; 0154 0155 /** @returns the number of children of this item, or 0 if there are none. */ 0156 int rowCount() const; 0157 0158 /** @returns the model to which this item belongs, or 0 if its not associated to a model. */ 0159 ProjectModel* model() const; 0160 0161 /** 0162 * Adds a new child item to this item. 0163 */ 0164 void appendRow( ProjectBaseItem* item ); 0165 0166 /** 0167 * Removes and deletes the item at the given @p row if there is one. 0168 */ 0169 void removeRow( int row ); 0170 0171 /** 0172 * Removes and deletes the @p count items after the given @p row if there is one. 0173 */ 0174 void removeRows( int row, int count ); 0175 0176 /** 0177 * Returns and removes the item at the given @p row if there is one. 0178 */ 0179 ProjectBaseItem* takeRow( int row ); 0180 0181 /** @returns RTTI info, allows one to know the type of item */ 0182 virtual int type() const; 0183 0184 /** @returns a string to pass to QIcon::fromTheme() as icon-name suitable to represent this item. */ 0185 virtual QString iconName() const; 0186 0187 /** 0188 * Set the path of this item. 0189 * 0190 * @note This function never renames the item in the project manager or 0191 * on the filesystem, it only changes the path and possibly the text nothing else. 0192 */ 0193 virtual void setPath( const Path& ); 0194 0195 /** 0196 * @returns the path of this item. 0197 */ 0198 Path path() const; 0199 0200 /** 0201 * @return the items indexed path, which is often required for performant 0202 * lookups or memory efficient storage. 0203 */ 0204 IndexedString indexedPath() const; 0205 0206 /** 0207 * @returns the basename of this items path (if any) 0208 * 0209 * Convenience function, returns the same as @c text() for most items. 0210 */ 0211 QString baseName() const; 0212 0213 /** 0214 * Renames the item to the new name. 0215 * @returns status information whether the renaming succeeded. 0216 */ 0217 virtual RenameStatus rename( const QString& newname ); 0218 0219 bool isProjectRoot() const; 0220 0221 /** 0222 * Default flags: Qt::ItemIsEnabled | Qt::ItemIsSelectable 0223 * 0224 * @returns the flags supported by the item 0225 */ 0226 virtual Qt::ItemFlags flags(); 0227 0228 /** 0229 * Sets what flags should be returned by flags() method. 0230 */ 0231 void setFlags(Qt::ItemFlags flags); 0232 0233 protected: 0234 /** 0235 * Allows to change the displayed text of this item. 0236 * 0237 * Most items assume text == baseName so this is *not* public. 0238 * 0239 * @param text the new text 0240 */ 0241 void setText( const QString& text ); 0242 0243 const QScopedPointer<class ProjectBaseItemPrivate> d_ptr; 0244 void setRow( int row ); 0245 void setModel( ProjectModel* model ); 0246 private: 0247 Q_DECLARE_PRIVATE(ProjectBaseItem) 0248 friend class ProjectModel; 0249 }; 0250 0251 /** 0252 * Implementation of the ProjectBaseItem interface that is specific to a 0253 * folder 0254 */ 0255 class KDEVPLATFORMPROJECT_EXPORT ProjectFolderItem: public ProjectBaseItem 0256 { 0257 public: 0258 /** 0259 * Create a new ProjectFolderItem with the given @p path and an optional @p parent 0260 * in the given @p project. 0261 */ 0262 ProjectFolderItem( IProject* project, const Path& path, ProjectBaseItem* parent = nullptr ); 0263 0264 /** 0265 * Create a child ProjectFolderItem of @p parent with @p name. 0266 * 0267 * The path is set automatically. 0268 */ 0269 ProjectFolderItem( const QString& name, ProjectBaseItem *parent ); 0270 0271 ~ProjectFolderItem() override; 0272 0273 void setPath(const Path& ) override; 0274 0275 ProjectFolderItem *folder() const override; 0276 0277 ///Reimplemented from QStandardItem 0278 int type() const override; 0279 0280 /** 0281 * Get the folder name, equal to path().fileName() or text(). 0282 */ 0283 QString folderName() const; 0284 0285 /** @returns Returns whether this folder directly contains the specified file or folder. */ 0286 bool hasFileOrFolder(const QString& name) const; 0287 0288 QString iconName() const override; 0289 RenameStatus rename(const QString& newname) override; 0290 0291 private: 0292 void propagateRename( const Path& newBase ) const; 0293 }; 0294 0295 0296 /** 0297 * Folder which contains buildable targets as part of a buildable project 0298 */ 0299 class KDEVPLATFORMPROJECT_EXPORT ProjectBuildFolderItem: public ProjectFolderItem 0300 { 0301 public: 0302 /** 0303 * Create a new ProjectBuildFolderItem with the given @p path with the optional 0304 * parent @p parent in the given @p project. 0305 */ 0306 ProjectBuildFolderItem( IProject* project, const Path &path, ProjectBaseItem* parent = nullptr ); 0307 /** 0308 * Create a child ProjectBuildFolderItem of @p parent with @p name. 0309 * 0310 * The path is set automatically. 0311 */ 0312 ProjectBuildFolderItem( const QString &name, ProjectBaseItem *parent ); 0313 0314 ///Reimplemented from QStandardItem 0315 int type() const override; 0316 QString iconName() const override; 0317 }; 0318 0319 /** 0320 * Object which represents a target in a build system. 0321 * 0322 * This object contains all properties specific to a target. 0323 */ 0324 class KDEVPLATFORMPROJECT_EXPORT ProjectTargetItem: public ProjectBaseItem 0325 { 0326 public: 0327 ProjectTargetItem( IProject*, const QString &name, ProjectBaseItem *parent = nullptr ); 0328 0329 ///Reimplemented from QStandardItem 0330 int type() const override; 0331 0332 ProjectTargetItem *target() const override; 0333 QString iconName() const override; 0334 void setPath(const Path& path ) override; 0335 }; 0336 0337 /** 0338 * Object which represents an executable target in a build system. 0339 * 0340 * This object contains all properties specific to an executable. 0341 */ 0342 class KDEVPLATFORMPROJECT_EXPORT ProjectExecutableTargetItem: public ProjectTargetItem 0343 { 0344 public: 0345 ProjectExecutableTargetItem( IProject*, const QString &name, ProjectBaseItem *parent = nullptr ); 0346 0347 ProjectExecutableTargetItem *executable() const override; 0348 int type() const override; 0349 virtual QUrl builtUrl() const=0; 0350 virtual QUrl installedUrl() const=0; 0351 }; 0352 0353 0354 /** 0355 * Object which represents a library target in a build system. 0356 * 0357 * This object contains all properties specific to a library. 0358 */ 0359 class KDEVPLATFORMPROJECT_EXPORT ProjectLibraryTargetItem: public ProjectTargetItem 0360 { 0361 public: 0362 ProjectLibraryTargetItem(IProject* project, const QString &name, ProjectBaseItem *parent = nullptr ); 0363 0364 int type() const override; 0365 }; 0366 0367 /** 0368 * Object which represents a file. 0369 */ 0370 class KDEVPLATFORMPROJECT_EXPORT ProjectFileItem: public ProjectBaseItem 0371 { 0372 public: 0373 /** 0374 * Create a new ProjectFileItem with the given @p path and an optional @p parent 0375 * in the given @p project. 0376 */ 0377 ProjectFileItem( IProject* project, const Path& path, ProjectBaseItem* parent = nullptr ); 0378 0379 /** 0380 * Create a child ProjectFileItem of @p parent with the given @p name. 0381 * 0382 * The path is set automatically. 0383 */ 0384 ProjectFileItem( const QString& name, ProjectBaseItem *parent ); 0385 ~ProjectFileItem() override; 0386 0387 ///Reimplemented from QStandardItem 0388 int type() const override; 0389 0390 ProjectFileItem *file() const override; 0391 0392 /** 0393 * @returns the file name, equal to path().fileName() or text() 0394 */ 0395 QString fileName() const; 0396 0397 void setPath( const Path& ) override; 0398 QString iconName() const override; 0399 RenameStatus rename(const QString& newname) override; 0400 }; 0401 0402 /** 0403 * Class providing some convenience methods for accessing the project model 0404 * @todo: maybe switch to QAbstractItemModel, would make the implementation 0405 * for at least the checkbox-behaviour easier 0406 */ 0407 class KDEVPLATFORMPROJECT_EXPORT ProjectModel: public QAbstractItemModel 0408 { 0409 Q_OBJECT 0410 public: 0411 enum Roles { 0412 ProjectRole = Qt::UserRole+1 0413 , ProjectItemRole 0414 , UrlRole 0415 , LastRole 0416 }; 0417 0418 explicit ProjectModel( QObject *parent = nullptr ); 0419 ~ProjectModel() override; 0420 0421 void clear(); 0422 0423 void appendRow( ProjectBaseItem* item ); 0424 void removeRow( int row ); 0425 ProjectBaseItem* takeRow( int row ); 0426 0427 ProjectBaseItem* itemAt( int row ) const; 0428 QList<ProjectBaseItem*> topItems() const; 0429 0430 QModelIndex pathToIndex(const QStringList& tofetch) const; 0431 QStringList pathFromIndex(const QModelIndex& index) const; 0432 0433 QModelIndex indexFromItem( const ProjectBaseItem* item ) const; 0434 ProjectBaseItem* itemFromIndex( const QModelIndex& ) const; 0435 0436 int columnCount( const QModelIndex& parent = QModelIndex() ) const override; 0437 QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override; 0438 QModelIndex parent( const QModelIndex& child ) const override; 0439 int rowCount( const QModelIndex& parent = QModelIndex() ) const override; 0440 QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; 0441 0442 bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; 0443 bool insertColumns(int column, int count, const QModelIndex& parent = QModelIndex()) override; 0444 bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()) override; 0445 0446 Qt::ItemFlags flags(const QModelIndex& index) const override; 0447 Qt::DropActions supportedDropActions() const override; 0448 0449 /** 0450 * @return all items for the given indexed path. 0451 */ 0452 QList<ProjectBaseItem*> itemsForPath(const IndexedString& path) const; 0453 0454 /** 0455 * Returns the first item for the given indexed path. 0456 */ 0457 ProjectBaseItem* itemForPath(const IndexedString& path) const; 0458 0459 private: 0460 const QScopedPointer<class ProjectModelPrivate> d_ptr; 0461 Q_DECLARE_PRIVATE(ProjectModel) 0462 friend class ProjectBaseItem; 0463 }; 0464 0465 KDEVPLATFORMPROJECT_EXPORT QStringList joinProjectBasePath( const QStringList& partialpath, KDevelop::ProjectBaseItem* item ); 0466 KDEVPLATFORMPROJECT_EXPORT QStringList removeProjectBasePath( const QStringList& fullpath, KDevelop::ProjectBaseItem* item ); 0467 0468 } 0469 0470 Q_DECLARE_METATYPE(KDevelop::ProjectBaseItem*) 0471 Q_DECLARE_METATYPE(KDevelop::ProjectFolderItem*) 0472 Q_DECLARE_METATYPE(KDevelop::ProjectFileItem*) 0473 Q_DECLARE_METATYPE(KDevelop::ProjectLibraryTargetItem*) 0474 Q_DECLARE_METATYPE(KDevelop::ProjectExecutableTargetItem*) 0475 Q_DECLARE_METATYPE(KDevelop::ProjectTargetItem*) 0476 Q_DECLARE_METATYPE(KDevelop::ProjectBuildFolderItem*) 0477 Q_DECLARE_METATYPE(QList<KDevelop::ProjectBaseItem*>) 0478 0479 #endif // KDEVPLATFORM_PROJECTMODEL_H