Skip to content

Commit 403039b

Browse files
authored
Feature: Remember previously selected option in conflicts dialog (#11399)
1 parent afd29fb commit 403039b

File tree

7 files changed

+42
-87
lines changed

7 files changed

+42
-87
lines changed

src/Files.App/Dialogs/FilesystemOperationDialog.xaml

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,35 +28,12 @@
2828
<ContentDialog.Resources>
2929
<x:Double x:Key="ContentDialogMaxWidth">800</x:Double>
3030

31-
<MenuFlyout
32-
x:Name="ItemContextFlyout"
33-
Opening="MenuFlyout_Opening"
34-
Placement="Bottom">
35-
<MenuFlyoutItem
36-
Click="MenuFlyoutItem_Click"
37-
Tag="0"
38-
Text="{helpers:ResourceString Name=GenerateNewName}" />
39-
<MenuFlyoutItem
40-
Click="MenuFlyoutItem_Click"
41-
Tag="1"
42-
Text="{helpers:ResourceString Name=ConflictingItemsDialogOptionReplaceExisting/Text}" />
43-
<MenuFlyoutItem
44-
Click="MenuFlyoutItem_Click"
45-
Tag="2"
46-
Text="{helpers:ResourceString Name=Skip}" />
47-
<MenuFlyoutSeparator x:Name="ApplyToAllSeparator" />
48-
<MenuFlyoutItem
49-
x:Name="ApplyToAllOption"
50-
Click="MenuFlyoutItem_Click"
51-
Tag="All"
52-
Text="{helpers:ResourceString Name=ConfictingItemsDialogOptionApplyToAll/Text}" />
53-
</MenuFlyout>
54-
5531
<vc:ImageModelToImageConverter x:Key="ImageModelToImageConverter" />
5632
<vc:GenericEnumConverter x:Key="GenericEnumConverter" />
5733
<vc2:ConflictResolveOptionToIndexConverter x:Key="ConflictResolveOptionToIndexConverter" />
5834
<vc3:VisibilityInvertConverter x:Key="VisibilityInvertConverter" />
5935
<tvc:BoolNegationConverter x:Key="BoolNegationConverter" />
36+
<tvc:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
6037

6138
<DataTemplate x:Key="ConflictItemDataTemplate" x:DataType="vm:FileSystemDialogConflictItemViewModel">
6239
<Grid ColumnSpacing="12">
@@ -128,13 +105,14 @@
128105
</Grid>
129106

130107
<!-- Options -->
108+
<!-- Use Visibility because x:Load does not reflect the SelectedIndex value in the combo box -->
131109
<ComboBox
132110
x:Name="ConflictOptions"
133111
Grid.Column="2"
134112
Width="200"
135113
HorizontalAlignment="Right"
136114
VerticalAlignment="Center"
137-
x:Load="{x:Bind IsConflict, Mode=OneWay}"
115+
Visibility="{x:Bind IsConflict, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"
138116
SelectedIndex="{x:Bind ConflictResolveOption, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Converter={StaticResource ConflictResolveOptionToIndexConverter}}">
139117
<ComboBox.Items>
140118
<ComboBoxItem Content="{helpers:ResourceString Name=GenerateNewName}" />

src/Files.App/Dialogs/FilesystemOperationDialog.xaml.cs

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -80,56 +80,11 @@ private void PrimaryButton_GotFocus(object sender, RoutedEventArgs e)
8080
DetailsGrid.IsEnabled = true;
8181
}
8282

83-
private void MenuFlyoutItem_Click(object sender, RoutedEventArgs e)
84-
{
85-
var t = (sender as MenuFlyoutItem).Tag as string;
86-
if (t == "All")
87-
{
88-
if (DetailsGrid.SelectedItems.FirstOrDefault() is FileSystemDialogConflictItemViewModel conflictItem)
89-
{
90-
ViewModel.ApplyConflictOptionToAll(conflictItem.ConflictResolveOption);
91-
}
92-
93-
return;
94-
}
95-
96-
var op = (FileNameConflictResolveOptionType)int.Parse(t);
97-
foreach (var item in DetailsGrid.SelectedItems)
98-
{
99-
if (item is FileSystemDialogConflictItemViewModel conflictItem)
100-
{
101-
conflictItem.ConflictResolveOption = op;
102-
}
103-
}
104-
}
105-
106-
private void MenuFlyout_Opening(object sender, object e)
107-
{
108-
if (!ViewModel.FileSystemDialogMode.ConflictsExist)
109-
{
110-
return;
111-
}
112-
113-
if (((sender as MenuFlyout)?.Target as ListViewItem)?.Content is BaseFileSystemDialogItemViewModel li &&
114-
!DetailsGrid.SelectedItems.Contains(li))
115-
{
116-
DetailsGrid.SelectedItems.Add(li);
117-
}
118-
119-
if (DetailsGrid.Items.Count > 1 && DetailsGrid.SelectedItems.Count == 1 && !DetailsGrid.SelectedItems.Any(x => (x as FileSystemDialogConflictItemViewModel).IsDefault))
120-
{
121-
ApplyToAllOption.Visibility = Visibility.Visible;
122-
ApplyToAllSeparator.Visibility = Visibility.Visible;
123-
}
124-
else
125-
{
126-
ApplyToAllOption.Visibility = Visibility.Collapsed;
127-
ApplyToAllSeparator.Visibility = Visibility.Collapsed;
128-
}
129-
}
130-
13183
private void RootDialog_Closing(ContentDialog sender, ContentDialogClosingEventArgs args)
13284
{
85+
if (args.Result == ContentDialogResult.Primary)
86+
ViewModel.SaveConflictResolveOption();
87+
13388
App.Window.SizeChanged -= Current_SizeChanged;
13489
ViewModel.CancelCts();
13590
}
@@ -181,6 +136,7 @@ private void FilesystemOperationDialog_Opened(ContentDialog sender, ContentDialo
181136
DescriptionText.Foreground = App.Current.Resources["TextControlForeground"] as SolidColorBrush;
182137
}
183138

139+
ViewModel.LoadConflictResolveOption();
184140
UpdateDialogLayout();
185141
}
186142
}

src/Files.App/ServicesImplementation/Settings/PreferencesSettingsService.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,12 @@ public bool ShowOpenInNewPane
207207
set => Set(value);
208208
}
209209

210+
public FileNameConflictResolveOptionType ConflictsResolveOption
211+
{
212+
get => (FileNameConflictResolveOptionType)Get((long)FileNameConflictResolveOptionType.GenerateNewName);
213+
set => Set((long)value);
214+
}
215+
210216
protected override void RaiseOnSettingChangedEvent(object sender, SettingChangedEventArgs e)
211217
{
212218
switch (e.SettingName)
@@ -236,6 +242,7 @@ protected override void RaiseOnSettingChangedEvent(object sender, SettingChanged
236242
case nameof(ShowOpenInNewTab):
237243
case nameof(ShowOpenInNewWindow):
238244
case nameof(ShowOpenInNewPane):
245+
case nameof(ConflictsResolveOption):
239246
Analytics.TrackEvent($"Set {e.SettingName} to {e.NewValue}");
240247
break;
241248
}

src/Files.App/ValueConverters/EnumConverters/ConflictResolveOptionToIndexConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ public object Convert(object value, Type targetType, object parameter, string la
1010
{
1111
return (FileNameConflictResolveOptionType)value switch
1212
{
13-
FileNameConflictResolveOptionType.None => 0,
13+
FileNameConflictResolveOptionType.None => -1,
1414
FileNameConflictResolveOptionType.GenerateNewName => 0,
1515
FileNameConflictResolveOptionType.ReplaceExisting => 1,
1616
FileNameConflictResolveOptionType.Skip => 2,
17-
_ => 0
17+
_ => -1
1818
};
1919
}
2020

src/Files.Backend/Services/Settings/IPreferencesSettingsService.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,5 +166,10 @@ public interface IPreferencesSettingsService : IBaseSettingsService, INotifyProp
166166
/// Gets or sets a value indicating whether or not to show the option to open folders in a new pane.
167167
/// </summary>
168168
bool ShowOpenInNewPane { get; set; }
169+
170+
/// <summary>
171+
/// Gets or sets a value indicating the default option to resolve conflicts.
172+
/// </summary>
173+
FileNameConflictResolveOptionType ConflictsResolveOption { get; set; }
169174
}
170175
}

src/Files.Backend/ViewModels/Dialogs/FileSystemDialog/FileSystemDialogConflictItemViewModel.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,6 @@ public string DestinationDirectoryDisplayName
5353
get => Path.GetFileName(Path.GetDirectoryName(DestinationPath));
5454
}
5555

56-
public bool IsDefault
57-
{
58-
get => ConflictResolveOption == FileNameConflictResolveOptionType.GenerateNewName; // Default value
59-
}
60-
6156
public bool IsConflict
6257
{
6358
get => ConflictResolveOption != FileNameConflictResolveOptionType.None;

src/Files.Backend/ViewModels/Dialogs/FileSystemDialog/FileSystemDialogViewModel.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Files.Backend.Extensions;
55
using Files.Backend.Messages;
66
using Files.Backend.Services;
7+
using Files.Backend.Services.Settings;
78
using Files.Shared.Enums;
89
using Files.Shared.Extensions;
910
using System;
@@ -17,6 +18,8 @@ namespace Files.Backend.ViewModels.Dialogs.FileSystemDialog
1718
{
1819
public sealed class FileSystemDialogViewModel : BaseDialogViewModel, IRecipient<FileSystemDialogOptionChangedMessage>
1920
{
21+
private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetRequiredService<IUserSettingsService>();
22+
2023
private readonly CancellationTokenSource _dialogClosingCts;
2124

2225
private readonly IMessenger _messenger;
@@ -85,7 +88,7 @@ public void ApplyConflictOptionToAll(FileNameConflictResolveOptionType e)
8588
{
8689
foreach (var item in Items)
8790
{
88-
if (item is FileSystemDialogConflictItemViewModel conflictItem)
91+
if (item is FileSystemDialogConflictItemViewModel conflictItem && conflictItem.ConflictResolveOption != FileNameConflictResolveOptionType.None)
8992
{
9093
conflictItem.ConflictResolveOption = e;
9194
}
@@ -102,15 +105,26 @@ public IEnumerable<IFileSystemDialogConflictItemViewModel> GetItemsResult()
102105

103106
public void Receive(FileSystemDialogOptionChangedMessage message)
104107
{
105-
if (Items.Count == 1)
108+
if (message.Value.ConflictResolveOption != FileNameConflictResolveOptionType.None)
106109
{
107-
AggregatedResolveOption = message.Value.ConflictResolveOption;
110+
var itemsWithoutNone = Items.Where(x => (x as FileSystemDialogConflictItemViewModel)!.ConflictResolveOption != FileNameConflictResolveOptionType.None);
111+
// If all items have the same resolve option -- set the aggregated option to that choice
112+
var first = (itemsWithoutNone.First() as FileSystemDialogConflictItemViewModel)!.ConflictResolveOption;
113+
AggregatedResolveOption = itemsWithoutNone.All(x => (x as FileSystemDialogConflictItemViewModel)!.ConflictResolveOption == first) ? first : FileNameConflictResolveOptionType.None;
108114
}
109-
else
115+
}
116+
117+
public void LoadConflictResolveOption()
118+
{
119+
AggregatedResolveOption = UserSettingsService.PreferencesSettingsService.ConflictsResolveOption;
120+
}
121+
122+
public void SaveConflictResolveOption()
123+
{
124+
if (AggregatedResolveOption != FileNameConflictResolveOptionType.None
125+
&& AggregatedResolveOption != UserSettingsService.PreferencesSettingsService.ConflictsResolveOption)
110126
{
111-
// If all items have the same resolve option -- set the aggregated option to that choice
112-
var first = (Items.First() as FileSystemDialogConflictItemViewModel)!.ConflictResolveOption;
113-
AggregatedResolveOption = Items.All(x => (x as FileSystemDialogConflictItemViewModel)!.ConflictResolveOption == first) ? first : FileNameConflictResolveOptionType.None;
127+
UserSettingsService.PreferencesSettingsService.ConflictsResolveOption = AggregatedResolveOption;
114128
}
115129
}
116130

0 commit comments

Comments
 (0)