diff --git a/include/eepp/core/memorymanager.hpp b/include/eepp/core/memorymanager.hpp index 9ea36da65..6a709be4e 100644 --- a/include/eepp/core/memorymanager.hpp +++ b/include/eepp/core/memorymanager.hpp @@ -45,10 +45,14 @@ class EE_API MemoryManager { template static T* free( T* Data ) { ::free( Data ); +#if defined( __GNUC__ ) && __GNUC__ >= 12 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wuse-after-free" return Data; #pragma GCC diagnostic pop +#else + return Data; +#endif } inline static void* allocate( size_t size ) { diff --git a/include/eepp/system/fileinfo.hpp b/include/eepp/system/fileinfo.hpp index 049cc718a..f5c449a98 100644 --- a/include/eepp/system/fileinfo.hpp +++ b/include/eepp/system/fileinfo.hpp @@ -76,6 +76,7 @@ class EE_API FileInfo { protected: mutable std::string mFilepath; + std::string mFileName; Uint64 mModificationTime{ 0 }; Uint64 mSize{ 0 }; Uint32 mOwnerId{ 0 }; diff --git a/include/eepp/ui/models/filesystemmodel.hpp b/include/eepp/ui/models/filesystemmodel.hpp index bfe3791ad..2ea0e73f8 100644 --- a/include/eepp/ui/models/filesystemmodel.hpp +++ b/include/eepp/ui/models/filesystemmodel.hpp @@ -95,6 +95,8 @@ class EE_API FileSystemModel : public Model { void invalidate(); + bool inParentTree( Node* parent ) const; + Node* findChildName( const std::string& name, const FileSystemModel& model, bool forceRefresh = false ); @@ -113,6 +115,8 @@ class EE_API FileSystemModel : public Model { Node* createChild( const std::string& childName, const FileSystemModel& model ); + void rename( const FileInfo& file ); + friend class FileSystemModel; std::string mName; std::string mMimeType; diff --git a/src/eepp/system/fileinfo.cpp b/src/eepp/system/fileinfo.cpp index 5c1b493c6..4323152eb 100644 --- a/src/eepp/system/fileinfo.cpp +++ b/src/eepp/system/fileinfo.cpp @@ -65,6 +65,7 @@ FileInfo::FileInfo() : FileInfo::FileInfo( const std::string& filepath ) : mFilepath( filepath ), + mFileName( FileSystem::fileNameFromPath( filepath ) ), mModificationTime( 0 ), mOwnerId( 0 ), mGroupId( 0 ), @@ -75,6 +76,7 @@ FileInfo::FileInfo( const std::string& filepath ) : FileInfo::FileInfo( const std::string& filepath, bool linkInfo ) : mFilepath( filepath ), + mFileName( FileSystem::fileNameFromPath( filepath ) ), mModificationTime( 0 ), mOwnerId( 0 ), mGroupId( 0 ), @@ -89,6 +91,7 @@ FileInfo::FileInfo( const std::string& filepath, bool linkInfo ) : FileInfo::FileInfo( const FileInfo& other ) : mFilepath( other.mFilepath ), + mFileName( other.mFileName ), mModificationTime( other.mModificationTime ), mSize( other.mSize ), mOwnerId( other.mOwnerId ), @@ -158,12 +161,7 @@ const std::string& FileInfo::getFilepath() const { } std::string FileInfo::getFileName() const { - if ( !mFilepath.empty() && mFilepath[mFilepath.size() - 1] != '\\' && - mFilepath[mFilepath.size() - 1] != '/' ) - return FileSystem::fileNameFromPath( mFilepath ); - std::string path( mFilepath ); - FileSystem::dirRemoveSlashAtEnd( mFilepath ); - return FileSystem::fileNameFromPath( path ); + return mFileName; } std::string FileInfo::getDirectoryPath() const { @@ -276,6 +274,7 @@ bool FileInfo::exists() const { FileInfo& FileInfo::operator=( const FileInfo& other ) { this->mFilepath = other.mFilepath; + this->mFileName = other.mFileName; this->mSize = other.mSize; this->mModificationTime = other.mModificationTime; this->mGroupId = other.mGroupId; diff --git a/src/eepp/ui/models/filesystemmodel.cpp b/src/eepp/ui/models/filesystemmodel.cpp index 4241dfa06..6fad20d14 100644 --- a/src/eepp/ui/models/filesystemmodel.cpp +++ b/src/eepp/ui/models/filesystemmodel.cpp @@ -5,6 +5,10 @@ #include #include +#ifndef INDEX_ALREADY_EXISTS +#define INDEX_ALREADY_EXISTS eeINDEX_NOT_FOUND +#endif + using namespace EE::Scene; namespace EE { namespace UI { namespace Models { @@ -42,6 +46,16 @@ void FileSystemModel::Node::invalidate() { mInfoDirty = true; } +bool FileSystemModel::Node::inParentTree( Node* parent ) const { + Node* parentLoop = mParent; + while ( parentLoop != nullptr ) { + if ( parentLoop == parent ) + return true; + parentLoop = parentLoop->getParent(); + } + return false; +} + FileSystemModel::Node* FileSystemModel::Node::findChildName( const std::string& name, const FileSystemModel& model, bool forceRefresh ) { @@ -99,6 +113,11 @@ FileSystemModel::Node* FileSystemModel::Node::createChild( const std::string& ch return child; } +void FileSystemModel::Node::rename( const FileInfo& file ) { + mInfo = file; + mName = file.getFileName(); +} + ModelIndex FileSystemModel::Node::index( const FileSystemModel& model, int column ) const { if ( !mParent ) return {}; @@ -433,6 +452,9 @@ size_t FileSystemModel::getFileIndex( Node* parent, const FileInfo& file ) { for ( Node* nodeFile : parent->mChildren ) { files.emplace_back( nodeFile->info() ); + + if ( nodeFile->info().getFileName() == file.getFileName() ) + return INDEX_ALREADY_EXISTS; } files.emplace_back( file ); @@ -499,6 +521,9 @@ bool FileSystemModel::handleFileEventLocked( const FileEvent& event ) { case FileSystemEventType::Add: { FileInfo file( event.directory + event.filename ); + if ( !file.exists() ) + return false; + if ( ( getMode() == Mode::DirectoriesOnly && !file.isDirectory() ) || ( getDisplayConfig().ignoreHidden && file.isHidden() ) ) return false; @@ -519,6 +544,9 @@ bool FileSystemModel::handleFileEventLocked( const FileEvent& event ) { if ( !childNode->getName().empty() ) { size_t pos = getFileIndex( parent, file ); + if ( pos == INDEX_ALREADY_EXISTS ) + return false; + beginInsertRows( parent->index( *this, 0 ), pos, pos ); if ( pos >= parent->mChildren.size() ) { @@ -572,14 +600,12 @@ bool FileSystemModel::handleFileEventLocked( const FileEvent& event ) { beginDeleteRows( index.parent(), index.row(), index.row() ); - eeDelete( parent->mChildren[index.row()] ); - parent->mChildren.erase( parent->mChildren.begin() + index.row() ); - - endDeleteRows(); - forEachView( [&]( UIAbstractView* view ) { view->getSelection().removeAllMatching( [&]( auto& selectionIndex ) { - return selectionIndex.internalData() == index.internalData(); + Node* node = static_cast( index.internalData() ); + Node* nodeSelected = static_cast( selectionIndex.internalData() ); + return selectionIndex.internalData() == index.internalData() || + ( node->childCount() > 0 && nodeSelected->inParentTree( node ) ); } ); std::vector newIndexes; view->getSelection().forEachIndex( [&]( const ModelIndex& selectedIndex ) { @@ -601,14 +627,18 @@ bool FileSystemModel::handleFileEventLocked( const FileEvent& event ) { view->getSelection().set( newIndexes, false ); } ); + eeDelete( parent->mChildren[index.row()] ); + parent->mChildren.erase( parent->mChildren.begin() + index.row() ); + + endDeleteRows(); + break; } case FileSystemEventType::Moved: { FileInfo file( event.directory + event.filename ); if ( file.exists() ) { - auto* node = getNodeFromPath( event.directory + event.oldFilename, - file.isDirectory(), false ); + auto* node = getNodeFromPath( event.directory + event.oldFilename, false, false ); if ( node ) { ModelIndex index = node->index( *this, 0 ); if ( !index.isValid() ) @@ -627,11 +657,18 @@ bool FileSystemModel::handleFileEventLocked( const FileEvent& event ) { { FileSystemEventType::Delete, event.directory, event.oldFilename } ); } + Node* childNode = parent->mChildren[index.row()]; + childNode->rename( file ); + parent->mChildren.erase( parent->mChildren.begin() + index.row() ); + size_t pos = getFileIndex( node->getParent(), file ); - if ( pos != SIZE_MAX ) - beginMoveRows( index.parent(), index.row(), index.row(), index.parent(), - pos ); + // Don't add the file if already exists (if moved an old file to another old + // file) + if ( pos == INDEX_ALREADY_EXISTS ) { + eeDelete( childNode ); + return false; + } std::map> keptSelections; std::map> prevSelections; @@ -652,9 +689,7 @@ bool FileSystemModel::handleFileEventLocked( const FileEvent& event ) { } ); } ); - eeDelete( parent->mChildren[index.row()] ); - parent->mChildren.erase( parent->mChildren.begin() + index.row() ); - Node* childNode = parent->createChild( file.getFileName(), *this ); + beginMoveRows( index.parent(), index.row(), index.row(), index.parent(), pos ); if ( pos >= parent->mChildren.size() ) { parent->mChildren.emplace_back( childNode ); @@ -662,8 +697,7 @@ bool FileSystemModel::handleFileEventLocked( const FileEvent& event ) { parent->mChildren.insert( parent->mChildren.begin() + pos, childNode ); } - if ( pos != SIZE_MAX ) - endMoveRows(); + endMoveRows(); forEachView( [&]( UIAbstractView* view ) { std::vector names = prevSelections[view]; diff --git a/src/thirdparty/SOIL2 b/src/thirdparty/SOIL2 index 200fac61d..db0218fae 160000 --- a/src/thirdparty/SOIL2 +++ b/src/thirdparty/SOIL2 @@ -1 +1 @@ -Subproject commit 200fac61db85e538efc64f54d523f98074604d8a +Subproject commit db0218fae63187613d07f812ab91fdf920b22fb7 diff --git a/src/thirdparty/efsw b/src/thirdparty/efsw index 74ca09bff..41feca17c 160000 --- a/src/thirdparty/efsw +++ b/src/thirdparty/efsw @@ -1 +1 @@ -Subproject commit 74ca09bff89bc8de1f7b8bf3faaa6275ce23b4c5 +Subproject commit 41feca17c0a4ec85b78552d8cb7eb641149b8735