Skip to content

Commit 5e5e4f3

Browse files
Feature: Added support for assigning a custom name when creating a new shortcut (#16506)
1 parent 20ef76a commit 5e5e4f3

File tree

2 files changed

+80
-25
lines changed

2 files changed

+80
-25
lines changed

src/Files.App/Dialogs/CreateShortcutDialog.xaml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
Title="{helpers:ResourceString Name=NewShortcutDialogTitle}"
1010
DefaultButton="Primary"
1111
HighContrastAdjustment="None"
12-
IsPrimaryButtonEnabled="{x:Bind ViewModel.IsLocationValid, Mode=OneWay}"
12+
IsPrimaryButtonEnabled="{x:Bind ViewModel.IsShortcutValid, Mode=OneWay}"
1313
PrimaryButtonCommand="{x:Bind ViewModel.PrimaryButtonCommand}"
1414
PrimaryButtonText="{helpers:ResourceString Name=Create}"
1515
RequestedTheme="{x:Bind RootAppElement.RequestedTheme, Mode=OneWay}"
@@ -30,6 +30,8 @@
3030
<RowDefinition Height="Auto" />
3131
<RowDefinition Height="Auto" />
3232
<RowDefinition Height="Auto" />
33+
<RowDefinition Height="Auto" />
34+
<RowDefinition Height="Auto" />
3335
</Grid.RowDefinitions>
3436

3537
<!-- Header -->
@@ -68,6 +70,28 @@
6870
Command="{x:Bind ViewModel.SelectDestinationCommand}"
6971
Content="{helpers:ResourceString Name=Browse}" />
7072

73+
<TextBlock
74+
Grid.Row="3"
75+
Grid.ColumnSpan="2"
76+
Margin="0,12,0,0"
77+
Text="{helpers:ResourceString Name=EnterAnItemName}" />
78+
79+
<!-- Name Box -->
80+
<TextBox
81+
x:Name="ShortcutNameTextBox"
82+
Grid.Row="4"
83+
Grid.ColumnSpan="2"
84+
HorizontalAlignment="Stretch"
85+
Text="{x:Bind ViewModel.ShortcutName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
86+
<TextBox.Resources>
87+
<TeachingTip
88+
x:Name="InvalidNameTeachingTip"
89+
Title="{helpers:ResourceString Name=InvalidFilename/Text}"
90+
IsOpen="{x:Bind ViewModel.ShowNameWarningTip, Mode=OneWay}"
91+
PreferredPlacement="Bottom"
92+
Target="{x:Bind ShortcutNameTextBox}" />
93+
</TextBox.Resources>
94+
</TextBox>
7195
</Grid>
7296
</Border>
7397
</ContentDialog>

src/Files.App/ViewModels/Dialogs/CreateShortcutDialogViewModel.cs

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Runtime.InteropServices;
66
using System.Text;
77
using System.Windows.Input;
8-
using Windows.Storage.Pickers;
98
using Files.Shared.Helpers;
109

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

38+
private string _shortcutName;
39+
public string ShortcutName
40+
{
41+
get => _shortcutName;
42+
set
43+
{
44+
if (SetProperty(ref _shortcutName, value))
45+
{
46+
OnPropertyChanged(nameof(ShowNameWarningTip));
47+
OnPropertyChanged(nameof(IsShortcutValid));
48+
}
49+
}
50+
}
51+
3952
// Destination of the shortcut chosen by the user (can be a path, a command or a URL)
4053
private string _shortcutTarget;
4154
public string ShortcutTarget
@@ -167,6 +180,10 @@ public string ShortcutTarget
167180
Arguments = string.Empty;
168181
_previousShortcutTargetPath = string.Empty;
169182
}
183+
finally
184+
{
185+
AutoFillName();
186+
}
170187
}
171188
}
172189

@@ -178,12 +195,19 @@ public bool IsLocationValid
178195
set
179196
{
180197
if (SetProperty(ref _isLocationValid, value))
198+
{
181199
OnPropertyChanged(nameof(ShowWarningTip));
200+
OnPropertyChanged(nameof(IsShortcutValid));
201+
}
182202
}
183203
}
184204

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

207+
public bool ShowNameWarningTip => !string.IsNullOrEmpty(_shortcutTarget) && !FilesystemHelpers.IsValidForFilename(_shortcutName);
208+
209+
public bool IsShortcutValid => _isLocationValid && !ShowNameWarningTip && !string.IsNullOrEmpty(_shortcutTarget);
210+
187211
// Command invoked when the user clicks the 'Browse' button
188212
public ICommand SelectDestinationCommand { get; private set; }
189213

@@ -225,31 +249,9 @@ private Task SelectDestination()
225249

226250
private async Task CreateShortcutAsync()
227251
{
228-
string? destinationName;
229252
var extension = DestinationPathExists ? ".lnk" : ".url";
230253

231-
if (DestinationPathExists)
232-
{
233-
destinationName = Path.GetFileName(FullPath);
234-
235-
if(string.IsNullOrEmpty(FullPath))
236-
{
237-
238-
var destinationPath = FullPath.Replace('/', '\\');
239-
240-
if (destinationPath.EndsWith('\\'))
241-
destinationPath = destinationPath.Substring(0, destinationPath.Length - 1);
242-
243-
destinationName = destinationPath.Substring(destinationPath.LastIndexOf('\\') + 1);
244-
}
245-
}
246-
else
247-
{
248-
var uri = new Uri(FullPath);
249-
destinationName = uri.Host;
250-
}
251-
252-
var shortcutName = FilesystemHelpers.GetShortcutNamingPreference(destinationName);
254+
var shortcutName = FilesystemHelpers.GetShortcutNamingPreference(_shortcutName);
253255
ShortcutCompleteName = shortcutName + extension;
254256
var filePath = Path.Combine(WorkingDirectory, ShortcutCompleteName);
255257

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

263265
ShortcutCreatedSuccessfully = await FileOperationsHelpers.CreateOrUpdateLinkAsync(filePath, FullPath, Arguments);
264266
}
267+
268+
private void AutoFillName()
269+
{
270+
if (DestinationPathExists)
271+
{
272+
var destinationName = Path.GetFileName(FullPath);
273+
if (DestinationPathExists)
274+
{
275+
destinationName = Path.GetFileName(FullPath);
276+
277+
if (string.IsNullOrEmpty(FullPath))
278+
{
279+
280+
var destinationPath = FullPath.Replace('/', '\\');
281+
282+
if (destinationPath.EndsWith('\\'))
283+
destinationPath = destinationPath.Substring(0, destinationPath.Length - 1);
284+
285+
destinationName = destinationPath.Substring(destinationPath.LastIndexOf('\\') + 1);
286+
}
287+
}
288+
ShortcutName = destinationName;
289+
}
290+
else if (!string.IsNullOrEmpty(FullPath))
291+
{
292+
var uri = new Uri(FullPath);
293+
ShortcutName = uri.Host;
294+
}
295+
}
265296
}
266297
}

0 commit comments

Comments
 (0)