mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-24 04:00:02 +01:00
Merge branch 'main' into dev/seraphima/tests/29239-fancyzones-tests-fzeditor
This commit is contained in:
2
.github/actions/spell-check/allow/names.txt
vendored
2
.github/actions/spell-check/allow/names.txt
vendored
@@ -46,6 +46,7 @@ chrdavis
|
||||
Chrzan
|
||||
clayton
|
||||
Coplen
|
||||
craigloewen
|
||||
crutkas
|
||||
damienleroy
|
||||
davidegiacometti
|
||||
@@ -87,6 +88,7 @@ martinchrzan
|
||||
martinmoene
|
||||
Melman
|
||||
Mikhayelyan
|
||||
msft
|
||||
Myrvold
|
||||
Nemeth
|
||||
nielslaute
|
||||
|
||||
33
.github/workflows/similarIssues.yml
vendored
Normal file
33
.github/workflows/similarIssues.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: GitGudSimilarIssues comments
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
getSimilarIssues:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
message: ${{ steps.getBody.outputs.message }}
|
||||
steps:
|
||||
- id: getBody
|
||||
uses: craigloewen-msft/GitGudSimilarIssues@main
|
||||
with:
|
||||
issueTitle: ${{ github.event.issue.title }}
|
||||
issueBody: ${{ github.event.issue.body }}
|
||||
repo: ${{ github.repository }}
|
||||
similarityTolerance: "0.75"
|
||||
add-comment:
|
||||
needs: getSimilarIssues
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
if: needs.getSimilarIssues.outputs.message != ''
|
||||
steps:
|
||||
- name: Add comment
|
||||
run: gh issue comment "$NUMBER" --repo "$REPO" --body "$BODY"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NUMBER: ${{ github.event.issue.number }}
|
||||
REPO: ${{ github.repository }}
|
||||
BODY: ${{ needs.getSimilarIssues.outputs.message }}
|
||||
@@ -54,6 +54,7 @@
|
||||
"fancyzones.dll",
|
||||
"PowerToys.FancyZonesEditor.exe",
|
||||
"PowerToys.FancyZonesEditor.dll",
|
||||
"PowerToys.FancyZonesEditorCommon.dll",
|
||||
"PowerToys.FancyZonesModuleInterface.dll",
|
||||
"PowerToys.FancyZones.exe",
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
|
||||
$WixDownloadUrl = "https://github.com/wixtoolset/wix3/releases/download/wix314rtm/wix314.exe"
|
||||
$WixBinariesDownloadUrl = "https://github.com/wixtoolset/wix3/releases/download/wix314rtm/wix314-binaries.zip"
|
||||
$WixDownloadUrl = "https://github.com/wixtoolset/wix3/releases/download/wix3141rtm/wix314.exe"
|
||||
$WixBinariesDownloadUrl = "https://github.com/wixtoolset/wix3/releases/download/wix3141rtm/wix314-binaries.zip"
|
||||
|
||||
# Download WiX binaries and verify their hash sums
|
||||
Invoke-WebRequest -Uri $WixDownloadUrl -OutFile "$($ENV:Temp)\wix314.exe"
|
||||
$Hash = (Get-FileHash -Algorithm SHA256 "$($ENV:Temp)\wix314.exe").Hash
|
||||
if ($Hash -ne '704439EA88FC9E5A3647EEDEEB45943F9A392E3D209F58512280130096847937')
|
||||
if ($Hash -ne '6BF6D03D6923D9EF827AE1D943B90B42B8EBB1B0F68EF6D55F868FA34C738A29')
|
||||
{
|
||||
Write-Error "$WixHash"
|
||||
throw "wix314.exe has unexpected SHA256 hash: $Hash"
|
||||
}
|
||||
Invoke-WebRequest -Uri $WixBinariesDownloadUrl -OutFile "$($ENV:Temp)\wix314-binaries.zip"
|
||||
$Hash = (Get-FileHash -Algorithm SHA256 "$($ENV:Temp)\wix314-binaries.zip").Hash
|
||||
if($Hash -ne '13F067F38969FAF163D93A804B48EA0576790A202C8F10291F2000F0E356E934')
|
||||
if($Hash -ne '6AC824E1642D6F7277D0ED7EA09411A508F6116BA6FAE0AA5F2C7DAA2FF43D31')
|
||||
{
|
||||
throw "wix314-binaries.zip has unexpected SHA256 hash: $Hash"
|
||||
}
|
||||
|
||||
@@ -80,8 +80,8 @@ The installer can only be compiled in `Release` mode; steps 1 and 2 must be perf
|
||||
### Prerequisites for building the MSI installer
|
||||
|
||||
1. Install the [WiX Toolset Visual Studio 2022 Extension](https://marketplace.visualstudio.com/items?itemName=WixToolset.WixToolsetVisualStudio2022Extension).
|
||||
1. Install the [WiX Toolset build tools](https://github.com/wixtoolset/wix3/releases/tag/wix314rtm). (installer [direct link](https://github.com/wixtoolset/wix3/releases/download/wix314rtm/wix314.exe))
|
||||
1. Download [WiX binaries](https://github.com/wixtoolset/wix3/releases/download/wix314rtm/wix314-binaries.zip) and extract `wix.targets` to `C:\Program Files (x86)\WiX Toolset v3.14`.
|
||||
1. Install the [WiX Toolset build tools](https://github.com/wixtoolset/wix3/releases/tag/wix3141rtm). (installer [direct link](https://github.com/wixtoolset/wix3/releases/download/wix3141rtm/wix314.exe))
|
||||
1. Download [WiX binaries](https://github.com/wixtoolset/wix3/releases/download/wix3141rtm/wix314-binaries.zip) and extract `wix.targets` to `C:\Program Files (x86)\WiX Toolset v3.14`.
|
||||
|
||||
### Building prerequisite projects
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
Vital="no">
|
||||
</ExePackage>
|
||||
<ExePackage
|
||||
DisplayName="Installing Microsoft Edge WebView2"
|
||||
DisplayName="Microsoft Edge WebView2"
|
||||
Name="MicrosoftEdgeWebview2Setup.exe"
|
||||
Compressed="yes"
|
||||
Id="WebView2"
|
||||
@@ -81,7 +81,7 @@
|
||||
UninstallCommand="/silent /uninstall">
|
||||
</ExePackage>
|
||||
<MsiPackage
|
||||
DisplayName="Installing PowerToys"
|
||||
DisplayName="PowerToys MSI"
|
||||
SourceFile="$(var.PowerToysPlatform)\Release\$(var.MSIPath)\$(var.MSIName)"
|
||||
Compressed="yes"
|
||||
DisplayInternalUI="no">
|
||||
|
||||
@@ -47,51 +47,17 @@ internal sealed class ImageMethods
|
||||
return destination;
|
||||
}
|
||||
|
||||
internal static ImageSource GetWindowBoundsImage(Window passedWindow)
|
||||
internal static ImageSource GetWindowBoundsImage(OCROverlay passedWindow)
|
||||
{
|
||||
DpiScale dpi = VisualTreeHelper.GetDpi(passedWindow);
|
||||
int windowWidth = (int)(passedWindow.ActualWidth * dpi.DpiScaleX);
|
||||
int windowHeight = (int)(passedWindow.ActualHeight * dpi.DpiScaleY);
|
||||
|
||||
System.Windows.Point absPosPoint = passedWindow.GetAbsolutePosition();
|
||||
int thisCorrectedLeft = (int)absPosPoint.X;
|
||||
int thisCorrectedTop = (int)absPosPoint.Y;
|
||||
|
||||
using Bitmap bmp = new(windowWidth, windowHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
Rectangle screenRectangle = passedWindow.GetScreenRectangle();
|
||||
using Bitmap bmp = new(screenRectangle.Width, screenRectangle.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
using Graphics g = Graphics.FromImage(bmp);
|
||||
|
||||
g.CopyFromScreen(thisCorrectedLeft, thisCorrectedTop, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy);
|
||||
g.CopyFromScreen(screenRectangle.Left, screenRectangle.Top, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy);
|
||||
return BitmapToImageSource(bmp);
|
||||
}
|
||||
|
||||
internal static Bitmap GetWindowBoundsBitmap(Window passedWindow)
|
||||
{
|
||||
DpiScale dpi = VisualTreeHelper.GetDpi(passedWindow);
|
||||
int windowWidth = (int)(passedWindow.ActualWidth * dpi.DpiScaleX);
|
||||
int windowHeight = (int)(passedWindow.ActualHeight * dpi.DpiScaleY);
|
||||
|
||||
System.Windows.Point absPosPoint = passedWindow.GetAbsolutePosition();
|
||||
int thisCorrectedLeft = (int)absPosPoint.X;
|
||||
int thisCorrectedTop = (int)absPosPoint.Y;
|
||||
|
||||
Bitmap bmp = new(
|
||||
windowWidth,
|
||||
windowHeight,
|
||||
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
using Graphics g = Graphics.FromImage(bmp);
|
||||
|
||||
g.CopyFromScreen(
|
||||
thisCorrectedLeft,
|
||||
thisCorrectedTop,
|
||||
0,
|
||||
0,
|
||||
bmp.Size,
|
||||
CopyPixelOperation.SourceCopy);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
internal static Bitmap GetRegionAsBitmap(Window passedWindow, Rectangle selectedRegion)
|
||||
internal static Bitmap GetRegionAsBitmap(OCROverlay passedWindow, Rectangle selectedRegion)
|
||||
{
|
||||
Bitmap bmp = new(
|
||||
selectedRegion.Width,
|
||||
@@ -99,15 +65,11 @@ internal sealed class ImageMethods
|
||||
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
|
||||
using Graphics g = Graphics.FromImage(bmp);
|
||||
|
||||
System.Windows.Point absPosPoint = passedWindow.GetAbsolutePosition();
|
||||
|
||||
int thisCorrectedLeft = (int)absPosPoint.X + selectedRegion.Left;
|
||||
int thisCorrectedTop = (int)absPosPoint.Y + selectedRegion.Top;
|
||||
Rectangle screenRectangle = passedWindow.GetScreenRectangle();
|
||||
|
||||
g.CopyFromScreen(
|
||||
thisCorrectedLeft,
|
||||
thisCorrectedTop,
|
||||
screenRectangle.Left + selectedRegion.Left,
|
||||
screenRectangle.Top + selectedRegion.Top,
|
||||
0,
|
||||
0,
|
||||
bmp.Size,
|
||||
@@ -117,7 +79,7 @@ internal sealed class ImageMethods
|
||||
return bmp;
|
||||
}
|
||||
|
||||
internal static async Task<string> GetRegionsText(Window? passedWindow, Rectangle selectedRegion, Language? preferredLanguage)
|
||||
internal static async Task<string> GetRegionsText(OCROverlay? passedWindow, Rectangle selectedRegion, Language? preferredLanguage)
|
||||
{
|
||||
if (passedWindow is null)
|
||||
{
|
||||
@@ -130,17 +92,15 @@ internal sealed class ImageMethods
|
||||
return resultText != null ? resultText.Trim() : string.Empty;
|
||||
}
|
||||
|
||||
internal static async Task<string> GetClickedWord(Window passedWindow, System.Windows.Point clickedPoint, Language? preferredLanguage)
|
||||
internal static async Task<string> GetClickedWord(OCROverlay passedWindow, System.Windows.Point clickedPoint, Language? preferredLanguage)
|
||||
{
|
||||
DpiScale dpi = VisualTreeHelper.GetDpi(passedWindow);
|
||||
Bitmap bmp = new((int)(passedWindow.ActualWidth * dpi.DpiScaleX), (int)(passedWindow.ActualHeight * dpi.DpiScaleY), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
Rectangle screenRectangle = passedWindow.GetScreenRectangle();
|
||||
Bitmap bmp = new((int)screenRectangle.Width, (int)passedWindow.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
Graphics g = Graphics.FromImage(bmp);
|
||||
|
||||
System.Windows.Point absPosPoint = passedWindow.GetAbsolutePosition();
|
||||
int thisCorrectedLeft = (int)absPosPoint.X;
|
||||
int thisCorrectedTop = (int)absPosPoint.Y;
|
||||
|
||||
g.CopyFromScreen(thisCorrectedLeft, thisCorrectedTop, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy);
|
||||
g.CopyFromScreen((int)absPosPoint.X, (int)absPosPoint.Y, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy);
|
||||
|
||||
System.Windows.Point adjustedPoint = new(clickedPoint.X, clickedPoint.Y);
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace PowerOCR.Helpers
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<string> GetRegionsTextAsTableAsync(Window passedWindow, Rectangle regionScaled, Language? language)
|
||||
public static async Task<string> GetRegionsTextAsTableAsync(OCROverlay passedWindow, Rectangle regionScaled, Language? language)
|
||||
{
|
||||
if (language is null)
|
||||
{
|
||||
|
||||
@@ -37,4 +37,28 @@ public static class WPFExtensionMethods
|
||||
|
||||
return new Point(r.X, r.Y);
|
||||
}
|
||||
|
||||
public static DpiScale GetDpi(this System.Windows.Forms.Screen screen)
|
||||
{
|
||||
var point = new System.Drawing.Point(screen.Bounds.Left + 1, screen.Bounds.Top + 1);
|
||||
var mon = MonitorFromPoint(point, 2/*MONITOR_DEFAULTTONEAREST*/);
|
||||
GetDpiForMonitor(mon, DpiType.Effective, out uint dpiX, out uint dpiY);
|
||||
return new DpiScale(dpiX / 96.0, dpiY / 96.0);
|
||||
}
|
||||
|
||||
// https://msdn.microsoft.com/library/windows/desktop/dd145062(v=vs.85).aspx
|
||||
[DllImport("User32.dll")]
|
||||
private static extern IntPtr MonitorFromPoint([In] System.Drawing.Point pt, [In] uint dwFlags);
|
||||
|
||||
// https://msdn.microsoft.com/library/windows/desktop/dn280510(v=vs.85).aspx
|
||||
[DllImport("Shcore.dll")]
|
||||
private static extern IntPtr GetDpiForMonitor([In] IntPtr hmonitor, [In] DpiType dpiType, [Out] out uint dpiX, [Out] out uint dpiY);
|
||||
|
||||
// https://msdn.microsoft.com/library/windows/desktop/dn280511(v=vs.85).aspx
|
||||
public enum DpiType
|
||||
{
|
||||
Effective = 0,
|
||||
Angular = 1,
|
||||
Raw = 2,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,9 @@ public static class WindowUtilities
|
||||
Logger.LogInfo($"Adding Overlays for each screen");
|
||||
foreach (Screen screen in Screen.AllScreens)
|
||||
{
|
||||
Logger.LogInfo($"screen {screen}");
|
||||
OCROverlay overlay = new(screen.Bounds);
|
||||
DpiScale dpiScale = screen.GetDpi();
|
||||
Logger.LogInfo($"screen {screen}, dpiScale {dpiScale.DpiScaleX}, {dpiScale.DpiScaleY}");
|
||||
OCROverlay overlay = new(screen.Bounds, dpiScale);
|
||||
|
||||
overlay.Show();
|
||||
ActivateWindow(overlay);
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
xmlns:p="clr-namespace:PowerOCR.Properties"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
Title="TextExtractor"
|
||||
Width="200"
|
||||
Height="200"
|
||||
ui:Design.Background="Transparent"
|
||||
AllowsTransparency="True"
|
||||
Background="Transparent"
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using Common.UI;
|
||||
using ManagedCommon;
|
||||
@@ -42,11 +44,21 @@ public partial class OCROverlay : Window
|
||||
private bool isComboBoxReady;
|
||||
private const double ActiveOpacity = 0.4;
|
||||
private readonly UserSettings userSettings = new(new ThrottledActionInvoker());
|
||||
private System.Drawing.Rectangle screenRectangle;
|
||||
private DpiScale dpiScale;
|
||||
|
||||
public OCROverlay(System.Drawing.Rectangle screenRectangle)
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern bool MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool bRepaint);
|
||||
|
||||
public OCROverlay(System.Drawing.Rectangle screenRectangleParam, DpiScale dpiScaleParam)
|
||||
{
|
||||
Left = screenRectangle.Left >= 0 ? screenRectangle.Left : screenRectangle.Left + (screenRectangle.Width / 2);
|
||||
Top = screenRectangle.Top >= 0 ? screenRectangle.Top : screenRectangle.Top + (screenRectangle.Height / 2);
|
||||
screenRectangle = screenRectangleParam;
|
||||
dpiScale = dpiScaleParam;
|
||||
|
||||
Left = screenRectangle.Left;
|
||||
Top = screenRectangle.Top;
|
||||
Width = screenRectangle.Width / dpiScale.DpiScaleX;
|
||||
Height = screenRectangle.Height / dpiScale.DpiScaleY;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
@@ -106,7 +118,6 @@ public partial class OCROverlay : Window
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
WindowState = WindowState.Maximized;
|
||||
FullWindow.Rect = new Rect(0, 0, Width, Height);
|
||||
KeyDown += MainWindow_KeyDown;
|
||||
KeyUp += MainWindow_KeyUp;
|
||||
@@ -119,6 +130,12 @@ public partial class OCROverlay : Window
|
||||
#if DEBUG
|
||||
Topmost = false;
|
||||
#endif
|
||||
IntPtr hwnd = new WindowInteropHelper(this).Handle;
|
||||
|
||||
// The first move puts it on the correct monitor, which triggers WM_DPICHANGED
|
||||
// The +1/-1 coerces WPF to update Window.Top/Left/Width/Height in the second move
|
||||
MoveWindow(hwnd, (int)(screenRectangle.Left + 1), (int)screenRectangle.Top, (int)(screenRectangle.Width - 1), (int)screenRectangle.Height, false);
|
||||
MoveWindow(hwnd, (int)screenRectangle.Left, (int)screenRectangle.Top, (int)screenRectangle.Width, (int)screenRectangle.Height, true);
|
||||
}
|
||||
|
||||
private void Window_Unloaded(object sender, RoutedEventArgs e)
|
||||
@@ -476,4 +493,9 @@ public partial class OCROverlay : Window
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public System.Drawing.Rectangle GetScreenRectangle()
|
||||
{
|
||||
return screenRectangle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,12 @@
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
|
||||
PerMonitor
|
||||
</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Windows;
|
||||
using FancyZonesEditor.Models;
|
||||
@@ -149,10 +150,13 @@ namespace FancyZonesEditor.Utils
|
||||
try
|
||||
{
|
||||
LayoutHotkeys parser = new LayoutHotkeys();
|
||||
if (!File.Exists(parser.File))
|
||||
{
|
||||
return new ParsingResult(true);
|
||||
}
|
||||
|
||||
var layoutHotkeys = parser.Read(parser.File);
|
||||
|
||||
bool layoutHotkeysParsingResult = SetLayoutHotkeys(layoutHotkeys);
|
||||
|
||||
if (!layoutHotkeysParsingResult)
|
||||
{
|
||||
return new ParsingResult(false, FancyZonesEditor.Properties.Resources.Error_Parsing_Layout_Hotkeys_Message);
|
||||
@@ -174,8 +178,12 @@ namespace FancyZonesEditor.Utils
|
||||
try
|
||||
{
|
||||
LayoutTemplates parser = new LayoutTemplates();
|
||||
var templates = parser.Read(parser.File);
|
||||
if (!File.Exists(parser.File))
|
||||
{
|
||||
return new ParsingResult(true);
|
||||
}
|
||||
|
||||
var templates = parser.Read(parser.File);
|
||||
bool parsingResult = SetTemplateLayouts(templates.LayoutTemplates);
|
||||
if (parsingResult)
|
||||
{
|
||||
@@ -198,8 +206,12 @@ namespace FancyZonesEditor.Utils
|
||||
try
|
||||
{
|
||||
CustomLayouts parser = new CustomLayouts();
|
||||
var wrapper = parser.Read(parser.File);
|
||||
if (!File.Exists(parser.File))
|
||||
{
|
||||
return new ParsingResult(true);
|
||||
}
|
||||
|
||||
var wrapper = parser.Read(parser.File);
|
||||
bool parsingResult = SetCustomLayouts(wrapper.CustomLayouts);
|
||||
if (parsingResult)
|
||||
{
|
||||
@@ -222,8 +234,12 @@ namespace FancyZonesEditor.Utils
|
||||
try
|
||||
{
|
||||
DefaultLayouts parser = new DefaultLayouts();
|
||||
var wrapper = parser.Read(parser.File);
|
||||
if (!File.Exists(parser.File))
|
||||
{
|
||||
return new ParsingResult(true);
|
||||
}
|
||||
|
||||
var wrapper = parser.Read(parser.File);
|
||||
bool parsingResult = SetDefaultLayouts(wrapper.DefaultLayouts);
|
||||
if (parsingResult)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using ManagedCommon;
|
||||
using Windows.Storage;
|
||||
@@ -25,6 +26,8 @@ namespace Peek.Common.Models
|
||||
|
||||
public string Path { get; init; }
|
||||
|
||||
public string Extension => System.IO.Path.GetExtension(Path).ToLower(CultureInfo.InvariantCulture);
|
||||
|
||||
public async Task<IStorageItem?> GetStorageItemAsync()
|
||||
{
|
||||
return await GetStorageFileAsync();
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace Peek.Common.Models
|
||||
|
||||
public string Path { get; init; }
|
||||
|
||||
public string Extension => string.Empty;
|
||||
|
||||
public async Task<IStorageItem?> GetStorageItemAsync()
|
||||
{
|
||||
return await GetStorageFolderAsync();
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using Peek.Common.Helpers;
|
||||
using Windows.Storage;
|
||||
@@ -32,7 +31,7 @@ namespace Peek.Common.Models
|
||||
}
|
||||
}
|
||||
|
||||
public string Extension => System.IO.Path.GetExtension(Path).ToLower(CultureInfo.InvariantCulture);
|
||||
public string Extension { get; }
|
||||
|
||||
public string Name { get; init; }
|
||||
|
||||
|
||||
@@ -111,9 +111,9 @@ namespace Peek.FilePreviewer.Previewers.Archives
|
||||
State = PreviewState.Loaded;
|
||||
}
|
||||
|
||||
public static bool IsFileTypeSupported(string fileExt)
|
||||
public static bool IsItemSupported(IFileSystemItem item)
|
||||
{
|
||||
return _supportedFileTypes.Contains(fileExt);
|
||||
return _supportedFileTypes.Contains(item.Extension);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -89,9 +89,9 @@ namespace Peek.FilePreviewer.Previewers.Drive
|
||||
State = PreviewState.Loaded;
|
||||
}
|
||||
|
||||
public static bool IsPathSupported(string path)
|
||||
public static bool IsItemSupported(IFileSystemItem item)
|
||||
{
|
||||
return DriveInfo.GetDrives().Any(d => d.Name == path);
|
||||
return DriveInfo.GetDrives().Any(d => d.Name == item.Path);
|
||||
}
|
||||
|
||||
private string GetDriveTypeDescription(DriveType driveType) => driveType switch
|
||||
|
||||
@@ -8,7 +8,7 @@ using Peek.FilePreviewer.Previewers.Archives.Models;
|
||||
|
||||
namespace Peek.FilePreviewer.Previewers.Interfaces
|
||||
{
|
||||
public interface IArchivePreviewer : IPreviewer, IDisposable
|
||||
public interface IArchivePreviewer : IPreviewer, IPreviewTarget, IDisposable
|
||||
{
|
||||
ObservableCollection<ArchiveItem> Tree { get; }
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ using Peek.FilePreviewer.Previewers.MediaPreviewer.Models;
|
||||
|
||||
namespace Peek.FilePreviewer.Previewers.Interfaces
|
||||
{
|
||||
public interface IAudioPreviewer : IPreviewer
|
||||
public interface IAudioPreviewer : IPreviewer, IPreviewTarget
|
||||
{
|
||||
public AudioPreviewData? Preview { get; }
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace Peek.FilePreviewer.Previewers
|
||||
namespace Peek.FilePreviewer.Previewers.Interfaces
|
||||
{
|
||||
public interface IBrowserPreviewer : IPreviewer
|
||||
public interface IBrowserPreviewer : IPreviewer, IPreviewTarget
|
||||
{
|
||||
public Uri? Preview { get; }
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ using Peek.FilePreviewer.Previewers.Drive.Models;
|
||||
|
||||
namespace Peek.FilePreviewer.Previewers.Interfaces
|
||||
{
|
||||
public interface IDrivePreviewer : IPreviewer
|
||||
public interface IDrivePreviewer : IPreviewer, IPreviewTarget
|
||||
{
|
||||
public DrivePreviewData? Preview { get; }
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ using Windows.Foundation;
|
||||
|
||||
namespace Peek.FilePreviewer.Previewers.Interfaces
|
||||
{
|
||||
public interface IImagePreviewer : IPreviewer
|
||||
public interface IImagePreviewer : IPreviewer, IPreviewTarget
|
||||
{
|
||||
public ImageSource? Preview { get; }
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// 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 Peek.Common.Models;
|
||||
|
||||
namespace Peek.FilePreviewer.Previewers.Interfaces
|
||||
{
|
||||
public interface IPreviewTarget
|
||||
{
|
||||
static abstract bool IsItemSupported(IFileSystemItem item);
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,10 @@
|
||||
// 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;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Peek.FilePreviewer.Models;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Peek.FilePreviewer.Previewers
|
||||
{
|
||||
@@ -15,8 +13,6 @@ namespace Peek.FilePreviewer.Previewers
|
||||
{
|
||||
PreviewState State { get; set; }
|
||||
|
||||
public static bool IsFileTypeSupported(string fileExt) => throw new NotImplementedException();
|
||||
|
||||
public Task<PreviewSize> GetPreviewSizeAsync(CancellationToken cancellationToken);
|
||||
|
||||
Task LoadPreviewAsync(CancellationToken cancellationToken);
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
using Windows.Win32.UI.Shell;
|
||||
|
||||
namespace Peek.FilePreviewer.Previewers
|
||||
namespace Peek.FilePreviewer.Previewers.Interfaces
|
||||
{
|
||||
public interface IShellPreviewHandlerPreviewer : IPreviewer
|
||||
public interface IShellPreviewHandlerPreviewer : IPreviewer, IPreviewTarget
|
||||
{
|
||||
public IPreviewHandler? Preview { get; }
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ using Windows.Media.Core;
|
||||
|
||||
namespace Peek.FilePreviewer.Previewers.Interfaces
|
||||
{
|
||||
public interface IVideoPreviewer : IPreviewer
|
||||
public interface IVideoPreviewer : IPreviewer, IPreviewTarget
|
||||
{
|
||||
public MediaSource? Preview { get; }
|
||||
}
|
||||
|
||||
@@ -154,9 +154,9 @@ namespace Peek.FilePreviewer.Previewers.MediaPreviewer
|
||||
});
|
||||
}
|
||||
|
||||
public static bool IsFileTypeSupported(string fileExt)
|
||||
public static bool IsItemSupported(IFileSystemItem item)
|
||||
{
|
||||
return _supportedFileTypes.Contains(fileExt);
|
||||
return _supportedFileTypes.Contains(item.Extension);
|
||||
}
|
||||
|
||||
private static readonly HashSet<string> _supportedFileTypes = new()
|
||||
|
||||
@@ -70,9 +70,9 @@ namespace Peek.FilePreviewer.Previewers
|
||||
|
||||
private ImageSource? highQualityThumbnailPreview;
|
||||
|
||||
public static bool IsFileTypeSupported(string fileExt)
|
||||
public static bool IsItemSupported(IFileSystemItem item)
|
||||
{
|
||||
return _supportedFileTypes.Contains(fileExt);
|
||||
return _supportedFileTypes.Contains(item.Extension);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -42,9 +42,9 @@ namespace Peek.FilePreviewer.Previewers
|
||||
|
||||
private Task<bool>? VideoTask { get; set; }
|
||||
|
||||
public static bool IsFileTypeSupported(string fileExt)
|
||||
public static bool IsItemSupported(IFileSystemItem item)
|
||||
{
|
||||
return _supportedFileTypes.Contains(fileExt);
|
||||
return _supportedFileTypes.Contains(item.Extension);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -23,39 +23,39 @@ namespace Peek.FilePreviewer.Previewers
|
||||
_previewSettings = Application.Current.GetService<IPreviewSettings>();
|
||||
}
|
||||
|
||||
public IPreviewer Create(IFileSystemItem file)
|
||||
public IPreviewer Create(IFileSystemItem item)
|
||||
{
|
||||
if (ImagePreviewer.IsFileTypeSupported(file.Extension))
|
||||
if (ImagePreviewer.IsItemSupported(item))
|
||||
{
|
||||
return new ImagePreviewer(file);
|
||||
return new ImagePreviewer(item);
|
||||
}
|
||||
else if (VideoPreviewer.IsFileTypeSupported(file.Extension))
|
||||
else if (VideoPreviewer.IsItemSupported(item))
|
||||
{
|
||||
return new VideoPreviewer(file);
|
||||
return new VideoPreviewer(item);
|
||||
}
|
||||
else if (AudioPreviewer.IsFileTypeSupported(file.Extension))
|
||||
else if (AudioPreviewer.IsItemSupported(item))
|
||||
{
|
||||
return new AudioPreviewer(file);
|
||||
return new AudioPreviewer(item);
|
||||
}
|
||||
else if (WebBrowserPreviewer.IsFileTypeSupported(file.Extension))
|
||||
else if (WebBrowserPreviewer.IsItemSupported(item))
|
||||
{
|
||||
return new WebBrowserPreviewer(file, _previewSettings);
|
||||
return new WebBrowserPreviewer(item, _previewSettings);
|
||||
}
|
||||
else if (ArchivePreviewer.IsFileTypeSupported(file.Extension))
|
||||
else if (ArchivePreviewer.IsItemSupported(item))
|
||||
{
|
||||
return new ArchivePreviewer(file);
|
||||
return new ArchivePreviewer(item);
|
||||
}
|
||||
else if (ShellPreviewHandlerPreviewer.IsFileTypeSupported(file.Extension))
|
||||
else if (ShellPreviewHandlerPreviewer.IsItemSupported(item))
|
||||
{
|
||||
return new ShellPreviewHandlerPreviewer(file);
|
||||
return new ShellPreviewHandlerPreviewer(item);
|
||||
}
|
||||
else if (DrivePreviewer.IsPathSupported(file.Path))
|
||||
else if (DrivePreviewer.IsItemSupported(item))
|
||||
{
|
||||
return new DrivePreviewer(file);
|
||||
return new DrivePreviewer(item);
|
||||
}
|
||||
|
||||
// Other previewer types check their supported file types here
|
||||
return CreateDefaultPreviewer(file);
|
||||
return CreateDefaultPreviewer(item);
|
||||
}
|
||||
|
||||
public IPreviewer CreateDefaultPreviewer(IFileSystemItem file)
|
||||
|
||||
@@ -16,6 +16,7 @@ using Peek.Common.Helpers;
|
||||
using Peek.Common.Models;
|
||||
using Peek.FilePreviewer.Models;
|
||||
using Peek.FilePreviewer.Previewers.Helpers;
|
||||
using Peek.FilePreviewer.Previewers.Interfaces;
|
||||
using Windows.Win32;
|
||||
using Windows.Win32.System.Com;
|
||||
using Windows.Win32.UI.Shell;
|
||||
@@ -205,9 +206,9 @@ namespace Peek.FilePreviewer.Previewers
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsFileTypeSupported(string fileExt)
|
||||
public static bool IsItemSupported(IFileSystemItem item)
|
||||
{
|
||||
return !string.IsNullOrEmpty(GetPreviewHandlerGuid(fileExt));
|
||||
return !string.IsNullOrEmpty(GetPreviewHandlerGuid(item.Extension));
|
||||
}
|
||||
|
||||
private static string? GetPreviewHandlerGuid(string fileExt)
|
||||
|
||||
@@ -13,6 +13,7 @@ using Peek.Common.Extensions;
|
||||
using Peek.Common.Helpers;
|
||||
using Peek.Common.Models;
|
||||
using Peek.FilePreviewer.Models;
|
||||
using Peek.FilePreviewer.Previewers.Interfaces;
|
||||
|
||||
namespace Peek.FilePreviewer.Previewers
|
||||
{
|
||||
@@ -137,9 +138,9 @@ namespace Peek.FilePreviewer.Previewers
|
||||
});
|
||||
}
|
||||
|
||||
public static bool IsFileTypeSupported(string fileExt)
|
||||
public static bool IsItemSupported(IFileSystemItem item)
|
||||
{
|
||||
return _supportedFileTypes.Contains(fileExt) || MonacoHelper.SupportedMonacoFileTypes.Contains(fileExt);
|
||||
return _supportedFileTypes.Contains(item.Extension) || MonacoHelper.SupportedMonacoFileTypes.Contains(item.Extension);
|
||||
}
|
||||
|
||||
private bool HasFailedLoadingPreview()
|
||||
|
||||
@@ -155,7 +155,9 @@ namespace RegistryPreview
|
||||
|
||||
// Pull in a new REG file - we have to use the direct Win32 method because FileOpenPicker crashes when it's
|
||||
// called while running as admin
|
||||
IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(this);
|
||||
string filename = OpenFilePicker.ShowDialog(
|
||||
windowHandle,
|
||||
resourceLoader.GetString("FilterRegistryName") + '\0' + "*.reg" + '\0' + resourceLoader.GetString("FilterAllFiles") + '\0' + "*.*" + '\0' + '\0',
|
||||
resourceLoader.GetString("OpenDialogTitle"));
|
||||
|
||||
@@ -197,7 +199,9 @@ namespace RegistryPreview
|
||||
{
|
||||
// Save out a new REG file and then open it - we have to use the direct Win32 method because FileOpenPicker crashes when it's
|
||||
// called while running as admin
|
||||
IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(this);
|
||||
string filename = SaveFilePicker.ShowDialog(
|
||||
windowHandle,
|
||||
resourceLoader.GetString("SuggestFileName"),
|
||||
resourceLoader.GetString("FilterRegistryName") + '\0' + "*.reg" + '\0' + resourceLoader.GetString("FilterAllFiles") + '\0' + "*.*" + '\0' + '\0',
|
||||
resourceLoader.GetString("SaveDialogTitle"));
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// 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;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace RegistryPreview
|
||||
@@ -13,11 +14,12 @@ namespace RegistryPreview
|
||||
[DllImport("comdlg32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
private static extern bool GetOpenFileName(ref FileName openFileName);
|
||||
|
||||
public static string ShowDialog(string filter, string dialogTitle)
|
||||
public static string ShowDialog(IntPtr windowHandle, string filter, string dialogTitle)
|
||||
{
|
||||
FileName openFileName = default(FileName);
|
||||
openFileName.StructSize = Marshal.SizeOf(openFileName);
|
||||
|
||||
openFileName.HwndOwner = windowHandle;
|
||||
openFileName.Filter = filter;
|
||||
openFileName.File = new string(new char[256]);
|
||||
openFileName.MaxFile = openFileName.File.Length;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// 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;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace RegistryPreview
|
||||
@@ -13,11 +14,12 @@ namespace RegistryPreview
|
||||
[DllImport("comdlg32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
private static extern bool GetSaveFileName(ref FileName saveFileName);
|
||||
|
||||
public static string ShowDialog(string suggestedFilename, string filter, string dialogTitle)
|
||||
public static string ShowDialog(IntPtr windowHandle, string suggestedFilename, string filter, string dialogTitle)
|
||||
{
|
||||
FileName saveFileName = default(FileName);
|
||||
saveFileName.StructSize = Marshal.SizeOf(saveFileName);
|
||||
|
||||
saveFileName.HwndOwner = windowHandle;
|
||||
saveFileName.Filter = filter;
|
||||
saveFileName.File = new string(new char[256]);
|
||||
saveFileName.MaxFile = saveFileName.File.Length;
|
||||
|
||||
Reference in New Issue
Block a user