mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 03:37:59 +01:00
Remove variable and profile logic
This commit is contained in:
@@ -11,6 +11,105 @@
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
<!-- Other merged dictionaries here -->
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<SolidColorBrush x:Key="SubtleButtonBackground" Color="{ThemeResource SubtleFillColorTransparent}" />
|
||||
<SolidColorBrush x:Key="SubtleButtonBackgroundPointerOver" Color="{ThemeResource SubtleFillColorSecondary}" />
|
||||
<SolidColorBrush x:Key="SubtleButtonBackgroundPressed" Color="{ThemeResource SubtleFillColorTertiary}" />
|
||||
<SolidColorBrush x:Key="SubtleButtonBackgroundDisabled" Color="{ThemeResource ControlFillColorDisabled}" />
|
||||
|
||||
<SolidColorBrush x:Key="SubtleButtonForeground" Color="{ThemeResource TextFillColorPrimary}" />
|
||||
<SolidColorBrush x:Key="SubtleButtonForegroundPointerOver" Color="{ThemeResource TextFillColorPrimary}" />
|
||||
<SolidColorBrush x:Key="SubtleButtonForegroundPressed" Color="{ThemeResource TextFillColorSecondary}" />
|
||||
<SolidColorBrush x:Key="SubtleButtonForegroundDisabled" Color="{ThemeResource TextFillColorDisabled}" />
|
||||
|
||||
<Style x:Key="SubtleButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="{ThemeResource SubtleButtonBackground}" />
|
||||
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource SubtleButtonForeground}" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Padding" Value="{StaticResource ButtonPadding}" />
|
||||
<Setter Property="HorizontalAlignment" Value="Left" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
|
||||
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
|
||||
<Setter Property="FocusVisualMargin" Value="-3" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<ContentPresenter
|
||||
x:Name="ContentPresenter"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
AnimatedIcon.State="Normal"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Background="{TemplateBinding Background}"
|
||||
BackgroundSizing="{TemplateBinding BackgroundSizing}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTransitions="{TemplateBinding ContentTransitions}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<ContentPresenter.BackgroundTransition>
|
||||
<BrushTransition Duration="0:0:0.083" />
|
||||
</ContentPresenter.BackgroundTransition>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonBackgroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonForegroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ContentPresenter.(AnimatedIcon.State)" Value="PointerOver" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
|
||||
<VisualState x:Name="Pressed">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonBackgroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonForegroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ContentPresenter.(AnimatedIcon.State)" Value="Pressed" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonBackgroundDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonForegroundDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<VisualState.Setters>
|
||||
<!-- DisabledVisual Should be handled by the control, not the animated icon. -->
|
||||
<Setter Target="ContentPresenter.(AnimatedIcon.State)" Value="Normal" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</ContentPresenter>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
xmlns:i="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:labs="using:CommunityToolkit.Labs.WinUI"
|
||||
xmlns:local="using:EnvironmentVariables.Views"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:models="using:EnvironmentVariables.Models"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI.UI"
|
||||
x:Name="RootPage"
|
||||
mc:Ignorable="d">
|
||||
<Page.Resources>
|
||||
<DataTemplate x:Key="VariableTemplate" x:DataType="models:Variable">
|
||||
@@ -21,11 +21,22 @@
|
||||
Click="EditVariable_Click"
|
||||
CommandParameter="{x:Bind (models:Variable)}"
|
||||
Header="{x:Bind Name, Mode=TwoWay}"
|
||||
IsClickEnabled="{x:Bind Editable, Mode=OneWay}">
|
||||
IsClickEnabled="{x:Bind IsEditable, Mode=OneWay}">
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
IsTextSelectionEnabled="True"
|
||||
Text="{x:Bind Values, Mode=TwoWay}" />
|
||||
<labs:SettingsCard.ContextFlyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem
|
||||
x:Uid="DeleteMenuItem"
|
||||
Click="Delete_Variable_Click"
|
||||
CommandParameter="{x:Bind (models:Variable)}"
|
||||
Icon="Delete"
|
||||
IsEnabled="{x:Bind IsEditable, Mode=OneWay}" />
|
||||
</MenuFlyout>
|
||||
</labs:SettingsCard.ContextFlyout>
|
||||
|
||||
</labs:SettingsCard>
|
||||
</DataTemplate>
|
||||
|
||||
@@ -98,7 +109,19 @@
|
||||
ItemTemplate="{StaticResource VariableTemplate}"
|
||||
ItemsSource="{x:Bind Variables, Mode=OneWay}">
|
||||
|
||||
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=IsEnabled}" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=IsEnabled}" />
|
||||
<Button
|
||||
x:Name="RemoveProfileBtn"
|
||||
x:Uid="RemoveProfileBtn"
|
||||
Width="40"
|
||||
Height="36"
|
||||
Click="RemoveProfileBtn_Click"
|
||||
CommandParameter="{x:Bind (models:ProfileVariablesSet)}"
|
||||
Content=""
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
Style="{StaticResource SubtleButtonStyle}" />
|
||||
</StackPanel>
|
||||
</labs:SettingsExpander>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace EnvironmentVariables.Views
|
||||
{
|
||||
public MainViewModel ViewModel { get; private set; }
|
||||
|
||||
public ICommand EditCommand => new RelayCommand<Variable>(EditVariable);
|
||||
public ICommand EditCommand => new RelayCommand<SettingsCard>(EditVariable);
|
||||
|
||||
public ICommand NewProfileCommand => new AsyncRelayCommand(AddProfileAsync);
|
||||
|
||||
@@ -32,15 +32,16 @@ namespace EnvironmentVariables.Views
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
private async Task ShowEditDialogAsync(Variable variable)
|
||||
private async Task ShowEditDialogAsync(SettingsCard card)
|
||||
{
|
||||
var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;
|
||||
|
||||
EditVariableDialog.Title = resourceLoader.GetString("EditVariableDialog_Title");
|
||||
EditVariableDialog.PrimaryButtonText = resourceLoader.GetString("SaveBtn");
|
||||
EditVariableDialog.PrimaryButtonCommand = EditCommand;
|
||||
EditVariableDialog.PrimaryButtonCommandParameter = variable;
|
||||
EditVariableDialog.PrimaryButtonCommandParameter = card;
|
||||
|
||||
var variable = card.CommandParameter as Variable;
|
||||
var clone = variable.Clone();
|
||||
EditVariableDialog.DataContext = clone;
|
||||
|
||||
@@ -52,14 +53,16 @@ namespace EnvironmentVariables.Views
|
||||
SettingsCard card = sender as SettingsCard;
|
||||
if (card != null)
|
||||
{
|
||||
await ShowEditDialogAsync(card.CommandParameter as Variable);
|
||||
await ShowEditDialogAsync(card);
|
||||
}
|
||||
}
|
||||
|
||||
private void EditVariable(Variable original)
|
||||
private void EditVariable(SettingsCard card)
|
||||
{
|
||||
var variableSet = card.DataContext as ProfileVariablesSet;
|
||||
var original = card.CommandParameter as Variable;
|
||||
var edited = EditVariableDialog.DataContext as Variable;
|
||||
ViewModel.EditVariable(original, edited);
|
||||
ViewModel.EditVariable(original, edited, variableSet);
|
||||
}
|
||||
|
||||
private async Task AddProfileAsync()
|
||||
@@ -80,6 +83,30 @@ namespace EnvironmentVariables.Views
|
||||
ViewModel.AddProfile(profile);
|
||||
}
|
||||
|
||||
private async void RemoveProfileBtn_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
var button = sender as Button;
|
||||
var profile = button.CommandParameter as ProfileVariablesSet;
|
||||
|
||||
if (profile != null)
|
||||
{
|
||||
var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;
|
||||
ContentDialog dialog = new ContentDialog();
|
||||
dialog.XamlRoot = RootPage.XamlRoot;
|
||||
dialog.Title = profile.Name;
|
||||
dialog.PrimaryButtonText = resourceLoader.GetString("Yes");
|
||||
dialog.CloseButtonText = resourceLoader.GetString("No");
|
||||
dialog.DefaultButton = ContentDialogButton.Primary;
|
||||
dialog.Content = new TextBlock() { Text = resourceLoader.GetString("Delete_Dialog_Description") };
|
||||
dialog.PrimaryButtonClick += (s, args) =>
|
||||
{
|
||||
ViewModel.RemoveProfile(profile);
|
||||
};
|
||||
|
||||
var result = await dialog.ShowAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void AddVariable()
|
||||
{
|
||||
var profile = AddProfileDialog.DataContext as ProfileVariablesSet;
|
||||
@@ -104,5 +131,17 @@ namespace EnvironmentVariables.Views
|
||||
ExistingVariablesListView.SelectedItems.Clear();
|
||||
AddVariableFlyout.Hide();
|
||||
}
|
||||
|
||||
private void Delete_Variable_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
MenuFlyoutItem menuItem = sender as MenuFlyoutItem;
|
||||
var variableSet = menuItem.DataContext as ProfileVariablesSet;
|
||||
var variable = menuItem.CommandParameter as Variable;
|
||||
|
||||
if (variable != null)
|
||||
{
|
||||
ViewModel.DeleteVariable(variable, variableSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
// 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.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using EnvironmentVariables.Helpers;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace EnvironmentVariables.Models
|
||||
private string _values;
|
||||
|
||||
[JsonIgnore]
|
||||
public bool Editable
|
||||
public bool IsEditable
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -49,44 +49,37 @@ namespace EnvironmentVariables.Models
|
||||
}
|
||||
}
|
||||
|
||||
internal void Update(Variable edited)
|
||||
internal Task Update(Variable edited, bool propagateChange)
|
||||
{
|
||||
bool changed = Name != edited.Name || Values != edited.Values;
|
||||
bool nameChanged = Name != edited.Name;
|
||||
bool success = false;
|
||||
bool success = true;
|
||||
|
||||
if (changed)
|
||||
var clone = this.Clone();
|
||||
|
||||
// Update state
|
||||
Name = edited.Name;
|
||||
Values = edited.Values;
|
||||
|
||||
ValuesList = new List<string>(Values.Split(';'));
|
||||
|
||||
return Task.Run(() =>
|
||||
{
|
||||
// Apply changes
|
||||
if (nameChanged)
|
||||
if (propagateChange)
|
||||
{
|
||||
success = EnvironmentVariablesHelper.UnsetVariable(this);
|
||||
}
|
||||
|
||||
success = EnvironmentVariablesHelper.SetVariable(edited);
|
||||
|
||||
// Update state
|
||||
if (success)
|
||||
{
|
||||
Name = edited.Name;
|
||||
Values = edited.Values;
|
||||
|
||||
ValuesList = new List<string>();
|
||||
|
||||
var splitValues = Values.Split(';');
|
||||
if (splitValues.Length > 0)
|
||||
if (nameChanged)
|
||||
{
|
||||
foreach (var splitValue in splitValues)
|
||||
{
|
||||
ValuesList.Add(splitValue);
|
||||
}
|
||||
success = EnvironmentVariablesHelper.UnsetVariable(clone);
|
||||
}
|
||||
|
||||
success = EnvironmentVariablesHelper.SetVariable(this);
|
||||
}
|
||||
else
|
||||
|
||||
if (!success)
|
||||
{
|
||||
// show error
|
||||
// Show error
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
internal Variable Clone(bool profile = false)
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace EnvironmentVariables.Models
|
||||
private static readonly string SystemIconPath = "/Assets/EnvironmentVariables/SystemIcon.png";
|
||||
protected static readonly string ProfileIconPath = "/Assets/EnvironmentVariables/ProfileIcon.png";
|
||||
|
||||
public Guid Id { get; }
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string _name;
|
||||
|
||||
@@ -203,7 +203,19 @@
|
||||
<data name="NewProfileVariablesListViewHeader.Text" xml:space="preserve">
|
||||
<value>Variables</value>
|
||||
</data>
|
||||
<data name="DeleteMenuItem.Text" xml:space="preserve">
|
||||
<value>Delete</value>
|
||||
</data>
|
||||
<data name="Delete_Dialog_Description" xml:space="preserve">
|
||||
<value>Are you sure you want to delete this profile? Deleting applied profile will remove all profile variables.</value>
|
||||
</data>
|
||||
<data name="EditSystemDefaultSetInfoBar.Title" xml:space="preserve">
|
||||
<value>You need to run as administrator to edit System environment variables</value>
|
||||
</data>
|
||||
<data name="No" xml:space="preserve">
|
||||
<value>No</value>
|
||||
</data>
|
||||
<data name="Yes" xml:space="preserve">
|
||||
<value>Yes</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -8,12 +8,14 @@ using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using EnvironmentVariables.Helpers;
|
||||
using EnvironmentVariables.Models;
|
||||
using ManagedCommon;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Windows.Foundation.Collections;
|
||||
|
||||
namespace EnvironmentVariables.ViewModels
|
||||
{
|
||||
@@ -111,9 +113,25 @@ namespace EnvironmentVariables.ViewModels
|
||||
AppliedVariables = new ObservableCollection<Variable>(variables);
|
||||
}
|
||||
|
||||
internal void EditVariable(Variable original, Variable edited)
|
||||
internal void EditVariable(Variable original, Variable edited, ProfileVariablesSet variablesSet)
|
||||
{
|
||||
original.Update(edited);
|
||||
bool propagateChange = variablesSet == null /* not a profile */ || variablesSet.Id.Equals(AppliedProfile?.Id);
|
||||
bool changed = original.Name != edited.Name || original.Values != edited.Values;
|
||||
if (changed)
|
||||
{
|
||||
ApplyingChanges = true;
|
||||
var task = original.Update(edited, propagateChange);
|
||||
PopulateAppliedVariables();
|
||||
task.ContinueWith(x =>
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
ApplyingChanges = false;
|
||||
});
|
||||
});
|
||||
|
||||
_ = Task.Run(SaveAsync);
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddProfile(ProfileVariablesSet profile)
|
||||
@@ -202,5 +220,62 @@ namespace EnvironmentVariables.ViewModels
|
||||
PopulateAppliedVariables();
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveProfile(ProfileVariablesSet profile)
|
||||
{
|
||||
if (profile.IsEnabled)
|
||||
{
|
||||
UnsetAppliedProfile();
|
||||
}
|
||||
|
||||
Profiles.Remove(profile);
|
||||
|
||||
_ = Task.Run(SaveAsync);
|
||||
}
|
||||
|
||||
internal void DeleteVariable(Variable variable, ProfileVariablesSet profile)
|
||||
{
|
||||
bool propagateChange = true;
|
||||
|
||||
if (profile != null)
|
||||
{
|
||||
// Profile variable
|
||||
profile.Variables.Remove(variable);
|
||||
|
||||
if (!profile.IsEnabled)
|
||||
{
|
||||
propagateChange = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (variable.ParentType == VariablesSetType.User)
|
||||
{
|
||||
UserDefaultSet.Variables.Remove(variable);
|
||||
}
|
||||
else if (variable.ParentType == VariablesSetType.System)
|
||||
{
|
||||
SystemDefaultSet.Variables.Remove(variable);
|
||||
}
|
||||
}
|
||||
|
||||
if (propagateChange)
|
||||
{
|
||||
ApplyingChanges = true;
|
||||
var task = Task.Run(() =>
|
||||
{
|
||||
EnvironmentVariablesHelper.UnsetVariable(variable);
|
||||
});
|
||||
task.ContinueWith((a) =>
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
ApplyingChanges = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
PopulateAppliedVariables();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user