diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs index ef39be8a3d..2fd3560e6f 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs @@ -182,7 +182,7 @@ namespace CSharpBinding.FormsDesigner string newline = DocumentUtilities.GetLineTerminator(script.OriginalDocument, bodyRegion.BeginLine); string indentation = DocumentUtilities.GetIndentation(script.OriginalDocument, bodyRegion.BeginLine); - string code = "{" + newline + GenerateInitializeComponents(codeMethod, indentation, newline) + indentation + "}"; + string code = "{" + newline + GenerateInitializeComponents(codeMethod, indentation, newline) + newline + indentation + "}"; int startOffset = script.GetCurrentOffset(bodyRegion.Begin); int endOffset = script.GetCurrentOffset(bodyRegion.End); diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs index 1138d7fe84..054ae638f6 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs @@ -83,10 +83,12 @@ namespace ICSharpCode.XamlBinding XamlCompletionItem cItem = item as XamlCompletionItem; if (xamlContext.Description == XamlContextDescription.InTag) { - context.Editor.Document.Insert(context.EndOffset, "=\"\""); - context.CompletionCharHandled = context.CompletionChar == '='; - context.Editor.Caret.Offset--; - new XamlCodeCompletionBinding().CtrlSpace(context.Editor); + if (cItem.Entity.SymbolKind == SymbolKind.Property || cItem.Entity.SymbolKind == SymbolKind.Event) { + context.Editor.Document.Insert(context.EndOffset, "=\"\""); + context.CompletionCharHandled = context.CompletionChar == '='; + context.Editor.Caret.Offset--; + new XamlCodeCompletionBinding().CtrlSpace(context.Editor); + } } else if (xamlContext.Description == XamlContextDescription.InMarkupExtension && !string.IsNullOrEmpty(xamlContext.RawAttributeValue)) { string valuePart = xamlContext.RawAttributeValue.Substring(0, xamlContext.ValueStartOffset); AttributeValue value = MarkupExtensionParser.ParseValue(valuePart); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/RotateThumb.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/RotateThumb.cs index f09d24855f..61a9257ee2 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/RotateThumb.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/RotateThumb.cs @@ -32,14 +32,6 @@ namespace ICSharpCode.WpfDesign.Designer.Controls { public class RotateThumb : ResizeThumb { -// private double initialAngle; -// private RotateTransform rotateTransform; -// private Vector startVector; -// private Point centerPoint; -// private Control designerItem; -// private Panel canvas; -// private AdornerPanel parent; - static RotateThumb() { DefaultStyleKeyProperty.OverrideMetadata(typeof(RotateThumb), new FrameworkPropertyMetadata(typeof(RotateThumb))); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SizeDisplay.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SizeDisplay.cs index 9f75cdb161..8f660b84db 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SizeDisplay.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SizeDisplay.cs @@ -26,25 +26,25 @@ using System.Windows.Controls; namespace ICSharpCode.WpfDesign.Designer.Controls { - /// - /// Display height of the element. - /// - class HeightDisplay : Control - { - static HeightDisplay() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(HeightDisplay), new FrameworkPropertyMetadata(typeof(HeightDisplay))); - } - } + /// + /// Display height of the element. + /// + class HeightDisplay : Control + { + static HeightDisplay() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(HeightDisplay), new FrameworkPropertyMetadata(typeof(HeightDisplay))); + } + } - /// - /// Display width of the element. - /// - class WidthDisplay : Control - { - static WidthDisplay() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(WidthDisplay), new FrameworkPropertyMetadata(typeof(WidthDisplay))); - } - } + /// + /// Display width of the element. + /// + class WidthDisplay : Control + { + static WidthDisplay() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(WidthDisplay), new FrameworkPropertyMetadata(typeof(WidthDisplay))); + } + } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/Initializers.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/Initializers.cs index 4486c4730e..433d48f307 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/Initializers.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/Initializers.cs @@ -30,55 +30,55 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions.Initializers { public override void InitializeDefaults(DesignItem item) { - //Not every Content Control can have a text as Content (e.g. ZoomBox of WPF Toolkit) - if (item.Component is Button) - { + //Not every Content Control can have a text as Content (e.g. ZoomBox of WPF Toolkit) + if (item.Component is Button) + { DesignItemProperty contentProperty = item.Properties["Content"]; - if (contentProperty.ValueOnInstance == null) - { + if (contentProperty.ValueOnInstance == null) + { contentProperty.SetValue(item.ComponentType.Name); } } - DesignItemProperty verticalAlignmentProperty = item.Properties["VerticalAlignment"]; - if (verticalAlignmentProperty.ValueOnInstance == null) - { - verticalAlignmentProperty.SetValue(VerticalAlignment.Center); - } + DesignItemProperty verticalAlignmentProperty = item.Properties["VerticalAlignment"]; + if (verticalAlignmentProperty.ValueOnInstance == null) + { + verticalAlignmentProperty.SetValue(VerticalAlignment.Center); + } - DesignItemProperty horizontalAlignmentProperty = item.Properties["HorizontalAlignment"]; - if (horizontalAlignmentProperty.ValueOnInstance == null) - { - horizontalAlignmentProperty.SetValue(HorizontalAlignment.Center); - } + DesignItemProperty horizontalAlignmentProperty = item.Properties["HorizontalAlignment"]; + if (horizontalAlignmentProperty.ValueOnInstance == null) + { + horizontalAlignmentProperty.SetValue(HorizontalAlignment.Center); + } } } [ExtensionFor(typeof(TextBlock))] - public class TextBlockInitializer : DefaultInitializer - { - public override void InitializeDefaults(DesignItem item) - { - DesignItemProperty textProperty = item.Properties["Text"]; - if (textProperty.ValueOnInstance == null || textProperty.ValueOnInstance.ToString() == "") - { - textProperty.SetValue(item.ComponentType.Name); - } + public class TextBlockInitializer : DefaultInitializer + { + public override void InitializeDefaults(DesignItem item) + { + DesignItemProperty textProperty = item.Properties["Text"]; + if (textProperty.ValueOnInstance == null || textProperty.ValueOnInstance.ToString() == "") + { + textProperty.SetValue(item.ComponentType.Name); + } - DesignItemProperty verticalAlignmentProperty = item.Properties["VerticalAlignment"]; - if (verticalAlignmentProperty.ValueOnInstance == null) - { - verticalAlignmentProperty.SetValue(VerticalAlignment.Center); - } + DesignItemProperty verticalAlignmentProperty = item.Properties["VerticalAlignment"]; + if (verticalAlignmentProperty.ValueOnInstance == null) + { + verticalAlignmentProperty.SetValue(VerticalAlignment.Center); + } - DesignItemProperty horizontalAlignmentProperty = item.Properties["HorizontalAlignment"]; - if (horizontalAlignmentProperty.ValueOnInstance == null) - { - horizontalAlignmentProperty.SetValue(HorizontalAlignment.Center); - } - } + DesignItemProperty horizontalAlignmentProperty = item.Properties["HorizontalAlignment"]; + if (horizontalAlignmentProperty.ValueOnInstance == null) + { + horizontalAlignmentProperty.SetValue(HorizontalAlignment.Center); + } + } } - + [ExtensionFor(typeof(HeaderedContentControl), OverrideExtension = typeof(ContentControlInitializer))] public class HeaderedContentControlInitializer : DefaultInitializer { @@ -96,7 +96,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions.Initializers } } - [ExtensionFor(typeof(Shape))] + [ExtensionFor(typeof(Shape))] public class ShapeInitializer : DefaultInitializer { public override void InitializeDefaults(DesignItem item) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickMultipleItemsContextMenu.xaml b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickMultipleItemsContextMenu.xaml new file mode 100644 index 0000000000..d6c69df71b --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickMultipleItemsContextMenu.xaml @@ -0,0 +1,8 @@ + + + + diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/SettingsFactory.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickMultipleItemsContextMenu.xaml.cs similarity index 52% rename from src/AddIns/Misc/PackageManagement/Project/Src/SettingsFactory.cs rename to src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickMultipleItemsContextMenu.xaml.cs index 807072f3e5..e616350d12 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/SettingsFactory.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickMultipleItemsContextMenu.xaml.cs @@ -17,16 +17,42 @@ // DEALINGS IN THE SOFTWARE. using System; -using NuGet; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using ICSharpCode.WpfDesign.PropertyGrid; +using ICSharpCode.WpfDesign.Designer.Xaml; -namespace ICSharpCode.PackageManagement +namespace ICSharpCode.WpfDesign.Designer.Extensions { - public class SettingsFactory : ISettingsFactory + public partial class RightClickMultipleItemsContextMenu { - public ISettings CreateSettings(string directory) + private DesignItem designItem; + + public RightClickMultipleItemsContextMenu(DesignItem designItem) { - var fileSystem = new PhysicalFileSystem(directory); - return new Settings(fileSystem); + this.designItem = designItem; + + InitializeComponent(); + } + + void Click_WrapInCanvas(object sender, System.Windows.RoutedEventArgs e) + { + ModelTools.WrapItemsNewContainer(this.designItem.Services.Selection.SelectedItems, typeof(Canvas)); + } + + void Click_WrapInGrid(object sender, System.Windows.RoutedEventArgs e) + { + ModelTools.WrapItemsNewContainer(this.designItem.Services.Selection.SelectedItems, typeof(Grid)); } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeSettingsFactory.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickMultipleItemsContextMenuExtension.cs similarity index 59% rename from src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeSettingsFactory.cs rename to src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickMultipleItemsContextMenuExtension.cs index c6ad46bacc..5f24f5caff 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeSettingsFactory.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickMultipleItemsContextMenuExtension.cs @@ -17,21 +17,38 @@ // DEALINGS IN THE SOFTWARE. using System; -using ICSharpCode.PackageManagement; -using ICSharpCode.PackageManagement.Design; -using NuGet; +using System.Windows; +using System.Windows.Media; +using System.Windows.Shapes; -namespace PackageManagement.Tests.Helpers +using ICSharpCode.WpfDesign.Adorners; +using ICSharpCode.WpfDesign.Extensions; +using ICSharpCode.WpfDesign.Designer; + +namespace ICSharpCode.WpfDesign.Designer.Extensions { - public class FakeSettingsFactory : ISettingsFactory + /// + /// + /// + [ExtensionServer(typeof(MultipleSelectedExtensionServer))] + [ExtensionFor(typeof(UIElement))] + public class RightClickMultipleItemsContextMenuExtension : SelectionAdornerProvider { - public FakeSettings FakeSettings = new FakeSettings(); - public string DirectoryPassedToCreateSettings; + DesignPanel panel; + + protected override void OnInitialized() + { + base.OnInitialized(); + + panel = ExtendedItem.Context.Services.DesignPanel as DesignPanel; + panel.ContextMenu = new RightClickMultipleItemsContextMenu(ExtendedItem); + } - public ISettings CreateSettings(string directory) + protected override void OnRemove() { - DirectoryPassedToCreateSettings = directory; - return FakeSettings; + panel.ContextMenu = null; + + base.OnRemove(); } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs index 67868fbfb7..b145816386 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs @@ -115,12 +115,10 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions if (Snap(horizontalInput, horizontalMap, Accuracy, out drawLines, out delta)) { if (operation.Type == PlacementType.Resize) { - if (info.ResizeThumbAlignment.Vertical == VerticalAlignment.Top) { - bounds.Y += delta; - bounds.Height = Math.Max(0, bounds.Height - delta); - } else { - bounds.Height = Math.Max(0, bounds.Height + delta); + if (info.ResizeThumbAlignment != null && info.ResizeThumbAlignment.Value.Vertical == VerticalAlignment.Top) { + bounds.Y += delta; } + bounds.Height = Math.Max(0, bounds.Height - delta); info.Bounds = bounds; } else { foreach (var item in operation.PlacedItems) { @@ -138,12 +136,10 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions if (Snap(verticalInput, verticalMap, Accuracy, out drawLines, out delta)) { if (operation.Type == PlacementType.Resize) { - if (info.ResizeThumbAlignment.Horizontal == HorizontalAlignment.Left) { - bounds.X += delta; - bounds.Width = Math.Max(0, bounds.Width - delta); - } else { - bounds.Width = Math.Max(0, bounds.Width + delta); + if (info.ResizeThumbAlignment != null && info.ResizeThumbAlignment.Value.Horizontal == HorizontalAlignment.Left) { + bounds.X += delta; } + bounds.Width = Math.Max(0, bounds.Width - delta); info.Bounds = bounds; } else { foreach (var item in operation.PlacedItems) { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs index 73a1510495..f8c8d22406 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs @@ -27,6 +27,7 @@ using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Xps.Serialization; +using ICSharpCode.WpfDesign.Designer.Xaml; namespace ICSharpCode.WpfDesign.Designer { @@ -137,7 +138,7 @@ namespace ICSharpCode.WpfDesign.Designer catch (Exception) { } } - + internal static Size GetDefaultSize(DesignItem createdItem) { CreateVisualTree(createdItem.View); @@ -198,5 +199,174 @@ namespace ICSharpCode.WpfDesign.Designer item.Properties.GetProperty(FrameworkElement.HeightProperty).SetValue(newHeight); } } + + + private class ItemPos + { + public HorizontalAlignment HorizontalAlignment{ get; set; } + + public VerticalAlignment VerticalAlignment{ get; set; } + + public double Xmin { get; set; } + + public double Xmax { get; set; } + + public double Ymin { get; set; } + + public double Ymax { get; set; } + + public DesignItem DesignItem { get; set; } + } + + public static void WrapItemsNewContainer(IEnumerable items, Type containerType) + { + var collection = items; + + var _context = collection.First().Context as XamlDesignContext; + + var oldContainer = collection.First().Parent; + + if (collection.Any(x => x.Parent != oldContainer)) + return; + + var newInstance = Activator.CreateInstance(containerType); + DesignItem newPanel = _context.Services.Component.RegisterComponentForDesigner(newInstance); + var changeGroup = newPanel.OpenGroup("Wrap in Container"); + + List itemList = new List(); + + foreach (var item in collection) { + + var itemPos = new ItemPos(){ DesignItem = item }; + itemList.Add(itemPos); + + if (oldContainer.Component is Canvas) { + var canvas = oldContainer.View as Canvas; + + if (item.Properties.GetAttachedProperty(Canvas.RightProperty) != null && item.Properties.GetAttachedProperty(Canvas.RightProperty).IsSet) { + itemPos.HorizontalAlignment = HorizontalAlignment.Right; + itemPos.Xmax = canvas.ActualWidth - (double)item.Properties.GetAttachedProperty(Canvas.RightProperty).ValueOnInstance; + itemPos.Xmin = itemPos.Xmax - ((FrameworkElement)item.View).ActualWidth; + } + else if (item.Properties.GetAttachedProperty(Canvas.LeftProperty) != null && item.Properties.GetAttachedProperty(Canvas.LeftProperty).IsSet) { + itemPos.HorizontalAlignment = HorizontalAlignment.Left; + itemPos.Xmin = (double)item.Properties.GetAttachedProperty(Canvas.LeftProperty).ValueOnInstance; + itemPos.Xmax = itemPos.Xmin + ((FrameworkElement)item.View).ActualWidth; + } else { + itemPos.HorizontalAlignment = HorizontalAlignment.Left; + itemPos.Xmax = itemPos.Xmin + ((FrameworkElement)item.View).ActualWidth; + } + + if (item.Properties.GetAttachedProperty(Canvas.BottomProperty) != null && item.Properties.GetAttachedProperty(Canvas.BottomProperty).IsSet) { + itemPos.VerticalAlignment = VerticalAlignment.Bottom; + itemPos.Ymax = canvas.ActualHeight - (double)item.Properties.GetAttachedProperty(Canvas.BottomProperty).ValueOnInstance; + itemPos.Ymin = itemPos.Ymax - ((FrameworkElement)item.View).ActualHeight; + } + else if (item.Properties.GetAttachedProperty(Canvas.TopProperty) != null && item.Properties.GetAttachedProperty(Canvas.TopProperty).IsSet) { + itemPos.VerticalAlignment = VerticalAlignment.Top; + itemPos.Ymin = (double)item.Properties.GetAttachedProperty(Canvas.TopProperty).ValueOnInstance; + itemPos.Ymax = itemPos.Ymin + ((FrameworkElement)item.View).ActualHeight; + } else { + itemPos.VerticalAlignment = VerticalAlignment.Top; + itemPos.Ymax = itemPos.Ymin + ((FrameworkElement)item.View).ActualHeight; + } + + item.Properties.GetAttachedProperty(Canvas.RightProperty).Reset(); + item.Properties.GetAttachedProperty(Canvas.LeftProperty).Reset(); + item.Properties.GetAttachedProperty(Canvas.TopProperty).Reset(); + item.Properties.GetAttachedProperty(Canvas.BottomProperty).Reset(); + } else if (oldContainer.Component is Grid) { + var grid = oldContainer.View as Grid; + + if ((HorizontalAlignment)item.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).ValueOnInstance == HorizontalAlignment.Right) { + itemPos.HorizontalAlignment = HorizontalAlignment.Right; + itemPos.Xmax = grid.ActualWidth - ((Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance).Right; + itemPos.Xmin = itemPos.Xmax - ((FrameworkElement)item.View).ActualWidth; + } else { + itemPos.HorizontalAlignment = HorizontalAlignment.Left; + itemPos.Xmin = ((Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance).Left; + itemPos.Xmax = itemPos.Xmin + ((FrameworkElement)item.View).ActualWidth; + } + + if ((VerticalAlignment)item.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).ValueOnInstance == VerticalAlignment.Bottom) { + itemPos.VerticalAlignment = VerticalAlignment.Bottom; + itemPos.Ymax = grid.ActualHeight - ((Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance).Bottom; + itemPos.Ymin = itemPos.Ymax - ((FrameworkElement)item.View).ActualHeight; + } else { + itemPos.VerticalAlignment = VerticalAlignment.Top; + itemPos.Ymin = ((Thickness)item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance).Top; + itemPos.Ymax = itemPos.Ymin + ((FrameworkElement)item.View).ActualHeight; + } + + item.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).Reset(); + item.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).Reset(); + item.Properties.GetProperty(FrameworkElement.MarginProperty).Reset(); + } + + var parCol = item.ParentProperty.CollectionElements; + parCol.Remove(item); + } + + var xmin = itemList.Min(x => x.Xmin); + var xmax = itemList.Max(x => x.Xmax); + var ymin = itemList.Min(x => x.Ymin); + var ymax = itemList.Max(x => x.Ymax); + + if (oldContainer.Component is Canvas) { + newPanel.Properties.GetProperty(FrameworkElement.WidthProperty).SetValue(xmax - xmin); + newPanel.Properties.GetProperty(FrameworkElement.HeightProperty).SetValue(ymax - ymin); + newPanel.Properties.GetAttachedProperty(Canvas.LeftProperty).SetValue(xmin); + newPanel.Properties.GetAttachedProperty(Canvas.TopProperty).SetValue(ymin); + } else if (oldContainer.Component is Grid) { + newPanel.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).SetValue(HorizontalAlignment.Left); + newPanel.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).SetValue(VerticalAlignment.Top); + newPanel.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(new Thickness(xmin, ymin, 0, 0)); + newPanel.Properties.GetProperty(FrameworkElement.WidthProperty).SetValue(xmax - xmin); + newPanel.Properties.GetProperty(FrameworkElement.HeightProperty).SetValue(ymax - ymin); + } + + foreach (var item in itemList) { + newPanel.ContentProperty.CollectionElements.Add(item.DesignItem); + + if (newPanel.Component is Canvas) { + if (item.HorizontalAlignment == HorizontalAlignment.Right) { + item.DesignItem.Properties.GetAttachedProperty(Canvas.RightProperty).SetValue(xmax - item.Xmax); + } else { + item.DesignItem.Properties.GetAttachedProperty(Canvas.LeftProperty).SetValue(item.Xmin - xmin); + } + + if (item.VerticalAlignment == VerticalAlignment.Bottom) { + item.DesignItem.Properties.GetAttachedProperty(Canvas.BottomProperty).SetValue(ymax - item.Ymax); + } else { + item.DesignItem.Properties.GetAttachedProperty(Canvas.TopProperty).SetValue(item.Ymin - ymin); + } + } else if (newPanel.Component is Grid) { + Thickness thickness = new Thickness(0); + if (item.HorizontalAlignment == HorizontalAlignment.Right) { + item.DesignItem.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).SetValue(HorizontalAlignment.Right); + thickness.Right = xmax - item.Xmax; + } else { + item.DesignItem.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).SetValue(HorizontalAlignment.Left); + thickness.Left = item.Xmin - xmin; + } + + if (item.VerticalAlignment == VerticalAlignment.Bottom) { + item.DesignItem.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).SetValue(VerticalAlignment.Bottom); + thickness.Bottom = ymax - item.Ymax; + } else { + item.DesignItem.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).SetValue(VerticalAlignment.Top); + thickness.Top = item.Ymin - ymin; + } + + item.DesignItem.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(thickness); + } + } + + oldContainer.ContentProperty.CollectionElements.Add(newPanel); + + changeGroup.Commit(); + + _context.Services.Selection.SetSelectedComponents(new []{ newPanel }); + } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Translations.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Translations.cs index 15677480c9..ebb196ca26 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Translations.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Translations.cs @@ -65,5 +65,23 @@ namespace ICSharpCode.WpfDesign.Designer return "Press \"Alt\" to Enter Container"; } } + + public virtual string WrapInCanvas { + get { + return "Wrap in Canvas"; + } + } + + public virtual string WrapInGrid { + get { + return "Wrap in Grid"; + } + } + + public virtual string WrapInBorder { + get { + return "Wrap in Border"; + } + } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj index 0cb8629e13..ee6c301f7f 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj @@ -90,6 +90,10 @@ + + + RightClickMultipleItemsContextMenu.xaml + @@ -263,6 +267,7 @@ + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs index dc675552f7..44d4611df9 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs @@ -149,6 +149,176 @@ namespace ICSharpCode.WpfDesign.Tests.Designer AssertLog(""); } + [Test] + public void UndoRedoImplicitList() + { + UndoRedoListInternal(false); + } + + [Test] + public void UndoRedoExplicitList() + { + UndoRedoListInternal(true); + } + + void UndoRedoListInternal(bool useExplicitList) + { + DesignItem button = CreateCanvasContext(""; + } else { + expectedXamlWithList = @""; + } + + DesignItem exampleClassItem = component.RegisterComponentForDesigner(new ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClass()); + exampleClassItem.Properties["StringProp"].SetValue("String value"); + otherListProp.CollectionElements.Add(exampleClassItem); + + button.Properties["Tag"].SetValue(containerItem); + g.Commit(); + } + + Assert.IsTrue(s.CanUndo); + Assert.IsFalse(s.CanRedo); + AssertCanvasDesignerOutput(expectedXamlWithList, button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); + + otherListProp = button.Properties["Tag"].Value.Properties["OtherList"]; + Assert.IsTrue(((ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClassList)otherListProp.ValueOnInstance).Count == otherListProp.CollectionElements.Count); + + s.Undo(); + Assert.IsFalse(s.CanUndo); + Assert.IsTrue(s.CanRedo); + AssertCanvasDesignerOutput("", button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); + + s.Redo(); + Assert.IsTrue(s.CanUndo); + Assert.IsFalse(s.CanRedo); + AssertCanvasDesignerOutput(expectedXamlWithList, button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); + + otherListProp = button.Properties["Tag"].Value.Properties["OtherList"]; + Assert.IsTrue(((ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClassList)otherListProp.ValueOnInstance).Count == otherListProp.CollectionElements.Count); + + AssertLog(""); + } + + [Test] + public void UndoRedoImplicitDictionary() + { + UndoRedoDictionaryInternal(false); + } + + [Test] + public void UndoRedoExplicitDictionary() + { + UndoRedoDictionaryInternal(true); + } + + void UndoRedoDictionaryInternal(bool useExplicitDictionary) + { + DesignItem button = CreateCanvasContext(""; + } else { + expectedXamlWithDictionary = @""; + } + + DesignItem exampleClassItem = component.RegisterComponentForDesigner(new ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClass()); + exampleClassItem.Key = "testKey"; + exampleClassItem.Properties["StringProp"].SetValue("String value"); + dictionaryProp.CollectionElements.Add(exampleClassItem); + + button.Properties["Tag"].SetValue(containerItem); + g.Commit(); + } + + Assert.IsTrue(s.CanUndo); + Assert.IsFalse(s.CanRedo); + AssertCanvasDesignerOutput(expectedXamlWithDictionary, button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); + + dictionaryProp = button.Properties["Tag"].Value.Properties["Dictionary"]; + Assert.IsTrue(((ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClassDictionary)dictionaryProp.ValueOnInstance).Count == dictionaryProp.CollectionElements.Count); + + s.Undo(); + Assert.IsFalse(s.CanUndo); + Assert.IsTrue(s.CanRedo); + AssertCanvasDesignerOutput("", button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); + + s.Redo(); + Assert.IsTrue(s.CanUndo); + Assert.IsFalse(s.CanRedo); + AssertCanvasDesignerOutput(expectedXamlWithDictionary, button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); + + dictionaryProp = button.Properties["Tag"].Value.Properties["Dictionary"]; + Assert.IsTrue(((ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClassDictionary)dictionaryProp.ValueOnInstance).Count == dictionaryProp.CollectionElements.Count); + + AssertLog(""); + } [Test] public void AddTextBoxToCanvas() @@ -254,6 +424,89 @@ namespace ICSharpCode.WpfDesign.Tests.Designer AssertLog(""); } + [Test] + public void ClearExplicitList() + { + DesignItem button = CreateCanvasContext("", button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); + AssertLog(""); + } + + [Test] + public void ClearExplicitDictionary() + { + DesignItem button = CreateCanvasContext("", button.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\""); + AssertLog(""); + } + [Test] public void AddMultiBindingToTextBox() { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/MarkupExtensionTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/MarkupExtensionTests.cs index 286f94409b..cfe333f062 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/MarkupExtensionTests.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/MarkupExtensionTests.cs @@ -27,6 +27,10 @@ namespace ICSharpCode.WpfDesign.Tests.XamlDom [TestFixture] public class MarkupExtensionTests : TestHelper { + private const string PathWithSpaces = @"C:\\Folder A\\SubFolder A\\SubFolder B\\file with spaces.txt"; + private const string PathWithoutSpaces = @"C:\\FolderA\\SubFolderA\\SubFolderB\\file.txt"; + private const string PathWithCommasAndSpaces = @"C:\\Folder A\\Sub,Folder,A\\SubFolderB\\file,with,commas and spaces.txt"; + [Test] public void Test1() { @@ -84,6 +88,36 @@ namespace ICSharpCode.WpfDesign.Tests.XamlDom { TestMarkupExtension("Content=\"{x:Static t:MyStaticClass.StaticString}\""); } + + [Test] + public void TestPathWithSpaces() + { + TestMarkupExtension("Content=\"{t:String " + PathWithSpaces + "}\""); + } + + [Test] + public void TestQuotedPathWithSpaces() + { + TestMarkupExtension("Content=\"{t:String '" + PathWithSpaces + "'}\""); + } + + [Test] + public void TestPathWithoutSpaces() + { + TestMarkupExtension("Content=\"{t:String " + PathWithoutSpaces + "}\""); + } + + [Test] + public void TestQuotedPathWithoutSpaces() + { + TestMarkupExtension("Content=\"{t:String '" + PathWithoutSpaces + "'}\""); + } + + [Test] + public void TestQuotedPathWithCommasAndSpaces() + { + TestMarkupExtension("Content=\"{t:String '" + PathWithCommasAndSpaces + "'}\""); + } // [Test] // public void Test10() @@ -114,6 +148,23 @@ namespace ICSharpCode.WpfDesign.Tests.XamlDom { public static string StaticString = "a"; } + + public class StringExtension : MarkupExtension + { + readonly string s; + + public StringExtension(string s) + { + TestHelperLog.Log(this.GetType().Name + " " + s); + + this.s = s; + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return s; + } + } public class MyExtension : MarkupExtension { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs index 86bc31adef..6566897e28 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionElementsCollection.cs @@ -54,7 +54,8 @@ namespace ICSharpCode.WpfDesign.XamlDom XamlPropertyInfo info = property.propertyInfo; object collection = info.GetValue(property.ParentObject.Instance); if (!CollectionSupport.RemoveItemAt(info.ReturnType, collection, index)) { - CollectionSupport.RemoveItem(info.ReturnType, collection, this[index].GetValueFor(info)); + var propertyValue = this[index]; + CollectionSupport.RemoveItem(info.ReturnType, collection, propertyValue.GetValueFor(info), propertyValue); } this[index].RemoveNodeFromParent(); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs index cf36fed5a4..09a3b28beb 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/CollectionSupport.cs @@ -154,5 +154,20 @@ namespace ICSharpCode.WpfDesign.XamlDom new object[] { item }, CultureInfo.InvariantCulture); } + + /// + /// Removes an item instance from the specified collection. + /// + internal static void RemoveItem(Type collectionType, object collectionInstance, object item, XamlPropertyValue element) + { + var dictionary = collectionInstance as IDictionary; + var xamlObject = element as XamlObject; + + if (dictionary != null && xamlObject != null) { + dictionary.Remove(xamlObject.GetXamlAttribute("Key")); + } else { + RemoveItem(collectionType, collectionInstance, item); + } + } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionParser.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionParser.cs index 30791350c1..713701b963 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionParser.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionParser.cs @@ -96,10 +96,17 @@ namespace ICSharpCode.WpfDesign.XamlDom if (text[pos] == '"' || text[pos] == '\'') { char quote = text[pos++]; CheckNotEOF(); + int lastBackslashPos = -1; while (!(text[pos] == quote && text[pos-1] != '\\')) { + int current = pos; char c = text[pos++]; - if (c != '\\') + //check if string is \\ and that the last backslash is not the previously saved char, ie that \\\\ does not become \\\ but just \\ + bool isEscapedBackslash = string.Concat(text[current-1],c)=="\\\\" && current-1 != lastBackslashPos; + if (c != '\\' || isEscapedBackslash){ b.Append(c); + if(isEscapedBackslash) + lastBackslashPos = current; + } CheckNotEOF(); } pos++; // consume closing quote diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs index 9fbeab0717..eee4a6848e 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs @@ -254,13 +254,21 @@ namespace ICSharpCode.WpfDesign.XamlDom void ResetInternal() { + bool isExplicitCollection = false; + if (propertyValue != null) { + isExplicitCollection = IsCollection; + propertyValue.RemoveNodeFromParent(); propertyValue.ParentProperty = null; propertyValue = null; } if (_propertyElement != null) { - _propertyElement.ParentNode.RemoveChild(_propertyElement); + Debug.Assert(!isExplicitCollection || _propertyElement.ParentNode == null); + + if (!isExplicitCollection) { + _propertyElement.ParentNode.RemoveChild(_propertyElement); + } _propertyElement = null; } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs index 75db9cd2c4..fc88c441a9 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs @@ -118,7 +118,7 @@ namespace ICSharpCode.WpfDesign.Extensions void OnSelectionChanged(object sender, EventArgs e) { - ReapplyExtensions(this.Services.Selection.SelectedItems); + ReapplyExtensions(this.Services.Selection.SelectedItems); } /// @@ -130,6 +130,34 @@ namespace ICSharpCode.WpfDesign.Extensions } } + /// + /// Applies an extension only when multiple Items are selected! + /// + public class MultipleSelectedExtensionServer : DefaultExtensionServer + { + /// + /// Is called after the extension server is initialized and the Context property has been set. + /// + protected override void OnInitialized() + { + base.OnInitialized(); + this.Services.Selection.SelectionChanged += OnSelectionChanged; + } + + void OnSelectionChanged(object sender, EventArgs e) + { + ReapplyExtensions(this.Services.Selection.SelectedItems); + } + + /// + /// Gets if the item is in the secondary selection. + /// + public override bool ShouldApplyExtensions(DesignItem extendedItem) + { + return Services.Selection.SelectionCount > 1; + } + } + /// /// Applies an extension to the primary selection if Only One Item is Selected. /// diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementInformation.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementInformation.cs index fa880e42ed..34832763b3 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementInformation.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementInformation.cs @@ -75,7 +75,7 @@ namespace ICSharpCode.WpfDesign /// /// Gets/sets the alignment of the resize thumb used to start the operation. /// - public PlacementAlignment ResizeThumbAlignment { get; set; } + public PlacementAlignment? ResizeThumbAlignment { get; set; } /// public override string ToString() diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs index 45940506e6..2f95f1b266 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs @@ -233,33 +233,33 @@ namespace ICSharpCode.WpfDesign #region IKeyBindingService /// - /// Service that handles all the key bindings in the designer. - /// - public interface IKeyBindingService - { - /// - /// Gets the object to which the bindings are being applied - /// - object Owner { get; } + /// Service that handles all the key bindings in the designer. + /// + public interface IKeyBindingService + { + /// + /// Gets the object to which the bindings are being applied + /// + object Owner { get; } - /// - /// Register with . - /// - /// The binding to be applied. - void RegisterBinding(KeyBinding binding); + /// + /// Register with . + /// + /// The binding to be applied. + void RegisterBinding(KeyBinding binding); - /// - /// De-register with . - /// - /// The binding to be applied. - void DeregisterBinding(KeyBinding binding); + /// + /// De-register with . + /// + /// The binding to be applied. + void DeregisterBinding(KeyBinding binding); - /// - /// Gets binding for the corresponding gesture otherwise returns null. - /// - /// The keyboard gesture requested. - KeyBinding GetBinding(KeyGesture gesture); - } - + /// + /// Gets binding for the corresponding gesture otherwise returns null. + /// + /// The keyboard gesture requested. + KeyBinding GetBinding(KeyGesture gesture); + } + #endregion } diff --git a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj index d1e99f1ec2..cdb4f112ec 100644 --- a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj +++ b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj @@ -154,6 +154,7 @@ + @@ -219,7 +220,6 @@ - @@ -252,6 +252,7 @@ + @@ -400,7 +401,6 @@ Code - diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs index cba1708045..8692456254 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs @@ -43,6 +43,7 @@ namespace ICSharpCode.PackageManagement.Design public void FireSolutionClosedEvent(ISolution solution) { + OpenSolution = null; if (SolutionClosed != null) { SolutionClosed(this, new SolutionEventArgs(solution)); } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/ISettingsFactory.cs b/src/AddIns/Misc/PackageManagement/Project/Src/ISettingsFactory.cs deleted file mode 100644 index 9167745e5c..0000000000 --- a/src/AddIns/Misc/PackageManagement/Project/Src/ISettingsFactory.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -using System; -using NuGet; - -namespace ICSharpCode.PackageManagement -{ - public interface ISettingsFactory - { - ISettings CreateSettings(string directory); - } -} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/ISettingsProvider.cs b/src/AddIns/Misc/PackageManagement/Project/Src/ISettingsProvider.cs new file mode 100644 index 0000000000..8a0a210b61 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/ISettingsProvider.cs @@ -0,0 +1,14 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using NuGet; + +namespace ICSharpCode.PackageManagement +{ + public interface ISettingsProvider + { + event EventHandler SettingsChanged; + ISettings LoadSettings(); + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementOptions.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementOptions.cs index 6200ce200b..655d9be0d1 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementOptions.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementOptions.cs @@ -35,15 +35,17 @@ namespace ICSharpCode.PackageManagement ObservableCollection recentPackages; PackageRestoreConsent packageRestoreConsent; - public PackageManagementOptions(Properties properties, ISettings settings) + public PackageManagementOptions( + Properties properties, + ISettingsProvider settingsProvider) { this.properties = properties; - registeredPackageSourceSettings = new RegisteredPackageSourceSettings(settings); - packageRestoreConsent = new PackageRestoreConsent(settings); + registeredPackageSourceSettings = new RegisteredPackageSourceSettings(settingsProvider); + packageRestoreConsent = new PackageRestoreConsent(settingsProvider.LoadSettings()); } public PackageManagementOptions(Properties properties) - : this(properties, Settings.LoadDefaultSettings(null, null, null)) + : this(properties, new SettingsProvider()) { } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs index 8a574eaa0e..a1fe7eb4f6 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementServices.cs @@ -42,7 +42,7 @@ namespace ICSharpCode.PackageManagement static PackageManagementServices() { options = new PackageManagementOptions(); - packageRepositoryCache = new PackageRepositoryCache(options.PackageSources, options.RecentPackages); + packageRepositoryCache = new PackageRepositoryCache(options); userAgentGenerator = new UserAgentGeneratorForRepositoryRequests(packageRepositoryCache); registeredPackageRepositories = new RegisteredPackageRepositories(packageRepositoryCache, options); diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryCache.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryCache.cs index 72c2212373..3500715fd6 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryCache.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageRepositoryCache.cs @@ -26,30 +26,36 @@ namespace ICSharpCode.PackageManagement public class PackageRepositoryCache : IPackageRepositoryCache, IPackageRepositoryFactoryEvents { ISharpDevelopPackageRepositoryFactory factory; - RegisteredPackageSources registeredPackageSources; + RegisteredPackageSources packageSources; + PackageManagementOptions options; IList recentPackages; IRecentPackageRepository recentPackageRepository; ConcurrentDictionary repositories = new ConcurrentDictionary(); public PackageRepositoryCache( - ISharpDevelopPackageRepositoryFactory factory, - RegisteredPackageSources registeredPackageSources, - IList recentPackages) + PackageManagementOptions options, + ISharpDevelopPackageRepositoryFactory factory) { + this.options = options; this.factory = factory; - this.registeredPackageSources = registeredPackageSources; - this.recentPackages = recentPackages; + this.recentPackages = options.RecentPackages; } - + + public PackageRepositoryCache(PackageManagementOptions options) + : this( + options, + new SharpDevelopPackageRepositoryFactory()) + { + } + public PackageRepositoryCache( - RegisteredPackageSources registeredPackageSources, + RegisteredPackageSources packageSources, IList recentPackages) - : this( - new SharpDevelopPackageRepositoryFactory(), - registeredPackageSources, - recentPackages) { + this.factory = new SharpDevelopPackageRepositoryFactory(); + this.recentPackages = recentPackages; + this.packageSources = packageSources; } public event EventHandler RepositoryCreated; @@ -102,10 +108,19 @@ namespace ICSharpCode.PackageManagement IEnumerable CreateAllEnabledRepositories() { - foreach (PackageSource source in registeredPackageSources.GetEnabledPackageSources()) { + foreach (PackageSource source in PackageSources.GetEnabledPackageSources()) { yield return CreateRepository(source.Source); } } + + RegisteredPackageSources PackageSources { + get { + if (packageSources != null) { + return packageSources; + } + return options.PackageSources; + } + } public IPackageRepository CreateAggregateRepository(IEnumerable repositories) { diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/RegisteredPackageSourceSettings.cs b/src/AddIns/Misc/PackageManagement/Project/Src/RegisteredPackageSourceSettings.cs index ba79003f2a..2a6aae2c30 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/RegisteredPackageSourceSettings.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/RegisteredPackageSourceSettings.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; +using ICSharpCode.SharpDevelop.Project; using NuGet; namespace ICSharpCode.PackageManagement @@ -35,20 +36,32 @@ namespace ICSharpCode.PackageManagement new PackageSource("(Aggregate source)", "All"); ISettings settings; + ISettingsProvider settingsProvider; PackageSource defaultPackageSource; RegisteredPackageSources packageSources; PackageSource activePackageSource; - public RegisteredPackageSourceSettings(ISettings settings) - : this(settings, RegisteredPackageSources.DefaultPackageSource) + public RegisteredPackageSourceSettings(ISettingsProvider settingsProvider) + : this(settingsProvider, RegisteredPackageSources.DefaultPackageSource) { } - public RegisteredPackageSourceSettings(ISettings settings, PackageSource defaultPackageSource) + public RegisteredPackageSourceSettings( + ISettingsProvider settingsProvider, + PackageSource defaultPackageSource) { - this.settings = settings; + this.settingsProvider = settingsProvider; this.defaultPackageSource = defaultPackageSource; + + settings = settingsProvider.LoadSettings(); + ReadActivePackageSource(); + RegisterSolutionEvents(); + } + + void RegisterSolutionEvents() + { + settingsProvider.SettingsChanged += SettingsChanged; } void ReadActivePackageSource() @@ -176,5 +189,20 @@ namespace ICSharpCode.PackageManagement { settings.SetValue(ActivePackageSourceSectionName, activePackageSource.Key, activePackageSource.Value); } + + void SettingsChanged(object sender, EventArgs e) + { + settings = settingsProvider.LoadSettings(); + ReadActivePackageSource(); + ResetPackageSources(); + } + + void ResetPackageSources() + { + if (packageSources != null) { + packageSources.CollectionChanged -= PackageSourcesChanged; + packageSources = null; + } + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/SettingsProvider.cs b/src/AddIns/Misc/PackageManagement/Project/Src/SettingsProvider.cs new file mode 100644 index 0000000000..7dfa1a5a25 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/SettingsProvider.cs @@ -0,0 +1,62 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.IO; +using ICSharpCode.SharpDevelop.Project; +using NuGet; + +namespace ICSharpCode.PackageManagement +{ + public class SettingsProvider : ISettingsProvider + { + public static Func LoadDefaultSettings + = Settings.LoadDefaultSettings; + + IPackageManagementProjectService projectService; + + public SettingsProvider() + : this(PackageManagementServices.ProjectService) + { + } + + public SettingsProvider(IPackageManagementProjectService projectService) + { + this.projectService = projectService; + projectService.SolutionOpened += OnSettingsChanged; + projectService.SolutionClosed += OnSettingsChanged; + } + + public event EventHandler SettingsChanged; + + void OnSettingsChanged(object sender, SolutionEventArgs e) + { + if (SettingsChanged != null) { + SettingsChanged(this, new EventArgs()); + } + } + + public ISettings LoadSettings() + { + return LoadSettings(GetSolutionDirectory()); + } + + string GetSolutionDirectory() + { + ISolution solution = projectService.OpenSolution; + if (solution != null) { + return Path.Combine(solution.Directory, ".nuget"); + } + return null; + } + + ISettings LoadSettings(string directory) + { + if (directory == null) { + return LoadDefaultSettings(null, null, null); + } + + return LoadDefaultSettings(new PhysicalFileSystem(directory), null, null); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj index 6dab719b65..fb3cc11e72 100644 --- a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj +++ b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj @@ -176,7 +176,6 @@ - @@ -195,6 +194,7 @@ + diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageRepositoryFactory.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageRepositoryFactory.cs index 1f5733638c..81e18deefa 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageRepositoryFactory.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageRepositoryFactory.cs @@ -38,6 +38,13 @@ namespace PackageManagement.Tests.Helpers public Dictionary FakePackageRepositories = new Dictionary(); + public FakePackageRepositoryFactory() + { + CreateAggregrateRepositoryAction = (repositories) => { + return FakeAggregateRepository; + }; + } + public IPackageRepository CreateRepository(string packageSource) { PackageSourcesPassedToCreateRepository.Add(packageSource); @@ -84,16 +91,17 @@ namespace PackageManagement.Tests.Helpers } public IEnumerable RepositoriesPassedToCreateAggregateRepository; + public Func, IPackageRepository> CreateAggregrateRepositoryAction; public IPackageRepository CreateAggregateRepository(IEnumerable repositories) { RepositoriesPassedToCreateAggregateRepository = repositories; - return FakeAggregateRepository; + return CreateAggregrateRepositoryAction(repositories); } public FakePackageRepository AddFakePackageRepositoryForPackageSource(string source) { - var repository = new FakePackageRepository(); + var repository = new FakePackageRepository(); FakePackageRepositories.Add(source, repository); return repository; } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/OneRegisteredPackageSourceHelper.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/OneRegisteredPackageSourceHelper.cs index 12d7da261c..f19e5545ed 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/OneRegisteredPackageSourceHelper.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/OneRegisteredPackageSourceHelper.cs @@ -26,11 +26,14 @@ namespace PackageManagement.Tests.Helpers { public class OneRegisteredPackageSourceHelper { - public RegisteredPackageSources RegisteredPackageSources; public TestablePackageManagementOptions Options; public FakeSettings FakeSettings; public PackageSource PackageSource = new PackageSource("http://sharpdevelop.com", "Test Package Source"); + public RegisteredPackageSources RegisteredPackageSources { + get { return Options.PackageSources; } + } + public OneRegisteredPackageSourceHelper() { CreateOneRegisteredPackageSource(); @@ -41,7 +44,6 @@ namespace PackageManagement.Tests.Helpers Properties properties = new Properties(); Options = new TestablePackageManagementOptions(); FakeSettings = Options.FakeSettings; - RegisteredPackageSources = Options.PackageSources; AddOnePackageSource(); } @@ -58,7 +60,7 @@ namespace PackageManagement.Tests.Helpers } public void AddTwoPackageSources() - { + { AddOnePackageSource(); var packageSource = new PackageSource("http://second.codeplex.com", "second"); RegisteredPackageSources.Add(packageSource); diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestablePackageManagementOptions.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestablePackageManagementOptions.cs index f454689290..c892b9f3b7 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestablePackageManagementOptions.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestablePackageManagementOptions.cs @@ -27,17 +27,35 @@ namespace PackageManagement.Tests.Helpers { public Properties Properties; public FakeSettings FakeSettings; + public FakePackageManagementProjectService ProjectService; public TestablePackageManagementOptions() - : this(new Properties(), new FakeSettings()) + : this(new Properties(), new FakeSettings(), new FakePackageManagementProjectService()) { } - public TestablePackageManagementOptions(Properties properties, FakeSettings fakeSettings) - : base(properties, fakeSettings) + public TestablePackageManagementOptions( + Properties properties, + FakeSettings fakeSettings, + FakePackageManagementProjectService projectService) + : base(properties, CreateSettingsProvider(fakeSettings, projectService)) { this.Properties = properties; this.FakeSettings = fakeSettings; + this.ProjectService = projectService; + } + + public static void ChangeSettingsReturnedBySettingsProvider(FakeSettings settings) + { + SettingsProvider.LoadDefaultSettings = (fileSystem, configFile, machineSettings) => { + return settings; + }; + } + + public static SettingsProvider CreateSettingsProvider(FakeSettings fakeSettings, FakePackageManagementProjectService projectService) + { + ChangeSettingsReturnedBySettingsProvider(fakeSettings); + return new SettingsProvider(projectService); } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementOptionsTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementOptionsTests.cs index b5673a5a41..29a111a445 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementOptionsTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementOptionsTests.cs @@ -36,6 +36,8 @@ namespace PackageManagement.Tests Properties properties; PackageManagementOptions options; FakeSettings fakeSettings; + SettingsProvider settingsProvider; + FakePackageManagementProjectService projectService; void CreateOptions() { @@ -63,12 +65,26 @@ namespace PackageManagement.Tests void CreateOptions(FakeSettings fakeSettings) { CreateProperties(); - options = new PackageManagementOptions(properties, fakeSettings); + CreateSettingsProvider(fakeSettings); + options = new PackageManagementOptions(properties, settingsProvider); + } + + void CreateSettingsProvider(FakeSettings fakeSettings) + { + projectService = new FakePackageManagementProjectService(); + settingsProvider = TestablePackageManagementOptions.CreateSettingsProvider(fakeSettings, projectService); + } + + void ChangeSettingsReturnedBySettingsProvider() + { + fakeSettings = new FakeSettings(); + TestablePackageManagementOptions.ChangeSettingsReturnedBySettingsProvider(fakeSettings); } void CreateOptions(Properties properties, FakeSettings fakeSettings) { - options = new PackageManagementOptions(properties, fakeSettings); + CreateSettingsProvider(fakeSettings); + options = new PackageManagementOptions(properties, settingsProvider); } void SaveOptions() @@ -88,6 +104,18 @@ namespace PackageManagement.Tests fakeSettings.SetPackageRestoreSetting(true); } + void OpenSolution() + { + var helper = new SolutionHelper(@"d:\projects\MyProject\MySolution.sln"); + projectService.FireSolutionOpenedEvent(helper.MSBuildSolution); + } + + void CloseSolution() + { + var helper = new SolutionHelper(@"d:\projects\MyProject\MySolution.sln"); + projectService.FireSolutionClosedEvent(helper.MSBuildSolution); + } + [Test] public void PackageSources_OnePackageSourceInSettings_ContainsSinglePackageSourceFromSettings() { @@ -465,5 +493,88 @@ namespace PackageManagement.Tests KeyValuePair keyValuePair = fakeSettings.GetValuePassedToSetValueForPackageRestoreSection(); Assert.AreEqual("False", keyValuePair.Value); } + + [Test] + public void PackageSources_SolutionOpenedAfterInitialPackageSourcesLoaded_ContainsPackageSourceFromSolutionSpecificSettings() + { + CreateSettings(); + var packageSource = new PackageSource("http://codeplex.com", "Test"); + fakeSettings.AddFakePackageSource(packageSource); + CreateOptions(fakeSettings); + RegisteredPackageSources initialSources = options.PackageSources; + var expectedInitialSources = new List(); + expectedInitialSources.Add(packageSource); + ChangeSettingsReturnedBySettingsProvider(); + packageSource = new PackageSource("http://codeplex.com", "Test"); + fakeSettings.AddFakePackageSource(packageSource); + var expectedSources = new List(); + expectedSources.Add(packageSource); + packageSource = new PackageSource("http://nuget.org", "ProjectSource"); + fakeSettings.AddFakePackageSource(packageSource); + expectedSources.Add(packageSource); + OpenSolution(); + + RegisteredPackageSources actualSources = options.PackageSources; + + Assert.AreEqual(expectedInitialSources, initialSources); + Assert.AreEqual(expectedSources, actualSources); + } + + [Test] + public void PackageSources_SolutionClosedAfterInitialPackageSourcesLoaded_PackageSourcesReloaded() + { + CreateSettings(); + var packageSource = new PackageSource("http://codeplex.com", "Test"); + fakeSettings.AddFakePackageSource(packageSource); + var expectedInitialSources = new List(); + expectedInitialSources.Add(packageSource); + packageSource = new PackageSource("http://nuget.org", "ProjectSource"); + fakeSettings.AddFakePackageSource(packageSource); + expectedInitialSources.Add(packageSource); + OpenSolution(); + CreateOptions(fakeSettings); + RegisteredPackageSources initialSources = options.PackageSources; + ChangeSettingsReturnedBySettingsProvider(); + packageSource = new PackageSource("http://codeplex.com", "Test"); + fakeSettings.AddFakePackageSource(packageSource); + var expectedSources = new List(); + expectedSources.Add(packageSource); + CloseSolution(); + + RegisteredPackageSources actualSources = options.PackageSources; + + Assert.AreEqual(expectedInitialSources, initialSources); + Assert.AreEqual(expectedSources, actualSources); + } + + [Test] + public void PackageSources_SolutionClosedAfterInitialPackageSourcesLoaded_ActivePackageSourceReloaded() + { + CreateSettings(); + var packageSource = new PackageSource("http://codeplex.com", "Test"); + fakeSettings.AddFakePackageSource(packageSource); + var expectedInitialSources = new List(); + expectedInitialSources.Add(packageSource); + var initialActivePackageSource = new PackageSource("http://nuget.org", "ProjectSource"); + fakeSettings.AddFakePackageSource(initialActivePackageSource); + fakeSettings.SetFakeActivePackageSource(initialActivePackageSource); + expectedInitialSources.Add(initialActivePackageSource); + OpenSolution(); + CreateOptions(fakeSettings); + RegisteredPackageSources actualInitialPackageSources = options.PackageSources; + PackageSource actualInitialActivePackageSource = options.ActivePackageSource; + ChangeSettingsReturnedBySettingsProvider(); + var expectedActivePackageSource = new PackageSource("http://codeplex.com", "Test"); + fakeSettings.SetFakeActivePackageSource(expectedActivePackageSource); + fakeSettings.AddFakePackageSource(expectedActivePackageSource); + CloseSolution(); + + PackageSource actualSource = options.ActivePackageSource; + + Assert.AreEqual(initialActivePackageSource, actualInitialActivePackageSource); + Assert.AreEqual(expectedActivePackageSource, actualSource); + Assert.AreEqual(expectedInitialSources, actualInitialPackageSources); + Assert.AreEqual(new PackageSource[] { expectedActivePackageSource }, options.PackageSources); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementOptionsViewModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementOptionsViewModelTests.cs index 87ec062600..12b6e35c5d 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementOptionsViewModelTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementOptionsViewModelTests.cs @@ -50,8 +50,10 @@ namespace PackageManagement.Tests void CreateOptions() { var properties = new Properties(); + var projectService = new FakePackageManagementProjectService(); fakeSettings = new FakeSettings(); - options = new PackageManagementOptions(properties, fakeSettings); + SettingsProvider settingsProvider = TestablePackageManagementOptions.CreateSettingsProvider(fakeSettings, projectService); + options = new PackageManagementOptions(properties, settingsProvider); } void EnablePackageRestoreInOptions() diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/PackageRepositoryCacheTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/PackageRepositoryCacheTests.cs index d559526161..0c33e09728 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/PackageRepositoryCacheTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/PackageRepositoryCacheTests.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using System.IO.Packaging; +using System.Linq; using ICSharpCode.PackageManagement; using ICSharpCode.PackageManagement.Design; using NuGet; @@ -52,9 +53,7 @@ namespace PackageManagement.Tests { nuGetPackageSource = new PackageSource("http://nuget.org", "NuGet"); fakePackageRepositoryFactory = new FakePackageRepositoryFactory(); - RegisteredPackageSources packageSources = packageSourcesHelper.Options.PackageSources; - IList recentPackages = packageSourcesHelper.Options.RecentPackages; - cache = new PackageRepositoryCache(fakePackageRepositoryFactory, packageSources, recentPackages); + cache = new PackageRepositoryCache(packageSourcesHelper.Options, fakePackageRepositoryFactory); } FakePackageRepository AddFakePackageRepositoryForPackageSource(string source) @@ -395,5 +394,38 @@ namespace PackageManagement.Tests Assert.IsNull(eventArgs); } + + [Test] + public void CreateAggregateRepository_SolutionClosedAndEnabledPackageSourcesChangedAfterCacheCreated_AggregateRepositoryContainsCorrectEnabledPackageRepositories() + { + CreatePackageSources(); + packageSourcesHelper.AddTwoPackageSources("Source1", "Source2"); + CreateCacheUsingPackageSources(); + FakePackageRepository source1Repo = AddFakePackageRepositoryForPackageSource("Source1"); + FakePackageRepository source2Repo = AddFakePackageRepositoryForPackageSource("Source2"); + fakePackageRepositoryFactory.CreateAggregrateRepositoryAction = (repositories) => { + return new AggregateRepository (repositories); + }; + var initialAggregateRepository = cache.CreateAggregateRepository() as AggregateRepository; + var expectedInitialRepositories = new FakePackageRepository[] { + source1Repo, + source2Repo + }; + List actualInitialRepositories = initialAggregateRepository.Repositories.ToList(); + var solution = new SolutionHelper().MSBuildSolution; + packageSourcesHelper.Options.ProjectService.FireSolutionClosedEvent(solution); + packageSourcesHelper.Options.PackageSources.Clear(); + packageSourcesHelper.Options.PackageSources.Add(new PackageSource ("Source3")); + FakePackageRepository source3Repo = AddFakePackageRepositoryForPackageSource("Source3"); + var expectedRepositories = new FakePackageRepository[] { + source3Repo + }; + + var aggregateRepository = cache.CreateAggregateRepository() as AggregateRepository; + List actualRepositories = aggregateRepository.Repositories.ToList(); + + CollectionAssert.AreEqual(expectedInitialRepositories, actualInitialRepositories); + CollectionAssert.AreEqual(expectedRepositories, actualRepositories); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/SettingsProviderTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/SettingsProviderTests.cs new file mode 100644 index 0000000000..10c2efd9fe --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/SettingsProviderTests.cs @@ -0,0 +1,80 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.PackageManagement; +using ICSharpCode.PackageManagement.Design; +using NuGet; +using NUnit.Framework; +using PackageManagement.Tests.Helpers; + +namespace PackageManagement.Tests +{ + [TestFixture] + public class SettingsProviderTests + { + SettingsProvider settingsProvider; + FakeSettings fakeSettings; + FakePackageManagementProjectService projectService; + IFileSystem fileSystemUsedToLoadSettings; + string configFileUsedToLoadSettings; + IMachineWideSettings machinesettingsUsedToLoadSettings; + + [SetUp] + public void SetUp() + { + fakeSettings = new FakeSettings(); + projectService = new FakePackageManagementProjectService(); + SettingsProvider.LoadDefaultSettings = LoadDefaultSettings; + settingsProvider = new SettingsProvider(projectService); + } + + ISettings LoadDefaultSettings(IFileSystem fileSystem, string configFile, IMachineWideSettings machineSettings) + { + fileSystemUsedToLoadSettings = fileSystem; + configFileUsedToLoadSettings = configFile; + machinesettingsUsedToLoadSettings = machineSettings; + + return fakeSettings; + } + + void OpenSolution(string fileName) + { + var helper = new SolutionHelper(fileName); + projectService.OpenSolution = helper.MSBuildSolution; + } + + [TearDown] + public void TearDown() + { + // This resets SettingsProvider.LoadDefaultSettings. + TestablePackageManagementOptions.CreateSettingsProvider(fakeSettings, projectService); + } + + [Test] + public void LoadSettings_NoSolutionOpen_NullFileSystemAndNullConfigFileAndNullMachineSettingsUsed() + { + fileSystemUsedToLoadSettings = new FakeFileSystem(); + configFileUsedToLoadSettings = "configFile"; + + ISettings settings = settingsProvider.LoadSettings(); + + Assert.IsNull(fileSystemUsedToLoadSettings); + Assert.IsNull(configFileUsedToLoadSettings); + Assert.IsNull(machinesettingsUsedToLoadSettings); + Assert.AreEqual(fakeSettings, settings); + } + + [Test] + public void LoadSettings_SolutionOpen_FileSystemWithRootSetToSolutionDotNuGetDirectoryUsedToLoadSettings() + { + string fileName = @"d:\projects\MyProject\MyProject.sln"; + OpenSolution(fileName); + + ISettings settings = settingsProvider.LoadSettings(); + + Assert.AreEqual(@"d:\projects\MyProject\.nuget", fileSystemUsedToLoadSettings.Root); + Assert.AreEqual(fakeSettings, settings); + } + } +} diff --git a/src/Main/GlobalAssemblyInfo.cs.template b/src/Main/GlobalAssemblyInfo.cs.template index 796f82f16a..24cb65ee69 100644 --- a/src/Main/GlobalAssemblyInfo.cs.template +++ b/src/Main/GlobalAssemblyInfo.cs.template @@ -46,7 +46,7 @@ internal static class RevisionClass public const string Minor = "0"; public const string Build = "0"; public const string Revision = "$INSERTREVISION$"; - public const string VersionName = "Beta 3"; // "" is not valid for no version name, you have to use null if you don't want a version name (eg "Beta 1") + public const string VersionName = "Beta 4"; // "" is not valid for no version name, you have to use null if you don't want a version name (eg "Beta 1") public const string FullVersion = Major + "." + Minor + "." + Build + ".$INSERTREVISION$$INSERTBRANCHPOSTFIX$$INSERTVERSIONNAMEPOSTFIX$"; }