Skip to content

Commit 70e81c5

Browse files
committed
add delete button to delete objects locally
1 parent 6676c06 commit 70e81c5

File tree

5 files changed

+76
-14
lines changed

5 files changed

+76
-14
lines changed

Dat/ObjectIndex.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,26 @@
44
using OpenLoco.Dat.Objects;
55
using OpenLoco.Dat.Types;
66
using System.Collections.Concurrent;
7+
using System.ComponentModel;
78
using System.Text;
89
using System.Text.Json;
910

1011
namespace OpenLoco.Dat
1112
{
12-
public class ObjectIndex
13+
public class ObjectIndex : INotifyPropertyChanged
1314
{
14-
public required IList<ObjectIndexEntry> Objects { get; init; } = [];
15+
public event PropertyChangedEventHandler? PropertyChanged;
16+
17+
IList<ObjectIndexEntry> _objects { get; init; } = [];
18+
19+
public IReadOnlyList<ObjectIndexEntry> Objects
20+
=> _objects.AsReadOnly();
1521

1622
public const string DefaultIndexFileName = "objectIndex.json";
1723

24+
public ObjectIndex(IList<ObjectIndexEntry> objects)
25+
=> _objects = objects;
26+
1827
public bool TryFind((string name, uint checksum) key, out ObjectIndexEntry? entry)
1928
{
2029
entry = Objects.FirstOrDefault(x => x.DatName == key.name && x.DatChecksum == key.checksum);
@@ -27,6 +36,17 @@ public void SaveIndex(string indexFile)
2736
public void SaveIndex(string indexFile, JsonSerializerOptions options)
2837
=> File.WriteAllText(indexFile, JsonSerializer.Serialize(this, options));
2938

39+
public void Delete(ObjectIndexEntry entry)
40+
{
41+
if (_objects.Remove(entry))
42+
{
43+
OnPropertyChanged(nameof(Objects));
44+
}
45+
}
46+
47+
protected virtual void OnPropertyChanged(string propertyName)
48+
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
49+
3050
public static async Task<ObjectIndexEntry?> GetDatFileInfoFromBytesAsync((string Filename, byte[] Data) file, ILogger logger)
3151
=> await Task.Run(() => GetDatFileInfoFromBytes(file, logger)).ConfigureAwait(false);
3252

@@ -67,7 +87,7 @@ public static async Task<ObjectIndex> CreateIndexAsync(string directory, ILogger
6787
await consumerTask.ConfigureAwait(false);
6888

6989
await Task.WhenAll(producerTask, consumerTask).ConfigureAwait(false);
70-
return new ObjectIndex() { Objects = [.. pendingIndices] };
90+
return new ObjectIndex([.. pendingIndices]);
7191
}
7292

7393
static async Task ConsumeInput(ConcurrentQueue<ObjectIndexEntry> pendingIndices, ConcurrentQueue<(string Filename, byte[] Data)> pendingFiles, ConcurrentQueue<string> failedFiles, int totalFiles, IProgress<float>? progress, ILogger logger)

Gui/ViewModels/DatTypes/DatObjectEditorViewModel.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,24 @@ public override void Load()
132132
}
133133
}
134134

135+
public override void Delete()
136+
{
137+
if (CurrentFile.FileLocation != FileLocation.Local)
138+
{
139+
Logger.Error("Cannot delete non-local files");
140+
return;
141+
}
142+
143+
// delete file
144+
var path = Path.Combine(Model.Settings.ObjDataDirectory, CurrentFile.Filename);
145+
Logger.Info($"Deleting file \"{path}\"");
146+
File.Delete(path);
147+
148+
// remove from object index
149+
var indexItem = Model.ObjectIndex.Objects.Single(x => x.Filename == CurrentFile.Filename);
150+
Model.ObjectIndex.Delete(indexItem);
151+
}
152+
135153
public override void Save()
136154
{
137155
var savePath = CurrentFile.FileLocation == FileLocation.Local

Gui/ViewModels/DatTypes/ILocoFileViewModel.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,38 @@
66

77
namespace OpenLoco.Gui.ViewModels
88
{
9+
public record FileViewButton(ReactiveCommand<Unit, Unit> Command, string Text, string Icon);
10+
11+
public interface ILocoFileViewModelControl
12+
{
13+
[Reactive]
14+
public FileSystemItem CurrentFile { get; init; }
15+
16+
ListObservable<FileViewButton> Buttons { get; }
17+
}
18+
919
public interface ILocoFileViewModel
1020
{
1121
public ReactiveCommand<Unit, Unit> ReloadCommand { get; init; }
1222
public ReactiveCommand<Unit, Unit> SaveCommand { get; init; }
1323
public ReactiveCommand<Unit, Unit> SaveAsCommand { get; init; }
24+
public ReactiveCommand<Unit, Unit> DeleteLocalFileCommand { get; init; }
1425

1526
[Reactive]
1627
public FileSystemItem CurrentFile { get; init; }
1728

29+
[Reactive]
30+
public bool IsLocalMode => CurrentFile.FileLocation == FileLocation.Local;
31+
1832
public string ReloadText { get; }
1933
public string SaveText { get; }
2034
public string SaveAsText { get; }
35+
public string DeleteLocalFileText { get; }
2136

2237
public string ReloadIcon { get; }
2338
public string SaveIcon { get; }
2439
public string SaveAsIcon { get; }
40+
public string DeleteLocalFileIcon { get; }
2541
}
2642

2743
public abstract class BaseLocoFileViewModel : ReactiveObject, ILocoFileViewModel
@@ -34,6 +50,7 @@ protected BaseLocoFileViewModel(FileSystemItem currentFile, ObjectEditorModel mo
3450
ReloadCommand = ReactiveCommand.Create(Load);
3551
SaveCommand = ReactiveCommand.Create(Save);
3652
SaveAsCommand = ReactiveCommand.Create(SaveAs);
53+
DeleteLocalFileCommand = ReactiveCommand.Create(Delete);
3754
}
3855

3956
[Reactive]
@@ -45,19 +62,23 @@ protected BaseLocoFileViewModel(FileSystemItem currentFile, ObjectEditorModel mo
4562
public ReactiveCommand<Unit, Unit> ReloadCommand { get; init; }
4663
public ReactiveCommand<Unit, Unit> SaveCommand { get; init; }
4764
public ReactiveCommand<Unit, Unit> SaveAsCommand { get; init; }
65+
public ReactiveCommand<Unit, Unit> DeleteLocalFileCommand { get; init; }
4866

4967
public abstract void Load();
5068

5169
public abstract void Save();
5270

5371
public abstract void SaveAs();
72+
public virtual void Delete() { }
5473

5574
public string ReloadText => CurrentFile.FileLocation == FileLocation.Local ? "Reload" : "Redownload";
5675
public string SaveText => CurrentFile.FileLocation == FileLocation.Local ? "Save" : "Download";
5776
public string SaveAsText => $"{SaveText} As";
77+
public string DeleteLocalFileText => "Delete File";
5878

5979
public string ReloadIcon => CurrentFile.FileLocation == FileLocation.Local ? "DatabaseRefresh" : "FileSync";
6080
public string SaveIcon => CurrentFile.FileLocation == FileLocation.Local ? "ContentSave" : "FileDownload";
6181
public string SaveAsIcon => CurrentFile.FileLocation == FileLocation.Local ? "ContentSavePlus" : "FileDownloadOutline";
82+
public string DeleteLocalFileIcon => "DeleteForever";
6283
}
6384
}

Gui/ViewModels/FolderTreeViewModel.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,9 @@ async Task LoadOnlineDirectoryAsync(bool useExistingIndex)
171171

172172
if ((!useExistingIndex || Model.ObjectIndexOnline == null) && Model.WebClient != null)
173173
{
174-
Model.ObjectIndexOnline = new ObjectIndex()
175-
{
176-
Objects = (await Client.GetObjectListAsync(Model.WebClient, Model.Logger))
177-
.Select(x => new ObjectIndexEntry(x.Id.ToString(), x.DatName, x.DatChecksum, x.ObjectType, x.ObjectSource, x.VehicleType))
178-
.ToList()
179-
};
174+
Model.ObjectIndexOnline = new ObjectIndex((await Client.GetObjectListAsync(Model.WebClient, Model.Logger))
175+
.Select(x => new ObjectIndexEntry(x.Id.ToString(), x.DatName, x.DatChecksum, x.ObjectType, x.ObjectSource, x.VehicleType))
176+
.ToList());
180177
}
181178

182179
if (Model.ObjectIndexOnline != null)

Gui/Views/MainWindow.axaml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -737,26 +737,32 @@
737737
</DockPanel>
738738
<Border Margin="8" BorderThickness="1">
739739
<DockPanel DataContext="{Binding CurrentEditorModel}" Margin="4">
740-
<StackPanel Orientation="Horizontal" DockPanel.Dock="Top">
741-
<Button Grid.Row="3" Command="{Binding ReloadCommand}" HorizontalAlignment="Stretch" Margin="4" Padding="2">
740+
<DockPanel DockPanel.Dock="Top">
741+
<Button Command="{Binding ReloadCommand}" Margin="4" Padding="2" DockPanel.Dock="Left">
742742
<DockPanel>
743743
<materialIcons:MaterialIcon Kind="{Binding ReloadIcon}" Width="24" Height="24" Margin="2" />
744744
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="4" Text="{Binding ReloadText}" />
745745
</DockPanel>
746746
</Button>
747-
<Button Grid.Row="3" Command="{Binding SaveCommand}" HorizontalAlignment="Stretch" Margin="4" Padding="2">
747+
<Button Command="{Binding SaveCommand}" Margin="4" Padding="2" DockPanel.Dock="Left">
748748
<DockPanel>
749749
<materialIcons:MaterialIcon Kind="{Binding SaveIcon}" Width="24" Height="24" Margin="2" />
750750
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="4" Text="{Binding SaveText}" />
751751
</DockPanel>
752752
</Button>
753-
<Button Grid.Row="3" Command="{Binding SaveAsCommand}" HorizontalAlignment="Stretch" Margin="4" Padding="2">
753+
<Button Command="{Binding SaveAsCommand}" Margin="4" Padding="2" DockPanel.Dock="Left">
754754
<DockPanel>
755755
<materialIcons:MaterialIcon Kind="{Binding SaveAsIcon}" Width="24" Height="24" Margin="2" />
756756
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="4" Text="{Binding SaveAsText}" />
757757
</DockPanel>
758758
</Button>
759-
</StackPanel>
759+
<Button Command="{Binding DeleteLocalFileCommand}" HorizontalAlignment="Right" Margin="4" Padding="2" IsVisible="{Binding IsLocalMode}" IsEnabled="{Binding IsLocalMode}" Background="DarkRed" DockPanel.Dock="Right">
760+
<DockPanel>
761+
<materialIcons:MaterialIcon Kind="{Binding DeleteLocalFileIcon}" Width="24" Height="24" Margin="2" />
762+
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="4" Text="{Binding DeleteLocalFileText}"/>
763+
</DockPanel>
764+
</Button>
765+
</DockPanel>
760766
<ContentControl Content="{Binding}"/>
761767
</DockPanel>
762768
</Border>

0 commit comments

Comments
 (0)