Merge branch 'main' into dev/seraphima/tests/29246-fancyzones-tests-initial-step
@@ -65,7 +65,6 @@ namespace powertoys_gpo {
|
||||
const std::wstring POLICY_DISABLE_AUTOMATIC_UPDATE_DOWNLOAD = L"AutomaticUpdateDownloadDisabled";
|
||||
const std::wstring POLICY_SUSPEND_NEW_UPDATE_TOAST = L"SuspendNewUpdateAvailableToast";
|
||||
const std::wstring POLICY_DISABLE_NEW_UPDATE_TOAST = L"DisableNewUpdateAvailableToast";
|
||||
const std::wstring POLICY_DISABLE_PERIODIC_UPDATE_CHECK = L"PeriodicUpdateCheckDisabled";
|
||||
const std::wstring POLICY_DISABLE_SHOW_WHATS_NEW_AFTER_UPDATES = L"DoNotShowWhatsNewAfterUpdates";
|
||||
|
||||
// The registry value names for other PowerToys policies.
|
||||
@@ -412,11 +411,6 @@ namespace powertoys_gpo {
|
||||
return getConfiguredValue(POLICY_DISABLE_NEW_UPDATE_TOAST);
|
||||
}
|
||||
|
||||
inline gpo_rule_configured_t getDisablePeriodicUpdateCheckValue()
|
||||
{
|
||||
return getConfiguredValue(POLICY_DISABLE_PERIODIC_UPDATE_CHECK);
|
||||
}
|
||||
|
||||
inline gpo_rule_configured_t getDisableShowWhatsNewAfterUpdatesValue()
|
||||
{
|
||||
return getConfiguredValue(POLICY_DISABLE_SHOW_WHATS_NEW_AFTER_UPDATES);
|
||||
|
||||
@@ -21,3 +21,4 @@ inline std::wstring get_resource_string(UINT resource_id, HINSTANCE instance, co
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
// Wrapper for getting a string from the resource file. Returns the resource id text when fails.
|
||||
#define GET_RESOURCE_STRING(resource_id) get_resource_string(resource_id, reinterpret_cast<HINSTANCE>(&__ImageBase), L#resource_id)
|
||||
#define GET_RESOURCE_STRING_FALLBACK(resource_id, fallback) get_resource_string(resource_id, reinterpret_cast<HINSTANCE>(&__ImageBase), fallback)
|
||||
|
||||
@@ -451,18 +451,6 @@
|
||||
<decimal value="0" />
|
||||
</disabledValue>
|
||||
</policy>
|
||||
<!-- This policy is implemented for later usage (PT v1.0 and later) and therefore inactive. (To make it working please update `src/runner/UpdateUtils.cpp`)
|
||||
<policy name="DisablePeriodicUpdateCheck" class="Both" displayName="$(string.DisablePeriodicUpdateCheck)" explainText="$(string.DisablePeriodicUpdateCheckDescription)" key="Software\Policies\PowerToys" valueName="PeriodicUpdateCheckDisabled">
|
||||
<parentCategory ref="InstallerUpdates" />
|
||||
<supportedOn ref="SUPPORTED_POWERTOYS_0_68_0" />
|
||||
<enabledValue>
|
||||
<decimal value="1" />
|
||||
</enabledValue>
|
||||
<disabledValue>
|
||||
<decimal value="0" />
|
||||
</disabledValue>
|
||||
</policy>
|
||||
-->
|
||||
<policy name="DoNotShowWhatsNewAfterUpdates" class="Both" displayName="$(string.DoNotShowWhatsNewAfterUpdates)" explainText="$(string.DoNotShowWhatsNewAfterUpdatesDescription)" key="Software\Policies\PowerToys" valueName="DoNotShowWhatsNewAfterUpdates">
|
||||
<parentCategory ref="InstallerUpdates" />
|
||||
<supportedOn ref="SUPPORTED_POWERTOYS_0_78_0" />
|
||||
|
||||
@@ -59,11 +59,11 @@ If enabled, per-user installation is not allowed.
|
||||
|
||||
If disabled or not configured, per-user installation is allowed.
|
||||
</string>
|
||||
<string id="DisableAutomaticUpdateDownloadDescription">This policy configures whether automatic downloads of available updates are disabled or not. (On metered connections updates are never downloaded.)
|
||||
<string id="DisableAutomaticUpdateDownloadDescription">This policy configures whether the automatic download and installation of available updates is disabled or not. (On metered connections updates are never downloaded.)
|
||||
|
||||
If enabled, automatic downloads are disabled.
|
||||
If enabled, automatic download and installation is disabled.
|
||||
|
||||
If disabled or not configured, the user is in control of automatic downloads setting.
|
||||
If disabled or not configured, the user can control this in the settings.
|
||||
</string>
|
||||
<string id="SuspendNewUpdateToastDescription">This policy configures whether the action center notification for new updates is suspended for 2 minor releases. (Example: if the installed version is v0.60.0, then the next notification is shown for the v0.63.* release.)
|
||||
|
||||
@@ -80,12 +80,6 @@ This policy has no effect if the update notification is disabled by the policy "
|
||||
If enabled, the notification is disabled.
|
||||
|
||||
If disabled or not configured, the user can control if the notification is shown or not.
|
||||
</string>
|
||||
<string id="DisablePeriodicUpdateCheckDescription">This policy allows you to disable automatic update checks running in the background. (The manual check in PT Settings is not affected by this policy.)
|
||||
|
||||
If enabled, the automatic update checks are disabled.
|
||||
|
||||
If disabled or not configured, the automatic update checks are enabled.
|
||||
</string>
|
||||
<string id="DoNotShowWhatsNewAfterUpdatesDescription">This policy allows you to configure if the window with the release notes is shown after updates.
|
||||
|
||||
@@ -165,7 +159,6 @@ Note: Changes require a restart of PowerToys Run.
|
||||
<string id="DoNotShowWhatsNewAfterUpdates">Do not show the release notes after updates</string>
|
||||
<string id="SuspendNewUpdateToast">Suspend Action Center notification for new updates</string>
|
||||
<string id="DisableNewUpdateToast">Disable Action Center notification for new updates</string>
|
||||
<string id="DisablePeriodicUpdateCheck">Disable automatic update checks</string>
|
||||
<string id="AllowExperimentation">Allow Experimentation</string>
|
||||
<string id="PowerToysRunAllPluginsEnabledState">Configure enabled state for all plugins</string>
|
||||
<string id="PowerToysRunIndividualPluginEnabledState">Configure enabled state for individual plugins</string>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <common/themes/icon_helpers.h>
|
||||
#include <common/utils/process_path.h>
|
||||
#include <common/utils/resources.h>
|
||||
|
||||
// Implementations of inherited IUnknown methods
|
||||
|
||||
@@ -42,9 +43,7 @@ IFACEMETHODIMP_(ULONG) ExplorerCommand::Release()
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::GetTitle(IShellItemArray* psiItemArray, LPWSTR* ppszName)
|
||||
{
|
||||
WCHAR buffer[128];
|
||||
LoadStringW(globals::instance, IDS_FILELOCKSMITH_COMMANDTITLE, buffer, ARRAYSIZE(buffer));
|
||||
return SHStrDupW(buffer, ppszName);
|
||||
return SHStrDup(context_menu_caption.c_str(), ppszName);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP ExplorerCommand::GetIcon(IShellItemArray* psiItemArray, LPWSTR* ppszIcon)
|
||||
@@ -126,18 +125,15 @@ IFACEMETHODIMP ExplorerCommand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UI
|
||||
HRESULT hr = E_UNEXPECTED;
|
||||
if (m_data_obj && !(uFlags & (CMF_DEFAULTONLY | CMF_VERBSONLY | CMF_OPTIMIZEFORINVOKE)))
|
||||
{
|
||||
wchar_t menuName[128] = { 0 };
|
||||
wcscpy_s(menuName, ARRAYSIZE(menuName), context_menu_caption.c_str());
|
||||
|
||||
MENUITEMINFO mii;
|
||||
mii.cbSize = sizeof(MENUITEMINFO);
|
||||
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
|
||||
mii.wID = idCmdFirst++;
|
||||
mii.fType = MFT_STRING;
|
||||
|
||||
hr = GetTitle(NULL, &mii.dwTypeData);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
mii.dwTypeData = (PWSTR)menuName;
|
||||
mii.fState = MFS_ENABLED;
|
||||
|
||||
// icon from file
|
||||
@@ -237,6 +233,7 @@ HRESULT ExplorerCommand::s_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void
|
||||
ExplorerCommand::ExplorerCommand()
|
||||
{
|
||||
++globals::ref_count;
|
||||
context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_FILELOCKSMITH_CONTEXT_MENU_ENTRY, L"Unlock with File Locksmith");
|
||||
}
|
||||
|
||||
ExplorerCommand::~ExplorerCommand()
|
||||
|
||||
@@ -49,4 +49,5 @@ private:
|
||||
|
||||
std::atomic<ULONG> m_ref_count = 1;
|
||||
IDataObject* m_data_obj = NULL;
|
||||
std::wstring context_menu_caption;
|
||||
};
|
||||
|
||||
@@ -117,9 +117,9 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="FileLocksmith_CommandTitle" xml:space="preserve">
|
||||
<value>What's using this file?</value>
|
||||
<comment>This text will be shown when the user opens the context menu (right clicks) a file.</comment>
|
||||
<data name="FileLocksmith_Context_Menu_Entry" xml:space="preserve">
|
||||
<value>Unlock with File Locksmith</value>
|
||||
<comment>This text will be shown when the user opens the context menu (right clicks) a file. File Locksmith is the product name, do not loc.</comment>
|
||||
</data>
|
||||
<data name="FileLocksmith_PowerToyName" xml:space="preserve">
|
||||
<value>File Locksmith</value>
|
||||
|
||||
@@ -185,6 +185,17 @@
|
||||
ScopeOwner="{x:Bind Entries}" />
|
||||
</MenuFlyoutItem.KeyboardAccelerators>
|
||||
</MenuFlyoutItem>
|
||||
<MenuFlyoutItem x:Uid="Duplicate" Click="Duplicate_Click">
|
||||
<MenuFlyoutItem.Icon>
|
||||
<FontIcon Glyph="" />
|
||||
</MenuFlyoutItem.Icon>
|
||||
<MenuFlyoutItem.KeyboardAccelerators>
|
||||
<KeyboardAccelerator
|
||||
Key="D"
|
||||
Modifiers="Control"
|
||||
ScopeOwner="{x:Bind Entries}" />
|
||||
</MenuFlyoutItem.KeyboardAccelerators>
|
||||
</MenuFlyoutItem>
|
||||
<MenuFlyoutItem
|
||||
x:Uid="Ping"
|
||||
Click="Ping_Click"
|
||||
|
||||
@@ -44,12 +44,7 @@ namespace Hosts.Views
|
||||
|
||||
private async Task OpenNewDialogAsync()
|
||||
{
|
||||
var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;
|
||||
EntryDialog.Title = resourceLoader.GetString("AddNewEntryDialog_Title");
|
||||
EntryDialog.PrimaryButtonText = resourceLoader.GetString("AddBtn");
|
||||
EntryDialog.PrimaryButtonCommand = AddCommand;
|
||||
EntryDialog.DataContext = new Entry(ViewModel.NextId, string.Empty, string.Empty, string.Empty, true);
|
||||
await EntryDialog.ShowAsync();
|
||||
await ShowAddDialogAsync();
|
||||
}
|
||||
|
||||
private async Task OpenAdditionalLinesDialogAsync()
|
||||
@@ -113,6 +108,14 @@ namespace Hosts.Views
|
||||
}
|
||||
}
|
||||
|
||||
private async void Duplicate_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (Entries.SelectedItem is Entry entry)
|
||||
{
|
||||
await ShowAddDialogAsync(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private async void Ping_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (Entries.SelectedItem is Entry entry)
|
||||
@@ -189,6 +192,20 @@ namespace Hosts.Views
|
||||
ViewModel.Selected = entry;
|
||||
}
|
||||
|
||||
private async Task ShowAddDialogAsync(Entry template = null)
|
||||
{
|
||||
var resourceLoader = ResourceLoaderInstance.ResourceLoader;
|
||||
EntryDialog.Title = resourceLoader.GetString("AddNewEntryDialog_Title");
|
||||
EntryDialog.PrimaryButtonText = resourceLoader.GetString("AddBtn");
|
||||
EntryDialog.PrimaryButtonCommand = AddCommand;
|
||||
|
||||
EntryDialog.DataContext = template == null
|
||||
? new Entry(ViewModel.NextId, string.Empty, string.Empty, string.Empty, true)
|
||||
: new Entry(ViewModel.NextId, template.Address, template.Hosts, template.Comment, template.Active);
|
||||
|
||||
await EntryDialog.ShowAsync();
|
||||
}
|
||||
|
||||
private void ContentDialog_Loaded_ApplyMargin(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -193,6 +193,10 @@
|
||||
<data name="DeleteDialogAreYouSure.Text" xml:space="preserve">
|
||||
<value>Are you sure you want to delete this entry?</value>
|
||||
</data>
|
||||
<data name="Duplicate.Text" xml:space="preserve">
|
||||
<value>Duplicate</value>
|
||||
<comment>Refers to the action of duplicate an existing entry</comment>
|
||||
</data>
|
||||
<data name="DuplicateEntryIcon.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Duplicate entry</value>
|
||||
</data>
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
<PackageReference Include="Microsoft.Windows.CsWinRT" />
|
||||
<PackageReference Include="Microsoft.Windows.Compatibility" />
|
||||
<PackageReference Include="StreamJsonRpc" />
|
||||
<PackageReference Include="System.Data.SqlClient" /> <!-- It's a dependency of Microsoft.Windows.Compatibility. We're adding it here to force it to the version specified in Directory.Packages.props -->
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
||||
|
||||
@@ -218,6 +218,7 @@
|
||||
<PackageReference Include="Microsoft.Windows.Compatibility" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.Contracts" />
|
||||
<PackageReference Include="StreamJsonRpc" />
|
||||
<PackageReference Include="System.Data.SqlClient" /> <!-- It's a dependency of Microsoft.Windows.Compatibility. We're adding it here to force it to the version specified in Directory.Packages.props -->
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" />
|
||||
<PackageReference Include="StreamJsonRpc" />
|
||||
<PackageReference Include="System.Data.SqlClient" /> <!-- It's a dependency of Microsoft.Windows.Compatibility. We're adding it here to force it to the version specified in Directory.Packages.props -->
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
||||
|
||||
@@ -117,8 +117,8 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Resize_Pictures_Title" xml:space="preserve">
|
||||
<value>Resize pictures</value>
|
||||
<data name="ImageResizer_Context_Menu_Entry" xml:space="preserve">
|
||||
<value>Resize with Image Resizer</value>
|
||||
</data>
|
||||
<data name="ImageResizer_App_Name" xml:space="preserve">
|
||||
<value>Image Resizer</value>
|
||||
|
||||
@@ -51,10 +51,7 @@ public:
|
||||
// IExplorerCommand
|
||||
IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name)
|
||||
{
|
||||
wchar_t strResizePictures[64] = { 0 };
|
||||
LoadString(g_hInst, IDS_RESIZE_PICTURES_TITLE, strResizePictures, ARRAYSIZE(strResizePictures));
|
||||
|
||||
return SHStrDup(strResizePictures, name);
|
||||
return SHStrDup(context_menu_caption.c_str(), name);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* icon)
|
||||
@@ -272,7 +269,7 @@ private:
|
||||
|
||||
std::thread create_pipe_thread;
|
||||
HANDLE hPipe = INVALID_HANDLE_VALUE;
|
||||
std::wstring app_name = L"ImageResizer";
|
||||
std::wstring context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_IMAGERESIZER_CONTEXT_MENU_ENTRY, L"Resize with Image Resizer");
|
||||
};
|
||||
|
||||
CoCreatableClass(ImageResizerContextMenuCommand)
|
||||
|
||||
@@ -18,7 +18,8 @@ CContextMenuHandler::CContextMenuHandler()
|
||||
{
|
||||
m_pidlFolder = NULL;
|
||||
m_pdtobj = NULL;
|
||||
app_name = GET_RESOURCE_STRING(IDS_RESIZE_PICTURES);
|
||||
context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_IMAGERESIZER_CONTEXT_MENU_ENTRY, L"Resize with Image Resizer");
|
||||
context_menu_caption_here = GET_RESOURCE_STRING_FALLBACK(IDS_IMAGERESIZER_CONTEXT_MENU_ENTRY_HERE, L"Resize with Image Resizer here");
|
||||
}
|
||||
|
||||
CContextMenuHandler::~CContextMenuHandler()
|
||||
@@ -105,22 +106,16 @@ HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu,
|
||||
if (type == PERCEIVED_TYPE_IMAGE)
|
||||
{
|
||||
HRESULT hr = E_UNEXPECTED;
|
||||
wchar_t strResizePictures[64] = { 0 };
|
||||
wchar_t strResizePictures[128] = { 0 };
|
||||
// If handling drag-and-drop...
|
||||
if (m_pidlFolder)
|
||||
{
|
||||
// Suppressing C6031 warning since return value is not required.
|
||||
#pragma warning(suppress : 6031)
|
||||
// Load 'Resize pictures here' string
|
||||
LoadString(g_hInst_imageResizer, IDS_RESIZE_PICTURES_HERE, strResizePictures, ARRAYSIZE(strResizePictures));
|
||||
dragDropFlag = true;
|
||||
dragDropFlag=true;
|
||||
wcscpy_s(strResizePictures, ARRAYSIZE(strResizePictures), context_menu_caption_here.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Suppressing C6031 warning since return value is not required.
|
||||
#pragma warning(suppress : 6031)
|
||||
// Load 'Resize pictures' string
|
||||
LoadString(g_hInst_imageResizer, IDS_RESIZE_PICTURES, strResizePictures, ARRAYSIZE(strResizePictures));
|
||||
wcscpy_s(strResizePictures, ARRAYSIZE(strResizePictures), context_menu_caption.c_str());
|
||||
}
|
||||
|
||||
MENUITEMINFO mii;
|
||||
@@ -348,7 +343,7 @@ HRESULT CContextMenuHandler::ResizePictures(CMINVOKECOMMANDINFO* pici, IShellIte
|
||||
|
||||
HRESULT __stdcall CContextMenuHandler::GetTitle(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszName)
|
||||
{
|
||||
return SHStrDup(app_name.c_str(), ppszName);
|
||||
return SHStrDup(context_menu_caption.c_str(), ppszName);
|
||||
}
|
||||
|
||||
HRESULT __stdcall CContextMenuHandler::GetIcon(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszIcon)
|
||||
|
||||
@@ -51,7 +51,8 @@ private:
|
||||
PCIDLIST_ABSOLUTE m_pidlFolder;
|
||||
IDataObject* m_pdtobj;
|
||||
HBITMAP m_hbmpIcon = nullptr;
|
||||
std::wstring app_name;
|
||||
std::wstring context_menu_caption;
|
||||
std::wstring context_menu_caption_here;
|
||||
};
|
||||
|
||||
OBJECT_ENTRY_AUTO(__uuidof(ContextMenuHandler), CContextMenuHandler)
|
||||
@@ -117,11 +117,11 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Resize_Pictures" xml:space="preserve">
|
||||
<value>Resize pictures</value>
|
||||
<data name="ImageResizer_Context_Menu_Entry" xml:space="preserve">
|
||||
<value>Resize with Image Resizer</value>
|
||||
</data>
|
||||
<data name="Resize_Pictures_Here" xml:space="preserve">
|
||||
<value>Resize pictures here</value>
|
||||
<data name="ImageResizer_Context_Menu_Entry_Here" xml:space="preserve">
|
||||
<value>Resize with Image Resizer here</value>
|
||||
</data>
|
||||
<data name="ImageResizer" xml:space="preserve">
|
||||
<value>Image Resizer</value>
|
||||
|
||||
@@ -13,24 +13,6 @@
|
||||
<ui:ControlsDictionary />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<ObjectDataProvider
|
||||
x:Key="ResizeFitValues"
|
||||
MethodName="GetValues"
|
||||
ObjectType="sys:Enum">
|
||||
<ObjectDataProvider.MethodParameters>
|
||||
<x:Type Type="{x:Type m:ResizeFit}" />
|
||||
</ObjectDataProvider.MethodParameters>
|
||||
</ObjectDataProvider>
|
||||
|
||||
<ObjectDataProvider
|
||||
x:Key="ResizeUnitValues"
|
||||
MethodName="GetValues"
|
||||
ObjectType="sys:Enum">
|
||||
<ObjectDataProvider.MethodParameters>
|
||||
<x:Type Type="{x:Type m:ResizeUnit}" />
|
||||
</ObjectDataProvider.MethodParameters>
|
||||
</ObjectDataProvider>
|
||||
|
||||
<v:SizeTypeToVisibilityConverter x:Key="SizeTypeToVisibilityConverter" />
|
||||
<v:EnumValueConverter x:Key="EnumValueConverter" />
|
||||
<v:AutoDoubleConverter x:Key="AutoDoubleConverter" />
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// The Brice Lambson licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Input;
|
||||
using Common.UI;
|
||||
@@ -55,6 +57,10 @@ namespace ImageResizer.ViewModels
|
||||
|
||||
public Settings Settings { get; }
|
||||
|
||||
public IEnumerable<ResizeFit> ResizeFitValues { get => Enum.GetValues(typeof(ResizeFit)).Cast<ResizeFit>(); }
|
||||
|
||||
public IEnumerable<ResizeUnit> ResizeUnitValues { get => Enum.GetValues(typeof(ResizeUnit)).Cast<ResizeUnit>(); }
|
||||
|
||||
public ICommand ResizeCommand { get; }
|
||||
|
||||
public ICommand CancelCommand { get; }
|
||||
|
||||
@@ -35,7 +35,10 @@ namespace ImageResizer.Views
|
||||
.Append(parameter);
|
||||
}
|
||||
|
||||
var targetValue = Resources.ResourceManager.GetString(builder.ToString(), culture);
|
||||
// Fixes #16792 - Looks like culture defaults to en-US, so wrong resource is being fetched.
|
||||
#pragma warning disable CA1304 // Specify CultureInfo
|
||||
var targetValue = Resources.ResourceManager.GetString(builder.ToString());
|
||||
#pragma warning restore CA1304 // Specify CultureInfo
|
||||
|
||||
if (toLower)
|
||||
{
|
||||
|
||||
@@ -178,8 +178,17 @@
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Static p:Resources.Resize_Type}"
|
||||
ItemsSource="{Binding Source={StaticResource ResizeFitValues}}"
|
||||
Text="{Binding ElementName=SizeComboBox, Path=SelectedValue.Fit, Mode=TwoWay}" />
|
||||
ItemsSource="{Binding ResizeFitValues, Mode=OneWay}"
|
||||
SelectedIndex="0">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate DataType="sys:Enum">
|
||||
<TextBlock
|
||||
Margin="4,0,0,0"
|
||||
FontSize="14"
|
||||
Text="{Binding {}, Converter={StaticResource EnumValueConverter}}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<ui:SymbolIcon
|
||||
Grid.Row="2"
|
||||
@@ -196,8 +205,17 @@
|
||||
Grid.Row="2"
|
||||
Grid.Column="4"
|
||||
AutomationProperties.Name="{x:Static p:Resources.Unit}"
|
||||
ItemsSource="{Binding Source={StaticResource ResizeUnitValues}}"
|
||||
Text="{Binding ElementName=SizeComboBox, Path=SelectedValue.Unit, Mode=TwoWay}" />
|
||||
ItemsSource="{Binding ResizeUnitValues, Mode=OneWay}"
|
||||
SelectedIndex="0">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate DataType="sys:Enum">
|
||||
<TextBlock
|
||||
Margin="4,0,0,0"
|
||||
FontSize="14"
|
||||
Text="{Binding {}, Converter={StaticResource EnumValueConverter}}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Community.PowerToys.Run.Plugin.UnitConverter.Properties {
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class Resources {
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to A plugin to calculate hashes and generate values..
|
||||
/// Looks up a localized string similar to Calculates hashes and generate values..
|
||||
/// </summary>
|
||||
public static string plugin_description {
|
||||
get {
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
<value>Value Generator Error</value>
|
||||
</data>
|
||||
<data name="plugin_description" xml:space="preserve">
|
||||
<value>A plugin to calculate hashes and generate values.</value>
|
||||
<value>Calculates hashes and generate values.</value>
|
||||
</data>
|
||||
<data name="plugin_name" xml:space="preserve">
|
||||
<value>Value Generator</value>
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace Community.PowerToys.Run.Plugin.WebSearch.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Search the web with your default search engine..
|
||||
/// Looks up a localized string similar to Searches the web with your default search engine..
|
||||
/// </summary>
|
||||
public static string plugin_description {
|
||||
get {
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
<value>the default browser</value>
|
||||
</data>
|
||||
<data name="plugin_description" xml:space="preserve">
|
||||
<value>Search the web with your default search engine.</value>
|
||||
<value>Searches the web with your default search engine.</value>
|
||||
</data>
|
||||
<data name="plugin_global_if_uri" xml:space="preserve">
|
||||
<value>Don't include in global results on queries that are URIs</value>
|
||||
|
||||
@@ -930,15 +930,15 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
|
||||
private static bool TryGetIcoPathForRunCommandProgram(Win32Program program, out string icoPath)
|
||||
{
|
||||
icoPath = null;
|
||||
|
||||
if (program.AppType != ApplicationType.RunCommand)
|
||||
{
|
||||
icoPath = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(program.FullPath))
|
||||
{
|
||||
icoPath = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -946,6 +946,11 @@ namespace Microsoft.Plugin.Program.Programs
|
||||
try
|
||||
{
|
||||
var redirectionPath = ReparsePoint.GetTarget(program.FullPath);
|
||||
if (string.IsNullOrEmpty(redirectionPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
icoPath = ExpandEnvironmentVariables(redirectionPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace Microsoft.Plugin.Shell.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Find and run executable file.
|
||||
/// Looks up a localized string similar to Find and run the executable file.
|
||||
/// </summary>
|
||||
public static string find_executable_file_and_run_it {
|
||||
get {
|
||||
@@ -178,7 +178,7 @@ namespace Microsoft.Plugin.Shell.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Executes commands (e.g 'ping', 'cmd')..
|
||||
/// Looks up a localized string similar to Executes commands (e.g. 'ping', 'cmd')..
|
||||
/// </summary>
|
||||
public static string wox_plugin_cmd_plugin_description {
|
||||
get {
|
||||
@@ -223,7 +223,7 @@ namespace Microsoft.Plugin.Shell.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to All entries that using the Windows Terminal forcing the Windows Terminal as console host regardless of the system setting.
|
||||
/// Looks up a localized string similar to All entries using the Windows Terminal force the Windows Terminal as the console host regardless of the system settings.
|
||||
/// </summary>
|
||||
public static string wox_shell_command_execution_description {
|
||||
get {
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
<value>Shell</value>
|
||||
</data>
|
||||
<data name="wox_plugin_cmd_plugin_description" xml:space="preserve">
|
||||
<value>Executes commands (e.g 'ping', 'cmd').</value>
|
||||
<value>Executes commands (e.g. 'ping', 'cmd').</value>
|
||||
</data>
|
||||
<data name="wox_plugin_cmd_cmd_has_been_executed_times" xml:space="preserve">
|
||||
<value>this command has been executed {0} times</value>
|
||||
|
||||
@@ -162,5 +162,22 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(expectedResult, result);
|
||||
}
|
||||
|
||||
[DataTestMethod]
|
||||
[DataRow("en-US", "0xF000", "0xF000")]
|
||||
[DataRow("en-US", "0xf4572220", "4099351072")]
|
||||
[DataRow("en-US", "0x12345678", "305419896")]
|
||||
public void Translate_LargeHexadecimalNumbersToDecimal(string sourceCultureName, string input, string expectedResult)
|
||||
{
|
||||
// Arrange
|
||||
var translator = NumberTranslator.Create(new CultureInfo(sourceCultureName, false), new CultureInfo("en-US", false));
|
||||
|
||||
// Act
|
||||
var result = translator.Translate(input);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(expectedResult, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,5 +233,26 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests
|
||||
Assert.AreEqual(answer.ToString(CultureInfo.CurrentCulture), result);
|
||||
Assert.AreEqual(answer.ToString(CultureInfo.CurrentCulture), resultWithKeyword);
|
||||
}
|
||||
|
||||
[DataTestMethod]
|
||||
[DataRow("0x1234+0x1234", 9320)]
|
||||
[DataRow("0x1234-0x1234", 0)]
|
||||
[DataRow("0x12345678+0x12345678", 610839792)]
|
||||
[DataRow("0xf4572220-0xf4572410", -496)]
|
||||
public void RightAnswerForLargeHexadecimalNumbers(string typedString, double answer)
|
||||
{
|
||||
// Setup
|
||||
Mock<Main> main = new();
|
||||
Query expectedQuery = new(typedString);
|
||||
Query expectedQueryWithKeyword = new("=" + typedString, "=");
|
||||
|
||||
// Act
|
||||
var result = main.Object.Query(expectedQuery).FirstOrDefault()?.Title;
|
||||
var resultWithKeyword = main.Object.Query(expectedQueryWithKeyword).FirstOrDefault()?.Title;
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(answer.ToString(CultureInfo.CurrentCulture), result);
|
||||
Assert.AreEqual(answer.ToString(CultureInfo.CurrentCulture), resultWithKeyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,25 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator
|
||||
{
|
||||
if (hexToken.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
outputBuilder.Append(hexToken);
|
||||
// Mages engine has issues processing large hex number (larger than 7 hex digits + 0x prefix = 9 characters). So we convert it to decimal and pass it to the engine.
|
||||
if (hexToken.Length > 9)
|
||||
{
|
||||
try
|
||||
{
|
||||
long num = Convert.ToInt64(hexToken, 16);
|
||||
string numStr = num.ToString(cultureFrom);
|
||||
outputBuilder.Append(numStr);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
outputBuilder.Append(hexToken);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
outputBuilder.Append(hexToken);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Does mathematical calculations (e.g. 5*3-2)..
|
||||
/// Looks up a localized string similar to Calculates mathematical equations (e.g. 5*3-2)..
|
||||
/// </summary>
|
||||
public static string wox_plugin_calculator_plugin_description {
|
||||
get {
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
<value>Calculator</value>
|
||||
</data>
|
||||
<data name="wox_plugin_calculator_plugin_description" xml:space="preserve">
|
||||
<value>Does mathematical calculations (e.g. 5*3-2).</value>
|
||||
<value>Calculates mathematical equations (e.g. 5*3-2).</value>
|
||||
</data>
|
||||
<data name="wox_plugin_calculator_not_a_number" xml:space="preserve">
|
||||
<value>Calculation result is not a valid number (NaN)</value>
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace Microsoft.PowerToys.Run.Plugin.History.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Quick access to previously selected results..
|
||||
/// Looks up a localized string similar to Accesses previously selected results..
|
||||
/// </summary>
|
||||
public static string wox_plugin_history_plugin_description {
|
||||
get {
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
<value>History</value>
|
||||
</data>
|
||||
<data name="wox_plugin_history_plugin_description" xml:space="preserve">
|
||||
<value>Quick access to previously selected results.</value>
|
||||
<value>Accesses previously selected results.</value>
|
||||
</data>
|
||||
<data name="wox_plugin_history_processing_failed" xml:space="preserve">
|
||||
<value>Failed to process the input</value>
|
||||
|
||||
@@ -81,39 +81,39 @@
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsColorPicker.png">
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\Icons\ColorPicker.png">
|
||||
<Link>Images\ColorPicker.png</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsFancyZones.png">
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\Icons\FancyZones.png">
|
||||
<Link>Images\FancyZones.png</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsCropAndLock.png">
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\Icons\CropAndLock.png">
|
||||
<Link>Images\CropAndLock.png</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsHosts.png">
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\Icons\Hosts.png">
|
||||
<Link>Images\Hosts.png</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsPowerOcr.png">
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\Icons\TextExtractor.png">
|
||||
<Link>Images\PowerOcr.png</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsRegistryPreview.png">
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\Icons\RegistryPreview.png">
|
||||
<Link>Images\RegistryPreview.png</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsScreenRuler.png">
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\Icons\ScreenRuler.png">
|
||||
<Link>Images\ScreenRuler.png</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsShortcutGuide.png">
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\Icons\ShortcutGuide.png">
|
||||
<Link>Images\ShortcutGuide.png</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\FluentIcons\FluentIconsEnvironmentVariables.png">
|
||||
<Content Include="..\..\..\..\settings-ui\Settings.UI\Assets\Settings\Icons\EnvironmentVariables.png">
|
||||
<Link>Images\EnvironmentVariables.png</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace Microsoft.PowerToys.Run.Plugin.PowerToys.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Open PowerToys utilities and settings..
|
||||
/// Looks up a localized string similar to Opens PowerToys utilities and settings..
|
||||
/// </summary>
|
||||
internal static string Plugin_Description {
|
||||
get {
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
<comment>"Hosts File Editor" is the name of the utility</comment>
|
||||
</data>
|
||||
<data name="Plugin_Description" xml:space="preserve">
|
||||
<value>Open PowerToys utilities and settings.</value>
|
||||
<value>Opens PowerToys utilities and settings.</value>
|
||||
</data>
|
||||
<data name="Plugin_Name" xml:space="preserve">
|
||||
<value>PowerToys</value>
|
||||
|
||||
@@ -3328,7 +3328,7 @@ namespace Microsoft.PowerToys.Run.Plugin.WindowsSettings.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Plugin to search for Windows settings.
|
||||
/// Looks up a localized string similar to Searches Windows settings.
|
||||
/// </summary>
|
||||
internal static string PluginDescription {
|
||||
get {
|
||||
|
||||
@@ -1439,7 +1439,8 @@
|
||||
<comment>Area Gaming</comment>
|
||||
</data>
|
||||
<data name="PluginDescription" xml:space="preserve">
|
||||
<value>Plugin to search for Windows settings</value>
|
||||
<value>Searches Windows settings</value>
|
||||
<comment>{Locked="Windows"}</comment>
|
||||
</data>
|
||||
<data name="PluginTitle" xml:space="preserve">
|
||||
<value>Windows settings</value>
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace Microsoft.PowerToys.Run.Plugin.WindowsTerminal.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Windows Terminal supports a "quake" feature where a terminal window is accessible using a global hotkey. Enable this option to open profiles in this window..
|
||||
/// Looks up a localized string similar to Windows Terminal supports a "quake" feature where a terminal window is accessible using a global hotkey. Enable this option to open profiles in a new tab in this window..
|
||||
/// </summary>
|
||||
internal static string open_quake_description {
|
||||
get {
|
||||
@@ -88,7 +88,7 @@ namespace Microsoft.PowerToys.Run.Plugin.WindowsTerminal.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Open Windows Terminal profiles..
|
||||
/// Looks up a localized string similar to Opens Windows Terminal profiles..
|
||||
/// </summary>
|
||||
internal static string plugin_description {
|
||||
get {
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
<comment>Quake is a well-known computer game. Don't localize. See https://en.wikipedia.org/wiki/Quake_(video_game)</comment>
|
||||
</data>
|
||||
<data name="plugin_description" xml:space="preserve">
|
||||
<value>Open Windows Terminal profiles.</value>
|
||||
<value>Opens Windows Terminal profiles.</value>
|
||||
</data>
|
||||
<data name="plugin_name" xml:space="preserve">
|
||||
<value>Windows Terminal</value>
|
||||
@@ -143,4 +143,4 @@
|
||||
<data name="show_hidden_profiles" xml:space="preserve">
|
||||
<value>Show hidden profiles</value>
|
||||
</data>
|
||||
</root>
|
||||
</root>
|
||||
@@ -51,7 +51,7 @@
|
||||
<Grid
|
||||
x:Name="KeywordsOverviewGrid"
|
||||
Grid.Row="1"
|
||||
MaxHeight="256"
|
||||
MaxHeight="{Binding Results.MaxHeight}"
|
||||
Visibility="{Binding PluginsOverviewVisibility}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
|
||||
@@ -41,5 +41,23 @@ namespace PowerLauncher.Storage
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
for (int i = Items.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Items[i].Query))
|
||||
{
|
||||
Items.RemoveAt(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Items[i].ExecutedDateTime == DateTime.MinValue)
|
||||
{
|
||||
Items[i].ExecutedDateTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
@@ -1033,7 +1034,24 @@ namespace PowerLauncher.ViewModel
|
||||
{
|
||||
if (!_saved)
|
||||
{
|
||||
if (_historyItemsStorage.CheckVersionMismatch())
|
||||
{
|
||||
if (!_historyItemsStorage.TryLoadData())
|
||||
{
|
||||
_history.Update();
|
||||
}
|
||||
}
|
||||
|
||||
_historyItemsStorage.Save();
|
||||
|
||||
if (_userSelectedRecordStorage.CheckVersionMismatch())
|
||||
{
|
||||
if (!_userSelectedRecordStorage.TryLoadData())
|
||||
{
|
||||
_userSelectedRecord.Update();
|
||||
}
|
||||
}
|
||||
|
||||
_userSelectedRecordStorage.Save();
|
||||
|
||||
_saved = true;
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
// 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.Text.Json;
|
||||
using Wox.Infrastructure.Storage;
|
||||
using Wox.Infrastructure.UserSettings;
|
||||
using Wox.Plugin;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
namespace PowerLauncher.ViewModel
|
||||
{
|
||||
@@ -16,6 +18,22 @@ namespace PowerLauncher.ViewModel
|
||||
{
|
||||
_storage = new WoxJsonStorage<PowerToysRunSettings>();
|
||||
Settings = _storage.Load();
|
||||
|
||||
// Check information file for version mismatch
|
||||
try
|
||||
{
|
||||
if (_storage.CheckVersionMismatch())
|
||||
{
|
||||
if (!_storage.TryLoadData())
|
||||
{
|
||||
_storage.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
Log.Exception($"Error in Load of PowerToysRunSettings: {e.Message}", e, GetType());
|
||||
}
|
||||
}
|
||||
|
||||
public PowerToysRunSettings Settings { get; }
|
||||
|
||||
@@ -24,9 +24,8 @@ public class Alphabet : IAlphabet
|
||||
PinyinFormat.WITHOUT_TONE;
|
||||
|
||||
private ConcurrentDictionary<string, string[][]> _pinyinCache;
|
||||
private WoxJsonStorage<Dictionary<string, string[][]>> _pinyinStorage;
|
||||
private WoxJsonStorage<ConcurrentDictionary<string, string[][]>> _pinyinStorage;
|
||||
private PowerToysRunSettings _settings;
|
||||
private Dictionary<string, string[][]> __cache;
|
||||
|
||||
public void Initialize(PowerToysRunSettings settings)
|
||||
{
|
||||
@@ -38,8 +37,8 @@ public class Alphabet : IAlphabet
|
||||
{
|
||||
Stopwatch.Normal("|Wox.Infrastructure.Alphabet.Initialize|Preload pinyin cache", () =>
|
||||
{
|
||||
_pinyinStorage = new WoxJsonStorage<Dictionary<string, string[][]>>("Pinyin");
|
||||
SetPinyinCacheAsDictionary(__cache = _pinyinStorage.Load());
|
||||
_pinyinStorage = new WoxJsonStorage<ConcurrentDictionary<string, string[][]>>("Pinyin");
|
||||
_pinyinCache = _pinyinStorage.Load();
|
||||
|
||||
// force pinyin library static constructor initialize
|
||||
Pinyin4Net.GetPinyin('一', _pinyinFormat);
|
||||
@@ -204,9 +203,4 @@ public class Alphabet : IAlphabet
|
||||
{
|
||||
return new Dictionary<string, string[][]>(_pinyinCache);
|
||||
}
|
||||
|
||||
private void SetPinyinCacheAsDictionary(Dictionary<string, string[][]> usage)
|
||||
{
|
||||
_pinyinCache = new ConcurrentDictionary<string, string[][]>(usage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
@@ -20,6 +22,8 @@ namespace Wox.Infrastructure.Storage
|
||||
private static readonly IPath Path = FileSystem.Path;
|
||||
private static readonly IFile File = FileSystem.File;
|
||||
|
||||
private readonly object _saveLock = new object();
|
||||
|
||||
// use property initialization instead of DefaultValueAttribute
|
||||
// easier and flexible for default value of object
|
||||
private static readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions
|
||||
@@ -28,6 +32,15 @@ namespace Wox.Infrastructure.Storage
|
||||
IncludeFields = true,
|
||||
PropertyNameCaseInsensitive = true,
|
||||
WriteIndented = true,
|
||||
UnmappedMemberHandling = System.Text.Json.Serialization.JsonUnmappedMemberHandling.Disallow,
|
||||
};
|
||||
|
||||
private static readonly JsonSerializerOptions _deserializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.Never,
|
||||
IncludeFields = true,
|
||||
PropertyNameCaseInsensitive = true,
|
||||
WriteIndented = true,
|
||||
};
|
||||
|
||||
private T _data;
|
||||
@@ -44,20 +57,10 @@ namespace Wox.Infrastructure.Storage
|
||||
private const int _jsonStorage = 1;
|
||||
private StoragePowerToysVersionInfo _storageHelper;
|
||||
|
||||
public T Load()
|
||||
public virtual T Load()
|
||||
{
|
||||
_storageHelper = new StoragePowerToysVersionInfo(FilePath, _jsonStorage);
|
||||
|
||||
// Depending on the version number of the previously installed PT Run, delete the cache if it is found to be incompatible
|
||||
if (_storageHelper.ClearCache)
|
||||
{
|
||||
if (File.Exists(FilePath))
|
||||
{
|
||||
File.Delete(FilePath);
|
||||
Log.Info($"Deleting cached data at <{FilePath}>", GetType());
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(FilePath))
|
||||
{
|
||||
var serialized = File.ReadAllText(FilePath);
|
||||
@@ -82,7 +85,7 @@ namespace Wox.Infrastructure.Storage
|
||||
{
|
||||
try
|
||||
{
|
||||
_data = JsonSerializer.Deserialize<T>(serialized, _serializerOptions);
|
||||
_data = JsonSerializer.Deserialize<T>(serialized, _deserializerOptions);
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
@@ -121,18 +124,59 @@ namespace Wox.Infrastructure.Storage
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
lock (_saveLock)
|
||||
{
|
||||
try
|
||||
{
|
||||
string serialized = JsonSerializer.Serialize(_data, _serializerOptions);
|
||||
File.WriteAllText(FilePath, serialized);
|
||||
_storageHelper.Close();
|
||||
|
||||
Log.Info($"Saving cached data at <{FilePath}>", GetType());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Log.Exception($"Error in saving data at <{FilePath}>", e, GetType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (File.Exists(FilePath))
|
||||
{
|
||||
File.Delete(FilePath);
|
||||
LoadDefault();
|
||||
Log.Info($"Deleting cached data at <{FilePath}>", GetType());
|
||||
}
|
||||
}
|
||||
|
||||
public bool CheckVersionMismatch()
|
||||
{
|
||||
// Skip the fields check if the version hasn't changed.
|
||||
// This optimization prevents unnecessary fields processing when the cache
|
||||
// is already up to date, enhancing performance and reducing IO operations
|
||||
if (!_storageHelper.ClearCache)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_storageHelper.ClearCache = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryLoadData()
|
||||
{
|
||||
try
|
||||
{
|
||||
string serialized = JsonSerializer.Serialize(_data, _serializerOptions);
|
||||
File.WriteAllText(FilePath, serialized);
|
||||
_storageHelper.Close();
|
||||
|
||||
Log.Info($"Saving cached data at <{FilePath}>", GetType());
|
||||
JsonSerializer.Deserialize<T>(File.ReadAllText(FilePath), _serializerOptions);
|
||||
return true;
|
||||
}
|
||||
catch (IOException e)
|
||||
catch (JsonException e)
|
||||
{
|
||||
Log.Exception($"Error in saving data at <{FilePath}>", e, GetType());
|
||||
Log.Exception($"Error in TryLoadData at <{FilePath}>", e, GetType());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.IO.Abstractions;
|
||||
using System.Text.Json;
|
||||
using Wox.Plugin;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
namespace Wox.Infrastructure.Storage
|
||||
{
|
||||
@@ -23,5 +25,28 @@ namespace Wox.Infrastructure.Storage
|
||||
|
||||
FilePath = Path.Combine(DirectoryPath, $"{dataType.Name}{FileSuffix}");
|
||||
}
|
||||
|
||||
public override T Load()
|
||||
{
|
||||
var data = base.Load();
|
||||
|
||||
// Check information file for version mismatch
|
||||
try
|
||||
{
|
||||
if (CheckVersionMismatch())
|
||||
{
|
||||
if (!TryLoadData())
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
Log.Exception($"Error in Load of PluginJsonStorage: {e.Message}", e, GetType());
|
||||
}
|
||||
|
||||
return data.NonNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using Wox.Plugin.Logger;
|
||||
|
||||
namespace Wox.Infrastructure.Storage
|
||||
{
|
||||
@@ -123,8 +125,15 @@ namespace Wox.Infrastructure.Storage
|
||||
|
||||
public void Close()
|
||||
{
|
||||
// Update the Version file to the current version of powertoys
|
||||
File.WriteAllText(FilePath, currentPowerToysVersion);
|
||||
try
|
||||
{
|
||||
// Update the Version file to the current version of powertoys
|
||||
File.WriteAllText(FilePath, currentPowerToysVersion);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Log.Exception($"Error in saving version at <{FilePath}>", e, GetType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Wox.Plugin
|
||||
@@ -73,6 +74,34 @@ namespace Wox.Plugin
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
foreach (var key in Records.Keys.ToList())
|
||||
{
|
||||
// Check if any of the specified fields are empty
|
||||
if (string.IsNullOrEmpty(Records[key].IconPath) ||
|
||||
string.IsNullOrEmpty(Records[key].Title) ||
|
||||
string.IsNullOrEmpty(Records[key].SubTitle) ||
|
||||
string.IsNullOrEmpty(Records[key].Search) ||
|
||||
string.IsNullOrEmpty(Records[key].PluginID))
|
||||
{
|
||||
Records.Remove(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Records[key].SelectedCount == 0)
|
||||
{
|
||||
Records[key].SelectedCount = 1;
|
||||
}
|
||||
|
||||
if (Records[key].LastSelected == DateTime.MinValue)
|
||||
{
|
||||
Records[key].LastSelected = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public UserSelectedRecordItem GetSelectedData(Result result)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(result);
|
||||
|
||||
@@ -42,7 +42,11 @@
|
||||
<ToolTip Content="{x:Bind FormatFileType(Source.FileType), Mode=OneWay}" />
|
||||
</ToolTipService.ToolTip>
|
||||
</TextBlock>
|
||||
<TextBlock Text="{x:Bind FormatFileSize(Source.FileSize), Mode=OneWay}" />
|
||||
<TextBlock Text="{x:Bind FormatFileSize(Source.FileSize), Mode=OneWay}">
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip Content="{x:Bind FormatFileSize(Source.FileSize), Mode=OneWay}" />
|
||||
</ToolTipService.ToolTip>
|
||||
</TextBlock>
|
||||
<TextBlock Text="{x:Bind FormatFileDateModified(Source.DateModified), Mode=OneWay}">
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip Content="{x:Bind FormatFileDateModified(Source.DateModified), Mode=OneWay}" />
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// 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;
|
||||
using ManagedCommon;
|
||||
using Microsoft.UI.Xaml;
|
||||
@@ -25,12 +24,31 @@ namespace Peek.UI.Extensions
|
||||
internal static void CenterOnMonitor(this Window window, HWND hwndDesktop, double? width = null, double? height = null)
|
||||
{
|
||||
var hwndToCenter = new HWND(window.GetWindowHandle());
|
||||
|
||||
// If the window is maximized, restore to normal state before change its size
|
||||
var placement = default(WINDOWPLACEMENT);
|
||||
if (PInvoke.GetWindowPlacement(hwndToCenter, ref placement))
|
||||
{
|
||||
if (placement.showCmd == SHOW_WINDOW_CMD.SW_MAXIMIZE)
|
||||
{
|
||||
placement.showCmd = SHOW_WINDOW_CMD.SW_SHOWNORMAL;
|
||||
if (!PInvoke.SetWindowPlacement(hwndToCenter, in placement))
|
||||
{
|
||||
Logger.LogError($"SetWindowPlacement failed with error {Marshal.GetLastWin32Error()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError($"GetWindowPlacement failed with error {Marshal.GetLastWin32Error()}");
|
||||
}
|
||||
|
||||
var monitor = PInvoke.MonitorFromWindow(hwndDesktop, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
|
||||
MONITORINFO info = default(MONITORINFO);
|
||||
info.cbSize = 40;
|
||||
PInvoke.GetMonitorInfo(monitor, ref info);
|
||||
var dpi = PInvoke.GetDpiForWindow(new HWND(hwndDesktop));
|
||||
PInvoke.GetWindowRect(new HWND(hwndToCenter), out RECT windowRect);
|
||||
PInvoke.GetWindowRect(hwndToCenter, out RECT windowRect);
|
||||
var scalingFactor = dpi / 96d;
|
||||
var w = width.HasValue ? (int)(width * scalingFactor) : windowRect.right - windowRect.left;
|
||||
var h = height.HasValue ? (int)(height * scalingFactor) : windowRect.bottom - windowRect.top;
|
||||
@@ -38,7 +56,8 @@ namespace Peek.UI.Extensions
|
||||
var cy = (info.rcMonitor.bottom + info.rcMonitor.top) / 2;
|
||||
var left = cx - (w / 2);
|
||||
var top = cy - (h / 2);
|
||||
SetWindowPosOrThrow(new HWND(hwndToCenter), default(HWND), left, top, w, h, SET_WINDOW_POS_FLAGS.SWP_SHOWWINDOW);
|
||||
|
||||
SetWindowPosOrThrow(hwndToCenter, default(HWND), left, top, w, h, SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
private static void SetWindowPosOrThrow(HWND hWnd, HWND hWndInsertAfter, int x, int y, int cx, int cy, SET_WINDOW_POS_FLAGS uFlags)
|
||||
|
||||
@@ -17,4 +17,6 @@ _SVGIO
|
||||
MONITORINFO
|
||||
GetWindowRect
|
||||
SET_WINDOW_POS_FLAGS
|
||||
SetWindowPos
|
||||
SetWindowPos
|
||||
GetWindowPlacement
|
||||
SetWindowPlacement
|
||||
@@ -154,7 +154,7 @@ namespace PowerAccent.Core
|
||||
LetterKey.VK_B => new[] { "ḃ" },
|
||||
LetterKey.VK_C => new[] { "ċ", "°C", "©", "ℂ", "∁" },
|
||||
LetterKey.VK_D => new[] { "ḍ", "ḋ", "∂" },
|
||||
LetterKey.VK_E => new[] { "∈", "∃", "∄", "∉" },
|
||||
LetterKey.VK_E => new[] { "∈", "∃", "∄", "∉", "ĕ" },
|
||||
LetterKey.VK_F => new[] { "ḟ", "°F" },
|
||||
LetterKey.VK_G => new[] { "ģ", "ǧ", "ġ", "ĝ", "ǥ" },
|
||||
LetterKey.VK_H => new[] { "ḣ", "ĥ", "ħ" },
|
||||
@@ -164,7 +164,7 @@ namespace PowerAccent.Core
|
||||
LetterKey.VK_M => new[] { "ṁ" },
|
||||
LetterKey.VK_N => new[] { "ņ", "ṅ", "ⁿ", "ℕ" },
|
||||
LetterKey.VK_O => new[] { "ȯ", "∅" },
|
||||
LetterKey.VK_P => new[] { "ṗ", "℗", "∏" },
|
||||
LetterKey.VK_P => new[] { "ṗ", "℗", "∏", "¶" },
|
||||
LetterKey.VK_Q => new[] { "ℚ" },
|
||||
LetterKey.VK_R => new[] { "ṙ", "®", "ℝ" },
|
||||
LetterKey.VK_S => new[] { "ṡ", "§", "∑" },
|
||||
@@ -176,7 +176,7 @@ namespace PowerAccent.Core
|
||||
LetterKey.VK_Y => new[] { "ẏ", "ꝡ" },
|
||||
LetterKey.VK_Z => new[] { "ʒ", "ǯ", "ℤ" },
|
||||
LetterKey.VK_COMMA => new[] { "∙", "₋", "⁻", "–", "√" }, // – is in VK_MINUS for other languages, but not VK_COMMA, so we add it here.
|
||||
LetterKey.VK_PERIOD => new[] { "\u0300", "\u0301", "\u0302", "\u0303", "\u0304", "\u0308", "\u030C" },
|
||||
LetterKey.VK_PERIOD => new[] { "…", "\u0300", "\u0301", "\u0302", "\u0303", "\u0304", "\u0308", "\u030C" },
|
||||
LetterKey.VK_MINUS => new[] { "~", "‐", "‑", "‒", "—", "―", "⁓", "−", "⸺", "⸻", "∓" },
|
||||
LetterKey.VK_SLASH_ => new[] { "÷", "√" },
|
||||
LetterKey.VK_DIVIDE_ => new[] { "÷", "√" },
|
||||
|
||||
@@ -56,6 +56,9 @@ public class SettingsService
|
||||
ActivationKey = settings.Properties.ActivationKey;
|
||||
_keyboardListener.UpdateActivationKey((int)ActivationKey);
|
||||
|
||||
DoNotActivateOnGameMode = settings.Properties.DoNotActivateOnGameMode;
|
||||
_keyboardListener.UpdateDoNotActivateOnGameMode(DoNotActivateOnGameMode);
|
||||
|
||||
InputTime = settings.Properties.InputTime.Value;
|
||||
_keyboardListener.UpdateInputTime(InputTime);
|
||||
|
||||
@@ -123,6 +126,21 @@ public class SettingsService
|
||||
}
|
||||
}
|
||||
|
||||
private bool _doNotActivateOnGameMode = true;
|
||||
|
||||
public bool DoNotActivateOnGameMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return _doNotActivateOnGameMode;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_doNotActivateOnGameMode = value;
|
||||
}
|
||||
}
|
||||
|
||||
private Position _position = Position.Top;
|
||||
|
||||
public Position Position
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <common/utils/string_utils.h>
|
||||
#include <common/utils/process_path.h>
|
||||
#include <common/utils/excluded_apps.h>
|
||||
#include <common/utils/game_mode.h>
|
||||
|
||||
namespace winrt::PowerToys::PowerAccentKeyboardService::implementation
|
||||
{
|
||||
@@ -85,6 +86,11 @@ namespace winrt::PowerToys::PowerAccentKeyboardService::implementation
|
||||
m_settings.activationKey = static_cast<PowerAccentActivationKey>(activationKey);
|
||||
}
|
||||
|
||||
void KeyboardListener::UpdateDoNotActivateOnGameMode(bool doNotActivateOnGameMode)
|
||||
{
|
||||
m_settings.doNotActivateOnGameMode = doNotActivateOnGameMode;
|
||||
}
|
||||
|
||||
void KeyboardListener::UpdateInputTime(int32_t inputTime)
|
||||
{
|
||||
m_settings.inputTime = std::chrono::milliseconds(inputTime);
|
||||
@@ -112,6 +118,11 @@ namespace winrt::PowerToys::PowerAccentKeyboardService::implementation
|
||||
}
|
||||
}
|
||||
|
||||
bool KeyboardListener::IsSuppressedByGameMode()
|
||||
{
|
||||
return m_settings.doNotActivateOnGameMode && detect_game_mode();
|
||||
}
|
||||
|
||||
bool KeyboardListener::IsForegroundAppExcluded()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex_excluded_apps);
|
||||
@@ -180,7 +191,7 @@ namespace winrt::PowerToys::PowerAccentKeyboardService::implementation
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_toolbarVisible && letterPressed != LetterKey::None && triggerPressed && !IsForegroundAppExcluded())
|
||||
if (!m_toolbarVisible && letterPressed != LetterKey::None && triggerPressed && !IsSuppressedByGameMode() && !IsForegroundAppExcluded())
|
||||
{
|
||||
Logger::debug(L"Show toolbar. Letter: {}, Trigger: {}", letterPressed, triggerPressed);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace winrt::PowerToys::PowerAccentKeyboardService::implementation
|
||||
struct PowerAccentSettings
|
||||
{
|
||||
PowerAccentActivationKey activationKey{ PowerAccentActivationKey::Both };
|
||||
bool doNotActivateOnGameMode{ true };
|
||||
std::chrono::milliseconds inputTime{ 300 }; // Should match with UI.Library.PowerAccentSettings.DefaultInputTimeMs
|
||||
std::vector<std::wstring> excludedApps;
|
||||
};
|
||||
@@ -36,6 +37,7 @@ namespace winrt::PowerToys::PowerAccentKeyboardService::implementation
|
||||
void SetIsLanguageLetterDelegate(IsLanguageLetter IsLanguageLetterDelegate);
|
||||
|
||||
void UpdateActivationKey(int32_t activationKey);
|
||||
void UpdateDoNotActivateOnGameMode(bool doNotActivateOnGameMode);
|
||||
void UpdateInputTime(int32_t inputTime);
|
||||
void UpdateExcludedApps(std::wstring_view excludedApps);
|
||||
|
||||
@@ -44,6 +46,7 @@ namespace winrt::PowerToys::PowerAccentKeyboardService::implementation
|
||||
private:
|
||||
bool OnKeyDown(KBDLLHOOKSTRUCT info) noexcept;
|
||||
bool OnKeyUp(KBDLLHOOKSTRUCT info) noexcept;
|
||||
bool IsSuppressedByGameMode();
|
||||
bool IsForegroundAppExcluded();
|
||||
|
||||
static inline KeyboardListener* s_instance;
|
||||
|
||||
@@ -80,6 +80,7 @@ namespace PowerToys
|
||||
void SetNextCharEvent(event NextChar nextCharEvent);
|
||||
void SetIsLanguageLetterDelegate(IsLanguageLetter isLanguageLetterDelegate);
|
||||
void UpdateActivationKey(Int32 activationKey);
|
||||
void UpdateDoNotActivateOnGameMode(Boolean doNotActivateOnGameMode);
|
||||
void UpdateInputTime(Int32 inputTime);
|
||||
void UpdateExcludedApps(String excludedApps);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
#include "../../../common/version/version.h"
|
||||
#include "Generated Files/resource.h"
|
||||
#include "../../../../common/version/version.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
#include "winres.h"
|
||||
@@ -1,6 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<Target Name="GenerateResourceFiles" BeforeTargets="PrepareForBuild">
|
||||
<Exec Command="powershell -NonInteractive -executionpolicy Unrestricted $(SolutionDir)tools\build\convert-resx-to-rc.ps1 $(MSBuildThisFileDirectory) resource.base.h resource.h PowerRenameContextMenu.base.rc PowerRenameContextMenu.rc" />
|
||||
</Target>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
@@ -85,7 +88,8 @@ MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv</Comma
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<None Include="resource.base.h" />
|
||||
<ClInclude Include="Generated Files/resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
@@ -97,7 +101,8 @@ MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv</Comma
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="PowerRenameContextMenu.rc" />
|
||||
<ResourceCompile Include="Generated Files/PowerRenameContextMenu.rc" />
|
||||
<None Include="PowerRenameContextMenu.base.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Assets\PowerRename\**" CopyToOutputDirectory="PreserveNewest" />
|
||||
@@ -110,6 +115,9 @@ MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv</Comma
|
||||
<Project>{51920f1f-c28c-4adf-8660-4238766796c2}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources.resx" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<ClInclude Include="Generated Files/resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
@@ -38,9 +38,18 @@
|
||||
<None Include="Assets\PowerRename\**">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="resource.base.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</None>
|
||||
<None Include="PowerRenameContextMenu.base.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="Resources.resx">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="PowerRenameContextMenu.rc">
|
||||
<ResourceCompile Include="Generated Files/PowerRenameContextMenu.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
|
||||
128
src/modules/powerrename/PowerRenameContextMenu/Resources.resx
Normal file
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="PowerRename_App_Name" xml:space="preserve">
|
||||
<value>PowerRename</value>
|
||||
<comment>do not loc, product name</comment>
|
||||
</data>
|
||||
<data name="PowerRename_Context_Menu_Entry" xml:space="preserve">
|
||||
<value>Rename with PowerRename</value>
|
||||
<comment>PowerRename is a product name. do not loc it</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -16,8 +16,11 @@
|
||||
#include <wrl/implements.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#include "Generated Files/resource.h"
|
||||
|
||||
#include <common/utils/elevation.h>
|
||||
#include <common/utils/process_path.h>
|
||||
#include <common/utils/resources.h>
|
||||
#include <Helpers.h>
|
||||
#include <Settings.h>
|
||||
#include <trace.h>
|
||||
@@ -60,7 +63,7 @@ public:
|
||||
// IExplorerCommand
|
||||
IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name)
|
||||
{
|
||||
return SHStrDup(app_name.c_str(), name);
|
||||
return SHStrDup(context_menu_caption.c_str(), name);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* icon)
|
||||
@@ -261,7 +264,7 @@ private:
|
||||
|
||||
std::thread create_pipe_thread;
|
||||
HANDLE hPipe = INVALID_HANDLE_VALUE;
|
||||
std::wstring app_name = L"PowerRename";
|
||||
std::wstring context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_POWERRENAME_CONTEXT_MENU_ENTRY, L"Rename with PowerRename");
|
||||
};
|
||||
|
||||
CoCreatableClass(PowerRenameContextMenuCommand)
|
||||
|
||||
@@ -22,7 +22,7 @@ struct InvokeStruct
|
||||
CPowerRenameMenu::CPowerRenameMenu()
|
||||
{
|
||||
ModuleAddRef();
|
||||
app_name = GET_RESOURCE_STRING(IDS_POWERRENAME_APP_NAME);
|
||||
context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_POWERRENAME_CONTEXT_MENU_ENTRY, L"Rename with PowerRename");
|
||||
}
|
||||
|
||||
CPowerRenameMenu::~CPowerRenameMenu()
|
||||
@@ -87,8 +87,8 @@ HRESULT CPowerRenameMenu::QueryContextMenu(HMENU hMenu, UINT index, UINT uIDFirs
|
||||
HRESULT hr = E_UNEXPECTED;
|
||||
if (m_spdo && !(uFlags & (CMF_DEFAULTONLY | CMF_VERBSONLY | CMF_OPTIMIZEFORINVOKE)))
|
||||
{
|
||||
wchar_t menuName[64] = { 0 };
|
||||
LoadString(g_hInst, IDS_POWERRENAME, menuName, ARRAYSIZE(menuName));
|
||||
wchar_t menuName[128] = { 0 };
|
||||
wcscpy_s(menuName, ARRAYSIZE(menuName), context_menu_caption.c_str());
|
||||
|
||||
MENUITEMINFO mii;
|
||||
mii.cbSize = sizeof(MENUITEMINFO);
|
||||
@@ -251,7 +251,7 @@ HRESULT CPowerRenameMenu::RunPowerRename(CMINVOKECOMMANDINFO* pici, IShellItemAr
|
||||
|
||||
HRESULT __stdcall CPowerRenameMenu::GetTitle(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszName)
|
||||
{
|
||||
return SHStrDup(app_name.c_str(), ppszName);
|
||||
return SHStrDup(context_menu_caption.c_str(), ppszName);
|
||||
}
|
||||
|
||||
HRESULT __stdcall CPowerRenameMenu::GetIcon(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszIcon)
|
||||
|
||||
@@ -72,5 +72,5 @@ private:
|
||||
std::atomic<long> m_refCount = 1;
|
||||
HBITMAP m_hbmpIcon = nullptr;
|
||||
CComPtr<IDataObject> m_spdo;
|
||||
std::wstring app_name;
|
||||
std::wstring context_menu_caption;
|
||||
};
|
||||
|
||||
@@ -125,6 +125,10 @@
|
||||
<value>PowerRename</value>
|
||||
<comment>do not loc, product name</comment>
|
||||
</data>
|
||||
<data name="PowerRename_Context_Menu_Entry" xml:space="preserve">
|
||||
<value>Rename with Po&werRename</value>
|
||||
<comment>PowerRename is a product name. do not loc it. The & allows to use W as a keyboard accelerator.</comment>
|
||||
</data>
|
||||
<data name="Settings_Description" xml:space="preserve">
|
||||
<value>A Windows Shell extension for more advanced bulk renaming using search and replace or regular expressions.</value>
|
||||
</data>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Globalization;
|
||||
using ManagedCommon;
|
||||
|
||||
namespace Microsoft.PowerToys.ThumbnailHandler.Svg
|
||||
{
|
||||
@@ -17,6 +18,7 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
ApplicationConfiguration.Initialize();
|
||||
Logger.InitializeLogger("\\FileExplorer_localLow\\SvgThumbnails\\logs", true);
|
||||
if (args != null)
|
||||
{
|
||||
if (args.Length == 2)
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using Common.Utilities;
|
||||
using ManagedCommon;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Microsoft.Web.WebView2.WinForms;
|
||||
|
||||
@@ -197,8 +198,10 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg
|
||||
_browser.NavigateToString(SvgContents);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"Failed running webView2Environment completed for {FilePath} : ", ex);
|
||||
thumbnailDone.Set();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -52,5 +52,6 @@
|
||||
<ProjectReference Include="..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
||||
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
||||
<ProjectReference Include="..\Common\PreviewHandlerCommon.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\Common.UI\Common.UI.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -200,14 +200,6 @@ void ProcessNewVersionInfo(const github_version_info& version_info,
|
||||
|
||||
void PeriodicUpdateWorker()
|
||||
{
|
||||
// Check if periodic update check is disabled by GPO.
|
||||
// This policy code is implemented but not active. It is for later usage in PT version after 1.0 release.
|
||||
//if (powertoys_gpo::getDisablePeriodicUpdateCheckValue() == powertoys_gpo::gpo_rule_configured_enabled)
|
||||
//{
|
||||
// Logger::info(L"Initialization of periodic update checks stopped. Periodic update checks are disabled by GPO.");
|
||||
// return;
|
||||
//}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
auto state = UpdateState::read();
|
||||
|
||||
@@ -12,6 +12,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
[JsonPropertyName("activation_key")]
|
||||
public PowerAccentActivationKey ActivationKey { get; set; }
|
||||
|
||||
[JsonPropertyName("do_not_activate_on_game_mode")]
|
||||
public bool DoNotActivateOnGameMode { get; set; }
|
||||
|
||||
[JsonPropertyName("toolbar_position")]
|
||||
public StringProperty ToolbarPosition { get; set; }
|
||||
|
||||
@@ -36,6 +39,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public PowerAccentProperties()
|
||||
{
|
||||
ActivationKey = PowerAccentActivationKey.Both;
|
||||
DoNotActivateOnGameMode = true;
|
||||
ToolbarPosition = "Top center";
|
||||
InputTime = new IntProperty(PowerAccentSettings.DefaultInputTimeMs);
|
||||
SelectedLang = "ALL";
|
||||
|
||||
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 968 B After Width: | Height: | Size: 968 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |