sort files in sln explorer
This commit is contained in:
@@ -108,7 +108,17 @@ public class IdeFileExternalChangeHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
sharpIdeFile = new SharpIdeFile(filePath, Path.GetFileName(filePath), containingFolderOrProject, []);
|
sharpIdeFile = new SharpIdeFile(filePath, Path.GetFileName(filePath), containingFolderOrProject, []);
|
||||||
containingFolderOrProject.Files.Add(sharpIdeFile);
|
|
||||||
|
var correctInsertionPosition = containingFolderOrProject.Files.list.BinarySearch(sharpIdeFile, SharpIdeFileComparer.Instance);
|
||||||
|
if (correctInsertionPosition < 0)
|
||||||
|
{
|
||||||
|
correctInsertionPosition = ~correctInsertionPosition;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("File already exists in the containing folder or project");
|
||||||
|
}
|
||||||
|
containingFolderOrProject.Files.Insert(correctInsertionPosition, sharpIdeFile);
|
||||||
SolutionModel.AllFiles.Add(sharpIdeFile);
|
SolutionModel.AllFiles.Add(sharpIdeFile);
|
||||||
|
|
||||||
await _fileChangedService.SharpIdeFileAdded(sharpIdeFile, await File.ReadAllTextAsync(filePath));
|
await _fileChangedService.SharpIdeFileAdded(sharpIdeFile, await File.ReadAllTextAsync(filePath));
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ public class SharpIdeFolder : ISharpIdeNode, IExpandableSharpIdeNode, IChildShar
|
|||||||
public required string Path { get; set; }
|
public required string Path { get; set; }
|
||||||
public string ChildNodeBasePath => Path;
|
public string ChildNodeBasePath => Path;
|
||||||
public required string Name { get; set; }
|
public required string Name { get; set; }
|
||||||
public ObservableSortedSet<SharpIdeFile> Files { get; init; }
|
public ObservableList<SharpIdeFile> Files { get; init; }
|
||||||
public ObservableSortedSet<SharpIdeFolder> Folders { get; init; }
|
public ObservableList<SharpIdeFolder> Folders { get; init; }
|
||||||
public bool Expanded { get; set; }
|
public bool Expanded { get; set; }
|
||||||
|
|
||||||
[SetsRequiredMembers]
|
[SetsRequiredMembers]
|
||||||
@@ -21,8 +21,8 @@ public class SharpIdeFolder : ISharpIdeNode, IExpandableSharpIdeNode, IChildShar
|
|||||||
Parent = parent;
|
Parent = parent;
|
||||||
Path = folderInfo.FullName;
|
Path = folderInfo.FullName;
|
||||||
Name = folderInfo.Name;
|
Name = folderInfo.Name;
|
||||||
Files = new ObservableSortedSet<SharpIdeFile>(folderInfo.GetFiles(this, allFiles), SharpIdeFileComparer.Instance);
|
Files = new ObservableList<SharpIdeFile>(folderInfo.GetFiles(this, allFiles));
|
||||||
Folders = new ObservableSortedSet<SharpIdeFolder>(this.GetSubFolders(this, allFiles, allFolders), SharpIdeFolderComparer.Instance);
|
Folders = new ObservableList<SharpIdeFolder>(this.GetSubFolders(this, allFiles, allFolders));
|
||||||
}
|
}
|
||||||
|
|
||||||
public SharpIdeFolder()
|
public SharpIdeFolder()
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ public static class TreeMapperV2
|
|||||||
allFolders.Add(subFolder);
|
allFolders.Add(subFolder);
|
||||||
});
|
});
|
||||||
|
|
||||||
return subFolders.ToList();
|
var sharpIdeFolders = subFolders.ToList();
|
||||||
|
sharpIdeFolders.Sort(SharpIdeFolderComparer.Instance);
|
||||||
|
return sharpIdeFolders;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<SharpIdeFile> GetFiles(string csprojectPath, SharpIdeProjectModel sharpIdeProjectModel, ConcurrentBag<SharpIdeFile> allFiles)
|
public static List<SharpIdeFile> GetFiles(string csprojectPath, SharpIdeProjectModel sharpIdeProjectModel, ConcurrentBag<SharpIdeFile> allFiles)
|
||||||
@@ -73,11 +75,13 @@ public static class TreeMapperV2
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileInfos.Select(f => new SharpIdeFile(f.FullName, f.Name, parent, allFiles)
|
var sharpIdeFiles = fileInfos.Select(f => new SharpIdeFile(f.FullName, f.Name, parent, allFiles)
|
||||||
{
|
{
|
||||||
Path = f.FullName,
|
Path = f.FullName,
|
||||||
Name = f.Name,
|
Name = f.Name,
|
||||||
Parent = parent
|
Parent = parent
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
sharpIdeFiles.Sort(SharpIdeFileComparer.Instance);
|
||||||
|
return sharpIdeFiles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ public interface IExpandableSharpIdeNode
|
|||||||
|
|
||||||
public interface IFolderOrProject : IExpandableSharpIdeNode, IChildSharpIdeNode
|
public interface IFolderOrProject : IExpandableSharpIdeNode, IChildSharpIdeNode
|
||||||
{
|
{
|
||||||
public ObservableSortedSet<SharpIdeFolder> Folders { get; init; }
|
public ObservableList<SharpIdeFolder> Folders { get; init; }
|
||||||
public ObservableSortedSet<SharpIdeFile> Files { get; init; }
|
public ObservableList<SharpIdeFile> Files { get; init; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string ChildNodeBasePath { get; }
|
public string ChildNodeBasePath { get; }
|
||||||
}
|
}
|
||||||
@@ -50,9 +50,9 @@ public class SharpIdeSolutionModel : ISharpIdeNode, IExpandableSharpIdeNode
|
|||||||
public required string DirectoryPath { get; set; }
|
public required string DirectoryPath { get; set; }
|
||||||
public required ObservableHashSet<SharpIdeProjectModel> Projects { get; set; }
|
public required ObservableHashSet<SharpIdeProjectModel> Projects { get; set; }
|
||||||
public required ObservableHashSet<SharpIdeSolutionFolder> SlnFolders { get; set; }
|
public required ObservableHashSet<SharpIdeSolutionFolder> SlnFolders { get; set; }
|
||||||
public required HashSet<SharpIdeProjectModel> AllProjects { get; set; }
|
public required HashSet<SharpIdeProjectModel> AllProjects { get; set; } // TODO: this isn't thread safe
|
||||||
public required HashSet<SharpIdeFile> AllFiles { get; set; }
|
public required HashSet<SharpIdeFile> AllFiles { get; set; } // TODO: this isn't thread safe
|
||||||
public required HashSet<SharpIdeFolder> AllFolders { get; set; }
|
public required HashSet<SharpIdeFolder> AllFolders { get; set; } // TODO: this isn't thread safe
|
||||||
public bool Expanded { get; set; }
|
public bool Expanded { get; set; }
|
||||||
|
|
||||||
[SetsRequiredMembers]
|
[SetsRequiredMembers]
|
||||||
@@ -96,8 +96,8 @@ public class SharpIdeProjectModel : ISharpIdeNode, IExpandableSharpIdeNode, IChi
|
|||||||
public required string Name { get; set; }
|
public required string Name { get; set; }
|
||||||
public required string FilePath { get; set; }
|
public required string FilePath { get; set; }
|
||||||
public string ChildNodeBasePath => Path.GetDirectoryName(FilePath)!;
|
public string ChildNodeBasePath => Path.GetDirectoryName(FilePath)!;
|
||||||
public required ObservableSortedSet<SharpIdeFolder> Folders { get; init; }
|
public required ObservableList<SharpIdeFolder> Folders { get; init; }
|
||||||
public required ObservableSortedSet<SharpIdeFile> Files { get; init; }
|
public required ObservableList<SharpIdeFile> Files { get; init; }
|
||||||
public bool Expanded { get; set; }
|
public bool Expanded { get; set; }
|
||||||
public required IExpandableSharpIdeNode Parent { get; set; }
|
public required IExpandableSharpIdeNode Parent { get; set; }
|
||||||
public bool Running { get; set; }
|
public bool Running { get; set; }
|
||||||
@@ -110,8 +110,8 @@ public class SharpIdeProjectModel : ISharpIdeNode, IExpandableSharpIdeNode, IChi
|
|||||||
Parent = parent;
|
Parent = parent;
|
||||||
Name = projectModel.Model.ActualDisplayName;
|
Name = projectModel.Model.ActualDisplayName;
|
||||||
FilePath = projectModel.FullFilePath;
|
FilePath = projectModel.FullFilePath;
|
||||||
Files = new ObservableSortedSet<SharpIdeFile>(TreeMapperV2.GetFiles(projectModel.FullFilePath, this, allFiles), SharpIdeFileComparer.Instance);
|
Files = new ObservableList<SharpIdeFile>(TreeMapperV2.GetFiles(projectModel.FullFilePath, this, allFiles));
|
||||||
Folders = new ObservableSortedSet<SharpIdeFolder>(TreeMapperV2.GetSubFolders(projectModel.FullFilePath, this, allFiles, allFolders), SharpIdeFolderComparer.Instance);
|
Folders = new ObservableList<SharpIdeFolder>(TreeMapperV2.GetSubFolders(projectModel.FullFilePath, this, allFiles, allFolders));
|
||||||
MsBuildEvaluationProjectTask = ProjectEvaluation.GetProject(projectModel.FullFilePath);
|
MsBuildEvaluationProjectTask = ProjectEvaluation.GetProject(projectModel.FullFilePath);
|
||||||
allProjects.Add(this);
|
allProjects.Add(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ public partial class SolutionExplorerPanel : MarginContainer
|
|||||||
filesView.ObserveChanged()
|
filesView.ObserveChanged()
|
||||||
.SubscribeAwait(async (innerEvent, ct) => await (innerEvent.Action switch
|
.SubscribeAwait(async (innerEvent, ct) => await (innerEvent.Action switch
|
||||||
{
|
{
|
||||||
NotifyCollectionChangedAction.Add => this.InvokeAsync(() => innerEvent.NewItem.View.Value = CreateFileTreeItem(_tree, folderItem, innerEvent.NewItem.Value)),
|
NotifyCollectionChangedAction.Add => this.InvokeAsync(() => innerEvent.NewItem.View.Value = CreateFileTreeItem(_tree, folderItem, innerEvent.NewItem.Value, innerEvent.NewStartingIndex)),
|
||||||
NotifyCollectionChangedAction.Remove => FreeTreeItem(innerEvent.OldItem.View.Value),
|
NotifyCollectionChangedAction.Remove => FreeTreeItem(innerEvent.OldItem.View.Value),
|
||||||
_ => Task.CompletedTask
|
_ => Task.CompletedTask
|
||||||
})).AddTo(this);
|
})).AddTo(this);
|
||||||
@@ -236,7 +236,7 @@ public partial class SolutionExplorerPanel : MarginContainer
|
|||||||
filesView.ObserveChanged()
|
filesView.ObserveChanged()
|
||||||
.SubscribeAwait(async (innerEvent, ct) => await (innerEvent.Action switch
|
.SubscribeAwait(async (innerEvent, ct) => await (innerEvent.Action switch
|
||||||
{
|
{
|
||||||
NotifyCollectionChangedAction.Add => this.InvokeAsync(() => innerEvent.NewItem.View.Value = CreateFileTreeItem(_tree, projectItem, innerEvent.NewItem.Value)),
|
NotifyCollectionChangedAction.Add => this.InvokeAsync(() => innerEvent.NewItem.View.Value = CreateFileTreeItem(_tree, projectItem, innerEvent.NewItem.Value, innerEvent.NewStartingIndex)),
|
||||||
NotifyCollectionChangedAction.Remove => FreeTreeItem(innerEvent.OldItem.View.Value),
|
NotifyCollectionChangedAction.Remove => FreeTreeItem(innerEvent.OldItem.View.Value),
|
||||||
_ => Task.CompletedTask
|
_ => Task.CompletedTask
|
||||||
})).AddTo(this);
|
})).AddTo(this);
|
||||||
@@ -275,7 +275,7 @@ public partial class SolutionExplorerPanel : MarginContainer
|
|||||||
filesView.ObserveChanged()
|
filesView.ObserveChanged()
|
||||||
.SubscribeAwait(async (innerEvent, ct) => await (innerEvent.Action switch
|
.SubscribeAwait(async (innerEvent, ct) => await (innerEvent.Action switch
|
||||||
{
|
{
|
||||||
NotifyCollectionChangedAction.Add => this.InvokeAsync(() => innerEvent.NewItem.View.Value = CreateFileTreeItem(_tree, folderItem, innerEvent.NewItem.Value)),
|
NotifyCollectionChangedAction.Add => this.InvokeAsync(() => innerEvent.NewItem.View.Value = CreateFileTreeItem(_tree, folderItem, innerEvent.NewItem.Value, innerEvent.NewStartingIndex)),
|
||||||
NotifyCollectionChangedAction.Remove => FreeTreeItem(innerEvent.OldItem.View.Value),
|
NotifyCollectionChangedAction.Remove => FreeTreeItem(innerEvent.OldItem.View.Value),
|
||||||
_ => Task.CompletedTask
|
_ => Task.CompletedTask
|
||||||
})).AddTo(this);
|
})).AddTo(this);
|
||||||
@@ -283,9 +283,18 @@ public partial class SolutionExplorerPanel : MarginContainer
|
|||||||
}
|
}
|
||||||
|
|
||||||
[RequiresGodotUiThread]
|
[RequiresGodotUiThread]
|
||||||
private TreeItem CreateFileTreeItem(Tree tree, TreeItem parent, SharpIdeFile sharpIdeFile)
|
private TreeItem CreateFileTreeItem(Tree tree, TreeItem parent, SharpIdeFile sharpIdeFile, int newStartingIndex = -1)
|
||||||
{
|
{
|
||||||
var fileItem = tree.CreateItem(parent);
|
// We need to offset the starting index by the number of non-file items (folders/projects) in the parent
|
||||||
|
// because the newStartingIndex is calculated based on all children, but we are only inserting files here
|
||||||
|
if (newStartingIndex >= 0)
|
||||||
|
{
|
||||||
|
var sharpIdeParent = sharpIdeFile.Parent as IFolderOrProject;
|
||||||
|
Guard.Against.Null(sharpIdeParent, nameof(sharpIdeParent));
|
||||||
|
var folderCount = sharpIdeParent.Folders.Count;
|
||||||
|
newStartingIndex += folderCount;
|
||||||
|
}
|
||||||
|
var fileItem = tree.CreateItem(parent, newStartingIndex);
|
||||||
fileItem.SetText(0, sharpIdeFile.Name);
|
fileItem.SetText(0, sharpIdeFile.Name);
|
||||||
fileItem.SetIcon(0, CsharpFileIcon);
|
fileItem.SetIcon(0, CsharpFileIcon);
|
||||||
fileItem.SetCustomColor(0, GetColorForGitStatus(sharpIdeFile.GitStatus));
|
fileItem.SetCustomColor(0, GetColorForGitStatus(sharpIdeFile.GitStatus));
|
||||||
|
|||||||
Reference in New Issue
Block a user