Skip to content

Commit aeb36bb

Browse files
committed
Add feature to load the last used IP configuration
1 parent 58f7ef7 commit aeb36bb

File tree

7 files changed

+190
-7
lines changed

7 files changed

+190
-7
lines changed

IPConfig/Languages/Lang.Designer.cs

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

IPConfig/Languages/Lang.en.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,9 @@
435435
<data name="Light" xml:space="preserve">
436436
<value>Light</value>
437437
</data>
438+
<data name="LoadLastUsedConfiguration_" xml:space="preserve">
439+
<value>_Load Last Used Configuration</value>
440+
</data>
438441
<data name="MakeSelectedIPConfigCopy_" xml:space="preserve">
439442
<value>Make _Copy</value>
440443
</data>

IPConfig/Languages/Lang.resx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,10 @@
517517
<value>浅色</value>
518518
<comment>MainWindow</comment>
519519
</data>
520+
<data name="LoadLastUsedConfiguration_" xml:space="preserve">
521+
<value>加载上次使用的配置(_L)</value>
522+
<comment>MainWindow</comment>
523+
</data>
520524
<data name="MakeSelectedIPConfigCopy_" xml:space="preserve">
521525
<value>生成副本(_C)</value>
522526
<comment>MainWindow</comment>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Text.Json;
5+
using System.Threading.Tasks;
6+
7+
using IPConfig.Languages;
8+
9+
namespace IPConfig.Models;
10+
11+
public partial class LastUsedIPv4Config : IPv4Config
12+
{
13+
public static readonly Dictionary<string, LastUsedIPv4Config> Backups = new();
14+
15+
public string FormatedLastUsedTime => LastUsedTime.ToString(LangSource.Instance.CurrentCulture);
16+
17+
public DateTime LastUsedTime { get; }
18+
19+
public LastUsedIPv4Config(DateTime lastUsedTime)
20+
{
21+
LastUsedTime = lastUsedTime;
22+
}
23+
24+
public static async Task BackupAsync(string nicId, IPv4Config value)
25+
{
26+
string path = $"backup/{nicId}.bak";
27+
string json = JsonSerializer.Serialize(value, App.JsonOptions);
28+
Directory.CreateDirectory("backup");
29+
await File.WriteAllTextAsync(path, json);
30+
var backup = new LastUsedIPv4Config(DateTime.Now);
31+
value.DeepCloneTo(backup);
32+
Backups[nicId] = backup;
33+
}
34+
35+
public static async Task<LastUsedIPv4Config?> ReadAsync(string nicId)
36+
{
37+
if (Backups.TryGetValue(nicId, out var cache))
38+
{
39+
return cache;
40+
}
41+
42+
string path = $"backup/{nicId}.bak";
43+
44+
if (!File.Exists(path))
45+
{
46+
return null;
47+
}
48+
49+
try
50+
{
51+
string json = await File.ReadAllTextAsync(path);
52+
var backup = JsonSerializer.Deserialize<IPv4Config>(json);
53+
54+
if (backup is null)
55+
{
56+
return null;
57+
}
58+
59+
var lastUsedIPv4Config = new LastUsedIPv4Config(File.GetLastWriteTime(path));
60+
backup.DeepCloneTo(lastUsedIPv4Config);
61+
Backups[nicId] = lastUsedIPv4Config;
62+
63+
return lastUsedIPv4Config;
64+
}
65+
catch
66+
{
67+
return null;
68+
}
69+
}
70+
}

IPConfig/ViewModels/IPConfigDetailViewModel.cs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public partial class IPConfigDetailViewModel : ObservableRecipient, IEditableObj
9090
private EditableIPConfigModel _editingIPConfig = IPConfigModel.Empty.AsEditable();
9191

9292
[ObservableProperty]
93+
[NotifyPropertyChangedFor(nameof(IsNicIPConfig))]
9394
private object _editingIPConfigSender = null!;
9495

9596
[ObservableProperty]
@@ -132,6 +133,8 @@ public partial class IPConfigDetailViewModel : ObservableRecipient, IEditableObj
132133

133134
public bool IsEditingIPConfigModifield => IsInContrastView || EditingIPConfig.IsChanged;
134135

136+
public bool IsNicIPConfig => EditingIPConfigSender is MainViewModel;
137+
135138
public ICommand PrimarySaveOrApplyCommand
136139
{
137140
get
@@ -389,7 +392,7 @@ private static async Task PingDnsGroupAsync(CollectionViewGroup group)
389392
}
390393

391394
[RelayCommand]
392-
private void Apply()
395+
private async Task ApplyAsync()
393396
{
394397
if (_nic is null)
395398
{
@@ -420,6 +423,8 @@ private void Apply()
420423
return;
421424
}
422425

426+
await BackupAsync();
427+
423428
var ipv4Config = EditingIPConfig.IPv4Config;
424429

425430
if (ipv4Config.IsDhcpEnabled)
@@ -571,13 +576,13 @@ private void Save()
571576
}
572577

573578
[RelayCommand]
574-
private void SaveAndApply()
579+
private async Task SaveAndApplyAsync()
575580
{
576581
Save();
577582

578583
if (_isSaveSuccessful)
579584
{
580-
Apply();
585+
await ApplyAsync();
581586
}
582587
}
583588

@@ -714,6 +719,28 @@ private static IEnumerable<IPv4Dns> ReadIPv4DnsList()
714719
return iPv4DnsList;
715720
}
716721

722+
private async Task BackupAsync()
723+
{
724+
if (_nic is null)
725+
{
726+
return;
727+
}
728+
729+
try
730+
{
731+
var current = NetworkManagement.GetIPv4Config(_nic);
732+
733+
if (current.PropertyEquals(EditingIPConfig.IPv4Config))
734+
{
735+
return;
736+
}
737+
738+
await LastUsedIPv4Config.BackupAsync(_nic.Id, current);
739+
}
740+
catch
741+
{ }
742+
}
743+
717744
private bool? CanShowIPConfigPropertyChangedIndicator<T>(Func<IPConfigModel, T> property) where T : notnull
718745
{
719746
if (EditingIPConfig.IsPropertyChanged(property))

IPConfig/ViewModels/MainViewModel.cs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ public partial class MainViewModel : ObservableRecipient,
5151

5252
private EditableIPConfigModel? _lastSelectedIPConfig;
5353

54+
private IPv4Config? _selectedNicIPv4Config;
55+
5456
#endregion Fields
5557

5658
#region ObservableProperties
@@ -78,13 +80,21 @@ public partial class MainViewModel : ObservableRecipient,
7880
[ObservableProperty]
7981
private ObservableCollection<CultureInfo> _languages = null!;
8082

83+
[ObservableProperty]
84+
[NotifyPropertyChangedFor(nameof(CanLoadLastUsedIPv4Config))]
85+
[NotifyCanExecuteChangedFor(nameof(LoadLastUsedIPv4ConfigCommand))]
86+
private LastUsedIPv4Config? _lastUsedIPv4Config;
87+
8188
[ObservableProperty]
8289
private int _selectedIPConfigsCount;
8390

8491
[ObservableProperty]
8592
[NotifyPropertyChangedRecipients]
8693
[NotifyPropertyChangedFor(nameof(IsSelectedNicNotNull))]
87-
[NotifyCanExecuteChangedFor(nameof(CopySelectedNicIPConfigAsTextCommand), nameof(MakeSelectedNicIPConfigCopyCommand), nameof(ViewToNicConfigDetailCommand))]
94+
[NotifyCanExecuteChangedFor(nameof(CopySelectedNicIPConfigAsTextCommand),
95+
nameof(MakeSelectedNicIPConfigCopyCommand),
96+
nameof(ViewToNicConfigDetailCommand),
97+
nameof(ReadLastUsedIPv4ConfigCommand))]
8898
private Nic? _selectedNic;
8999

90100
[ObservableProperty]
@@ -106,6 +116,8 @@ public partial class MainViewModel : ObservableRecipient,
106116

107117
#region Properties
108118

119+
public bool CanLoadLastUsedIPv4Config => LastUsedIPv4Config is not null;
120+
109121
public string GetNicsToolTip { get; private set; } = Lang.AdapterNotFound;
110122

111123
public bool IsSelectedNicNotNull => SelectedNic is not null;
@@ -363,12 +375,34 @@ private async Task LoadedAsync()
363375
await GetLatestReleaseInfoAsync();
364376
}
365377

378+
[RelayCommand(CanExecute = nameof(CanLoadLastUsedIPv4Config))]
379+
private void LoadLastUsedIPv4Config()
380+
{
381+
LastUsedIPv4Config!.DeepCloneTo(SelectedNicIPConfig!.IPv4Config);
382+
SelectedNicIPConfigCheckedCommand.Execute(null);
383+
}
384+
366385
[RelayCommand(CanExecute = nameof(IsSelectedNicNotNull))]
367386
private void MakeSelectedNicIPConfigCopy()
368387
{
369388
Messenger.Send<EditableIPConfigModel, string>(SelectedNicIPConfig!, "MakeSelectedNicIPConfigCopy");
370389
}
371390

391+
[RelayCommand(CanExecute = nameof(IsSelectedNicNotNull))]
392+
private async Task ReadLastUsedIPv4ConfigAsync()
393+
{
394+
var backup = await LastUsedIPv4Config.ReadAsync(SelectedNic!.Id);
395+
396+
if (backup is null || backup.PropertyEquals(_selectedNicIPv4Config!))
397+
{
398+
LastUsedIPv4Config = null;
399+
}
400+
else
401+
{
402+
LastUsedIPv4Config = backup;
403+
}
404+
}
405+
372406
[RelayCommand]
373407
private void Refresh()
374408
{
@@ -496,12 +530,11 @@ partial void OnSelectedNicChanged(Nic? value)
496530
return;
497531
}
498532

499-
var iPv4Config = NetworkManagement.GetIPv4Config(nic);
500-
501533
var oldSelectedNicIPConfig = SelectedNicIPConfig;
534+
_selectedNicIPv4Config = NetworkManagement.GetIPv4Config(nic);
502535

503536
SelectedNicIPConfig = new($"{nic.Name} - {nic.Description}") {
504-
IPv4Config = iPv4Config
537+
IPv4Config = _selectedNicIPv4Config.DeepClone()
505538
};
506539

507540
SelectedNicIPConfig.BeginEdit();
@@ -583,6 +616,9 @@ private static void OpenUri(string uri)
583616
[GeneratedRegex("^\\-\\s", RegexOptions.Multiline)]
584617
private static partial Regex ReleaseNoteFormatRegex();
585618

619+
[GeneratedRegex("^[0-9A-Z]{8}-[0-9A-Z]{4}-[0-9A-Z]{4}-[0-9A-Z]{4}-[0-9A-Z]{12}.json$", RegexOptions.IgnoreCase)]
620+
private static partial Regex TempFileNameRegex();
621+
586622
private async Task GetLatestReleaseInfoAsync()
587623
{
588624
try

IPConfig/Views/MainWindow.xaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@
186186
SelectedItem="{Binding SelectedNic}"
187187
ToolTip="{Binding SelectedNic}"
188188
UseLayoutRounding="False">
189+
<i:Interaction.Triggers>
190+
<i:EventTrigger EventName="SelectionChanged">
191+
<i:InvokeCommandAction Command="{Binding ReadLastUsedIPv4ConfigCommand}" />
192+
</i:EventTrigger>
193+
</i:Interaction.Triggers>
194+
189195
<hc:ComboBox.ItemTemplate>
190196
<DataTemplate DataType="{x:Type m:Nic}">
191197
<hc:SimpleStackPanel Orientation="Horizontal"
@@ -285,6 +291,10 @@
285291
<i:EventTrigger EventName="MouseDoubleClick">
286292
<i:InvokeCommandAction Command="{Binding ViewToNicConfigDetailCommand}" />
287293
</i:EventTrigger>
294+
295+
<i:EventTrigger EventName="ContextMenuOpening">
296+
<i:InvokeCommandAction Command="{Binding ReadLastUsedIPv4ConfigCommand}" />
297+
</i:EventTrigger>
288298
</i:Interaction.Triggers>
289299

290300
<RadioButton.ToolTip>
@@ -306,6 +316,20 @@
306316

307317
<Separator />
308318

319+
<MenuItem Command="{Binding LoadLastUsedIPv4ConfigCommand}"
320+
Header="{lang:Lang {x:Static lang:LangKey.LoadLastUsedConfiguration_}}">
321+
<MenuItem.ToolTip>
322+
<TextBlock>
323+
<Run Text="{Binding LastUsedIPv4Config.FormatedLastUsedTime, Mode=OneWay}" />
324+
<LineBreak />
325+
<LineBreak />
326+
<Run Text="{Binding LastUsedIPv4Config, Mode=OneWay}" />
327+
</TextBlock>
328+
</MenuItem.ToolTip>
329+
</MenuItem>
330+
331+
<Separator />
332+
309333
<MenuItem Command="{Binding ViewToNicConfigDetailCommand}"
310334
Header="{lang:Lang {x:Static lang:LangKey.ViewToAdapterConfigDetail_}}"
311335
InputGestureText="F12" />

0 commit comments

Comments
 (0)