Add cross-directory filesystem move support

- enable efsw cross-directory move reporting in ecode
  - transfer FileSystemModel nodes between materialized parents
  - preserve selections, descendant paths, and lazy destination branches
  - update open document paths when parent directories move
  - fix persistent indexes across insert, delete, and move operations
  - clear stale tree-view metadata before model nodes are deleted
  - safely handle getRealPath() failures for stale paths
  - add model operation and filesystem move regression tests
  - update efsw and SOIL2 submodules
This commit is contained in:
Martín Lucas Golini
2026-08-17 22:42:52 -03:00
parent ffabb19d60
commit 1534253e54
17 changed files with 626 additions and 215 deletions
+6
View File
@@ -74,6 +74,10 @@ class EE_API FileInfo {
const Uint64& getInode() const;
const Uint64& getDevice() const;
const Uint64& getLinkCount() const;
bool isUninitialized() const;
std::string getExtension( const bool& lowerExt = true ) const;
@@ -87,6 +91,8 @@ class EE_API FileInfo {
Uint32 mGroupId{ 0 };
Uint32 mPermissions{ 0 };
Uint64 mInode{ 0 };
Uint64 mDevice{ 0 };
Uint64 mLinkCount{ 0 };
};
typedef std::map<std::string, FileInfo> FileInfoMap;
@@ -137,6 +137,8 @@ class EE_API UIAbstractView : public UIScrollableWidget {
virtual void onModelSelectionChange();
virtual void onModelIndexDeleted( const void* ) {}
void modelUpdate( unsigned flags );
UIAbstractView( const std::string& tag );
+1 -1
View File
@@ -228,7 +228,7 @@ class EE_API FileSystemModel : public Model {
const DisplayConfig& displayConfig, Translator* translator,
std::shared_ptr<ThreadPool> threadPool );
size_t getFileIndex( Node* parent, const FileInfo& file );
size_t getFileIndex( Node* parent, const FileInfo& file, const Node* excludedNode = nullptr );
bool handleFileEventLocked( const FileEvent& event );
+11
View File
@@ -174,6 +174,12 @@ class EE_API Model {
enum class Direction { Row, Column };
struct Operation {
struct PersistentMove {
ModelIndex index;
ModelIndex targetParent;
int targetDimension;
};
OperationType type{ OperationType::Invalid };
Direction direction{ Direction::Row };
ModelIndex sourceParent;
@@ -181,6 +187,7 @@ class EE_API Model {
int last{ 0 };
ModelIndex targetParent;
int target{ 0 };
std::vector<PersistentMove> persistentMoves;
Operation( OperationType type ) : type( type ) {}
@@ -206,6 +213,10 @@ class EE_API Model {
void handleInsert( Operation const& );
void handleMove( Operation const& );
void handleDelete( Operation const& );
void saveMovedIndices( Operation& );
void notifyIndexDeleted( const void* internalData ) const;
void applyPersistentIndexChanges(
const std::vector<std::pair<ModelIndex, ModelIndex>>& indexChanges );
template <bool IsRow> void saveDeletedIndices( ModelIndex const& parent, int first, int last );
@@ -18,7 +18,7 @@ class PersistentHandle {
ModelIndex mIndex;
};
class PersistentModelIndex {
class EE_API PersistentModelIndex {
public:
PersistentModelIndex() {}
PersistentModelIndex( ModelIndex const& );
+2
View File
@@ -165,6 +165,8 @@ class EE_API UITreeView : public UIAbstractTableView {
virtual void onColumnSizeChange( const size_t& colIndex, bool fromUserInteraction = false );
virtual void onModelIndexDeleted( const void* internalData );
virtual UIWidget* updateCell( const Vector2<Int64>& posIndex, const ModelIndex& index,
const size_t& indentLevel, const Float& yOffset );