[Run-Plugin] Settings plugin (#11663)

* Current settings plugin state on fresh master

* typo fixes

* Add to YML

* Add to WXS

* Address feedback - highlight the note in the tool-tip a little bit

* Address feedback add extra note for "Manage known networks"

* Address feedback - Show type of settings in sub-line and remove extra ControlPanel prefix in json

* Add "WiFi" as alternative name for each Wi-Fi setting

* Add a few more alternative names

* Make RESX happy

* exclude WindowsSettings.json from spell checker because all entries are placeholders  for the translation

* Translate all alternative names

* Translate all notes

* fix for not find "wifi"

* fix typo

* typo fixes and remove debug

* Address feedback - correct author

* Address feedback - settings entries

* Address feedback - code changes

* Address feedback - RESX changes and tool-tip

* fix typo

* Address feedback - remove superfluous interface

* Address feedback - Update RESX

* Address feedback - simplification

* Address feedback - remove enumeration

* Address feedback - move big function in extra helper classes

* Address feedback - move big function in extra helper class

* Address feedback - correct namespace

* Address feedback - move translation to translation helper and make translation more robust

* fix typo

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Main.cs

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Helper/ResultHelper.cs

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Main.cs

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>

* fix build

* Address feedback

* ups

* Address feedback - Correct windows update settings name

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/WindowsSettings.json

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>

* adding in dependencies so when you build Launcher, all plugins are included

* Address feedback - add optional updates

* Address feedback - use build numebr instaed of Windows version

* Address feedback - Log difference between registry values + fix wrong ValueType (ushort -> uint)

* Address feebdback - improved warning message on different registry values

* fix typo

* removed not need using

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Helper/UnsupportedSettingsHelper.cs

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Helper/UnsupportedSettingsHelper.cs

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>

* Update src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Helper/UnsupportedSettingsHelper.cs

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>

* Addrress feedback, don't copy embed file

* Address feedback - Remove duplicated or not available settings

* Address feedback - Improve scoring

* Address feedback - Add extra filter

* Address feedback - replace the are filter sign with a better one

* Address feedback - fix unwanted behavior

* Address feedback - Change class name

* Address feedback - Rename settings type

* typo fix

* Fix installer

* Comment out localization support

Co-authored-by: Sekan, Tobias <tobias.sekan@startmail.com>
Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>
Co-authored-by: crutkas <crutkas@microsoft.com>
This commit is contained in:
Mykhailo Pylyp
2021-06-09 18:04:03 +03:00
committed by GitHub
parent fc9d7e4f1b
commit c9c54b7780
19 changed files with 8567 additions and 4 deletions

View File

@@ -0,0 +1,66 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
namespace Microsoft.PowerToys.Run.Plugin.WindowsSettings
{
/// <summary>
/// A windows setting
/// </summary>
internal class WindowsSetting
{
/// <summary>
/// Initializes a new instance of the <see cref="WindowsSetting"/> class.
/// </summary>
public WindowsSetting()
{
Name = string.Empty;
Area = string.Empty;
Command = string.Empty;
Type = string.Empty;
}
/// <summary>
/// Gets or sets the name of this setting.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Gets or sets the area of this setting.
/// </summary>
public string Area { get; set; }
/// <summary>
/// Gets or sets the command of this setting.
/// </summary>
public string Command { get; set; }
/// <summary>
/// Gets or sets the type of the windows setting.
/// </summary>
public string Type { get; set; }
/// <summary>
/// Gets or sets the alternative names of this setting.
/// </summary>
public IEnumerable<string>? AltNames { get; set; }
/// <summary>
/// Gets or sets a additional note of this settings.
/// <para>(e.g. why is not supported on your system)</para>
/// </summary>
public string? Note { get; set; }
/// <summary>
/// Gets or sets the minimum need Windows build for this setting.
/// </summary>
public uint? IntroducedInBuild { get; set; }
/// <summary>
/// Gets or sets the Windows build since this settings is not longer present.
/// </summary>
public uint? DeprecatedInBuild { get; set; }
}
}

View File

@@ -0,0 +1,71 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using Microsoft.PowerToys.Run.Plugin.WindowsSettings.Properties;
using Wox.Plugin;
using Wox.Plugin.Logger;
namespace Microsoft.PowerToys.Run.Plugin.WindowsSettings.Helper
{
/// <summary>
/// Helper class to easier work with context menu entries
/// </summary>
internal static class ContextMenuHelper
{
/// <summary>
/// Return a list with all context menu entries for the given <see cref="Result"/>
/// <para>Symbols taken from <see href="https://docs.microsoft.com/en-us/windows/uwp/design/style/segoe-ui-symbol-font"/></para>
/// </summary>
/// <param name="result">The result for the context menu entires</param>
/// <param name="assemblyName">The name of the this assembly</param>
/// <returns>A list with context menu entries</returns>
internal static List<ContextMenuResult> GetContextMenu(in Result result, in string assemblyName)
{
if (!(result?.ContextData is WindowsSetting entry))
{
return new List<ContextMenuResult>(0);
}
var list = new List<ContextMenuResult>(1)
{
new ContextMenuResult
{
AcceleratorKey = Key.C,
AcceleratorModifiers = ModifierKeys.Control,
Action = _ => TryToCopyToClipBoard(entry.Command),
FontFamily = "Segoe MDL2 Assets",
Glyph = "\xE8C8", // E8C8 => Symbol: Copy
PluginName = assemblyName,
Title = $"{Resources.CopyCommand} (Ctrl+C)",
},
};
return list;
}
/// <summary>
/// Copy the given text to the clipboard
/// </summary>
/// <param name="text">The text to copy to the clipboard</param>
/// <returns><see langword="true"/>The text successful copy to the clipboard, otherwise <see langword="false"/></returns>
private static bool TryToCopyToClipBoard(in string text)
{
try
{
Clipboard.Clear();
Clipboard.SetText(text);
return true;
}
catch (Exception exception)
{
Log.Exception("Can't copy to clipboard", exception, typeof(Main));
return false;
}
}
}
}

View File

@@ -0,0 +1,62 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using Wox.Plugin.Logger;
namespace Microsoft.PowerToys.Run.Plugin.WindowsSettings.Helper
{
/// <summary>
/// Helper class to easier work with the JSON file that contains all Windows settings
/// </summary>
internal static class JsonSettingsListHelper
{
/// <summary>
/// The name of the file that contains all settings for the query
/// </summary>
private const string _settingsFile = "WindowsSettings.json";
/// <summary>
/// Read all possible Windows settings.
/// </summary>
/// <returns>A list with all possible windows settings.</returns>
internal static IEnumerable<WindowsSetting> ReadAllPossibleSettings()
{
var assembly = Assembly.GetExecutingAssembly();
var type = assembly.GetTypes().FirstOrDefault(x => x.Name == nameof(Main));
IEnumerable<WindowsSetting>? settingsList = null;
try
{
var resourceName = $"{type?.Namespace}.{_settingsFile}";
using var stream = assembly.GetManifestResourceStream(resourceName);
if (stream is null)
{
throw new Exception("stream is null");
}
var options = new JsonSerializerOptions();
options.Converters.Add(new JsonStringEnumConverter());
using var reader = new StreamReader(stream);
var text = reader.ReadToEnd();
settingsList = JsonSerializer.Deserialize<IEnumerable<WindowsSetting>>(text, options);
}
catch (Exception exception)
{
Log.Exception("Error loading settings JSON file", exception, typeof(Main));
}
return settingsList ?? Enumerable.Empty<WindowsSetting>();
}
}
}

View File

@@ -0,0 +1,188 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.PowerToys.Run.Plugin.WindowsSettings.Properties;
using Wox.Plugin;
using Wox.Plugin.Logger;
namespace Microsoft.PowerToys.Run.Plugin.WindowsSettings.Helper
{
/// <summary>
/// Helper class to easier work with results
/// </summary>
internal static class ResultHelper
{
/// <summary>
/// Return a list with <see cref="Result"/>s, based on the given list.
/// </summary>
/// <param name="list">The original result list to convert.</param>
/// <param name="iconPath">The path to the icon of each entry.</param>
/// <returns>A list with <see cref="Result"/>.</returns>
internal static List<Result> GetResultList(
in IEnumerable<WindowsSetting> list,
string query,
in string iconPath)
{
var resultList = new List<Result>(list.Count());
foreach (var entry in list)
{
var result = new Result
{
Action = (_) => DoOpenSettingsAction(entry),
IcoPath = iconPath,
SubTitle = $"{Resources.Area} \"{entry.Area}\" {Resources.SubtitlePreposition} {entry.Type}",
Title = entry.Name,
ContextData = entry,
};
AddOptionalToolTip(entry, result);
resultList.Add(result);
}
SetScores(resultList, query);
return resultList;
}
/// <summary>
/// Add a tool-tip to the given <see cref="Result"/>, based o the given <see cref="IWindowsSetting"/>.
/// </summary>
/// <param name="entry">The <see cref="WindowsSetting"/> that contain informations for the tool-tip.</param>
/// <param name="result">The <see cref="Result"/> that need a tool-tip.</param>
private static void AddOptionalToolTip(WindowsSetting entry, Result result)
{
var toolTipText = new StringBuilder();
toolTipText.AppendLine($"{Resources.Application}: {entry.Type}");
toolTipText.AppendLine($"{Resources.Area}: {entry.Area}");
if (entry.AltNames != null && entry.AltNames.Any())
{
var altList = entry.AltNames.Aggregate((current, next) => $"{current}, {next}");
toolTipText.AppendLine($"{Resources.AlternativeName}: {altList}");
}
toolTipText.Append($"{Resources.Command}: {entry.Command}");
if (!string.IsNullOrEmpty(entry.Note))
{
toolTipText.AppendLine(string.Empty);
toolTipText.AppendLine(string.Empty);
toolTipText.Append($"{Resources.Note}: {entry.Note}");
}
result.ToolTipData = new ToolTipData(entry.Name, toolTipText.ToString());
}
/// <summary>
/// Open the settings page of the given <see cref="IWindowsSetting"/>.
/// </summary>
/// <param name="entry">The <see cref="WindowsSetting"/> that contain the information to open the setting on command level.</param>
/// <returns><see langword="true"/> if the settings could be opened, otherwise <see langword="false"/>.</returns>
private static bool DoOpenSettingsAction(WindowsSetting entry)
{
ProcessStartInfo processStartInfo;
var command = entry.Command;
if (command.Contains("%windir%", StringComparison.InvariantCultureIgnoreCase))
{
var windowsFolder = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
command = command.Replace("%windir%", windowsFolder, StringComparison.InvariantCultureIgnoreCase);
}
if (command.Contains(' '))
{
var commandSplit = command.Split(' ');
var file = commandSplit.FirstOrDefault();
var arguments = command[file.Length..].TrimStart();
processStartInfo = new ProcessStartInfo(file, arguments)
{
UseShellExecute = false,
};
}
else
{
processStartInfo = new ProcessStartInfo(command)
{
UseShellExecute = true,
};
}
try
{
Process.Start(processStartInfo);
return true;
}
catch (Exception exception)
{
Log.Exception("can't open settings", exception, typeof(ResultHelper));
return false;
}
}
/// <summary>
/// Set the score (known as order number or ranking number)
/// for all <see cref="Results"/> in the given list, based on the given query.
/// </summary>
/// <param name="resultList">A list with <see cref="Result"/>s that need scores.</param>
/// <param name="query">The query to calculated the score for the <see cref="Result"/>s.</param>
private static void SetScores(IEnumerable<Result> resultList, string query)
{
var lowScore = 1_000;
var mediumScore = 5_000;
var highScore = 10_000;
foreach (var result in resultList)
{
if (!(result.ContextData is WindowsSetting windowsSetting))
{
continue;
}
if (windowsSetting.Name.StartsWith(query, StringComparison.CurrentCultureIgnoreCase))
{
result.Score = highScore--;
continue;
}
// If query starts with second or next word of name, set score.
if (windowsSetting.Name.Contains($" {query}", StringComparison.CurrentCultureIgnoreCase))
{
result.Score = mediumScore--;
continue;
}
if (windowsSetting.Area.StartsWith(query, StringComparison.CurrentCultureIgnoreCase))
{
result.Score = lowScore--;
continue;
}
if (windowsSetting.AltNames is null)
{
result.Score = lowScore--;
continue;
}
if (windowsSetting.AltNames.Any(x => x.StartsWith(query, StringComparison.CurrentCultureIgnoreCase)))
{
result.Score = mediumScore--;
continue;
}
result.Score = lowScore--;
}
}
}
}

View File

@@ -0,0 +1,90 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.PowerToys.Run.Plugin.WindowsSettings.Properties;
using Wox.Plugin.Logger;
namespace Microsoft.PowerToys.Run.Plugin.WindowsSettings.Helper
{
/// <summary>
/// Helper class to easier work with translations.
/// </summary>
internal static class TranslationHelper
{
/// <summary>
/// Translate all settings of the given list with <see cref="WindowsSetting"/>.
/// </summary>
/// <param name="settingsList">The list that contains <see cref="WindowsSetting"/> to translate.</param>
internal static void TranslateAllSettings(in IEnumerable<WindowsSetting>? settingsList)
{
if (settingsList is null)
{
return;
}
foreach (var settings in settingsList)
{
var area = Resources.ResourceManager.GetString($"Area{settings.Area}");
var name = Resources.ResourceManager.GetString(settings.Name);
var type = Resources.ResourceManager.GetString(settings.Type);
if (string.IsNullOrEmpty(area))
{
Log.Warn($"Resource string for [Area{settings.Area}] not found", typeof(Main));
}
if (string.IsNullOrEmpty(name))
{
Log.Warn($"Resource string for [{settings.Name}] not found", typeof(Main));
}
if (string.IsNullOrEmpty(type))
{
Log.Warn($"Resource string for [{settings.Name}] not found", typeof(Main));
}
settings.Area = area ?? settings.Area ?? string.Empty;
settings.Name = name ?? settings.Name ?? string.Empty;
settings.Type = type ?? settings.Type ?? string.Empty;
if (!string.IsNullOrEmpty(settings.Note))
{
var note = Resources.ResourceManager.GetString(settings.Note);
if (string.IsNullOrEmpty(note))
{
Log.Warn($"Resource string for [{settings.Note}] not found", typeof(Main));
}
settings.Note = note ?? settings.Note ?? string.Empty;
}
if (!(settings.AltNames is null) && settings.AltNames.Any())
{
var translatedAltNames = new Collection<string>();
foreach (var altName in settings.AltNames)
{
if (string.IsNullOrWhiteSpace(altName))
{
continue;
}
var translatedAltName = Resources.ResourceManager.GetString(altName);
if (string.IsNullOrEmpty(translatedAltName))
{
Log.Warn($"Resource string for [{altName}] not found", typeof(Main));
}
translatedAltNames.Add(translatedAltName ?? altName);
}
settings.AltNames = translatedAltNames;
}
}
}
}
}

View File

@@ -0,0 +1,89 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using Wox.Plugin.Logger;
namespace Microsoft.PowerToys.Run.Plugin.WindowsSettings.Helper
{
/// <summary>
/// Helper class to easier work with the version of the Windows OS
/// </summary>
internal static class UnsupportedSettingsHelper
{
private const string _keyPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
private const string _keyNameBuild = "CurrentBuild";
private const string _keyNameBuildNumber = "CurrentBuildNumber";
/// <summary>
/// Remove all <see cref="WindowsSetting"/> of the given list that are not present on the current used Windows build.
/// </summary>
/// <param name="settingsList">The list with <see cref="WindowsSetting"/> to filter.</param>
/// <returns>A new list with <see cref="WindowsSetting"/> that only contain present Windows settings for this OS.</returns>
internal static IEnumerable<WindowsSetting> FilterByBuild(in IEnumerable<WindowsSetting>? settingsList)
{
if (settingsList is null)
{
return Enumerable.Empty<WindowsSetting>();
}
var currentBuild = GetNumericRegistryValue(_keyPath, _keyNameBuild);
var currentBuildNumber = GetNumericRegistryValue(_keyPath, _keyNameBuildNumber);
if (currentBuild != currentBuildNumber)
{
var usedValueName = currentBuild != uint.MinValue ? _keyNameBuild : _keyNameBuildNumber;
var warningMessage =
$"Detecting the Windows version in registry ({_keyPath}) leads to an inconclusive"
+ $" result ({_keyNameBuild}={currentBuild}, {_keyNameBuildNumber}={currentBuildNumber})!"
+ $" For resolving the conflict we use the value of '{usedValueName}'.";
Log.Warn(warningMessage, typeof(UnsupportedSettingsHelper));
}
var currentWindowsBuild = currentBuild != uint.MinValue
? currentBuild
: currentBuildNumber;
var filteredSettingsList = settingsList.Where(found
=> (found.DeprecatedInBuild == null || currentWindowsBuild < found.DeprecatedInBuild)
&& (found.IntroducedInBuild == null || currentWindowsBuild >= found.IntroducedInBuild));
filteredSettingsList = filteredSettingsList.OrderBy(found => found.Name);
return filteredSettingsList;
}
/// <summary>
/// Return a unsigned numeric value from given registry value name inside the given registry key.
/// </summary>
/// <param name="registryKey">The registry key.</param>
/// <param name="valueName">The name of the registry value.</param>
/// <returns>A registry value or <see cref="uint.MinValue"/> on error.</returns>
private static uint GetNumericRegistryValue(in string registryKey, in string valueName)
{
object registryValueData;
try
{
registryValueData = Win32.Registry.GetValue(registryKey, valueName, uint.MinValue);
}
catch (Exception exception)
{
Log.Exception(
$"Can't get registry value for '{valueName}'",
exception,
typeof(UnsupportedSettingsHelper));
return uint.MinValue;
}
return uint.TryParse(registryValueData as string, out var buildNumber)
? buildNumber
: uint.MinValue;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,217 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ManagedCommon;
using Microsoft.PowerToys.Run.Plugin.WindowsSettings.Helper;
using Microsoft.PowerToys.Run.Plugin.WindowsSettings.Properties;
using Wox.Plugin;
namespace Microsoft.PowerToys.Run.Plugin.WindowsSettings
{
/// <summary>
/// Main class of this plugin that implement all used interfaces.
/// </summary>
public class Main : IPlugin, IContextMenu, IPluginI18n, IDisposable
{
/// <summary>
/// The path to the symbol for a light theme.
/// </summary>
private const string _lightSymbol = "Images/WindowsSettings.light.png";
/// <summary>
/// The path to the symbol for a dark theme.
/// </summary>
private const string _darkSymbol = "Images/WindowsSettings.dark.png";
/// <summary>
/// The name of this assembly.
/// </summary>
private readonly string _assemblyName;
/// <summary>
/// The initial context for this plugin (contains API and meta-data).
/// </summary>
private PluginInitContext? _context;
/// <summary>
/// The path to the icon for each result.
/// </summary>
private string _defaultIconPath;
/// <summary>
/// Indicate that the plugin is disposed.
/// </summary>
private bool _disposed;
/// <summary>
/// List that contain all settings.
/// </summary>
private IEnumerable<WindowsSetting>? _settingsList;
/// <summary>
/// Initializes a new instance of the <see cref="Main"/> class.
/// </summary>
public Main()
{
_assemblyName = Assembly.GetExecutingAssembly().GetName().Name ?? Name;
_defaultIconPath = _lightSymbol;
}
/// <summary>
/// Gets the localized name.
/// </summary>
public string Name => Resources.PluginTitle;
/// <summary>
/// Gets the localized description.
/// </summary>
public string Description => Resources.PluginDescription;
/// <summary>
/// Initialize the plugin with the given <see cref="PluginInitContext"/>.
/// </summary>
/// <param name="context">The <see cref="PluginInitContext"/> for this plugin.</param>
public void Init(PluginInitContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
_context.API.ThemeChanged += OnThemeChanged;
UpdateIconPath(_context.API.GetCurrentTheme());
_settingsList = JsonSettingsListHelper.ReadAllPossibleSettings();
_settingsList = UnsupportedSettingsHelper.FilterByBuild(_settingsList);
TranslationHelper.TranslateAllSettings(_settingsList);
}
/// <summary>
/// Return a filtered list, based on the given query.
/// </summary>
/// <param name="query">The query to filter the list.</param>
/// <returns>A filtered list, can be empty when nothing was found.</returns>
public List<Result> Query(Query query)
{
if (_settingsList is null)
{
return new List<Result>(0);
}
var filteredList = _settingsList
.Where(Predicate)
.OrderBy(found => found.Name);
var newList = ResultHelper.GetResultList(filteredList, query.Search, _defaultIconPath);
return newList;
bool Predicate(WindowsSetting found)
{
if (found.Name.Contains(query.Search, StringComparison.CurrentCultureIgnoreCase))
{
return true;
}
// Search for Area only by key char
if (found.Area.Contains(query.Search.Replace(":", string.Empty), StringComparison.CurrentCultureIgnoreCase)
&& query.Search.EndsWith(":"))
{
return true;
}
if (found.Area.Contains(query.Search, StringComparison.CurrentCultureIgnoreCase))
{
return true;
}
if (!(found.AltNames is null))
{
foreach (var altName in found.AltNames)
{
if (altName.Contains(query.Search, StringComparison.CurrentCultureIgnoreCase))
{
return true;
}
}
}
return false;
}
}
/// <summary>
/// Return a list context menu entries for a given <see cref="Result"/> (shown at the right side of the result).
/// </summary>
/// <param name="selectedResult">The <see cref="Result"/> for the list with context menu entries.</param>
/// <returns>A list context menu entries.</returns>
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
{
return ContextMenuHelper.GetContextMenu(selectedResult, _assemblyName);
}
/// <inheritdoc/>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Wrapper method for <see cref="Dispose"/> that dispose additional objects and events form the plugin itself.
/// </summary>
/// <param name="disposing">Indicate that the plugin is disposed.</param>
protected virtual void Dispose(bool disposing)
{
if (_disposed || !disposing)
{
return;
}
if (!(_context is null))
{
_context.API.ThemeChanged -= OnThemeChanged;
}
_disposed = true;
}
/// <summary>
/// Gets the localized name.
/// </summary>
public string GetTranslatedPluginTitle()
{
return Name;
}
/// <summary>
/// Gets the localized description.
/// </summary>
public string GetTranslatedPluginDescription()
{
return Description;
}
/// <summary>
/// Change all theme-based elements (typical called when the plugin theme has changed).
/// </summary>
/// <param name="oldtheme">The old <see cref="Theme"/>.</param>
/// <param name="newTheme">The new <see cref="Theme"/>.</param>
private void OnThemeChanged(Theme oldtheme, Theme newTheme)
{
UpdateIconPath(newTheme);
}
/// <summary>
/// Update all icons (typical called when the plugin theme has changed).
/// </summary>
/// <param name="theme">The new <see cref="Theme"/> for the icons.</param>
private void UpdateIconPath(Theme theme)
{
_defaultIconPath = theme == Theme.Light || theme == Theme.HighContrastWhite
? _lightSymbol
: _darkSymbol;
}
}
}

View File

@@ -0,0 +1,111 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{5043CECE-E6A7-4867-9CBE-02D27D83747A}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.PowerToys.Run.Plugin.WindowsSettings</RootNamespace>
<AssemblyName>Microsoft.PowerToys.Run.Plugin.WindowsSettings</AssemblyName>
<Version>$(Version).0</Version>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<Platforms>x64</Platforms>
<ErrorReport>prompt</ErrorReport>
<UseWindowsForms>true</UseWindowsForms>
<NeutralLanguage>en-US</NeutralLanguage>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutputPath>..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsSettings\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<Optimize>false</Optimize>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<LangVersion>8.0</LangVersion>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutputPath>..\..\..\..\..\x64\Release\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsSettings\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<LangVersion>8.0</LangVersion>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<None Remove="WindowsSettings.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj">
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj">
<Private>false</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\..\..\codeAnalysis\GlobalSuppressions.cs">
<Link>GlobalSuppressions.cs</Link>
</Compile>
<AdditionalFiles Include="..\..\..\..\codeAnalysis\StyleCop.json">
<Link>StyleCop.json</Link>
</AdditionalFiles>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="WindowsSettings.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers">
<Version>1.1.118</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="Images\WindowsSettings.dark.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\WindowsSettings.light.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,13 @@
{
"ID": "5043CECEE6A748679CBE02D27D83747A",
"ActionKeyword": "$",
"IsGlobal": false,
"Name": "Windows Settings",
"Author": "TobiasSekan",
"Version": "1.0.0",
"Language": "csharp",
"Website": "https://aka.ms/powertoys",
"ExecuteFileName": "Microsoft.PowerToys.Run.Plugin.WindowsSettings.dll",
"IcoPathDark": "Images\\WindowsSettings.dark.png",
"IcoPathLight": "Images\\WindowsSettings.light.png"
}