Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
25 changes: 24 additions & 1 deletion src/Files.App/Dialogs/CreateShortcutDialog.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
Title="{helpers:ResourceString Name=NewShortcutDialogTitle}"
DefaultButton="Primary"
HighContrastAdjustment="None"
IsPrimaryButtonEnabled="{x:Bind ViewModel.IsLocationValid, Mode=OneWay}"
IsPrimaryButtonEnabled="{x:Bind ViewModel.IsShortcutValid, Mode=OneWay}"
PrimaryButtonCommand="{x:Bind ViewModel.PrimaryButtonCommand}"
PrimaryButtonText="{helpers:ResourceString Name=Create}"
RequestedTheme="{x:Bind RootAppElement.RequestedTheme, Mode=OneWay}"
Expand All @@ -30,6 +30,8 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<!-- Header -->
Expand Down Expand Up @@ -68,6 +70,27 @@
Command="{x:Bind ViewModel.SelectDestinationCommand}"
Content="{helpers:ResourceString Name=Browse}" />

<TextBlock
Grid.Row="3"
Grid.ColumnSpan="2"
Margin="0,12,0,0"
Text="{helpers:ResourceString Name=EnterAnItemName}" />

<!-- Name Box -->
<TextBox
x:Name="ShortcutName"
Grid.Row="4"
Grid.ColumnSpan="2"
HorizontalAlignment="Stretch"
Text="{x:Bind ViewModel.ShortcutName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<TextBox.Resources>
<TeachingTip
x:Name="InvalidNameWarning"
Title="{helpers:ResourceString Name=InvalidFilename/Text}"
IsOpen="{x:Bind ViewModel.ShowNameWarningTip, Mode=OneWay}"
PreferredPlacement="Bottom" />
</TextBox.Resources>
</TextBox>
</Grid>
</Border>
</ContentDialog>
79 changes: 55 additions & 24 deletions src/Files.App/ViewModels/Dialogs/CreateShortcutDialogViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Input;
using Windows.Storage.Pickers;
using Files.Shared.Helpers;

namespace Files.App.ViewModels.Dialogs
Expand Down Expand Up @@ -36,6 +35,20 @@ public sealed class CreateShortcutDialogViewModel : ObservableObject
// Previous path of the destination item
private string _previousShortcutTargetPath;

private string _shortcutName;
public string ShortcutName
{
get => _shortcutName;
set
{
if (SetProperty(ref _shortcutName, value))
{
OnPropertyChanged(nameof(ShowNameWarningTip));
OnPropertyChanged(nameof(IsShortcutValid));
}
}
}

// Destination of the shortcut chosen by the user (can be a path, a command or a URL)
private string _shortcutTarget;
public string ShortcutTarget
Expand Down Expand Up @@ -167,6 +180,10 @@ public string ShortcutTarget
Arguments = string.Empty;
_previousShortcutTargetPath = string.Empty;
}
finally
{
SetDefaultName();
}
}
}

Expand All @@ -178,12 +195,19 @@ public bool IsLocationValid
set
{
if (SetProperty(ref _isLocationValid, value))
{
OnPropertyChanged(nameof(ShowWarningTip));
OnPropertyChanged(nameof(IsShortcutValid));
}
}
}

public bool ShowWarningTip => !string.IsNullOrEmpty(ShortcutTarget) && !_isLocationValid;

public bool ShowNameWarningTip => !string.IsNullOrEmpty(_shortcutTarget) && !FilesystemHelpers.IsValidForFilename(_shortcutName);

public bool IsShortcutValid => _isLocationValid && !ShowNameWarningTip && !string.IsNullOrEmpty(_shortcutTarget);

// Command invoked when the user clicks the 'Browse' button
public ICommand SelectDestinationCommand { get; private set; }

Expand Down Expand Up @@ -225,31 +249,9 @@ private Task SelectDestination()

private async Task CreateShortcutAsync()
{
string? destinationName;
var extension = DestinationPathExists ? ".lnk" : ".url";

if (DestinationPathExists)
{
destinationName = Path.GetFileName(FullPath);

if(string.IsNullOrEmpty(FullPath))
{

var destinationPath = FullPath.Replace('/', '\\');

if (destinationPath.EndsWith('\\'))
destinationPath = destinationPath.Substring(0, destinationPath.Length - 1);

destinationName = destinationPath.Substring(destinationPath.LastIndexOf('\\') + 1);
}
}
else
{
var uri = new Uri(FullPath);
destinationName = uri.Host;
}

var shortcutName = FilesystemHelpers.GetShortcutNamingPreference(destinationName);
var shortcutName = FilesystemHelpers.GetShortcutNamingPreference(_shortcutName);
ShortcutCompleteName = shortcutName + extension;
var filePath = Path.Combine(WorkingDirectory, ShortcutCompleteName);

Expand All @@ -262,5 +264,34 @@ private async Task CreateShortcutAsync()

ShortcutCreatedSuccessfully = await FileOperationsHelpers.CreateOrUpdateLinkAsync(filePath, FullPath, Arguments);
}

private void SetDefaultName()
{
if (DestinationPathExists)
{
var destinationName = Path.GetFileName(FullPath);
if (DestinationPathExists)
{
destinationName = Path.GetFileName(FullPath);

if (string.IsNullOrEmpty(FullPath))
{

var destinationPath = FullPath.Replace('/', '\\');

if (destinationPath.EndsWith('\\'))
destinationPath = destinationPath.Substring(0, destinationPath.Length - 1);

destinationName = destinationPath.Substring(destinationPath.LastIndexOf('\\') + 1);
}
}
ShortcutName = destinationName;
}
else
{
var uri = new Uri(FullPath);
ShortcutName = uri.Host;
}
}
}
}