Skip to content

Feature: Remember previously selected option in conflicts dialog #11399

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 3 additions & 25 deletions src/Files.App/Dialogs/FilesystemOperationDialog.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,12 @@
<ContentDialog.Resources>
<x:Double x:Key="ContentDialogMaxWidth">800</x:Double>

<MenuFlyout
x:Name="ItemContextFlyout"
Opening="MenuFlyout_Opening"
Placement="Bottom">
<MenuFlyoutItem
Click="MenuFlyoutItem_Click"
Tag="0"
Text="{helpers:ResourceString Name=GenerateNewName}" />
<MenuFlyoutItem
Click="MenuFlyoutItem_Click"
Tag="1"
Text="{helpers:ResourceString Name=ConflictingItemsDialogOptionReplaceExisting/Text}" />
<MenuFlyoutItem
Click="MenuFlyoutItem_Click"
Tag="2"
Text="{helpers:ResourceString Name=Skip}" />
<MenuFlyoutSeparator x:Name="ApplyToAllSeparator" />
<MenuFlyoutItem
x:Name="ApplyToAllOption"
Click="MenuFlyoutItem_Click"
Tag="All"
Text="{helpers:ResourceString Name=ConfictingItemsDialogOptionApplyToAll/Text}" />
</MenuFlyout>

<vc:ImageModelToImageConverter x:Key="ImageModelToImageConverter" />
<vc:GenericEnumConverter x:Key="GenericEnumConverter" />
<vc2:ConflictResolveOptionToIndexConverter x:Key="ConflictResolveOptionToIndexConverter" />
<vc3:VisibilityInvertConverter x:Key="VisibilityInvertConverter" />
<tvc:BoolNegationConverter x:Key="BoolNegationConverter" />
<tvc:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />

<DataTemplate x:Key="ConflictItemDataTemplate" x:DataType="vm:FileSystemDialogConflictItemViewModel">
<Grid ColumnSpacing="12">
Expand Down Expand Up @@ -128,13 +105,14 @@
</Grid>

<!-- Options -->
<!-- Use Visibility because x:Load does not reflect the SelectedIndex value in the combo box -->
<ComboBox
x:Name="ConflictOptions"
Grid.Column="2"
Width="200"
HorizontalAlignment="Right"
VerticalAlignment="Center"
x:Load="{x:Bind IsConflict, Mode=OneWay}"
Visibility="{x:Bind IsConflict, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"
SelectedIndex="{x:Bind ConflictResolveOption, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Converter={StaticResource ConflictResolveOptionToIndexConverter}}">
<ComboBox.Items>
<ComboBoxItem Content="{helpers:ResourceString Name=GenerateNewName}" />
Expand Down
52 changes: 4 additions & 48 deletions src/Files.App/Dialogs/FilesystemOperationDialog.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,56 +80,11 @@ private void PrimaryButton_GotFocus(object sender, RoutedEventArgs e)
DetailsGrid.IsEnabled = true;
}

private void MenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
var t = (sender as MenuFlyoutItem).Tag as string;
if (t == "All")
{
if (DetailsGrid.SelectedItems.FirstOrDefault() is FileSystemDialogConflictItemViewModel conflictItem)
{
ViewModel.ApplyConflictOptionToAll(conflictItem.ConflictResolveOption);
}

return;
}

var op = (FileNameConflictResolveOptionType)int.Parse(t);
foreach (var item in DetailsGrid.SelectedItems)
{
if (item is FileSystemDialogConflictItemViewModel conflictItem)
{
conflictItem.ConflictResolveOption = op;
}
}
}

private void MenuFlyout_Opening(object sender, object e)
{
if (!ViewModel.FileSystemDialogMode.ConflictsExist)
{
return;
}

if (((sender as MenuFlyout)?.Target as ListViewItem)?.Content is BaseFileSystemDialogItemViewModel li &&
!DetailsGrid.SelectedItems.Contains(li))
{
DetailsGrid.SelectedItems.Add(li);
}

if (DetailsGrid.Items.Count > 1 && DetailsGrid.SelectedItems.Count == 1 && !DetailsGrid.SelectedItems.Any(x => (x as FileSystemDialogConflictItemViewModel).IsDefault))
{
ApplyToAllOption.Visibility = Visibility.Visible;
ApplyToAllSeparator.Visibility = Visibility.Visible;
}
else
{
ApplyToAllOption.Visibility = Visibility.Collapsed;
ApplyToAllSeparator.Visibility = Visibility.Collapsed;
}
}

private void RootDialog_Closing(ContentDialog sender, ContentDialogClosingEventArgs args)
{
if (args.Result == ContentDialogResult.Primary)
ViewModel.SaveConflictResolveOption();

App.Window.SizeChanged -= Current_SizeChanged;
ViewModel.CancelCts();
}
Expand Down Expand Up @@ -181,6 +136,7 @@ private void FilesystemOperationDialog_Opened(ContentDialog sender, ContentDialo
DescriptionText.Foreground = App.Current.Resources["TextControlForeground"] as SolidColorBrush;
}

ViewModel.LoadConflictResolveOption();
UpdateDialogLayout();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ public bool ShowOpenInNewPane
set => Set(value);
}

public FileNameConflictResolveOptionType ConflictsResolveOption
{
get => (FileNameConflictResolveOptionType)Get((long)FileNameConflictResolveOptionType.GenerateNewName);
set => Set((long)value);
}

protected override void RaiseOnSettingChangedEvent(object sender, SettingChangedEventArgs e)
{
switch (e.SettingName)
Expand Down Expand Up @@ -236,6 +242,7 @@ protected override void RaiseOnSettingChangedEvent(object sender, SettingChanged
case nameof(ShowOpenInNewTab):
case nameof(ShowOpenInNewWindow):
case nameof(ShowOpenInNewPane):
case nameof(ConflictsResolveOption):
Analytics.TrackEvent($"Set {e.SettingName} to {e.NewValue}");
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ public object Convert(object value, Type targetType, object parameter, string la
{
return (FileNameConflictResolveOptionType)value switch
{
FileNameConflictResolveOptionType.None => 0,
FileNameConflictResolveOptionType.None => -1,
FileNameConflictResolveOptionType.GenerateNewName => 0,
FileNameConflictResolveOptionType.ReplaceExisting => 1,
FileNameConflictResolveOptionType.Skip => 2,
_ => 0
_ => -1
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,10 @@ public interface IPreferencesSettingsService : IBaseSettingsService, INotifyProp
/// Gets or sets a value indicating whether or not to show the option to open folders in a new pane.
/// </summary>
bool ShowOpenInNewPane { get; set; }

/// <summary>
/// Gets or sets a value indicating the default option to resolve conflicts.
/// </summary>
FileNameConflictResolveOptionType ConflictsResolveOption { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,6 @@ public string DestinationDirectoryDisplayName
get => Path.GetFileName(Path.GetDirectoryName(DestinationPath));
}

public bool IsDefault
{
get => ConflictResolveOption == FileNameConflictResolveOptionType.GenerateNewName; // Default value
}

public bool IsConflict
{
get => ConflictResolveOption != FileNameConflictResolveOptionType.None;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Files.Backend.Extensions;
using Files.Backend.Messages;
using Files.Backend.Services;
using Files.Backend.Services.Settings;
using Files.Shared.Enums;
using Files.Shared.Extensions;
using System;
Expand All @@ -17,6 +18,8 @@ namespace Files.Backend.ViewModels.Dialogs.FileSystemDialog
{
public sealed class FileSystemDialogViewModel : BaseDialogViewModel, IRecipient<FileSystemDialogOptionChangedMessage>
{
private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetRequiredService<IUserSettingsService>();

private readonly CancellationTokenSource _dialogClosingCts;

private readonly IMessenger _messenger;
Expand Down Expand Up @@ -85,7 +88,7 @@ public void ApplyConflictOptionToAll(FileNameConflictResolveOptionType e)
{
foreach (var item in Items)
{
if (item is FileSystemDialogConflictItemViewModel conflictItem)
if (item is FileSystemDialogConflictItemViewModel conflictItem && conflictItem.ConflictResolveOption != FileNameConflictResolveOptionType.None)
{
conflictItem.ConflictResolveOption = e;
}
Expand All @@ -102,15 +105,26 @@ public IEnumerable<IFileSystemDialogConflictItemViewModel> GetItemsResult()

public void Receive(FileSystemDialogOptionChangedMessage message)
{
if (Items.Count == 1)
if (message.Value.ConflictResolveOption != FileNameConflictResolveOptionType.None)
{
AggregatedResolveOption = message.Value.ConflictResolveOption;
var itemsWithoutNone = Items.Where(x => (x as FileSystemDialogConflictItemViewModel)!.ConflictResolveOption != FileNameConflictResolveOptionType.None);
// If all items have the same resolve option -- set the aggregated option to that choice
var first = (itemsWithoutNone.First() as FileSystemDialogConflictItemViewModel)!.ConflictResolveOption;
AggregatedResolveOption = itemsWithoutNone.All(x => (x as FileSystemDialogConflictItemViewModel)!.ConflictResolveOption == first) ? first : FileNameConflictResolveOptionType.None;
}
else
}

public void LoadConflictResolveOption()
{
AggregatedResolveOption = UserSettingsService.PreferencesSettingsService.ConflictsResolveOption;
}

public void SaveConflictResolveOption()
{
if (AggregatedResolveOption != FileNameConflictResolveOptionType.None
&& AggregatedResolveOption != UserSettingsService.PreferencesSettingsService.ConflictsResolveOption)
{
// If all items have the same resolve option -- set the aggregated option to that choice
var first = (Items.First() as FileSystemDialogConflictItemViewModel)!.ConflictResolveOption;
AggregatedResolveOption = Items.All(x => (x as FileSystemDialogConflictItemViewModel)!.ConflictResolveOption == first) ? first : FileNameConflictResolveOptionType.None;
UserSettingsService.PreferencesSettingsService.ConflictsResolveOption = AggregatedResolveOption;
}
}

Expand Down