mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-24 23:49:40 +01:00
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request This PR removes the ISettingsUtils and ISettingsPath interfaces to reduce some complexity. They only existed so the classes can be used with moq. But this is also possible by using virtual methods which is cleaner. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] Closes: #xxx <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx
280 lines
9.0 KiB
C#
280 lines
9.0 KiB
C#
// 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.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using global::PowerToys.GPOWrapper;
|
|
using Microsoft.PowerToys.Settings.UI.Helpers;
|
|
using Microsoft.PowerToys.Settings.UI.Library;
|
|
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
|
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
|
using Microsoft.PowerToys.Settings.UI.Library.ViewModels.Commands;
|
|
using PowerToys.Interop;
|
|
using Settings.UI.Library.Enumerations;
|
|
|
|
namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|
{
|
|
public partial class HostsViewModel : Observable
|
|
{
|
|
private bool _isElevated;
|
|
private GpoRuleConfigured _enabledGpoRuleConfiguration;
|
|
private bool _enabledStateIsGPOConfigured;
|
|
private bool _isEnabled;
|
|
|
|
private SettingsUtils SettingsUtils { get; set; }
|
|
|
|
private GeneralSettings GeneralSettingsConfig { get; set; }
|
|
|
|
private HostsSettings Settings { get; set; }
|
|
|
|
private Func<string, int> SendConfigMSG { get; }
|
|
|
|
public ButtonClickCommand LaunchEventHandler => new ButtonClickCommand(Launch);
|
|
|
|
public ButtonClickCommand SelectBackupPathEventHandler => new ButtonClickCommand(SelectBackupPath);
|
|
|
|
public bool IsEnabled
|
|
{
|
|
get => _isEnabled;
|
|
|
|
set
|
|
{
|
|
if (_enabledStateIsGPOConfigured)
|
|
{
|
|
// If it's GPO configured, shouldn't be able to change this state.
|
|
return;
|
|
}
|
|
|
|
if (value != _isEnabled)
|
|
{
|
|
_isEnabled = value;
|
|
|
|
// Set the status in the general settings configuration
|
|
GeneralSettingsConfig.Enabled.Hosts = value;
|
|
OutGoingGeneralSettings snd = new OutGoingGeneralSettings(GeneralSettingsConfig);
|
|
|
|
SendConfigMSG(snd.ToString());
|
|
OnPropertyChanged(nameof(IsEnabled));
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsEnabledGpoConfigured
|
|
{
|
|
get => _enabledStateIsGPOConfigured;
|
|
}
|
|
|
|
public bool LaunchAdministratorEnabled => IsEnabled && !_isElevated;
|
|
|
|
public bool ShowStartupWarning
|
|
{
|
|
get => Settings.Properties.ShowStartupWarning;
|
|
set
|
|
{
|
|
if (value != Settings.Properties.ShowStartupWarning)
|
|
{
|
|
Settings.Properties.ShowStartupWarning = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool LoopbackDuplicates
|
|
{
|
|
get => Settings.Properties.LoopbackDuplicates;
|
|
set
|
|
{
|
|
if (value != Settings.Properties.LoopbackDuplicates)
|
|
{
|
|
Settings.Properties.LoopbackDuplicates = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool LaunchAdministrator
|
|
{
|
|
get => Settings.Properties.LaunchAdministrator;
|
|
set
|
|
{
|
|
if (value != Settings.Properties.LaunchAdministrator)
|
|
{
|
|
Settings.Properties.LaunchAdministrator = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool NoLeadingSpaces
|
|
{
|
|
get => Settings.Properties.NoLeadingSpaces;
|
|
set
|
|
{
|
|
if (value != Settings.Properties.NoLeadingSpaces)
|
|
{
|
|
Settings.Properties.NoLeadingSpaces = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public int AdditionalLinesPosition
|
|
{
|
|
get => (int)Settings.Properties.AdditionalLinesPosition;
|
|
set
|
|
{
|
|
if (value != (int)Settings.Properties.AdditionalLinesPosition)
|
|
{
|
|
Settings.Properties.AdditionalLinesPosition = (HostsAdditionalLinesPosition)value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public int Encoding
|
|
{
|
|
get => (int)Settings.Properties.Encoding;
|
|
set
|
|
{
|
|
if (value != (int)Settings.Properties.Encoding)
|
|
{
|
|
Settings.Properties.Encoding = (HostsEncoding)value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool BackupHosts
|
|
{
|
|
get => Settings.Properties.BackupHosts;
|
|
set
|
|
{
|
|
if (value != Settings.Properties.BackupHosts)
|
|
{
|
|
Settings.Properties.BackupHosts = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public string BackupPath
|
|
{
|
|
get => Settings.Properties.BackupPath;
|
|
set
|
|
{
|
|
if (value != Settings.Properties.BackupPath)
|
|
{
|
|
Settings.Properties.BackupPath = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public int DeleteBackupsMode
|
|
{
|
|
get => (int)Settings.Properties.DeleteBackupsMode;
|
|
set
|
|
{
|
|
if (value != (int)Settings.Properties.DeleteBackupsMode)
|
|
{
|
|
Settings.Properties.DeleteBackupsMode = (HostsDeleteBackupMode)value;
|
|
NotifyPropertyChanged();
|
|
OnPropertyChanged(nameof(MinimumBackupsCount));
|
|
}
|
|
}
|
|
}
|
|
|
|
public int DeleteBackupsDays
|
|
{
|
|
get => Settings.Properties.DeleteBackupsDays;
|
|
set
|
|
{
|
|
if (value != Settings.Properties.DeleteBackupsDays)
|
|
{
|
|
Settings.Properties.DeleteBackupsDays = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public int DeleteBackupsCount
|
|
{
|
|
get => Settings.Properties.DeleteBackupsCount;
|
|
set
|
|
{
|
|
if (value != Settings.Properties.DeleteBackupsCount)
|
|
{
|
|
Settings.Properties.DeleteBackupsCount = value;
|
|
NotifyPropertyChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public int MinimumBackupsCount => DeleteBackupsMode == 1 ? 1 : 0;
|
|
|
|
public HostsViewModel(SettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<HostsSettings> moduleSettingsRepository, Func<string, int> ipcMSGCallBackFunc, bool isElevated)
|
|
{
|
|
SettingsUtils = settingsUtils;
|
|
GeneralSettingsConfig = settingsRepository.SettingsConfig;
|
|
Settings = moduleSettingsRepository.SettingsConfig;
|
|
SendConfigMSG = ipcMSGCallBackFunc;
|
|
_isElevated = isElevated;
|
|
InitializeEnabledValue();
|
|
}
|
|
|
|
private void InitializeEnabledValue()
|
|
{
|
|
_enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredHostsFileEditorEnabledValue();
|
|
if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
|
|
{
|
|
// Get the enabled state from GPO.
|
|
_enabledStateIsGPOConfigured = true;
|
|
_isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
|
|
}
|
|
else
|
|
{
|
|
_isEnabled = GeneralSettingsConfig.Enabled.Hosts;
|
|
}
|
|
}
|
|
|
|
public void Launch()
|
|
{
|
|
string eventName = !_isElevated && LaunchAdministrator
|
|
? Constants.ShowHostsAdminSharedEvent()
|
|
: Constants.ShowHostsSharedEvent();
|
|
|
|
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName))
|
|
{
|
|
eventHandle.Set();
|
|
}
|
|
}
|
|
|
|
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
|
|
{
|
|
OnPropertyChanged(propertyName);
|
|
SettingsUtils.SaveSettings(Settings.ToJsonString(), HostsSettings.ModuleName);
|
|
}
|
|
|
|
public void RefreshEnabledState()
|
|
{
|
|
InitializeEnabledValue();
|
|
OnPropertyChanged(nameof(IsEnabled));
|
|
}
|
|
|
|
public void SelectBackupPath()
|
|
{
|
|
// This function was changed to use the shell32 API to open folder dialog
|
|
// as the old one (PickSingleFolderAsync) can't work when the process is elevated
|
|
// TODO: go back PickSingleFolderAsync when it's fixed
|
|
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.GetSettingsWindow());
|
|
var result = ShellGetFolder.GetFolderDialog(hwnd);
|
|
if (!string.IsNullOrEmpty(result))
|
|
{
|
|
BackupPath = result;
|
|
}
|
|
}
|
|
}
|
|
}
|