#ifndef ECODE_PROJECTDIRECTORYTREE_HPP #define ECODE_PROJECTDIRECTORYTREE_HPP #include "ignorematcher.hpp" #include "plugins/pluginmanager.hpp" #include #include #include #include #include #include #include #include #include #include #include #include using namespace EE; using namespace EE::System; using namespace EE::UI; using namespace EE::UI::Models; namespace ecode { class App; class FileListModel : public Model { public: FileListModel( const std::vector& files, const std::vector& names ) : mFiles( files ), mNames( names ), mIcons( mNames.size(), nullptr ) {} virtual size_t rowCount( const ModelIndex& ) const { return mNames.size(); } virtual size_t columnCount( const ModelIndex& ) const { return 2; } virtual std::string columnName( const size_t& index ) const { return index == 0 ? "Name" : "Path"; } virtual Variant data( const ModelIndex& index, ModelRole role = ModelRole::Display ) const { if ( index.row() >= (Int64)mFiles.size() ) return {}; switch ( role ) { case ModelRole::Icon: return Variant( iconFor( index ) ); case ModelRole::Display: return Variant( index.column() == 0 ? mNames[index.row()].c_str() : mFiles[index.row()].c_str() ); default: break; } return {}; } void setIcon( size_t idx, UIIcon* icon ) { eeASSERT( idx < mIcons.size() ); mIcons[idx] = icon; } virtual void update() { onModelUpdate(); } protected: std::vector mFiles; std::vector mNames; mutable std::vector mIcons; UIIcon* iconFor( const ModelIndex& index ) const { if ( index.column() == 0 ) { if ( mIcons[index.row()] ) return mIcons[index.row()]; auto* scene = SceneManager::instance()->getUISceneNode(); auto* d = scene->findIcon( UIIconThemeManager::getIconNameFromFileName( mNames[index.row()], true ) ); if ( !d ) d = scene->findIcon( "file" ); mIcons[index.row()] = d; return d; } return nullptr; } }; class ProjectDirectoryTree { public: enum Action { /// Sent when a file is created or renamed Add = 1, /// Sent when a file is deleted or renamed Delete = 2, /// Sent when a file is modified Modified = 3, /// Sent when a file is moved Moved = 4 }; typedef std::function ScanCompleteEvent; typedef std::function )> MatchResultCb; ProjectDirectoryTree( const std::string& path, std::shared_ptr threadPool, App* app ); ~ProjectDirectoryTree(); void scan( const ScanCompleteEvent& scanComplete, const std::vector& acceptedPatterns = {}, const bool& ignoreHidden = true ); std::shared_ptr fuzzyMatchTree( const std::vector& matches, const size_t& max ) const; std::shared_ptr fuzzyMatchTree( const std::string& match, const size_t& max ) const; std::shared_ptr matchTree( const std::string& match, const size_t& max ) const; void asyncFuzzyMatchTree( const std::string& match, const size_t& max, MatchResultCb res ) const; void asyncMatchTree( const std::string& match, const size_t& max, MatchResultCb res ) const; struct CommandInfo { std::string name; std::string desc; UIIcon* icon{ nullptr }; }; std::shared_ptr asModel( const size_t& max, const std::vector& prependCommands = {} ) const; static std::shared_ptr emptyModel( const std::vector& prependCommands = {} ); size_t getFilesCount() const; const std::vector& getFiles() const; const std::vector& getDirectories() const; bool isFileInTree( const std::string& filePath ) const; bool isDirInTree( const std::string& dirTree ) const; void onChange( const Action& action, const FileInfo& file, const std::string& oldFilename ); const std::string& getPath() const { return mPath; } protected: std::string mPath; std::shared_ptr mPool; std::vector mFiles; std::vector mNames; std::vector mDirectories; std::vector mAcceptedPatterns; std::unique_ptr mAllowedMatcher; bool mRunning; bool mIsReady; bool mIgnoreHidden; mutable Mutex mFilesMutex; mutable Mutex mMatchingMutex; IgnoreMatcherManager mIgnoreMatcher; App* mApp{ nullptr }; void getDirectoryFiles( std::vector& files, std::vector& names, std::string directory, std::set currentDirs, const bool& ignoreHidden, IgnoreMatcherManager& ignoreMatcher, GitIgnoreMatcher* allowedMatcher ); void addFile( const FileInfo& file ); void tryAddFile( const FileInfo& file ); void moveFile( const FileInfo& file, const std::string& oldFilename ); void removeFile( const FileInfo& file ); IgnoreMatcherManager getIgnoreMatcherFromPath( const std::string& path ); size_t findFileIndex( const std::string& path ); PluginRequestHandle processMessage( const PluginMessage& msg ); }; } // namespace ecode #endif // ECODE_PROJECTDIRECTORYTREE_HPP