Browse Source

[Avalonia] Restore set as lockscreen image

Ruben 1 year ago
parent
commit
9e7a13c9a8

+ 2 - 1
src/PicView.Avalonia.MacOS/App.axaml.cs

@@ -295,9 +295,10 @@ public void ShowAboutWindow()
         // TODO: Implement SetAsWallpaper
     }
 
-    public void SetAsLockScreen(string path)
+    public bool SetAsLockScreen(string path)
     {
         // TODO: Implement SetAsLockScreen
+        return false;
     }
     
     public bool CopyFile(string path)

+ 2 - 3
src/PicView.Avalonia.Win32/App.axaml.cs

@@ -321,10 +321,9 @@ public class App : Application, IPlatformSpecificService
         WallpaperHelper.SetDesktopWallpaper(path, style);
     }
     
-    public void SetAsLockScreen(string path)
+    public bool SetAsLockScreen(string path)
     {
-        // TODO: Run a new instance with admin rights and execute SetLockScreenImage
-        LockscreenHelper.SetLockScreenImage(path);
+        return LockscreenHelper.SetLockScreenImage(path);
     }
 
     public bool CopyFile(string path)

+ 72 - 2
src/PicView.Avalonia/ImageHandling/ImageFunctions.cs

@@ -1,7 +1,8 @@
-using Avalonia.Controls;
+using System.Diagnostics;
+using Avalonia.Controls;
 using Avalonia.Media.Imaging;
 using Avalonia.Svg.Skia;
-using PicView.Avalonia.Navigation;
+using PicView.Core.FileHandling;
 using PicView.Core.ImageDecoding;
 
 namespace PicView.Avalonia.ImageHandling;
@@ -23,4 +24,73 @@ public static class ImageFunctions
         var frames = ImageFunctionHelper.GetImageFrames(fileInfo.FullName);
         return frames > 1;
     }
+    
+    public static async Task<string> ConvertToCommonSupportedFormatAsync(string path)
+    {
+        var url = path.GetURL();
+        if (!string.IsNullOrWhiteSpace(url))
+        {
+            // Download the image from the URL
+            path = await DownloadImageFromUrlAsync(url);
+            if (string.IsNullOrEmpty(path))
+            {
+                return string.Empty; // If download fails, return empty
+            }
+        }
+        
+        if (path.StartsWith("file:///"))
+        {
+            path = path.Replace("file:///", "");
+            path = path.Replace("%20", " ");
+        }
+        if (!File.Exists(path))
+            return string.Empty;
+        
+        var ext = Path.GetExtension(path).ToLower();
+        switch (ext)
+        {
+            case ".gif": // Don't know what to do if animated?
+            case ".png":
+            case ".jpg":
+            case ".jpeg":
+            case ".jpe":
+            case ".bmp":
+            case ".jfif":
+                return path;
+
+            default:
+                var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ext);
+                // Save image to temp path
+                var success = await SaveImageFileHelper.SaveImageAsync(null, path, tempPath, null, null, null, ".png");
+                return !success ? string.Empty : tempPath;
+        }
+    }
+    
+    
+    private static async Task<string> DownloadImageFromUrlAsync(string url)
+    {
+        // TODO: Refactoring needed: Need to combine with the one in LoadPicFromUrlAsync and add unit tests
+        try
+        {
+            var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + Path.GetExtension(url));
+
+            using var client = new HttpClient();
+            var response = await client.GetAsync(url);
+            if (response.IsSuccessStatusCode)
+            {
+                await using var fs = new FileStream(tempPath, FileMode.Create);
+                await response.Content.CopyToAsync(fs);
+                return tempPath;
+            }
+        }
+        catch (Exception ex)
+        {
+#if DEBUG
+            Trace.WriteLine($"Error downloading image: {ex.Message}");
+#endif
+            return string.Empty;
+        }
+
+        return string.Empty;
+    }
 }

+ 1 - 1
src/PicView.Avalonia/Interfaces/IPlatformSpecificService.cs

@@ -35,7 +35,7 @@ public interface IPlatformSpecificService
     
     void SetAsWallpaper(string path, int wallpaperStyle);
     
-    void SetAsLockScreen(string path);
+    bool SetAsLockScreen(string path);
     
     bool CopyFile(string path);
     

+ 10 - 1
src/PicView.Avalonia/UI/StartUpHelper.cs

@@ -160,8 +160,17 @@ public static class StartUpHelper
 
         if (args.Length > 1)
         {
+            var arg = args[1];
+            if (arg.StartsWith("lockscreen"))
+            {
+                var path = arg[(arg.LastIndexOf(',') + 1)..];
+                path = Path.GetFullPath(path);
+                vm.PlatformService.SetAsLockScreen(path);
+                Environment.Exit(0);
+            }
+            
             vm.CurrentView = vm.ImageViewer;
-            Task.Run(() => QuickLoad.QuickLoadAsync(vm, args[1]));
+            Task.Run(() => QuickLoad.QuickLoadAsync(vm, arg));
         }
         else if (SettingsHelper.Settings.StartUp.OpenLastFile)
         {

+ 21 - 4
src/PicView.Avalonia/ViewModels/MainViewModel.cs

@@ -1,4 +1,5 @@
-using System.Reactive;
+using System.Diagnostics;
+using System.Reactive;
 using System.Reactive.Linq;
 using Avalonia;
 using Avalonia.Controls;
@@ -17,6 +18,7 @@ using PicView.Core.Calculations;
 using PicView.Core.Config;
 using PicView.Core.FileHandling;
 using PicView.Core.Gallery;
+using PicView.Core.Localization;
 using PicView.Core.ProcessHandling;
 using ReactiveUI;
 using ImageViewer = PicView.Avalonia.Views.ImageViewer;
@@ -1581,10 +1583,25 @@ public class MainViewModel : ViewModelBase
         {
             return;
         }
-        await Task.Run(() =>
+        
+        IsLoading = true;
+
+        var file = await ImageFunctions.ConvertToCommonSupportedFormatAsync(path).ConfigureAwait(false);
+
+        var process = new Process
         {
-            PlatformService?.SetAsLockScreen(path);
-        });
+            StartInfo = new ProcessStartInfo
+            {
+                Verb = "runas",
+                UseShellExecute = true,
+                FileName = "PicView.exe",
+                Arguments = "lockscreen," + file,
+                WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory
+            }
+        };
+        process.Start();
+        await TooltipHelper.ShowTooltipMessageAsync(TranslationHelper.Translation.Applying);
+        await process.WaitForExitAsync();
     }
 
     public async Task GalleryItemStretchTask(string value)

+ 1 - 2
src/PicView.Avalonia/Views/MainView.axaml

@@ -423,8 +423,7 @@
                 CommandParameter="{CompiledBinding FileInfo.FullName,
                                                    FallbackValue=''}"
                 Header="{CompiledBinding SetAsLockScreenImage,
-                                         Mode=OneWay}"
-                IsEnabled="False">
+                                         Mode=OneWay}">
                 <MenuItem.Icon>
                     <Path
                         Data="{StaticResource PanoramaGeometry}"

+ 4 - 3
src/PicView.WindowsNT/Lockscreen/LockscreenHelper.cs

@@ -3,10 +3,11 @@ using Microsoft.Win32;
 
 namespace PicView.WindowsNT.Lockscreen;
 
-public static class LockscreenHelper
+public static partial class LockscreenHelper
 {
-    [DllImport("kernel32.dll", SetLastError = true)]
-    public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr); //If on 64 bit, C# will replace "System32" with "SysWOW64". This disables that.
+    [LibraryImport("kernel32.dll", SetLastError = true)]
+    [return: MarshalAs(UnmanagedType.Bool)]
+    public static partial bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
 
     public static bool SetLockScreenImage(string path)
     {