Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
08e2b4c
Add a 'remove all desktop shortcuts' option to the desktop shortcut m…
mrixner Feb 21, 2025
02e0b76
Honor the 'remove all desktop shortcuts' setting
mrixner Feb 21, 2025
111f401
Remove all shortcuts will remove any shortcuts on the desktop after a…
mrixner Feb 22, 2025
6c4af06
Fix a bug where user wouldn't be prompted about new shortcuts
marticliment Feb 26, 2025
35b8831
Dialog improvements
marticliment Feb 26, 2025
461e982
Clarify dialog text
mrixner Feb 26, 2025
b456fc4
Ask the user about all shortcuts on a manual scan, irrespective of th…
mrixner Mar 2, 2025
def1fdb
Merge branch 'main' into remove-all-desktop-shortcuts
mrixner Mar 2, 2025
5aeb78f
Update PackageOperations.cs
mrixner Mar 2, 2025
4800f6a
Merge branch 'main' into pr/3338
marticliment Mar 8, 2025
415c58a
Remove duplicated lines
marticliment Mar 8, 2025
6dc1f65
Discard changes to src/UniGetUI/Controls/OperationWidgets/OperationCo…
marticliment Mar 8, 2025
8fcc428
Improve the codebase's management of new shortcuts depending on the '…
mrixner Mar 8, 2025
a4c2e2b
Check shortcuts to be deleted by default
mrixner Mar 8, 2025
a399351
Merge branch 'remove-all-desktop-shortcuts' of https://github.com/mri…
mrixner Mar 9, 2025
4d0349d
Merge branch 'main' into remove-all-desktop-shortcuts
mrixner Mar 9, 2025
5ef7e51
Update DesktopShortcuts.xaml
mrixner Mar 9, 2025
51ae9cc
Merge branch 'main' into remove-all-desktop-shortcuts
mrixner Mar 10, 2025
7a77de2
Remove desktop shortcuts dialog width value (fix marticliment#3369)
mrixner Mar 10, 2025
a75b794
Merge branch 'main' into remove-all-desktop-shortcuts
marticliment Mar 11, 2025
9ed979a
Change how shortcuts are handled (still needs to be thorougly tested)
marticliment Mar 11, 2025
67e20da
Different behaviour to when pre-existing shortcuts are handled or not.
marticliment Mar 12, 2025
ef38789
Upgrade NuGet packages to the latest version
marticliment Mar 12, 2025
a52052c
Improvements to how shortcuts are shown on the ManageDesktopShortcuts…
marticliment Mar 12, 2025
f200b07
Manual scan is not needed anymore (the dialog loads always all undete…
marticliment Mar 12, 2025
efe09ae
Add a new "Delete?" text over the checkbox on the Desktop Shortcut re…
marticliment Mar 12, 2025
aa236e1
Update DesktopShortcuts.xaml
marticliment Mar 12, 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
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@

<ItemGroup>
<PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" />
<PackageReference Include="System.Drawing.Common" Version="9.0.2" />
<PackageReference Include="System.Drawing.Common" Version="9.0.3" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MessageFormat" Version="7.1.2" />
<PackageReference Include="MessageFormat" Version="7.1.3" />
</ItemGroup>

<ItemGroup>
Expand Down
8 changes: 4 additions & 4 deletions src/UniGetUI.PackageEngine.Operations/PackageOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ protected override Task HandleSuccess()

if (Settings.Get("AskToDeleteNewDesktopShortcuts"))
{
DesktopShortcutsDatabase.TryRemoveNewShortcuts(DesktopShortcutsBeforeStart);
DesktopShortcutsDatabase.HandleNewShortcuts(DesktopShortcutsBeforeStart);
}
return Task.CompletedTask;
}
Expand All @@ -177,7 +177,7 @@ protected override void Initialize()

if (Settings.Get("AskToDeleteNewDesktopShortcuts"))
{
DesktopShortcutsBeforeStart = DesktopShortcutsDatabase.GetShortcuts();
DesktopShortcutsBeforeStart = DesktopShortcutsDatabase.GetShortcutsOnDisk();
}
}
}
Expand Down Expand Up @@ -209,7 +209,7 @@ protected override async Task HandleSuccess()

if (Settings.Get("AskToDeleteNewDesktopShortcuts"))
{
DesktopShortcutsDatabase.TryRemoveNewShortcuts(DesktopShortcutsBeforeStart);
DesktopShortcutsDatabase.HandleNewShortcuts(DesktopShortcutsBeforeStart);
}

if (await Package.HasUpdatesIgnoredAsync() && await Package.GetIgnoredUpdatesVersionAsync() != "*")
Expand All @@ -231,7 +231,7 @@ protected override void Initialize()

if (Settings.Get("AskToDeleteNewDesktopShortcuts"))
{
DesktopShortcutsBeforeStart = DesktopShortcutsDatabase.GetShortcuts();
DesktopShortcutsBeforeStart = DesktopShortcutsDatabase.GetShortcutsOnDisk();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ public static class DesktopShortcutsDatabase
public enum Status
{
Maintain, // The user has explicitly requested this shortcut not be deleted
Delete, // The user has allowed the shortcut to be deleted
Unknown, // The user has not said whether they want this shortcut to be deleted
Delete, // The user has allowed the shortcut to be deleted
}

private static readonly List<string> UnknownShortcuts = [];
Expand All @@ -28,10 +28,13 @@ public static void ResetDatabase()
/// Adds a desktop shortcut to the deletable desktop shortcuts database
/// </summary>
/// <param name="shortcutPath">The path of the shortcut to delete</param>
/// <param name="deletable">Whether or not to mark this entry as deletable in the database. Defaults to true</param>
public static void AddToDatabase(string shortcutPath, bool deletable = true)
/// <param name="shortcutStatus">The status to set</param>
public static void AddToDatabase(string shortcutPath, Status shortcutStatus)
{
Settings.SetDictionaryItem("DeletableDesktopShortcuts", shortcutPath, deletable);
if (shortcutStatus is Status.Unknown)
Settings.RemoveDictionaryKey<string, bool>("DeletableDesktopShortcuts", shortcutPath);
else
Settings.SetDictionaryItem<string, bool>("DeletableDesktopShortcuts", shortcutPath, shortcutStatus is Status.Delete);
}

/// <summary>
Expand All @@ -54,28 +57,6 @@ public static bool Remove(string shortcutPath)
return false;
}

/// <summary>
/// Attempts to reset the configuration of a given shortcut path from the database.
/// This will make it so the user is asked about it the next time it is discovered.
/// Different from `Remove` as Remove simply marks it as non-deletable, whereas this removes the configuration entirely.
/// </summary>
/// <param name="shortcutPath">The path of the shortcut to delete</param>
/// <returns>True if the shortcut was completely removed, false if it was not there from the beginning</returns>
public static bool ResetShortcut(string shortcutPath)
{
// Remove the entry if present
if (Settings.DictionaryContainsKey<string, bool>("DeletableDesktopShortcuts", shortcutPath))
{
// Remove the entry and propagate changes to disk
Settings.RemoveDictionaryKey<string, bool>("DeletableDesktopShortcuts", shortcutPath);
return true;
}

// Do nothing if the entry was not there
Logger.Warn($"Attempted to reset a deletable desktop shortcut {{shortcutPath={shortcutPath}}} that was not found there");
return false;
}

/// <summary>
/// Attempts to delete the given shortcut path off the disk
/// </summary>
Expand Down Expand Up @@ -103,7 +84,7 @@ public static bool DeleteFromDisk(string shortcutPath)
/// until a choice is given to the user and they explicitly request that it be deleted.
/// </summary>
/// <param name="shortcutPath">The path of the shortcut to be deleted</param>
/// <returns>True if the package is ignored, false otherwhise</returns>
/// <returns>The status of a shortcut</returns>
public static Status GetStatus(string shortcutPath)
{
// Check if the package is ignored
Expand All @@ -120,7 +101,7 @@ public static Status GetStatus(string shortcutPath)
/// Get a list of shortcuts (.lnk files only) currently on the user's desktop
/// </summary>
/// <returns>A list of desktop shortcut paths</returns>
public static List<string> GetShortcuts()
public static List<string> GetShortcutsOnDisk()
{
List<string> shortcuts = [];
string UserDesktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
Expand All @@ -130,6 +111,23 @@ public static List<string> GetShortcuts()
return shortcuts;
}

/// <summary>
/// Gets all the shortcuts exist on disk or/and on the database
/// </summary>
/// <returns></returns>
public static List<string> GetAllShortcuts()
{
var shortcuts = GetShortcutsOnDisk();

foreach (var item in Settings.GetDictionary<string, bool>("DeletableDesktopShortcuts"))
{
if (!shortcuts.Contains(item.Key))
shortcuts.Add(item.Key);
}

return shortcuts;
}

/// <summary>
/// Remove a shortcut from the list of shortcuts whose deletion verdicts are unknown (as in, the user needs to be asked about deleting them when their operations finish)
/// </summary>
Expand All @@ -150,29 +148,52 @@ public static List<string> GetUnknownShortcuts()
}

/// <summary>
/// Will attempt to remove new desktop shortcuts, if applicable.
/// Will handle the removal, if applicable, of any shortcut that is not present on the given PreviousShortCutList.
/// </summary>
/// <param name="PreviousShortCutList"></param>
public static void TryRemoveNewShortcuts(IReadOnlyList<string> PreviousShortCutList)
/// <param name="PreviousShortCutList">The shortcuts that already existed</param>
public static void HandleNewShortcuts(IReadOnlyList<string> PreviousShortCutList)
{
HashSet<string> ShortcutSet = PreviousShortCutList.ToHashSet();
List<string> CurrentShortcutList = DesktopShortcutsDatabase.GetShortcuts();
foreach (string shortcut in CurrentShortcutList)
bool DeleteUnknownShortcuts = Settings.Get("RemoveAllDesktopShortcuts");
HashSet<string> PreviousShortcuts = [.. PreviousShortCutList];
List<string> CurrentShortcuts = GetShortcutsOnDisk();

foreach (string shortcut in CurrentShortcuts)
{
if (ShortcutSet.Contains(shortcut)) continue;
switch (DesktopShortcutsDatabase.GetStatus(shortcut))
var status = GetStatus(shortcut);
if (status is Status.Maintain)
{
// Don't delete this shortcut, it has been set to be kept
}
else if (status is Status.Delete)
{
// If a shortcut is set to be deleted, delete it,
// even when it was not created during an UniGetUI operation
DeleteFromDisk(shortcut);
}
else if (status is Status.Unknown)
{
case Status.Delete:
DesktopShortcutsDatabase.DeleteFromDisk(shortcut);
break;
case Status.Maintain:
Logger.Debug("Refraining from deleting new shortcut " + shortcut + ": user disabled its deletion");
break;
case Status.Unknown:
if (UnknownShortcuts.Contains(shortcut)) continue;
Logger.Info("Marking the shortcut " + shortcut + " to be asked to be deleted");
UnknownShortcuts.Add(shortcut);
break;
if (DeleteUnknownShortcuts)
{
// If a shortcut has not been detected yet, and it
// existed before an operation started, then do nothing.
if(PreviousShortcuts.Contains(shortcut))
continue;

// If the shortcut was created during an operation
// and autodelete is enabled, delete that icon
Logger.Warn($"New shortcut {shortcut} will be set for deletion (this shortcut was never seen before)");
AddToDatabase(shortcut, Status.Delete);
DeleteFromDisk(shortcut);
}
else
{
// Mark the shortcut as unknown and prompt the user.
if (!UnknownShortcuts.Contains(shortcut))
{
Logger.Info($"Marking the shortcut {shortcut} to be asked to be deleted");
UnknownShortcuts.Add(shortcut);
}
}
}
}
}
Expand Down
66 changes: 46 additions & 20 deletions src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
xmlns:local="using:UniGetUI.Interface"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:widgets="using:UniGetUI.Interface.Widgets"
Width="900"
MaxWidth="1100"
MaxWidth="950"
mc:Ignorable="d">

<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
Expand All @@ -30,7 +29,7 @@
VerticalAlignment="Bottom"
Orientation="Vertical"
Spacing="4">
<Button Margin="10,0,0,0" HorizontalAlignment="Stretch">
<!--Button Margin="10,0,0,0" HorizontalAlignment="Stretch">
<widgets:TranslatedTextBlock Text="Manual scan" />
<Button.Flyout>
<Flyout
Expand All @@ -49,11 +48,11 @@
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
<widgets:TranslatedTextBlock
Grid.ColumnSpan="2"
Margin="0,0,0,0"
Text="Existing shortcuts on your desktop will be scanned, and you will need to pick which ones to keep and which ones to remove."
TextWrapping="WrapWholeWords" />
WrappingMode="WrapWholeWords" />
<Button
Grid.Row="1"
Grid.Column="1"
Expand All @@ -65,7 +64,7 @@
</Grid>
</Flyout>
</Button.Flyout>
</Button>
</Button-->
<Button Margin="10,0,0,0" HorizontalAlignment="Stretch">
<widgets:TranslatedTextBlock Text="Reset list" />
<Button.Flyout>
Expand All @@ -85,11 +84,11 @@
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
<widgets:TranslatedTextBlock
Grid.ColumnSpan="2"
Margin="0,0,0,0"
Text="Do you really want to reset this list? This action cannot be reverted."
TextWrapping="WrapWholeWords" />
WrappingMode="WrapWholeWords" />
<Button
Grid.Row="1"
Grid.Column="1"
Expand All @@ -115,56 +114,83 @@
<ListView
Name="DeletableDesktopShortcutsList"
Height="350"
Padding="2,4,2,4"
Padding="0,4,2,4"
HorizontalAlignment="Stretch"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
CornerRadius="6"
DoubleTapped="DeletableDesktopShortcutsList_DoubleTapped">
ItemsSource="{x:Bind Shortcuts}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:ShortcutEntry">
<Grid ColumnSpacing="4">
<Grid Margin="-4,2,0,2" ColumnSpacing="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="2" />
<ColumnDefinition Width="24" />
<ColumnDefinition Width="*" MaxWidth="200" />
<ColumnDefinition Width="24" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0" IsChecked="{x:Bind IsChecked, Mode=TwoWay}" />
<Border
Grid.Column="0"
Width="20"
HorizontalAlignment="Center">
<CheckBox
MaxWidth="10"
Margin="0,8,0,0"
IsChecked="{x:Bind IsDeletable, Mode=TwoWay}" />
</Border>
<widgets:TranslatedTextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Top"
FontSize="10"
Text="Delete?" />
<FontIcon
Grid.Column="1"
Grid.Column="2"
Width="24"
Height="24"
Glyph="&#xECAA;" />
<TextBlock
Grid.Column="2"
Grid.Column="3"
VerticalAlignment="Center"
Text="{x:Bind ShortcutPath}" />
Text="{x:Bind Name}" />
<FontIcon
Grid.Column="4"
Width="24"
Height="24"
Glyph="&#xE71B;" />
<TextBlock
Grid.Column="5"
VerticalAlignment="Center"
Text="{x:Bind Path}" />
<Button
Grid.Column="3"
Grid.Column="6"
Width="32"
Height="32"
Padding="0"
Click="{x:Bind OpenShortcutPath}"
IsEnabled="{x:Bind ShortcutExists}">
IsEnabled="{x:Bind ExistsOnDisk}">
<widgets:LocalIcon
Width="24"
Height="24"
Icon="launch" />
</Button>
<Button
Grid.Column="4"
Grid.Column="7"
Width="32"
Height="32"
Padding="0"
Click="{x:Bind ResetConfiguration}">
Click="{x:Bind ResetShortcut}">
<FontIcon FontSize="16" Glyph="&#xE74D;" />
</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
<CheckBox Name="AutoDeleteShortcutsCheckbox" Content="When new shortcuts are detected, delete them automatically instead of showing this dialog." />
</StackPanel>
<!-- Close Button -->
<widgets:DialogCloseButton Margin="0,-63,-24,0" Click="CloseButton_Click" />
Expand Down
Loading
Loading