Skip to content

Add Delete functionality for Peek #35418

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 21 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8a919f5
Add Delete functionality for Peek.
daverayment Oct 13, 2024
23d600f
Updated the "No More Files" text block to use a Uid to load its resou…
daverayment Oct 13, 2024
a5afc8e
Revert "Delete Directory.Packages.props"
daverayment Oct 14, 2024
f575e6d
Attempt to appease the spell-checking bot by renaming flag const.
daverayment Oct 14, 2024
92a22ff
Show error message InfoBar if file deletion failed.
daverayment Oct 19, 2024
43c9ae8
Resolve XAML styling.
daverayment Oct 19, 2024
dc285e7
XAML styling fix.
daverayment Oct 19, 2024
441898a
Settings app updates for new delete confirmation setting.
daverayment Jan 22, 2025
36882f4
Add delete confirmation dialog and settings to Peek. Add shell notifi…
daverayment Jan 22, 2025
a3c0fa4
Spelling updates.
daverayment Jan 27, 2025
c94f1e7
Spelling update.
daverayment Jan 27, 2025
614c662
Remove permanent delete parameter, YAGNI. Add hwnd parameter to delet…
daverayment Jan 28, 2025
098d912
Simplify delete confirmation dialog. Remove workaround for focus visu…
daverayment Jan 28, 2025
e030084
Fix delete delay. Do not regard user cancellations of permanent delet…
daverayment Jan 28, 2025
ff2b287
Fix multiple Content_KeyUp events being raised for MainWindow.
daverayment Mar 3, 2025
a7b1752
Synchronise ConfirmFileDelete setting between Peek and Settings app.
daverayment Mar 6, 2025
43539df
Merge branch 'main' into peek-delete
daverayment Mar 6, 2025
1f77218
Update following review: split System usings from others; do not log …
daverayment Mar 6, 2025
76ce44e
Merge branch 'peek-delete' of https://github.com/daverayment/PowerToy…
daverayment Mar 6, 2025
6e23367
Fix XAML style
jaimecbernardo Mar 17, 2025
50f709d
Merge branch 'main' into pr35418
jaimecbernardo Mar 17, 2025
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
3 changes: 3 additions & 0 deletions .github/actions/spell-check/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ flac
flyouts
FMask
FOF
WANTNUKEWARNING
FOFX
FOLDERID
folderpath
Expand Down Expand Up @@ -1418,6 +1419,7 @@ SHCNE
SHCNF
SHCONTF
Shcore
shellapi
SHELLDETAILS
SHELLDLL
shellex
Expand Down Expand Up @@ -1812,6 +1814,7 @@ windowssearch
windowssettings
WINDOWSTYLES
WINDOWSTYLESICON
winerror
WINEVENT
winget
wingetcreate
Expand Down
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,4 @@
<PackageVersion Include="Microsoft.VariantAssignment.Client" Version="2.4.17140001" />
<PackageVersion Include="Microsoft.VariantAssignment.Contract" Version="3.0.16990001" />
</ItemGroup>
</Project>
</Project>
10 changes: 10 additions & 0 deletions src/modules/peek/Peek.FilePreviewer/FilePreview.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@
LoadingState="{x:Bind UnsupportedFilePreviewer.State, Mode=OneWay}"
Source="{x:Bind UnsupportedFilePreviewer.Preview, Mode=OneWay}"
Visibility="{x:Bind IsUnsupportedPreviewVisible(UnsupportedFilePreviewer, Previewer.State), Mode=OneWay}" />

<TextBlock
x:Name="NoMoreFiles"
x:Uid="NoMoreFiles"
HorizontalAlignment="Center"
VerticalAlignment="Center"
AutomationProperties.HeadingLevel="1"
Foreground="{StaticResource TextFillColorSecondaryBrush}"
TextWrapping="Wrap"
Visibility="Collapsed" />
</Grid>
<UserControl.KeyboardAccelerators>
<KeyboardAccelerator
Expand Down
8 changes: 8 additions & 0 deletions src/modules/peek/Peek.FilePreviewer/FilePreview.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ public sealed partial class FilePreview : UserControl, IDisposable
typeof(FilePreview),
new PropertyMetadata(false, async (d, e) => await ((FilePreview)d).OnScalingFactorPropertyChanged()));

[ObservableProperty]
private int numberOfFiles;

[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ImagePreviewer))]
[NotifyPropertyChangedFor(nameof(VideoPreviewer))]
Expand All @@ -62,6 +65,9 @@ public sealed partial class FilePreview : UserControl, IDisposable
[ObservableProperty]
private string infoTooltip = ResourceLoaderInstance.ResourceLoader.GetString("PreviewTooltip_Blank");

[ObservableProperty]
private string noMoreFilesText = ResourceLoaderInstance.ResourceLoader.GetString("NoMoreFiles");

private CancellationTokenSource _cancellationTokenSource = new();

public FilePreview()
Expand Down Expand Up @@ -158,6 +164,8 @@ private async Task OnItemPropertyChanged()
// Clear up any unmanaged resources before creating a new previewer instance.
(Previewer as IDisposable)?.Dispose();

NoMoreFiles.Visibility = NumberOfFiles == 0 ? Visibility.Visible : Visibility.Collapsed;

if (Item == null)
{
Previewer = null;
Expand Down
100 changes: 100 additions & 0 deletions src/modules/peek/Peek.UI/Helpers/DeleteErrorMessageHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using System.Globalization;
using System.Text;
using ManagedCommon;
using static Peek.Common.Helpers.ResourceLoaderInstance;

namespace Peek.UI.Helpers;

public static class DeleteErrorMessageHelper
{
/// <summary>
/// The "Could not delete 'filename'." message, which begins every user-facing error string.
/// </summary>
private static readonly CompositeFormat UserMessagePrefix =
CompositeFormat.Parse(ResourceLoader.GetString("DeleteFileError_Prefix") + " ");

/// <summary>
/// The message displayed if the delete failed but the error code isn't covered in the
/// <see cref="DeleteFileErrors"/> collection.
/// </summary>
private static readonly string GenericErrorMessage = ResourceLoader.GetString("DeleteFileError_Generic");

/// <summary>
/// The collection of the most common error codes with their matching log messages and user-
/// facing descriptions.
/// </summary>
private static readonly Dictionary<int, (string LogMessage, string UserMessage)> DeleteFileErrors = new()
{
{
2,
(
"The system cannot find the file specified.",
ResourceLoader.GetString("DeleteFileError_NotFound")
)
},
{
3,
(
"The system cannot find the path specified.",
ResourceLoader.GetString("DeleteFileError_NotFound")
)
},
{
5,
(
"Access is denied.",
ResourceLoader.GetString("DeleteFileError_AccessDenied")
)
},
{
19,
(
"The media is write protected.",
ResourceLoader.GetString("DeleteFileError_WriteProtected")
)
},
{
32,
(
"The process cannot access the file because it is being used by another process.",
ResourceLoader.GetString("DeleteFileError_FileInUse")
)
},
{
33,
(
"The process cannot access the file because another process has locked a portion of the file.",
ResourceLoader.GetString("DeleteFileError_FileInUse")
)
},
};

/// <summary>
/// Logs an error message in response to a failed file deletion attempt.
/// </summary>
/// <param name="errorCode">The error code returned from the delete call.</param>
public static void LogError(int errorCode) =>
Logger.LogError(DeleteFileErrors.TryGetValue(errorCode, out var messages) ?
messages.LogMessage :
$"Error {errorCode} occurred while deleting the file.");

/// <summary>
/// Gets the message to display in the UI for a specific delete error code.
/// </summary>
/// <param name="filename">The name of the file which could not be deleted.</param>
/// <param name="errorCode">The error code result from the delete call.</param>
/// <returns>A string containing the message to show in the user interface.</returns>
public static string GetUserErrorMessage(string filename, int errorCode)
{
string prefix = string.Format(CultureInfo.InvariantCulture, UserMessagePrefix, filename);

return DeleteFileErrors.TryGetValue(errorCode, out var messages) ?
prefix + messages.UserMessage :
prefix + GenericErrorMessage;
}
}
Loading
Loading