diff --git a/project/projectmodel.h b/project/projectmodel.h index 19f43d772b..89e037fd03 100644 --- a/project/projectmodel.h +++ b/project/projectmodel.h @@ -1,492 +1,491 @@ /* This file is part of KDevelop Copyright 2005 Roberto Raggi Copyright 2007 Andreas Pakulat Copyright 2007 Aleix Pol This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEVPLATFORM_PROJECTMODEL_H #define KDEVPLATFORM_PROJECTMODEL_H #include #include #include "projectexport.h" #include template struct QPair; template class QList; namespace KDevelop { class IProject; class ProjectFolderItem; class ProjectBuildFolderItem; class ProjectFileItem; class ProjectTargetItem; class ProjectExecutableTargetItem; class ProjectLibraryTargetItem; class ProjectModel; class IndexedString; class Path; /** * Base class to implement the visitor pattern for the project item tree. * * Feel free to subclass it and add overloads for the methods corresponding * to the items you are interested in. * * Start visiting using one of the visit methods. */ class KDEVPLATFORMPROJECT_EXPORT ProjectVisitor { public: ProjectVisitor(); virtual ~ProjectVisitor(); /** * Visit the whole project model tree. */ virtual void visit( ProjectModel* ); /** * Visit the tree starting from the project root item. */ virtual void visit( IProject* ); /** * Visit the folder and anything it contains. */ virtual void visit( ProjectFolderItem* ); /** * Visit the file. */ virtual void visit( ProjectFileItem* ); /** * Visit the build folder and anything it contains. */ virtual void visit( ProjectBuildFolderItem* ); /** * Visit the target and all children it may contain. */ virtual void visit( ProjectExecutableTargetItem* ); /** * Visit the target and all children it may contain. */ virtual void visit( ProjectLibraryTargetItem* ); }; /** * Interface that allows a developer to implement the three basic types of * items you would see in a multi-project * \li Folder * \li Project * \li Custom Target * \li Library Target * \li Executable Target * \li File */ class KDEVPLATFORMPROJECT_EXPORT ProjectBaseItem { public: ProjectBaseItem( IProject*, const QString &name, ProjectBaseItem *parent = nullptr ); virtual ~ProjectBaseItem(); enum ProjectItemType { BaseItem = 0 /** item is a base item */, BuildFolder = 1 /** item is a buildable folder */, Folder = 2 /** item is a folder */, ExecutableTarget = 3 /** item is an executable target */, LibraryTarget = 4 /** item is a library target */, Target = 5 /** item is a target */, File = 6 /** item is a file */, CustomProjectItemType = 100 /** type which should be used as base for custom types */ }; enum RenameStatus { RenameOk = 0, ExistingItemSameName = 1, ProjectManagerRenameFailed = 2, InvalidNewName = 3 }; /** @returns Returns the project that the item belongs to. */ IProject* project() const; /** @returns If this item is a folder, it returns a pointer to the folder, otherwise returns a 0 pointer. */ virtual ProjectFolderItem *folder() const; /** @returns If this item is a target, it returns a pointer to the target, otherwise returns a 0 pointer. */ virtual ProjectTargetItem *target() const; /** @returns If this item is a file, it returns a pointer to the file, otherwise returns a 0 pointer. */ virtual ProjectFileItem *file() const; /** @returns If this item is a file, it returns a pointer to the file, otherwise returns a 0 pointer. */ virtual ProjectExecutableTargetItem *executable() const; /** @returns Returns a list of the folders that have this object as the parent. */ QList folderList() const; /** @returns Returns a list of the targets that have this object as the parent. */ QList targetList() const; /** @returns Returns a list of the files that have this object as the parent. */ QList fileList() const; virtual bool lessThan( const KDevelop::ProjectBaseItem* ) const; static bool pathLessThan(KDevelop::ProjectBaseItem* item1, KDevelop::ProjectBaseItem* item2); /** @returns the @p row item in the list of children of this item or 0 if there is no such child. */ ProjectBaseItem* child( int row ) const; /** @returns the list of children of this item. */ QList children() const; /** @returns a valid QModelIndex for usage with the model API for this item. */ QModelIndex index() const; /** @returns The parent item if this item has one, else it return 0. */ virtual ProjectBaseItem* parent() const; /** @returns the displayed text of this item. */ QString text() const; /** @returns the row in the list of children of this items parent, or -1. */ int row() const; /** @returns the number of children of this item, or 0 if there are none. */ int rowCount() const; /** @returns the model to which this item belongs, or 0 if its not associated to a model. */ ProjectModel* model() const; /** * Adds a new child item to this item. */ void appendRow( ProjectBaseItem* item ); /** * Removes and deletes the item at the given @p row if there is one. */ void removeRow( int row ); /** * Removes and deletes the @p count items after the given @p row if there is one. */ void removeRows( int row, int count ); /** * Returns and removes the item at the given @p row if there is one. */ ProjectBaseItem* takeRow( int row ); /** @returns RTTI info, allows one to know the type of item */ virtual int type() const; /** @returns a string to pass to QIcon::fromTheme() as icon-name suitable to represent this item. */ virtual QString iconName() const; /** * Set the path of this item. * * @note This function never renames the item in the project manager or * on the filesystem, it only changes the path and possibly the text nothing else. */ virtual void setPath( const Path& ); /** * @returns the path of this item. */ Path path() const; /** * @returns the basename of this items path (if any) * * Convenience function, returns the same as @c text() for most items. */ QString baseName() const; /** * Renames the item to the new name. * @returns status information whether the renaming succeeded. */ virtual RenameStatus rename( const QString& newname ); bool isProjectRoot() const; /** * Default flags: Qt::ItemIsEnabled | Qt::ItemIsSelectable * * @returns the flags supported by the item */ virtual Qt::ItemFlags flags(); /** * Sets what flags should be returned by ::flags() method. */ void setFlags(Qt::ItemFlags flags); protected: /** * Allows to change the displayed text of this item. * * Most items assume text == baseName so this is *not* public. * * @param text the new text */ void setText( const QString& text ); class ProjectBaseItemPrivate* const d_ptr; - ProjectBaseItem( ProjectBaseItemPrivate& dd ); void setRow( int row ); void setModel( ProjectModel* model ); private: Q_DECLARE_PRIVATE(ProjectBaseItem) friend class ProjectModel; }; /** * Implementation of the ProjectBaseItem interface that is specific to a * folder */ class KDEVPLATFORMPROJECT_EXPORT ProjectFolderItem: public ProjectBaseItem { public: /** * Create a new ProjectFolderItem with the given @p path and an optional @p parent * in the given @p project. */ ProjectFolderItem( IProject* project, const Path& path, ProjectBaseItem* parent = nullptr ); /** * Create a child ProjectFolderItem of @p parent with @p name. * * The path is set automatically. */ ProjectFolderItem( const QString& name, ProjectBaseItem *parent ); ~ProjectFolderItem() override; void setPath(const Path& ) override; ProjectFolderItem *folder() const override; ///Reimplemented from QStandardItem int type() const override; /** * Get the folder name, equal to path().fileName() or text(). */ QString folderName() const; /** @returns Returns whether this folder directly contains the specified file or folder. */ bool hasFileOrFolder(const QString& name) const; QString iconName() const override; RenameStatus rename(const QString& newname) override; private: void propagateRename( const Path& newBase ) const; }; /** * Folder which contains buildable targets as part of a buildable project */ class KDEVPLATFORMPROJECT_EXPORT ProjectBuildFolderItem: public ProjectFolderItem { public: /** * Create a new ProjectBuildFolderItem with the given @p path with the optional * parent @p parent in the given @p project. */ ProjectBuildFolderItem( IProject* project, const Path &path, ProjectBaseItem* parent = nullptr ); /** * Create a child ProjectBuildFolderItem of @p parent with @p name. * * The path is set automatically. */ ProjectBuildFolderItem( const QString &name, ProjectBaseItem *parent ); ///Reimplemented from QStandardItem int type() const override; QString iconName() const override; }; /** * Object which represents a target in a build system. * * This object contains all properties specific to a target. */ class KDEVPLATFORMPROJECT_EXPORT ProjectTargetItem: public ProjectBaseItem { public: ProjectTargetItem( IProject*, const QString &name, ProjectBaseItem *parent = nullptr ); ///Reimplemented from QStandardItem int type() const override; ProjectTargetItem *target() const override; QString iconName() const override; void setPath(const Path& path ) override; }; /** * Object which represents an executable target in a build system. * * This object contains all properties specific to an executable. */ class KDEVPLATFORMPROJECT_EXPORT ProjectExecutableTargetItem: public ProjectTargetItem { public: ProjectExecutableTargetItem( IProject*, const QString &name, ProjectBaseItem *parent = nullptr ); ProjectExecutableTargetItem *executable() const override; int type() const override; virtual QUrl builtUrl() const=0; virtual QUrl installedUrl() const=0; }; /** * Object which represents a library target in a build system. * * This object contains all properties specific to a library. */ class KDEVPLATFORMPROJECT_EXPORT ProjectLibraryTargetItem: public ProjectTargetItem { public: ProjectLibraryTargetItem(IProject* project, const QString &name, ProjectBaseItem *parent = nullptr ); int type() const override; }; /** * Object which represents a file. */ class KDEVPLATFORMPROJECT_EXPORT ProjectFileItem: public ProjectBaseItem { public: /** * Create a new ProjectFileItem with the given @p path and an optional @p parent * in the given @p project. */ ProjectFileItem( IProject* project, const Path& path, ProjectBaseItem* parent = nullptr ); /** * Create a child ProjectFileItem of @p parent with the given @p name. * * The path is set automatically. */ ProjectFileItem( const QString& name, ProjectBaseItem *parent ); ~ProjectFileItem() override; ///Reimplemented from QStandardItem int type() const override; ProjectFileItem *file() const override; /** * @returns the file name, equal to path().fileName() or text() */ QString fileName() const; void setPath( const Path& ) override; QString iconName() const override; RenameStatus rename(const QString& newname) override; /** * @return the items indexed path, which is often required for performant * lookups or memory efficient storage. */ IndexedString indexedPath() const; }; /** * Class providing some convenience methods for accessing the project model * @todo: maybe switch to QAbstractItemModel, would make the implementation * for at least the checkbox-behaviour easier */ class KDEVPLATFORMPROJECT_EXPORT ProjectModel: public QAbstractItemModel { Q_OBJECT public: enum Roles { ProjectRole = Qt::UserRole+1 , ProjectItemRole , UrlRole , LastRole }; explicit ProjectModel( QObject *parent = nullptr ); ~ProjectModel() override; void clear(); void appendRow( ProjectBaseItem* item ); void removeRow( int row ); ProjectBaseItem* takeRow( int row ); ProjectBaseItem* itemAt( int row ) const; QList topItems() const; QModelIndex pathToIndex(const QStringList& tofetch) const; QStringList pathFromIndex(const QModelIndex& index) const; QModelIndex indexFromItem( const ProjectBaseItem* item ) const; ProjectBaseItem* itemFromIndex( const QModelIndex& ) const; int columnCount( const QModelIndex& parent = QModelIndex() ) const override; QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override; QModelIndex parent( const QModelIndex& child ) const override; int rowCount( const QModelIndex& parent = QModelIndex() ) const override; QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; bool insertColumns(int column, int count, const QModelIndex& parent = QModelIndex()) override; bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()) override; Qt::ItemFlags flags(const QModelIndex& index) const override; Qt::DropActions supportedDropActions() const override; /** * @return all items for the given indexed path. */ QList itemsForPath(const IndexedString& path) const; /** * Returns the first item for the given indexed path. */ ProjectBaseItem* itemForPath(const IndexedString& path) const; private: class ProjectModelPrivate* const d; friend class ProjectBaseItem; }; KDEVPLATFORMPROJECT_EXPORT QStringList joinProjectBasePath( const QStringList& partialpath, KDevelop::ProjectBaseItem* item ); KDEVPLATFORMPROJECT_EXPORT QStringList removeProjectBasePath( const QStringList& fullpath, KDevelop::ProjectBaseItem* item ); } Q_DECLARE_METATYPE(KDevelop::ProjectBaseItem*) Q_DECLARE_METATYPE(KDevelop::ProjectFolderItem*) Q_DECLARE_METATYPE(KDevelop::ProjectFileItem*) Q_DECLARE_METATYPE(KDevelop::ProjectLibraryTargetItem*) Q_DECLARE_METATYPE(KDevelop::ProjectExecutableTargetItem*) Q_DECLARE_METATYPE(KDevelop::ProjectTargetItem*) Q_DECLARE_METATYPE(KDevelop::ProjectBuildFolderItem*) Q_DECLARE_METATYPE(QList) #endif // KDEVPLATFORM_PROJECTMODEL_H