Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,5 @@
[assembly: SuppressMessage("Build", "CA1501:'VulnerabilitiesControl' has an object hierarchy '9' levels deep within the defining module. If possible, eliminate base classes within the hierarchy to decrease its hierarchy level below '6': 'UserControl, ContentControl, Control, FrameworkElement, UIElement, Visual, DependencyObject, DispatcherObject, Object'", Justification = "Default WPF class hierarchy", Scope = "type", Target = "~T:NuGet.PackageManagement.UI.VulnerabilitiesControl")]
[assembly: SuppressMessage("Usage", "VSTHRD010:Invoke single-threaded types on Main thread", Justification = "https://github.com/microsoft/vs-threading/issues/577", Scope = "member", Target = "~M:NuGet.PackageManagement.UI.InfiniteScrollList.WaitForCompletionAsync(NuGet.PackageManagement.UI.IItemLoader{NuGet.PackageManagement.UI.PackageItemViewModel},System.Threading.CancellationToken)~System.Threading.Tasks.Task")]
[assembly: SuppressMessage("Usage", "VSTHRD010:Invoke single-threaded types on Main thread", Justification = "https://github.com/microsoft/vs-threading/issues/577", Scope = "member", Target = "~M:NuGet.PackageManagement.UI.InfiniteScrollList.LoadNextPageAsync(NuGet.PackageManagement.UI.IPackageItemLoader,System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.Collections.Generic.IEnumerable{NuGet.PackageManagement.UI.PackageItemViewModel}}")]
[assembly: SuppressMessage("Build", "CA1501:'PackageSourceMappingOptionsControl' has an object hierarchy '9' levels deep within the defining module. If possible, eliminate base classes within the hierarchy to decrease its hierarchy level below '6': 'UserControl, ContentControl, Control, FrameworkElement, UIElement, Visual, DependencyObject, DispatcherObject, Object'", Justification = "Default WPF class hierarchy", Scope = "type", Target = "~T:NuGet.Options.PackageSourceMappingOptionsControl")]
[assembly: SuppressMessage("Build", "CA1501:'AddMappingDialog' has an object hierarchy '9' levels deep within the defining module. If possible, eliminate base classes within the hierarchy to decrease its hierarchy level below '6': 'UserControl, ContentControl, Control, FrameworkElement, UIElement, Visual, DependencyObject, DispatcherObject, Object'", Justification = "Default WPF class hierarchy", Scope = "type", Target = "~T:NuGet.Options.AddMappingDialog")]
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected DetailControlModel(
{
_nugetProjects = projects;
ServiceBroker = serviceBroker;
_options = new Options();
_options = new OptionsViewModel();

// Show dependency behavior and file conflict options if any of the projects are non-build integrated
_options.ShowClassicOptions = projects.Any(project => project.ProjectKind == NuGetProjectKind.PackagesConfig);
Expand Down Expand Up @@ -802,9 +802,9 @@ public virtual string OptionsBlockedUrlText
}
}

private Options _options;
private OptionsViewModel _options;

public Options Options
public OptionsViewModel Options
{
get { return _options; }
set
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

Expand All @@ -13,9 +14,23 @@ namespace NuGet.PackageManagement.UI
/// <typeparam name="T"></typeparam>
public class ItemsChangeObservableCollection<T> : ObservableCollection<T>
{
public ItemsChangeObservableCollection()
: base() { }

public ItemsChangeObservableCollection(IEnumerable<T> collection)
: base(collection) { }
public void Refresh()
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}

public void AddRange(IEnumerable<T> newItems)
{
foreach (var item in newItems)
{
Items.Add(item);
}
Refresh();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Data" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceProcess" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this namespace? I don't see any namespace reference to System.ServiceProcess

<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
<Reference Include="Microsoft.CSharp" />
Expand Down Expand Up @@ -84,6 +86,19 @@
<Compile Include="Models\LicenseText.cs" />
<Compile Include="Models\LicenseFileText.cs" />
<Compile Include="Models\PackageItemDeprecationLabelState.cs" />
<Compile Include="OptionsViewModel.cs" />
<Compile Include="Options\ButtonCommand.cs" />
<Compile Include="Options\AddMappingDialog.xaml.cs">
<DependentUpon>AddMappingDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Options\SourceMappingViewModel.cs" />
<Compile Include="Options\PackageSourceViewModel.cs" />
<Compile Include="Options\PackageSourceMappingOptionsControl.xaml.cs">
<DependentUpon>PackageSourceMappingOptionsControl.xaml</DependentUpon>
</Compile>
<Compile Include="Options\PackageSourceMappingOptionsPage.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Utility\IReconnectingNuGetSearchService.cs" />
<Compile Include="Utility\NuGetSearchServiceReconnector.cs" />
<Compile Include="ViewModels\LoadingStatusViewModel.cs" />
Expand Down Expand Up @@ -221,7 +236,6 @@
<Compile Include="Models\PackageLicenseInfo.cs" />
<Compile Include="Models\DetailedPackageMetadata.cs" />
<Compile Include="Models\PackageDependencyMetadata.cs" />
<Compile Include="Options.cs" />
<Compile Include="Models\PackageDetailControlModel.cs" />
<Compile Include="PackageManagerControlCommands.cs" />
<Compile Include="Models\PackageManagerModel.cs" />
Expand Down Expand Up @@ -301,6 +315,14 @@
<DesignDataWithDesignTimeCreatableTypes Include="Design\PackageItemListViewSampleData.xaml">
<SubType>Designer</SubType>
</DesignDataWithDesignTimeCreatableTypes>
<Page Include="Options\AddMappingDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Options\PackageSourceMappingOptionsControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Themes\generic.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
Expand Down Expand Up @@ -440,6 +462,7 @@
<ItemGroup>
<EmbeddedResource Include="Options\GeneralOptionControl.resx">
<DependentUpon>GeneralOptionControl.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Options\PackageSourcesOptionsControl.resx">
<DependentUpon>PackageSourcesOptionsControl.cs</DependentUpon>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<nuget:VsDialogWindow x:Class="NuGet.Options.AddMappingDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vsui="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0"
xmlns:nuget="clr-namespace:NuGet.PackageManagement.UI"
mc:Ignorable="d"
x:Uid="AddMappingDialogWindow"
AutomationProperties.Name="AddMappingDialogWindow"
Height="304"
Width="456"
ShowInTaskbar="False"
WindowStyle="None"
AllowsTransparency="True"
WindowStartupLocation="CenterOwner"
BorderBrush="{DynamicResource {x:Static vsui:EnvironmentColors.PanelBorderBrushKey}}"
BorderThickness="1"
Foreground="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="36"/>
</Grid.RowDefinitions>
<Grid.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ScrollBarColorKey}}"/>
</Style>
</Grid.Resources>
<StackPanel Grid.Row="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="24"/>
</Grid.ColumnDefinitions>
<TextBlock AutomationProperties.Name="AddNewPackageNamespace"
Grid.Column="0"
Text="{x:Static nuget:Resources.VSOptions_Label_AddPackageNamespace}"
Margin="12,12,0,0"/>
<Button x:Uid="ButtonClose"
Grid.Column="1"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="0,6,6,0"
Command="{Binding HideButtonCommand}"
AutomationProperties.Name="Close"
IsCancel="True"
BorderBrush="Transparent"
BorderThickness="0"
Background="{Binding Path=(Window.Background), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
<Canvas x:Uid="canvas" Width="12" Height="10">
<Path x:Uid="CloseButtonPath"
Width="10"
Height="8"
Fill="{Binding Path=(TextElement.Foreground), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
Stretch="Uniform"
Data="F1 M 0,0L 2,0L 5,3L 8,0L 10,0L 6,4L 10,8L 8,8L 5,5L 2,8L 0,8L 4,4L 0,0 Z" />
</Canvas>
</Button>
</Grid>
</StackPanel>
<StackPanel Grid.Row="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48"/>
<RowDefinition Height="*"/>
<RowDefinition Height="36"/>
</Grid.RowDefinitions>
<vsui:WatermarkedTextBox Grid.Row="0"
AutomationProperties.Name="Package ID"
x:Name="packageID"
MaxLength="100"
Margin="12,6,12,6"
Watermark="{x:Static nuget:Resources.VSOptions_Watermark_AddPackageNamespace}"
Foreground="{Binding Path=(TextElement.Foreground), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
Background="{Binding Path=(Window.Background), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
TextChanged="PackageID_TextChanged"/>
<StackPanel Orientation="Vertical" Grid.Row="1">
<ListView AutomationProperties.Name="Sources List"
x:Name="sourcesListBox"
ItemsSource="{Binding SourcesCollection}"
Margin="12,0,12,12"
Height="184">
<ListView.View>
<GridView>
<!-- checkbox column -->
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox AutomationProperties.Name="SourcesCheckBox"
IsTabStop="False"
IsChecked="{Binding Path=IsChecked, Mode=TwoWay}"
Checked="CheckBox_Checked"
Unchecked="CheckBox_Checked"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!-- the text column -->
<GridViewColumn x:Name="_projectColumn">
<GridViewColumnHeader Content="{x:Static nuget:Resources.VSOptions_Label_Source}" HorizontalContentAlignment="Left"/>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Name="SourceInfo"
Text="{Binding SourceInfo.Name}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</Grid>
</StackPanel>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="190"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Column="1">
<Button Name="AddCloud" Height="24" Width="86" Command="{Binding AddButtonCommand}" Margin="0,0,3,12" Content="{x:Static nuget:Resources.VSOptions_Button_Add}"/>
<Button Name="CancelClose" Height="24" Width="86" Command ="{Binding HideButtonCommand}" Margin="3,0,12,12" Content="{x:Static nuget:Resources.VSOptions_Button_Cancel}"/>
</StackPanel>
</Grid>
</Grid>
</nuget:VsDialogWindow>
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Threading;
using System.Windows.Input;
using Microsoft.ServiceHub.Framework;
using Microsoft.VisualStudio.PlatformUI;
using NuGet.PackageManagement.UI;
using NuGet.VisualStudio;
using NuGet.VisualStudio.Common;
using NuGet.VisualStudio.Internal.Contracts;
using Task = System.Threading.Tasks.Task;

namespace NuGet.Options
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This namespace doesn't feel right to me. Usually project default namespaces are the project name + folder within the project, so shouldn't the namespace be NuGet.PackageManagement.UI.Options?

Same question for the other new files in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided not to change the namespace since the two existing options pages are in the NuGet.Options namespace.

{
public partial class AddMappingDialog : DialogWindow
{
public ICommand HideButtonCommand { get; set; }

public ICommand AddButtonCommand { get; set; }

public ItemsChangeObservableCollection<PackageSourceViewModel> SourcesCollection { get; private set; }

private IReadOnlyList<PackageSourceContextInfo> _originalPackageSources;

#pragma warning disable ISB001 // Dispose of proxies, disposed in disposing event or in ClearSettings
private INuGetSourcesService _nugetSourcesService;
#pragma warning restore ISB001 // Dispose of proxies, disposed in disposing event or in ClearSettings

private PackageSourceMappingOptionsControl _parent;

public AddMappingDialog(PackageSourceMappingOptionsControl parent)
{
_parent = parent;
HideButtonCommand = new ButtonCommand(ExecuteHideButtonCommand, CanExecuteHideButtonCommand);
AddButtonCommand = new ButtonCommand(ExecuteAddButtonCommand, CanExecuteAddButtonCommand);
SourcesCollection = new ItemsChangeObservableCollection<PackageSourceViewModel>();
DataContext = this;
InitializeComponent();
CancellationToken cancellationToken = new CancellationToken(false);
NuGetUIThreadHelper.JoinableTaskFactory.Run(async () => await InitializeOnActivatedAsync(cancellationToken));
}

internal async Task InitializeOnActivatedAsync(CancellationToken cancellationToken)
{
IServiceBrokerProvider serviceBrokerProvider = await ServiceLocator.GetComponentModelServiceAsync<IServiceBrokerProvider>();
IServiceBroker serviceBroker = await serviceBrokerProvider.GetAsync();
#pragma warning disable ISB001 // Dispose of proxies, disposed in disposing event or in ClearSettings
_nugetSourcesService = await serviceBroker.GetProxyAsync<INuGetSourcesService>(
NuGetServices.SourceProviderService,
cancellationToken: cancellationToken);
#pragma warning restore ISB001 // Dispose of proxies, disposed in disposing event or in ClearSettings

//show package sources on open
_originalPackageSources = await _nugetSourcesService.GetPackageSourcesAsync(cancellationToken);
SourcesCollection.Clear();
foreach (PackageSourceContextInfo source in _originalPackageSources)
{
var tempSource = new PackageSourceViewModel(source, false);
SourcesCollection.Add(tempSource);
}
}

private void ExecuteHideButtonCommand(object parameter)
{
Close();
(_parent.ShowButtonCommand as ButtonCommand).InvokeCanExecuteChanged();
}

private bool CanExecuteHideButtonCommand(object parameter)
{
return true;
}

private void ExecuteAddButtonCommand(object parameter)
{
Close();
//does not add mapping if package ID is null
if (!string.IsNullOrEmpty(packageID.Text))
{
string tempPkgID = packageID.Text;
List<PackageSourceContextInfo> tempSources = new List<PackageSourceContextInfo>();
foreach (PackageSourceViewModel source in sourcesListBox.Items)
{
if (source.IsChecked)
{
tempSources.Add(source.SourceInfo);
}
}
var tempPkg = new SourceMappingViewModel(tempPkgID, tempSources);
_parent.SourceMappingsCollection.Add(tempPkg);
}
(_parent.ShowButtonCommand as ButtonCommand).InvokeCanExecuteChanged();
(_parent.RemoveButtonCommand as ButtonCommand).InvokeCanExecuteChanged();
(_parent.ClearButtonCommand as ButtonCommand).InvokeCanExecuteChanged();
}

private bool CanExecuteAddButtonCommand(object parameter)
{
foreach (PackageSourceViewModel source in sourcesListBox.Items)
{
if (source.IsChecked)
{
if (!string.IsNullOrEmpty(packageID.Text))
{
return true;
}
}
}
return false;
}

// Allows the user to drag the window around
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
DragMove();
}

private void CheckBox_Checked(object sender, System.Windows.RoutedEventArgs e)
{
(AddButtonCommand as ButtonCommand).InvokeCanExecuteChanged();
}

private void PackageID_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
(AddButtonCommand as ButtonCommand).InvokeCanExecuteChanged();
}
}
}
Loading