diff --git a/.gitignore b/.gitignore index defcc3fe2f..bd3b475b46 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,5 @@ bin/ /src/Main/GlobalAssemblyInfo.vb /src/AddIns/Misc/UsageDataCollector/UsageDataCollector.AddIn/AnalyticsMonitor.AppProperties.cs -/src/AddIns/Misc/PackageManagement/Packages/AvalonEdit/lib \ No newline at end of file +/src/AddIns/Misc/PackageManagement/Packages/AvalonEdit/lib +/packages/ diff --git a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/Commands/DomMenuCommand.cs b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/Commands/DomMenuCommand.cs index c58b7ea78a..3a065bb70c 100644 --- a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/Commands/DomMenuCommand.cs +++ b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/Commands/DomMenuCommand.cs @@ -41,16 +41,13 @@ namespace ICSharpCode.Profiler.AddIn.Commands if (name == null || c == null) return null; - if (name == ".ctor" || name == ".cctor") // Constructor - name = name.Replace('.', '#'); - - if (name.StartsWith("get_") || name.StartsWith("set_")) { + if (name.StartsWith("get_", StringComparison.Ordinal) || name.StartsWith("set_", StringComparison.Ordinal)) { // Property Getter or Setter name = name.Substring(4); IProperty prop = c.Properties.FirstOrDefault(p => p.Name == name); if (prop != null) return prop; - } else if (name.StartsWith("add_") || name.StartsWith("remove_")) { + } else if (name.StartsWith("add_", StringComparison.Ordinal) || name.StartsWith("remove_", StringComparison.Ordinal)) { name = name.Substring(4); IEvent ev = c.Events.FirstOrDefault(e => e.Name == name); if (ev != null) diff --git a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/Commands/GoToDefinition.cs b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/Commands/GoToDefinition.cs index a51ce45018..c23405d090 100644 --- a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/Commands/GoToDefinition.cs +++ b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/Commands/GoToDefinition.cs @@ -39,7 +39,7 @@ namespace ICSharpCode.Profiler.AddIn.Commands ITypeDefinition c = GetClassFromName(selectedItem.FullyQualifiedClassName); if (c != null) { IMember member = GetMemberFromName(c, selectedItem.MethodName, selectedItem.Parameters); - if (!member.Region.IsEmpty && !string.IsNullOrEmpty(member.Region.FileName)) { + if (member != null && !member.Region.IsEmpty && !string.IsNullOrEmpty(member.Region.FileName)) { FileName fn = new FileName(member.Region.FileName); SD.FileService.JumpToFilePosition(fn, member.Region.BeginLine, member.Region.BeginColumn); } diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs index f3bc043736..0dd30bc82a 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs @@ -127,7 +127,6 @@ namespace CSharpBinding.FormattingStrategy if ((e.PropertyName == "Parent") || (e.PropertyName == null)) { // All properties might have changed -> update everything cachedOptions = CreateCachedOptions(); - OnPropertyChanged(e.PropertyName); } else { // Some other property has changed, check if we have our own value for it if (!activeOptions.Contains(e.PropertyName)) { @@ -136,7 +135,6 @@ namespace CSharpBinding.FormattingStrategy if (propertyInfo != null) { var val = GetEffectiveOption(e.PropertyName); propertyInfo.SetValue(cachedOptions, val); - OnPropertyChanged(e.PropertyName); } } } @@ -265,14 +263,16 @@ namespace CSharpBinding.FormattingStrategy if (parentProperties == null) throw new ArgumentNullException("parentProperties"); - Properties formatProperties = parentProperties.NestedProperties("CSharpFormatting"); - if (formatProperties != null) { - foreach (var key in formatProperties.Keys) { - try { - object val = formatProperties.Get(key, (object) null); - SetOption(key, val); - } catch (Exception) { - // Silently ignore loading error, then this property will be "as parent" automatically + if (parentProperties.Contains("CSharpFormatting")) { + Properties formatProperties = parentProperties.NestedProperties("CSharpFormatting"); + if (formatProperties != null) { + foreach (var key in formatProperties.Keys) { + try { + object val = formatProperties.Get(key, (object)null); + SetOption(key, val); + } catch (Exception) { + // Silently ignore loading error, then this property will be "as parent" automatically + } } } } diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs index ef39be8a3d..f10b094d8e 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); @@ -284,7 +284,7 @@ namespace CSharpBinding.FormsDesigner return false; } - return oldType.ReflectionName != newType.BaseType; + return oldType.GetDefinition().ReflectionName != newType.BaseType; } string GenerateField(CodeMemberField newField) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpEventBindingService.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpEventBindingService.cs index 9144138095..b7c635c055 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpEventBindingService.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpEventBindingService.cs @@ -57,6 +57,8 @@ namespace CSharpBinding.FormsDesigner string GetComponentName(IComponent component) { string siteName = component.Site.Name; + if (GeneralOptionsPanel.GenerateVisualStudioStyleEventHandlers) + return siteName; return Char.ToUpper(siteName[0]) + siteName.Substring(1); } diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/SecondaryDisplayBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/SecondaryDisplayBinding.cs index dfa1dad641..ee4287e6bc 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/SecondaryDisplayBinding.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/SecondaryDisplayBinding.cs @@ -64,7 +64,8 @@ namespace CSharpBinding.FormsDesigner foreach (var baseType in c.GetNonInterfaceBaseTypes()) { var baseTypeName = baseType.FullName; if (baseTypeName == "System.Windows.Forms.Form" - || baseTypeName == "System.Windows.Forms.UserControl") + || baseTypeName == "System.Windows.Forms.UserControl" + || baseTypeName == "System.ComponentModel.Component") { return true; } diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml.cs index 56df385daa..e358b6c90c 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml.cs @@ -64,6 +64,7 @@ namespace CSharpBinding.OptionPanels internal partial class CSharpFormattingOptionPanel : OptionPanel { readonly CSharpFormattingOptionsPersistence persistenceHelper; + bool isDirty; public CSharpFormattingOptionPanel(CSharpFormattingOptionsPersistence persistenceHelper, bool allowPresets) { @@ -71,6 +72,7 @@ namespace CSharpBinding.OptionPanels throw new ArgumentNullException("persistenceHelper"); this.persistenceHelper = persistenceHelper; + this.isDirty = false; InitializeComponent(); formattingEditor.AllowPresets = allowPresets; @@ -79,12 +81,20 @@ namespace CSharpBinding.OptionPanels public override void LoadOptions() { base.LoadOptions(); - formattingEditor.OptionsContainer = persistenceHelper.StartEditing(); + formattingEditor.OptionsContainer = persistenceHelper.StartEditing(); + formattingEditor.OptionsContainer.PropertyChanged += ContainerPropertyChanged; + } + + void ContainerPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + isDirty = true; } public override bool SaveOptions() { - return persistenceHelper.Save() && base.SaveOptions(); + // Only save container, if some option really has changed + formattingEditor.OptionsContainer.PropertyChanged -= ContainerPropertyChanged; + return (!isDirty || persistenceHelper.Save()) && base.SaveOptions(); } } } \ No newline at end of file diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs index 9c4293e204..3e2c2dfe8f 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs @@ -122,15 +122,26 @@ namespace ICSharpCode.XamlBinding { if (context.ParseInformation == null) return EmptyList.Instance; + List result = new List(); AXmlElement last = context.ParentElement; ITextEditor editor = context.Editor; compilation = SD.ParserService.GetCompilationForFile(editor.FileName); IUnresolvedFile file = context.ParseInformation.UnresolvedFile; - var items = GetClassesFromContext(context); + + foreach (string item in XamlConst.GetAllowedItems(context)) { + result.Add(new XamlCompletionItem(item)); + } + IType rt = null; if (last != null) { + if (string.Equals(last.Prefix, context.XamlNamespacePrefix, StringComparison.OrdinalIgnoreCase)) { + if (string.Equals(last.LocalName, "Members", StringComparison.OrdinalIgnoreCase)) + return result; + if (string.Equals(last.LocalName, "Code", StringComparison.OrdinalIgnoreCase)) + return result; + } // If we have an element that is not a property or an incomplete // definition => interpret element as a type. XamlResolver resolver = new XamlResolver(compilation); @@ -172,6 +183,8 @@ namespace ICSharpCode.XamlBinding .ToList(); } + var items = GetClassesFromContext(context); + foreach (var ns in items) { foreach (ITypeDefinition td in ns.Value) { if (td.Kind != TypeKind.Class && (!includeAbstract || td.Kind != TypeKind.Interface)) @@ -198,15 +211,6 @@ namespace ICSharpCode.XamlBinding // result.Add(new XamlCodeCompletionItem(itemClass, last.Prefix)); // } - var xamlItems = XamlConst.XamlNamespaceAttributes.AsEnumerable(); - - if (XamlConst.EnableXaml2009) - xamlItems = XamlConst.XamlBuiltInTypes.Concat(xamlItems); - - foreach (string item in xamlItems) { - result.Add(new XamlCompletionItem(context.XamlNamespacePrefix + ":" + item)); - } - return result; } @@ -266,8 +270,11 @@ namespace ICSharpCode.XamlBinding string xamlPrefix = context.XamlNamespacePrefix; string xKey = string.IsNullOrEmpty(xamlPrefix) ? "" : xamlPrefix + ":"; - if (lastElement.Prefix == context.XamlNamespacePrefix && XamlConst.IsBuiltin(lastElement.LocalName)) - return EmptyList.Instance; + if (context.Description == XamlContextDescription.InTag) + list.AddRange(XamlConst.GetAllowedItems(context).Select(item => new XamlCompletionItem(item))); + + if (string.Equals(lastElement.Prefix, context.XamlNamespacePrefix, StringComparison.OrdinalIgnoreCase) && XamlConst.IsBuiltin(lastElement.LocalName)) + return list; if (lastElement.LocalName.EndsWith(".", StringComparison.OrdinalIgnoreCase) || context.PressedKey == '.') { if (type.Kind == TypeKind.Unknown) @@ -279,16 +286,9 @@ namespace ICSharpCode.XamlBinding } AddAttachedProperties(type.GetDefinition(), list); } else { - if (type.Kind == TypeKind.Unknown) { - list.Add(new XamlCompletionItem(xKey + "Uid")); - } else { + if (type.Kind != TypeKind.Unknown) { AddAttributes(type, list, includeEvents); list.AddRange(GetListOfAttached(context, null, includeEvents, true)); - list.AddRange( - XamlConst.XamlNamespaceAttributes - .Where(localName => XamlConst.IsAttributeAllowed(context.InRoot, localName)) - .Select(item => new XamlCompletionItem(xKey + item)) - ); } } @@ -384,11 +384,11 @@ namespace ICSharpCode.XamlBinding ITextEditor editor = context.Editor; compilation = SD.ParserService.GetCompilationForFile(editor.FileName); + string xamlPrefix = context.XamlNamespacePrefix; + string xKey = string.IsNullOrEmpty(xamlPrefix) ? "" : xamlPrefix + ":"; + if (type.Name == typeof(System.Nullable<>).Name) { - string nullExtensionName = "Null"; - if (!string.IsNullOrEmpty(context.XamlNamespacePrefix)) - nullExtensionName = context.XamlNamespacePrefix + ":" + nullExtensionName; - yield return new XamlCompletionItem("{" + nullExtensionName + "}"); + yield return new XamlCompletionItem("{" + xKey + "Null}"); type = type.TypeArguments.FirstOrDefault(); if (type == null) yield break; } @@ -397,6 +397,18 @@ namespace ICSharpCode.XamlBinding if (definition == null) yield break; + definition.IsCollectionType(); + + switch (definition.KnownTypeCode) { + case KnownTypeCode.Array: + case KnownTypeCode.ICollection: + case KnownTypeCode.ICollectionOfT: + case KnownTypeCode.IEnumerable: + case KnownTypeCode.IEnumerableOfT: + yield return new XamlCompletionItem("{" + xKey + "Array}"); + break; + } + switch (definition.Kind) { case TypeKind.Class: IType typeName; diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs index 4d848c3002..479dac1373 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs @@ -398,6 +398,17 @@ namespace ICSharpCode.XamlBinding return thisValue.GetAllBaseTypeDefinitions().Any(t => t.FullName == "System.Collections.IList"); } + public static bool Implements(this IType thisValue, IType interfaceType) + { + if (thisValue == null) + throw new ArgumentNullException("thisValue"); + if (interfaceType == null) + throw new ArgumentNullException("interfaceType"); + if (interfaceType.Kind != TypeKind.Interface) + throw new ArgumentException("must be TypeKind.Interface", "interfaceType"); + return thisValue.GetAllBaseTypes().Any(t => t.Equals(interfaceType)); + } + public static bool HasAttached(this ITypeDefinition thisValue, bool lookForProperties, bool lookForEvents) { if (!lookForProperties && !lookForEvents) diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs index 1138d7fe84..54b80fb5de 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 == null || 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/BackendBindings/XamlBinding/XamlBinding/XamlConst.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlConst.cs index af660c9d54..6180233a48 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlConst.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlConst.cs @@ -20,6 +20,11 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Windows; +using System.Xml.Serialization; +using ICSharpCode.NRefactory.TypeSystem; +using ICSharpCode.NRefactory.Semantics; +using ICSharpCode.SharpDevelop; namespace ICSharpCode.XamlBinding { @@ -28,33 +33,22 @@ namespace ICSharpCode.XamlBinding /// public static class XamlConst { - public const bool EnableXaml2009 = true; - // [XAML 2009] public static readonly List XamlBuiltInTypes = new List { "Object", "Boolean", "Char", "String", "Decimal", "Single", "Double", "Int16", "Int32", "Int64", "TimeSpan", "Uri", "Byte", "Array", "List", "Dictionary", - // This is no built in type, but a markup extension "Reference" }; public static readonly ReadOnlyCollection XamlNamespaceAttributes = new List { - "Class", "ClassModifier", "FieldModifier", "Name", "Subclass", "TypeArguments", "Uid", "Key" - }.AsReadOnly(); - - public static readonly ReadOnlyCollection RootOnlyElements = new List { - "Class", "ClassModifier", "Subclass" - }.AsReadOnly(); - - public static readonly ReadOnlyCollection ChildOnlyElements = new List { - "FieldModifier" + "Class", "ClassModifier", "FieldModifier", "Name", "Subclass", "TypeArguments", "Uid", "Key", "Shared" }.AsReadOnly(); /// /// values: http://schemas.microsoft.com/winfx/2006/xaml/presentation, /// http://schemas.microsoft.com/netfx/2007/xaml/presentation /// - public static readonly string[] WpfXamlNamespaces = new[] { + public static readonly string[] WpfXamlNamespaces = { "http://schemas.microsoft.com/winfx/2006/xaml/presentation", "http://schemas.microsoft.com/netfx/2007/xaml/presentation" }; @@ -88,11 +82,86 @@ namespace ICSharpCode.XamlBinding } /// - /// Returns true if the given attribute is allowed in the current element. + /// Returns the list of allow XAML2009 completion items. /// - public static bool IsAttributeAllowed(bool inRoot, string localName) + public static IEnumerable GetAllowedItems(XamlCompletionContext context) { - return inRoot ? !ChildOnlyElements.Contains(localName) : !RootOnlyElements.Contains(localName); + string xamlPrefix = context.XamlNamespacePrefix; + string xKey = string.IsNullOrEmpty(xamlPrefix) ? "" : xamlPrefix + ":"; + var compilation = SD.ParserService.GetCompilationForFile(context.Editor.FileName); + var resolver = new XamlAstResolver(compilation, context.ParseInformation); + // TODO : add support for x:Key as attribute element (XAML 2009 only) + + switch (context.Description) { + case XamlContextDescription.AtTag: + if (context.ParentElement != null && string.Equals(context.ParentElement.Name, xKey + "Members", StringComparison.OrdinalIgnoreCase)) { + yield return xKey + "Member"; + yield return xKey + "Property"; + } else if (context.ParentElement == context.RootElement && context.RootElement.Attributes.Any(attr => string.Equals(attr.Name, xKey + "Class", StringComparison.OrdinalIgnoreCase))) { + yield return xKey + "Code"; + yield return xKey + "Members"; + } else { + if (context.ParentElement != null && string.Equals(context.ParentElement.Name, xKey + "Code", StringComparison.OrdinalIgnoreCase)) + yield break; + yield return xKey + "Array"; + yield return xKey + "Boolean"; + yield return xKey + "Byte"; + yield return xKey + "Char"; + yield return xKey + "Decimal"; + yield return xKey + "Dictionary"; + yield return xKey + "Double"; + yield return xKey + "Int16"; + yield return xKey + "Int32"; + yield return xKey + "Int64"; + yield return xKey + "List"; + yield return xKey + "Object"; + yield return xKey + "Reference"; + yield return xKey + "Single"; + yield return xKey + "String"; + yield return xKey + "TimeSpan"; + yield return xKey + "Uri"; + if (context.RootElement.Attributes.Any(attr => string.Equals(attr.Name, xKey + "Class", StringComparison.OrdinalIgnoreCase))) + yield return xKey + "Members"; + } + break; + case XamlContextDescription.InTag: + yield return xKey + "Uid"; + if (context.InRoot) { + yield return xKey + "Class"; + yield return xKey + "ClassModifier"; + yield return xKey + "Subclass"; + yield return xKey + "Name"; + } else { + var resourceDictionaryType = compilation.FindType(typeof(ResourceDictionary)); + if (context.ActiveElement != null && string.Equals(context.ActiveElement.Name, xKey + "Array", StringComparison.OrdinalIgnoreCase)) { + yield return "Type"; + } else if (context.ActiveElement != null && string.Equals(context.ActiveElement.Name, xKey + "Member", StringComparison.OrdinalIgnoreCase)) { + yield return "Name"; + } else if (context.ActiveElement != null && string.Equals(context.ActiveElement.Name, xKey + "Property", StringComparison.OrdinalIgnoreCase)) { + yield return "Name"; + yield return "Type"; + } else if (context.RootElement.Attributes.Any(attr => string.Equals(attr.Name, xKey + "Class", StringComparison.OrdinalIgnoreCase))) { + yield return xKey + "FieldModifier"; + yield return xKey + "Name"; + } else { + yield return xKey + "Name"; + } + + if (context.ParentElement != null) { + var rr = resolver.ResolveElement(context.ParentElement); + if (rr != null) { + if (rr.Type.Equals(resourceDictionaryType)) { + yield return xKey + "Key"; + yield return xKey + "Shared"; + } else if (rr.Type.TypeParameterCount > 0) { + yield return xKey + "TypeArguments"; + } + } + } + } + break; + } + yield break; } } } diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs index 8c94a8fe33..8b4829eb6f 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs @@ -94,6 +94,7 @@ namespace ICSharpCode.XamlBinding { public AXmlElement ActiveElement { get; set; } public AXmlElement ParentElement { get; set; } + public AXmlElement RootElement { get; set; } public ReadOnlyCollection Ancestors { get; set; } public AXmlAttribute Attribute { get; set; } public AttributeValue AttributeValue { get; set; } @@ -131,6 +132,7 @@ namespace ICSharpCode.XamlBinding this.AttributeValue = context.AttributeValue; this.Description = context.Description; this.ParentElement = context.ParentElement; + this.RootElement = context.RootElement; this.ParseInformation = context.ParseInformation; this.RawAttributeValue = context.RawAttributeValue; this.ValueStartOffset = context.ValueStartOffset; diff --git a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContextResolver.cs b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContextResolver.cs index 78092c4ed0..9e53df2407 100644 --- a/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContextResolver.cs +++ b/src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContextResolver.cs @@ -59,6 +59,7 @@ namespace ICSharpCode.XamlBinding string xamlNamespacePrefix = string.Empty; var item = currentData; + AXmlElement root = null; while (item != document) { if (item is AXmlElement) { @@ -78,8 +79,11 @@ namespace ICSharpCode.XamlBinding xamlNamespacePrefix = attr.LocalName; } - if (!wasAXmlElement && item.Parent is AXmlDocument) - isRoot = true; + if (element.Parent is AXmlDocument) { + root = element; + if (!wasAXmlElement) + isRoot = true; + } wasAXmlElement = true; } @@ -91,7 +95,7 @@ namespace ICSharpCode.XamlBinding AXmlElement active = null; AXmlElement parent = null; - + if (currentData is AXmlAttribute) { AXmlAttribute a = currentData as AXmlAttribute; int valueStartOffset = a.ValueSegment.Offset + 1; @@ -140,6 +144,7 @@ namespace ICSharpCode.XamlBinding Description = description, ActiveElement = active, ParentElement = parent, + RootElement = root, Ancestors = ancestors.AsReadOnly(), Attribute = xAttribute, InRoot = isRoot, diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/XmlDoc/XmlDocTooltipProvider.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/XmlDoc/XmlDocTooltipProvider.cs index 44c4afb430..ba0ea7ef2b 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/XmlDoc/XmlDocTooltipProvider.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/XmlDoc/XmlDocTooltipProvider.cs @@ -80,6 +80,17 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc base.OnLostKeyboardFocus(e); this.IsOpen = false; } + + protected override void OnMouseLeave(MouseEventArgs e) + { + base.OnMouseLeave(e); + // When the mouse is over the popup, it is possible for SharpDevelop to be minimized, + // or moved into the background, and yet the popup stays open. + // We don't have a good method here to check whether the mouse moved back into the text area + // or somewhere else, so we'll just close the popup. + if (CloseWhenMouseMovesAway) + this.IsOpen = false; + } } object CreateTooltip(IType type) diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/FormKeyHandler.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/FormKeyHandler.cs index 5d3b29254a..97b6f7fadd 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/FormKeyHandler.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/FormKeyHandler.cs @@ -24,6 +24,7 @@ using System.ComponentModel.Design; using System.Reflection; using System.Windows.Forms; using System.Windows.Forms.Design; +using System.Linq; using ICSharpCode.Core; using ICSharpCode.SharpDevelop; @@ -134,6 +135,16 @@ namespace ICSharpCode.FormsDesigner selectionService.SetSelectedComponents(components); } return true; + } else if (keyPressed == Keys.Escape) { + ISelectionService selectionService = (ISelectionService)formDesigner.Host.GetService(typeof(ISelectionService)); + ICollection components = selectionService.GetSelectedComponents(); + if (components.Count == 1) { + Control ctrl = components.OfType().FirstOrDefault(); + if (ctrl != null && ctrl.Parent != null) { + selectionService.SetSelectedComponents(new IComponent[] { ctrl.Parent }, SelectionTypes.Primary); + } + } + return true; } return false; diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs index 0a5ba978a3..48fee4dbe8 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs @@ -368,8 +368,7 @@ namespace ICSharpCode.WpfDesign.Designer void DesignPanel_KeyDown(object sender, KeyEventArgs e) { - if (e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up || e.Key == Key.Down) - { + if (e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up || e.Key == Key.Down) { e.Handled = true; if (placementOp == null) { @@ -379,32 +378,38 @@ namespace ICSharpCode.WpfDesign.Designer } - dx += (e.Key == Key.Left) ? Keyboard.IsKeyDown(Key.LeftShift) ? -10 : -1 : 0; - dy += (e.Key == Key.Up) ? Keyboard.IsKeyDown(Key.LeftShift) ? -10 : -1 : 0; - dx += (e.Key == Key.Right) ? Keyboard.IsKeyDown(Key.LeftShift) ? 10 : 1 : 0; - dy += (e.Key == Key.Down) ? Keyboard.IsKeyDown(Key.LeftShift) ? 10 : 1 : 0; + dx = (e.Key == Key.Left) ? Keyboard.IsKeyDown(Key.LeftShift) ? -10 : -1 : 0; + dy = (e.Key == Key.Up) ? Keyboard.IsKeyDown(Key.LeftShift) ? -10 : -1 : 0; + dx = (e.Key == Key.Right) ? Keyboard.IsKeyDown(Key.LeftShift) ? 10 : 1 : (dx != 0 ? dx : 0); + dy = (e.Key == Key.Down) ? Keyboard.IsKeyDown(Key.LeftShift) ? 10 : 1 : (dy != 0 ? dy : 0); + double left, top; foreach (PlacementInformation info in placementOp.PlacedItems) { - if (!Keyboard.IsKeyDown(Key.LeftCtrl)) - { - info.Bounds = new Rect(info.OriginalBounds.Left + dx, - info.OriginalBounds.Top + dy, + //Let canvas position preceed bounds definition since there can be a discrepancy between them. + left = IsPropertySet(info.Item.View,Canvas.LeftProperty)?(double)info.Item.Properties.GetAttachedProperty(Canvas.LeftProperty).ValueOnInstance: info.OriginalBounds.Left; + + top = IsPropertySet(info.Item.View, Canvas.TopProperty) ? (double)info.Item.Properties.GetAttachedProperty(Canvas.TopProperty).ValueOnInstance : info.OriginalBounds.Top; + if (!Keyboard.IsKeyDown(Key.LeftCtrl)) { + info.Bounds = new Rect(left + dx, + top + dy, info.OriginalBounds.Width, info.OriginalBounds.Height); - } - else - { - info.Bounds = new Rect(info.OriginalBounds.Left, - info.OriginalBounds.Top, + } else { + info.Bounds = new Rect(left, + top, info.OriginalBounds.Width + dx, info.OriginalBounds.Height + dy); } - placementOp.CurrentContainerBehavior.SetPosition(info); } } } + static bool IsPropertySet(UIElement element, DependencyProperty d) + { + return element.ReadLocalValue(d) != DependencyProperty.UnsetValue; + } + protected override void OnQueryCursor(QueryCursorEventArgs e) { base.OnQueryCursor(e); 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..a113913de2 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,13 @@ 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) { + if (info.ResizeThumbAlignment != null && info.ResizeThumbAlignment.Value.Vertical == VerticalAlignment.Top) { bounds.Y += delta; bounds.Height = Math.Max(0, bounds.Height - delta); } else { bounds.Height = Math.Max(0, bounds.Height + delta); } + bounds.Height = Math.Max(0, bounds.Height - delta); info.Bounds = bounds; } else { foreach (var item in operation.PlacedItems) { @@ -138,12 +139,13 @@ 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) { + if (info.ResizeThumbAlignment != null && info.ResizeThumbAlignment.Value.Horizontal == HorizontalAlignment.Left) { bounds.X += delta; bounds.Width = Math.Max(0, bounds.Width - delta); } else { bounds.Width = Math.Max(0, bounds.Width + 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/Xaml/XamlModelProperty.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs index 80ad7a3f3b..aa61d75eae 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs @@ -121,6 +121,18 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml } } + public override string TextValue + { + get { + var xamlTextValue = _property.PropertyValue as XamlTextValue; + if (xamlTextValue != null) { + return xamlTextValue.Text; + } + + return null; + } + } + // There may be multiple XamlModelProperty instances for the same property, // so this class may not have any mutable fields / events - instead, // we forward all event handlers to the XamlProperty. diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/MarkupExtensionModelTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/MarkupExtensionModelTests.cs new file mode 100644 index 0000000000..4d51eb94c8 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/MarkupExtensionModelTests.cs @@ -0,0 +1,132 @@ +// 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 System.Linq; +using System.Text; +using System.Windows.Controls; +using System.Windows.Markup; +using NUnit.Framework; + +namespace ICSharpCode.WpfDesign.Tests.Designer +{ + [TestFixture] + public class MarkupExtensionModelTests : ModelTestHelper + { + private const string PathWithCommasAndSpaces = "C:\\Folder A\\Sub,Folder,A\\SubFolderB\\file,with,commas and spaces.txt"; + private const string Simple = "AbcDef"; + + [Test] + public void ElementMarkupExtensionWithSimpleString() + { + TestMarkupExtensionPrinter(Simple, true); + } + + [Test] + public void ShorthandMarkupExtensionWithSimpleString() + { + TestMarkupExtensionPrinter(Simple, false); + } + + [Test] + public void ElementMarkupExtensionWithFilePathString() + { + TestMarkupExtensionPrinter(PathWithCommasAndSpaces, true); + } + + [Test] + public void ShorthandMarkupExtensionWithFilePathString() + { + TestMarkupExtensionPrinter(PathWithCommasAndSpaces, false); + } + + private void TestMarkupExtensionPrinter(string s, bool useElementStyle) + { + var checkBoxItem = CreateCanvasContext(""); + var tagProp = checkBoxItem.Properties["Tag"]; + + tagProp.SetValue(new DataExtension()); + tagProp.Value.Properties["Data"].SetValue(s); + + string expectedXaml; + + if (useElementStyle) { + // Setting this should force element style + tagProp.Value.Properties["Object"].SetValue(new ExampleClass()); + + expectedXaml = @" + + + + + + + +"; + } else { + StringBuilder sb = new StringBuilder(""); + + expectedXaml = sb.ToString(); + } + + AssertCanvasDesignerOutput(expectedXaml, checkBoxItem.Context); + AssertLog(""); + + // The following tests that the official XamlReader is parsing the resulting xaml into the + // same string that we are testing, regardless if element or shorthand style is being used. + + string xaml = expectedXaml.Insert(""); DesignItem canvas = textBlock.Parent; DesignItemProperty canvasResources = canvas.Properties.GetProperty("Resources"); - DesignItem str = canvas.Services.Component.RegisterComponentForDesigner("stringresource 1"); - str.Key = "str1"; + DesignItem componentItem = canvas.Services.Component.RegisterComponentForDesigner(component); + componentItem.Key = "res1"; Assert.IsTrue(canvasResources.IsCollection); - canvasResources.CollectionElements.Add(str); + canvasResources.CollectionElements.Add(componentItem); - textBlock.Properties[TextBlock.TextProperty].SetValue(new StaticResourceExtension()); - DesignItemProperty prop = textBlock.Properties[TextBlock.TextProperty]; - prop.Value.Properties["ResourceKey"].SetValue("str1"); + DesignItemProperty prop = textBlock.Properties[TextBlock.TagProperty]; + prop.SetValue(new StaticResourceExtension()); + prop.Value.Properties["ResourceKey"].SetValue("res1"); + + string typeName = component.GetType().Name; string expectedXaml = "\n" + - " stringresource 1\n" + + " " + expectedXamlValue + "\n" + "\n" + - ""; + ""; AssertCanvasDesignerOutput(expectedXaml, textBlock.Context, "xmlns:Controls0=\"clr-namespace:System;assembly=mscorlib\""); AssertLog(""); } + + [Test] + public void TestTextValue() + { + // An invalid path (in this case containing a question mark), or a path to a file that does not exist, will give the same result. + // It will cause the typeconverter to fail and no value can be get from neither ValueOnInstance nor Value from the Image.Source DesignItemProperty. + // TextValue was added to have a way of getting the xaml value. + string sourceTextValue = "file:///C:/Folder/image?.bmp"; + + string xaml = ""; + DesignItem image = CreateCanvasContext(xaml); + + var sourceProp = image.Properties[Image.SourceProperty]; + + Assert.IsNull(sourceProp.ValueOnInstance); + Assert.IsNull(sourceProp.Value); + Assert.IsNotNull(sourceProp.TextValue); + Assert.AreEqual(sourceTextValue, sourceProp.TextValue); + + string expectedXaml = xaml; + AssertCanvasDesignerOutput(expectedXaml, image.Context); + AssertLog(""); + } + + [Test] + public void AddStringAsResource() + { + AddNativeTypeAsResource("stringresource 1", "stringresource 1"); + } + + [Test] + public void AddDoubleAsResource() + { + AddNativeTypeAsResource(0.0123456789d, "0.0123456789"); + } + + [Test] + public void AddInt32AsResource() + { + const int i = 123; + AddNativeTypeAsResource(i, "123"); + } } public class MyMultiConverter : IMultiValueConverter diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Tests.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Tests.csproj index 73295de0bd..9ed980b88b 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Tests.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Tests.csproj @@ -62,6 +62,7 @@ + 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.Designer/Tests/XamlDom/SimpleLoadTests.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SimpleLoadTests.cs index 966bf37b5d..1854242157 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SimpleLoadTests.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/XamlDom/SimpleLoadTests.cs @@ -97,6 +97,19 @@ namespace ICSharpCode.WpfDesign.Tests.XamlDom "); } + [Test] + public void ExampleClassWithFilePathStringPropAttribute() + { + TestLoading(@" + + + "); + } + [Test] public void ExampleClassUseDefaultProperty() { 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/MarkupExtensionPrinter.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionPrinter.cs index a1a849ad2d..d7b1b1949e 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionPrinter.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionPrinter.cs @@ -93,8 +93,20 @@ namespace ICSharpCode.WpfDesign.XamlDom sb.Append("="); var value = property.PropertyValue; - if (value is XamlTextValue) { - sb.Append((value as XamlTextValue).Text); + var textValue = value as XamlTextValue; + if (textValue != null) { + string text = textValue.Text; + bool containsSpace = text.Contains(' '); + + if(containsSpace) { + sb.Append('\''); + } + + sb.Append(text.Replace("\\", "\\\\")); + + if(containsSpace) { + sb.Append('\''); + } } else if (value is XamlObject) { sb.Append(Print(value as XamlObject)); } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs index 7a23eabac7..48ee85ec63 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs @@ -193,7 +193,7 @@ namespace ICSharpCode.WpfDesign.XamlDom XmlElement xml = _xmlDoc.CreateElement(prefix, elementType.Name, ns); - if (hasStringConverter && XamlObject.GetContentPropertyName(elementType) != null) { + if (hasStringConverter && (XamlObject.GetContentPropertyName(elementType) != null || IsNativeType(instance))) { xml.InnerText = c.ConvertToInvariantString(instance); } else if (instance is Brush && forProperty != null) { // TODO: this is a hacky fix, because Brush Editor doesn't // edit Design Items and so we have no XML, only the Brush @@ -214,8 +214,6 @@ namespace ICSharpCode.WpfDesign.XamlDom } } } - } else if (instance is string) { - xml.InnerText = (string)instance; } return new XamlObject(this, xml, elementType, instance); @@ -274,5 +272,10 @@ namespace ICSharpCode.WpfDesign.XamlDom return prefix; } + + bool IsNativeType(object instance) + { + return instance.GetType().Assembly == typeof(String).Assembly; + } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs index 5af9e0188b..e8275a34e4 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs @@ -223,7 +223,7 @@ namespace ICSharpCode.WpfDesign.XamlDom foreach(XamlObject propXamlObject in holder.Properties.Where((prop) => prop.IsSet).Select((prop) => prop.PropertyValue).OfType()) { XamlObject innerHolder; bool updateResult = propXamlObject.UpdateXmlAttribute(true, out innerHolder); - Debug.Assert(updateResult); + Debug.Assert(updateResult || innerHolder == null); if (propXamlObject == this) isThisUpdated = true; diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItemProperty.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItemProperty.cs index 8b7191329a..ef5294de55 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItemProperty.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItemProperty.cs @@ -81,6 +81,12 @@ namespace ICSharpCode.WpfDesign /// public abstract DesignItem Value { get; } + /// + /// Gets the string value of the property. This property returns null if the value is not set, + /// or if the value is set to a non-primitive value (i.e. represented by a , accessible through property). + /// + public abstract string TextValue { get; } + /// /// Is raised when the value of the property changes (by calling or ). /// diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignPanelHitTestResult.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignPanelHitTestResult.cs index 06c84f4cbc..dfeed9fa60 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignPanelHitTestResult.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignPanelHitTestResult.cs @@ -24,7 +24,7 @@ using ICSharpCode.WpfDesign.Adorners; namespace ICSharpCode.WpfDesign { /// - /// Describes the result of a call. + /// Describes the result of a call. /// public struct DesignPanelHitTestResult : IEquatable { 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/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/SettingsFactory.cs b/src/AddIns/Misc/PackageManagement/Project/Src/SettingsFactory.cs deleted file mode 100644 index 807072f3e5..0000000000 --- a/src/AddIns/Misc/PackageManagement/Project/Src/SettingsFactory.cs +++ /dev/null @@ -1,32 +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 class SettingsFactory : ISettingsFactory - { - public ISettings CreateSettings(string directory) - { - var fileSystem = new PhysicalFileSystem(directory); - return new Settings(fileSystem); - } - } -} 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/FakeSettingsFactory.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeSettingsFactory.cs deleted file mode 100644 index c6ad46bacc..0000000000 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeSettingsFactory.cs +++ /dev/null @@ -1,37 +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 ICSharpCode.PackageManagement; -using ICSharpCode.PackageManagement.Design; -using NuGet; - -namespace PackageManagement.Tests.Helpers -{ - public class FakeSettingsFactory : ISettingsFactory - { - public FakeSettings FakeSettings = new FakeSettings(); - public string DirectoryPassedToCreateSettings; - - public ISettings CreateSettings(string directory) - { - DirectoryPassedToCreateSettings = directory; - return FakeSettings; - } - } -} 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/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/ICSharpCode.Reporting.Addin.csproj b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/ICSharpCode.Reporting.Addin.csproj index 7fb6f7b30d..19879aca23 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/ICSharpCode.Reporting.Addin.csproj +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/ICSharpCode.Reporting.Addin.csproj @@ -84,7 +84,7 @@ - + @@ -97,6 +97,8 @@ Configuration\GlobalAssemblyInfo.cs + + @@ -160,6 +162,7 @@ + diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/ICSharpCode.Reporting.addin b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/ICSharpCode.Reporting.addin index f83c86033d..e2632686af 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/ICSharpCode.Reporting.addin +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/ICSharpCode.Reporting.addin @@ -105,17 +105,19 @@ --> - + - - --> + + diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/Commands/DesignerVerbSubmenuBuilder.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/Commands/DesignerVerbSubmenuBuilder.cs new file mode 100644 index 0000000000..b5e470b94b --- /dev/null +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/Commands/DesignerVerbSubmenuBuilder.cs @@ -0,0 +1,68 @@ +/* + * Created by SharpDevelop. + * User: Peter Forstmeier + * Date: 21.05.2014 + * Time: 20:05 + * + * To change this template use Tools | Options | Coding | Edit Standard Headers. + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.Design; +using System.Windows.Forms; +using ICSharpCode.Core; +using ICSharpCode.Core.WinForms; + +namespace ICSharpCode.Reporting.Addin.Commands +{ + /// + /// Description of DesignerVerbSubmenuBuilder. + /// + public class DesignerVerbSubmenuBuilder : IMenuItemBuilder + { + #region IMenuItemBuilder implementation + + public IEnumerable BuildItems(Codon codon, object owner) + { + var menuCommandService = (IMenuCommandService)owner; + + var items = new List(); + + foreach (DesignerVerb verb in menuCommandService.Verbs) { + Console.WriteLine("{0}",verb.Text); + items.Add(new ContextMenuCommand(verb)); + } + + // add separator at the end of custom designer verbs + if (items.Count > 0) { + items.Add(new MenuSeparator()); + } + + return items.ToArray(); + } + + #endregion + } + + sealed class ContextMenuCommand : ICSharpCode.Core.WinForms.MenuCommand + { + DesignerVerb verb; + + public ContextMenuCommand(DesignerVerb verb) : base(verb.Text) + { + this.Enabled = verb.Enabled; +// this.Checked = verb.Checked; + this.verb = verb; + Click += InvokeCommand; + } + + void InvokeCommand(object sender, EventArgs e) + { + try { + verb.Invoke(); + } catch (Exception ex) { + MessageService.ShowException(ex); + } + } + } +} diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/Commands/FormsCommands.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/Commands/FormsCommands.cs new file mode 100644 index 0000000000..8f724d87ff --- /dev/null +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/Commands/FormsCommands.cs @@ -0,0 +1,83 @@ +/* + * Created by SharpDevelop. + * User: Peter Forstmeier + * Date: 21.05.2014 + * Time: 20:35 + * + * To change this template use Tools | Options | Coding | Edit Standard Headers. + */ +using System; +using System.ComponentModel.Design; +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.Reporting.Addin.Views; + +namespace ICSharpCode.Reporting.Addin.Commands +{ + /// + /// Description of FormsCommands. + /// + + public abstract class AbstractFormsDesignerCommand : AbstractMenuCommand + { + public abstract CommandID CommandID { + get; + } + + protected virtual bool CanExecuteCommand(IDesignerHost host) + { + return true; + } + + protected static DesignerView ReportDesigner { + get { + var window = SD.Workbench; + if (window == null) { + return null; + } + return window.ActiveViewContent as DesignerView; + } + } + + + public override void Run() + { + var formDesigner = ReportDesigner; + if (formDesigner != null && CanExecuteCommand(formDesigner.Host)) { + var menuCommandService = (IMenuCommandService)formDesigner.Host.GetService(typeof(IMenuCommandService)); + menuCommandService.GlobalInvoke(CommandID); + } + } + + internal virtual void CommandCallBack(object sender, EventArgs e) + { + Run(); + } + } + + + + public class ViewCode : AbstractFormsDesignerCommand + { + public override CommandID CommandID { + get { + return StandardCommands.ViewCode; + } + } + + public override void Run() + { +// var window = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow; + var window = SD.Workbench; + if (window == null) { + return; + } + + var formDesigner = AbstractFormsDesignerCommand.ReportDesigner; + if (formDesigner != null) { + formDesigner.ShowSourceCode(); + } + } + } +} diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/DesignableItems/BaseLineItem.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/DesignableItems/BaseLineItem.cs index 46778def47..db2dd66f2d 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/DesignableItems/BaseLineItem.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/DesignableItems/BaseLineItem.cs @@ -58,7 +58,7 @@ namespace ICSharpCode.Reporting.Addin.DesignableItems throw new ArgumentNullException("graphics"); } using (var p = new Pen(ForeColor,Thickness)) { - p.SetLineCap(StartLineCap,EndLineCap,DashLineCap); + p.SetLineCap(StartLineCap,EndLineCap,DashCap.Flat); graphics.DrawLine(p,fromPoint,toPoint); } } @@ -115,14 +115,14 @@ namespace ICSharpCode.Reporting.Addin.DesignableItems } - [Category("Appearance")] - public DashCap DashLineCap { - get { return dashLineCap; } - set { - dashLineCap = value; - Invalidate(); - } - } +// [Category("Appearance")] +// public DashCap DashLineCap { +// get { return dashLineCap; } +// set { +// dashLineCap = value; +// Invalidate(); +// } +// } } } diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/DesignableItems/BaseSection.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/DesignableItems/BaseSection.cs index 87ccb29873..55ac69ff3a 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/DesignableItems/BaseSection.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/DesignableItems/BaseSection.cs @@ -43,14 +43,14 @@ namespace ICSharpCode.Reporting.Addin.DesignableItems #region Propertys +// +// [Browsable(false)] +// public int SectionOffset {get;set;} - [Browsable(false)] - public int SectionOffset {get;set;} - - [Browsable(false)] - public int SectionMargin {get;set;} +// [Browsable(false)] +// public int SectionMargin {get;set;} - public bool PageBreakAfter {get;set;} +// public bool PageBreakAfter {get;set;} public bool CanGrow {get;set;} diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/TypeProvider/LineItemTypeProvider.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/TypeProvider/LineItemTypeProvider.cs index c08ef163cb..00929e7a2a 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/TypeProvider/LineItemTypeProvider.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/TypeProvider/LineItemTypeProvider.cs @@ -71,8 +71,8 @@ namespace ICSharpCode.Reporting.Addin.TypeProvider prop = props.Find("EndLineCap",true); allProperties.Add(prop); - prop = props.Find("dashLineCap",true); - allProperties.Add(prop); +// prop = props.Find("DashLineCap",true); +// allProperties.Add(prop); prop = props.Find("DashStyle",true); allProperties.Add(prop); diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/TypeProvider/SectionItemTypeProvider.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/TypeProvider/SectionItemTypeProvider.cs index 6736f69835..a3521a9622 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/TypeProvider/SectionItemTypeProvider.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/TypeProvider/SectionItemTypeProvider.cs @@ -55,17 +55,17 @@ namespace ICSharpCode.Reporting.Addin.TypeProvider TypeProviderHelper.AddDefaultProperties(allProperties,props); PropertyDescriptor prop = null; - prop = props.Find("SectionOffset",true); - allProperties.Add(prop); +// prop = props.Find("SectionOffset",true); +// allProperties.Add(prop); - prop = props.Find("SectionMargin",true); - allProperties.Add(prop); +// prop = props.Find("SectionMargin",true); +// allProperties.Add(prop); prop = props.Find("DrawBorder",true); allProperties.Add(prop); - prop = props.Find("PageBreakAfter",true); - allProperties.Add(prop); +// prop = props.Find("PageBreakAfter",true); +// allProperties.Add(prop); prop = props.Find("Controls",true); allProperties.Add(prop); diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/UndoRedo/ReportDesignerUndoEngine.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/UndoRedo/ReportDesignerUndoEngine.cs new file mode 100644 index 0000000000..8e8f57b503 --- /dev/null +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/UndoRedo/ReportDesignerUndoEngine.cs @@ -0,0 +1,66 @@ +/* + * Created by SharpDevelop. + * User: Peter Forstmeier + * Date: 21.05.2014 + * Time: 19:37 + * + * To change this template use Tools | Options | Coding | Edit Standard Headers. + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.Design; +using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.SharpDevelop.WinForms; + +namespace ICSharpCode.Reporting.Addin.UndoRedo +{ + /// + /// Description of ReportDesignerUndoEngine. + /// + public class ReportDesignerUndoEngine : UndoEngine, IUndoHandler + { + Stack undoStack = new Stack(); + Stack redoStack = new Stack(); + + public ReportDesignerUndoEngine(IServiceProvider provider) : base(provider) + { + } + + #region IUndoHandler + public bool EnableUndo { + get { + return undoStack.Count > 0; + } + } + + public bool EnableRedo { + get { + return redoStack.Count > 0; + } + } + + public void Undo() + { + if (undoStack.Count > 0) { + UndoEngine.UndoUnit unit = undoStack.Pop(); + unit.Undo(); + redoStack.Push(unit); + } + } + + public void Redo() + { + if (redoStack.Count > 0) { + UndoEngine.UndoUnit unit = redoStack.Pop(); + unit.Undo(); + undoStack.Push(unit); + } + } + #endregion + + protected override void AddUndoUnit(UndoEngine.UndoUnit unit) + { + undoStack.Push(unit); + } + } +} diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/Views/DesignerView.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/Views/DesignerView.cs index 7b147e14d0..14704122d8 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/Views/DesignerView.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting.Addin/src/Views/DesignerView.cs @@ -19,20 +19,23 @@ using System.Windows.Forms; using System.Windows.Forms.Design; using ICSharpCode.Core; using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.SharpDevelop.WinForms; using ICSharpCode.SharpDevelop.Workbench; using ICSharpCode.Reporting.Addin.DesignableItems; using ICSharpCode.Reporting.Addin.DesignerBinding; using ICSharpCode.Reporting.Addin.Services; using ICSharpCode.Reporting.Addin.Toolbox; +using ICSharpCode.Reporting.Addin.UndoRedo; namespace ICSharpCode.Reporting.Addin.Views { /// /// Description of the view content /// - public class DesignerView : AbstractViewContent,IHasPropertyContainer, IToolsHost + public class DesignerView : AbstractViewContent,IHasPropertyContainer, IToolsHost,IUndoHandler,IClipboardHandler { readonly IDesignerGenerator generator; + ReportDesignerUndoEngine undoEngine; bool unloading; bool hasUnmergedChanges; bool shouldUpdateSelectableObjects; @@ -98,9 +101,9 @@ namespace ICSharpCode.Reporting.Addin.Views var selectionService = (ISelectionService)this.designSurface.GetService(typeof(ISelectionService)); selectionService.SelectionChanged += SelectionChangedHandler; - /* + undoEngine = new ReportDesignerUndoEngine(Host); - */ + var componentChangeService = (IComponentChangeService)this.designSurface.GetService(typeof(IComponentChangeService)); @@ -228,6 +231,7 @@ namespace ICSharpCode.Reporting.Addin.Views #endregion + #region IToolsHost object IToolsHost.ToolsContent { @@ -273,6 +277,7 @@ namespace ICSharpCode.Reporting.Addin.Views #endregion + #region DesignerEvents @@ -311,6 +316,7 @@ namespace ICSharpCode.Reporting.Addin.Views { LoggingService.Debug("ReportDesigner: Event > DesignernUnloading..."); } + #endregion @@ -336,6 +342,130 @@ namespace ICSharpCode.Reporting.Addin.Views #endregion + + #region IUndoHandler implementation + + public bool EnableUndo { + get { + if (undoEngine != null) { + return undoEngine.EnableUndo; + } + return false; + } + } + + + public bool EnableRedo { + get { + if (undoEngine != null) { + return undoEngine.EnableRedo; + } + return false; + } + } + + + public virtual void Undo() + { + if (undoEngine != null) { + undoEngine.Undo(); + } + } + + + public virtual void Redo() + { + if (undoEngine != null) { + undoEngine.Redo(); + } + } + + #endregion + + + #region IClipboardHandler implementation + + + public void Cut() + { + var menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService)); + menuCommandService.GlobalInvoke(StandardCommands.Cut); + } + + public void Copy() + { + var menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService)); + menuCommandService.GlobalInvoke(StandardCommands.Copy); + } + + public void Paste() + { + var menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService)); + menuCommandService.GlobalInvoke(StandardCommands.Paste); + } + + public void Delete() + { + var menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService)); + menuCommandService.GlobalInvoke(StandardCommands.Delete); + } + + public void SelectAll() + { + throw new NotImplementedException(); + } + + public bool EnableCut { + get {return IsMenuCommandEnabled(StandardCommands.Cut);} + } + + public bool EnableCopy { + get {return IsMenuCommandEnabled(StandardCommands.Copy);} + } + + public bool EnablePaste { + get {return IsMenuCommandEnabled(StandardCommands.Paste);} + } + + + public bool EnableDelete { + get {return IsMenuCommandEnabled(StandardCommands.Delete);} + } + + + public bool EnableSelectAll { + get {return designSurface != null;} + } + + + bool IsMenuCommandEnabled(CommandID commandID) + { + if (designSurface == null) { + return false; + } + + var menuCommandService = (IMenuCommandService)designSurface.GetService(typeof(IMenuCommandService)); + if (menuCommandService == null) { + return false; + } + + MenuCommand menuCommand = menuCommandService.FindCommand(commandID); + if (menuCommand == null) { + return false; + } + return menuCommand.Enabled; + } + #endregion + + + #region Commands + + public void ShowSourceCode() + { + WorkbenchWindow.SwitchView(1); + } + + #endregion #region UI void SetupDesignSurface() @@ -344,6 +474,7 @@ namespace ICSharpCode.Reporting.Addin.Views ctrl.Parent = panel; ctrl.Dock = DockStyle.Fill; } + void MergeFormChanges() diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/BaseClasses/ExtensionMethods.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/BaseClasses/ExtensionMethods.cs index 6458759e5a..a73d3984fc 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/BaseClasses/ExtensionMethods.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/BaseClasses/ExtensionMethods.cs @@ -60,11 +60,23 @@ namespace ICSharpCode.Reporting.BaseClasses return new Rect(rect.Location.ToWpf(), rect.Size.ToWpf()); } - public static System.Windows.Media.Color ToWpf(this System.Drawing.Color c) + public static Color ToWpf(this System.Drawing.Color c) { - return System.Windows.Media.Color.FromArgb(c.A, c.R, c.G, c.B); + return Color.FromArgb(c.A, c.R, c.G, c.B); } + + public static int FromPoints(double value) + { + return (int)Math.Round(value * 72.0 / 96.0); + } + + public static double ToPoints(int value) + { + return Math.Round(value * 96.0 / 72.0); + } + + #endregion #region DPI independence diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Exporter/Visitors/AbstractVisitor.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Exporter/Visitors/AbstractVisitor.cs index 2c20438422..c9f0e1c603 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Exporter/Visitors/AbstractVisitor.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Exporter/Visitors/AbstractVisitor.cs @@ -20,6 +20,7 @@ using System; using System.Collections.ObjectModel; using System.Drawing; +using ICSharpCode.Reporting.Interfaces.Export; using ICSharpCode.Reporting.PageBuilder.ExportColumns; namespace ICSharpCode.Reporting.Exporter.Visitors @@ -84,5 +85,13 @@ namespace ICSharpCode.Reporting.Exporter.Visitors protected Collection Pages {get; private set;} + protected bool IsContainer (IExportColumn column) { + return (column is ExportContainer)|| (column is GraphicsContainer); + } + + + protected bool IsGraphicsContainer (IExportColumn column) { + return column is GraphicsContainer; + } } } diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Items/Graphics/BaseLineItem.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Items/Graphics/BaseLineItem.cs index 866c4c5b22..638df50eeb 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Items/Graphics/BaseLineItem.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Items/Graphics/BaseLineItem.cs @@ -16,6 +16,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System.Drawing; using ICSharpCode.Reporting.Interfaces.Export; using ICSharpCode.Reporting.PageBuilder.ExportColumns; @@ -41,7 +42,16 @@ namespace ICSharpCode.Reporting.Items{ ex.DashStyle = DashStyle; ex.StartLineCap = StartLineCap; ex.EndLineCap = EndLineCap; + ex.FromPoint = FromPoint; + ex.ToPoint = ToPoint; return ex; } + + + public Point FromPoint {get;set;} + + public Point ToPoint {get;set;} + + } } diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/PageBuilder/ExportColumns/ExportLine.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/PageBuilder/ExportColumns/ExportLine.cs index 3e4aa40d33..5026432666 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/PageBuilder/ExportColumns/ExportLine.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/PageBuilder/ExportColumns/ExportLine.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Drawing; using System.Drawing.Drawing2D; using ICSharpCode.Reporting.Exporter.Visitors; using ICSharpCode.Reporting.Interfaces.Export; @@ -60,5 +61,9 @@ namespace ICSharpCode.Reporting.PageBuilder.ExportColumns public LineCap StartLineCap {get;set;} public LineCap EndLineCap {get;set;} + + public Point FromPoint {get;set;} + + public Point ToPoint {get;set;} } } diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfHelper.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfHelper.cs index a7b03d1699..9bf54f516b 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfHelper.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfHelper.cs @@ -21,7 +21,6 @@ using System.Drawing; using ICSharpCode.Reporting.Interfaces.Export; using ICSharpCode.Reporting.PageBuilder.ExportColumns; using PdfSharp.Drawing; -using System.Drawing.Drawing2D; using PdfSharp.Drawing.Layout; namespace ICSharpCode.Reporting.Pdf @@ -34,11 +33,11 @@ namespace ICSharpCode.Reporting.Pdf public static void WriteText(XTextFormatter textFormatter,Point columnLocation, ExportText exportColumn) { - XFont font = PdfHelper.CreatePdfFont(exportColumn); + var font = PdfHelper.CreatePdfFont(exportColumn); var rect = new Rectangle(columnLocation,exportColumn.DesiredSize).ToXRect(); textFormatter.DrawString(exportColumn.Text, font, - new XSolidBrush(ToXColor(exportColumn.ForeColor)), + CreateBrush(exportColumn.ForeColor), rect, XStringFormats.TopLeft); } @@ -76,6 +75,19 @@ namespace ICSharpCode.Reporting.Pdf } + public static XPen CreateDashedPen(IExportGraphics exportRectangle) + { + var pen = PdfHelper.PdfPen(exportRectangle); + pen.DashStyle = PdfHelper.DashStyle(exportRectangle); + return pen; + } + + + public static XSolidBrush CreateBrush(Color color) { + return new XSolidBrush(color); + } + + public static XLineCap LineCap (IExportGraphics column) { return XLineCap.Round; diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfVisitor.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfVisitor.cs index b7f3962c8e..76bc22968c 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfVisitor.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Pdf/PdfVisitor.cs @@ -16,8 +16,10 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +using System; using System.Drawing; using ICSharpCode.Reporting.Exporter.Visitors; +using ICSharpCode.Reporting.Interfaces.Export; using ICSharpCode.Reporting.PageBuilder.ExportColumns; using PdfSharp.Drawing; using PdfSharp.Drawing.Layout; @@ -31,7 +33,7 @@ namespace ICSharpCode.Reporting.Pdf class PdfVisitor: AbstractVisitor { readonly PdfDocument pdfDocument; - XGraphics gfx; + XGraphics xGraphics; XTextFormatter textFormatter; Point containerLocation; @@ -43,36 +45,69 @@ namespace ICSharpCode.Reporting.Pdf public override void Visit(ExportPage page) { PdfPage = pdfDocument.AddPage(); - gfx = XGraphics.FromPdfPage(PdfPage); - textFormatter = new XTextFormatter(gfx); + xGraphics = XGraphics.FromPdfPage(PdfPage); + textFormatter = new XTextFormatter(xGraphics); base.Visit(page); } - public override void Visit(ExportContainer exportContainer) - { + public override void Visit(ExportContainer exportContainer){ + foreach (var element in exportContainer.ExportedItems) { - var container = element as ExportContainer; - if (container != null) { + if (IsContainer(element)) { + var container = element as ExportContainer; containerLocation = PdfHelper.LocationRelToParent(container); - var r = new Rectangle(containerLocation,container.DisplayRectangle.Size); - PdfHelper.FillRectangle(r,container.BackColor,gfx); - Visit(container); + RenderRow(container); + } else { + containerLocation = PdfHelper.LocationRelToParent(exportContainer); + var acceptor = element as IAcceptor; + acceptor.Accept(this); } - containerLocation = PdfHelper.LocationRelToParent(exportContainer); - var ac = element as IAcceptor; - ac.Accept(this); } } - public override void Visit(ExportText exportText) + void RenderRow(IExportContainer container) { - var columnLocation = containerLocation; - columnLocation.Offset(exportText.Location); + if (IsGraphicsContainer(container)) { + RenderGraphicsContainer(container); + } else { + RenderDataRow(container); + } + } + + + void RenderGraphicsContainer(IExportColumn column) + { + var graphicsContainer = column as GraphicsContainer; + if (graphicsContainer != null) { + var rect = column as ExportRectangle; + if (rect != null) { + Visit(rect); + } + + var circle = column as ExportCircle; + if (circle != null) { + Visit(circle); + } + } + } + + + void RenderDataRow (IExportContainer row) { + var r = new Rectangle(containerLocation,row.DisplayRectangle.Size); + PdfHelper.FillRectangle(r,row.BackColor,xGraphics); + foreach (IAcceptor element in row.ExportedItems) { + element.Accept(this); + } + } + + + public override void Visit(ExportText exportText){ + var columnLocation = new Point(containerLocation.X + exportText.Location.X,containerLocation.Y + exportText.Location.Y); if (ShouldSetBackcolor(exportText)) { var r = new Rectangle(columnLocation,exportText.DisplayRectangle.Size); - PdfHelper.FillRectangle(r,exportText.BackColor,gfx); + PdfHelper.FillRectangle(r,exportText.BackColor,xGraphics); } PdfHelper.WriteText(textFormatter,columnLocation, exportText); @@ -84,32 +119,28 @@ namespace ICSharpCode.Reporting.Pdf { var columnLocation = containerLocation; columnLocation.Offset(exportLine.Location); - var pen = PdfHelper.PdfPen(exportLine); - pen.DashStyle = PdfHelper.DashStyle(exportLine); - pen.LineCap = PdfHelper.LineCap(exportLine); - gfx.DrawLine(pen,columnLocation.ToXPoints(),new Point(exportLine.Size.Width,columnLocation.Y).ToXPoints()); + var pen = PdfHelper.CreateDashedPen(exportLine); + xGraphics.DrawLine(pen,columnLocation.ToXPoints(),new Point(exportLine.Size.Width,columnLocation.Y).ToXPoints()); } public override void Visit (ExportRectangle exportRectangle) { - var columnLocation = containerLocation; - columnLocation.Offset(exportRectangle.Location); - var pen = PdfHelper.PdfPen(exportRectangle); - pen.DashStyle = PdfHelper.DashStyle(exportRectangle); - gfx.DrawRectangle(pen,new XRect(columnLocation.ToXPoints(), - exportRectangle.Size.ToXSize())); + var pen = PdfHelper.CreateDashedPen(exportRectangle); + xGraphics.DrawRectangle(pen, + PdfHelper.CreateBrush(exportRectangle.BackColor), + new XRect(containerLocation.ToXPoints(), + exportRectangle.Size.ToXSize())); } public override void Visit(ExportCircle exportCircle){ - var columnLocation = containerLocation; - columnLocation.Offset(exportCircle.Location); - var pen = PdfHelper.PdfPen(exportCircle); - pen.DashStyle = PdfHelper.DashStyle(exportCircle); - gfx.DrawEllipse(pen,new XRect(columnLocation.ToXPoints(), - exportCircle.Size.ToXSize())); + var pen = PdfHelper.CreateDashedPen(exportCircle); + xGraphics.DrawEllipse(pen, + PdfHelper.CreateBrush(exportCircle.BackColor) , + new XRect(containerLocation.ToXPoints(), + exportCircle.Size.ToXSize())); } - + public PdfPage PdfPage {get; private set;} } diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Wpf/Visitor/FixedDocumentCreator.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Wpf/Visitor/FixedDocumentCreator.cs index 28f634e986..ce9af88a6f 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Wpf/Visitor/FixedDocumentCreator.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Wpf/Visitor/FixedDocumentCreator.cs @@ -63,29 +63,64 @@ namespace ICSharpCode.Reporting.WpfReportViewer.Visitor public static FormattedText CreateFormattedText(ExportText exportText) { + FlowDirection flowDirection; + + var culture = CultureInfo.CurrentCulture; + if (culture.TextInfo.IsRightToLeft) { + flowDirection = FlowDirection.RightToLeft; + } else { + flowDirection = FlowDirection.LeftToRight; + } + + var emSize = ExtensionMethodes.ToPoints((int)exportText.Font.SizeInPoints +1); + var formattedText = new FormattedText(exportText.Text, CultureInfo.CurrentCulture, - FlowDirection.LeftToRight, + flowDirection, new Typeface(exportText.Font.FontFamily.Name), - exportText.Font.Size, + emSize, new SolidColorBrush(exportText.ForeColor.ToWpf()), null, TextFormattingMode.Display); - formattedText.MaxTextWidth = exportText.DesiredSize.Width * 96.0 / 72.0; - formattedText.SetFontSize(Math.Floor(exportText.Font.Size * 96.0 / 72.0)); + formattedText.MaxTextWidth = ExtensionMethodes.ToPoints(exportText.DesiredSize.Width); - var td = new TextDecorationCollection() ; - CheckUnderline(td,exportText); - formattedText.SetTextDecorations(td); + ApplyPrintStyles(formattedText,exportText); + return formattedText; } - static void CheckUnderline(TextDecorationCollection td, ExportText exportText) - { - if (exportText.Font.Underline) { - td.Add(new TextDecoration{Location = TextDecorationLocation.Underline}); + + static void ApplyPrintStyles (FormattedText formattedText,ExportText exportText) { + var font = exportText.Font; + var textDecorations = new TextDecorationCollection(); + FontStyle fontStyle; + FontWeight fontWeight; + + if ((font.Style & System.Drawing.FontStyle.Italic) != 0) { + fontStyle = FontStyles.Italic; + } else { + fontStyle = FontStyles.Normal; + } + + formattedText.SetFontStyle(fontStyle); + + if ((font.Style & System.Drawing.FontStyle.Bold) != 0) { + fontWeight = FontWeights.Bold; + } else { + fontWeight = FontWeights.Normal; } + formattedText.SetFontWeight(fontWeight); + + if ((font.Style & System.Drawing.FontStyle.Underline) != 0) { + textDecorations.Add(TextDecorations.Underline); + } + + if ((font.Style & System.Drawing.FontStyle.Strikeout) != 0) { + textDecorations.Add(TextDecorations.Strikethrough); + } + + formattedText.SetTextDecorations(textDecorations); } - + static Canvas CreateCanvas(ExportContainer container){ var canvas = new Canvas(); @@ -116,33 +151,9 @@ namespace ICSharpCode.Reporting.WpfReportViewer.Visitor FixedPage.SetTop(element,exportColumn.Location.Y); } - /* - static void SetFont(TextBlock textBlock,IExportText exportText){ - textBlock.FontFamily = new FontFamily(exportText.Font.FontFamily.Name); - - //http://www.codeproject.com/Articles/441009/Drawing-Formatted-Text-in-a-Windows-Forms-Applicat - - textBlock.FontSize = Math.Floor(exportText.Font.Size * 96/72); - - if (exportText.Font.Bold) { - textBlock.FontWeight = FontWeights.Bold; - } - if (exportText.Font.Underline) { - CreateUnderline(textBlock,exportText); - } - - if (exportText.Font.Italic) { - textBlock.FontStyle = FontStyles.Italic ; - } - if (exportText.Font.Strikeout) { - CreateStrikeout(textBlock,exportText); - } - } - */ static void SetContentAlignment(TextBlock textBlock,ExportText exportText) { - // http://social.msdn.microsoft.com/Forums/vstudio/en-US/e480abb9-a86c-4f78-8955-dddb866bcfef/vertical-text-alignment-in-textblock?forum=wpf //Vertical alignment not working switch (exportText.ContentAlignment) { @@ -188,34 +199,6 @@ namespace ICSharpCode.Reporting.WpfReportViewer.Visitor } - static void CreateStrikeout (TextBlock textBlock,IExportText exportColumn ){ - if (textBlock == null) - throw new ArgumentNullException("textBlock"); - if (exportColumn == null) - throw new ArgumentNullException("exportColumn"); - var strikeOut = new TextDecoration(); - strikeOut.Location = TextDecorationLocation.Strikethrough; - - Pen p = CreateWpfPen(exportColumn); - strikeOut.Pen = p ; - strikeOut.PenThicknessUnit = TextDecorationUnit.FontRecommended; - textBlock.TextDecorations.Add(strikeOut); - } - - /* - static void CreateUnderline(TextBlock textBlock,IExportText exportColumn){ - if (exportColumn == null) - throw new ArgumentNullException("exportColumn"); - if (textBlock == null) - throw new ArgumentNullException("textBlock"); - var underLine = new TextDecoration(); - Pen p = CreateWpfPen(exportColumn); - underLine.Pen = p ; - underLine.PenThicknessUnit = TextDecorationUnit.FontRecommended; - textBlock.TextDecorations.Add(underLine); - } - */ - public static Pen CreateWpfPen(IReportObject exportColumn){ if (exportColumn == null) throw new ArgumentNullException("exportColumn"); @@ -226,9 +209,9 @@ namespace ICSharpCode.Reporting.WpfReportViewer.Visitor var exportGraphics = exportColumn as IExportGraphics; if (exportGraphics != null) { pen.Thickness = exportGraphics.Thickness; - pen.DashStyle = FixedDocumentCreator.DashStyle(exportGraphics); - pen.StartLineCap = FixedDocumentCreator.LineCap(exportGraphics.StartLineCap); - pen.EndLineCap = FixedDocumentCreator.LineCap(exportGraphics.EndLineCap); + pen.DashStyle = DashStyle(exportGraphics); + pen.StartLineCap = LineCap(exportGraphics.StartLineCap); + pen.EndLineCap = LineCap(exportGraphics.EndLineCap); } return pen; } diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Wpf/Visitor/WpfVisitor.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Wpf/Visitor/WpfVisitor.cs index ca067ea386..5624ba60fd 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Wpf/Visitor/WpfVisitor.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Wpf/Visitor/WpfVisitor.cs @@ -75,6 +75,7 @@ namespace ICSharpCode.Reporting.WpfReportViewer.Visitor return canvas; } + void RenderRow(Canvas canvas, IExportContainer container) { if (IsGraphicsContainer(container)) { @@ -117,7 +118,7 @@ namespace ICSharpCode.Reporting.WpfReportViewer.Visitor public override void Visit(ExportText exportColumn){ - + var ft = FixedDocumentCreator.CreateFormattedText((ExportText)exportColumn); var visual = new DrawingVisual(); var location = new Point(exportColumn.Location.X,exportColumn.Location.Y); @@ -134,14 +135,15 @@ namespace ICSharpCode.Reporting.WpfReportViewer.Visitor } - public override void Visit(ExportLine exportGraphics) + public override void Visit(ExportLine exportLine) { - var pen = FixedDocumentCreator.CreateWpfPen(exportGraphics); + var pen = FixedDocumentCreator.CreateWpfPen(exportLine); var visual = new DrawingVisual(); using (var dc = visual.RenderOpen()){ dc.DrawLine(pen, - new Point(exportGraphics.Location.X, exportGraphics.Location.Y), - new Point(exportGraphics.Location.X + exportGraphics.Size.Width,exportGraphics.Location.Y)); + new Point(exportLine.Location.X + exportLine.FromPoint.X, exportLine.Location.Y + exportLine.FromPoint.Y), + new Point(exportLine.Location.X + exportLine.ToPoint.X , + exportLine.Location.Y + exportLine.FromPoint.Y)); } var dragingElement = new DrawingElement(visual); UIElement = dragingElement; @@ -179,16 +181,6 @@ namespace ICSharpCode.Reporting.WpfReportViewer.Visitor } - bool IsGraphicsContainer (IExportColumn column) { - return column is GraphicsContainer; - } - - - bool IsContainer (IExportColumn column) { - return (column is ExportContainer)|| (column is GraphicsContainer); - } - - DrawingElement CircleVisual(GraphicsContainer circle){ var pen = FixedDocumentCreator.CreateWpfPen(circle); var rad = CalcRadius(circle.Size); diff --git a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Xml/MycroParser.cs b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Xml/MycroParser.cs index 32fe9c9bd0..521f46f15a 100644 --- a/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Xml/MycroParser.cs +++ b/src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Xml/MycroParser.cs @@ -62,7 +62,7 @@ namespace ICSharpCode.Reporting.Xml // instantiate the class string ns=node.Prefix; string cname=node.LocalName; - + Type t=GetTypeByName(ns, cname); // Trace.Assert(t != null, "Type "+cname+" could not be determined."); @@ -119,7 +119,7 @@ namespace ICSharpCode.Reporting.Xml { if (!(child is XmlElement)) continue; string pname=child.LocalName; - + var pi=t.GetProperty(pname); if (pi==null) diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin index 4cc90ca9b4..c590200465 100755 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin @@ -1961,28 +1961,26 @@ link = "home://doc/ReadMe.rtf" /> - + - + + - - - diff --git a/src/Main/Core/Project/Src/Services/PropertyService/Properties.cs b/src/Main/Core/Project/Src/Services/PropertyService/Properties.cs index c0c87b368d..6d2d292e91 100644 --- a/src/Main/Core/Project/Src/Services/PropertyService/Properties.cs +++ b/src/Main/Core/Project/Src/Services/PropertyService/Properties.cs @@ -430,7 +430,7 @@ namespace ICSharpCode.Core if (result == null) { result = new Properties(this); dict[key] = result; - result.MakeDirty(); + isNewContainer = true; } } if (isNewContainer) diff --git a/src/Main/SharpDevelop/Logging/SDTraceListener.cs b/src/Main/SharpDevelop/Logging/SDTraceListener.cs index 86acf70abd..6b7da53f98 100644 --- a/src/Main/SharpDevelop/Logging/SDTraceListener.cs +++ b/src/Main/SharpDevelop/Logging/SDTraceListener.cs @@ -62,47 +62,34 @@ namespace ICSharpCode.SharpDevelop.Logging } if (!dialogIsOpen.Set()) return; - if (!SD.MainThread.InvokeRequired) { - // Use a dispatcher frame that immediately exits after it is pushed - // to detect whether dispatcher processing is suspended. - DispatcherFrame frame = new DispatcherFrame(); - frame.Continue = false; - try { - Dispatcher.PushFrame(frame); - } catch (InvalidOperationException) { - // Dispatcher processing is suspended. - // We currently can't show dialogs on the UI thread; so use a new thread instead. - new Thread(() => ShowAssertionDialog(message, detailMessage, stackTrace, false)).Start(); - return; - } - } - ShowAssertionDialog(message, detailMessage, stackTrace, true); + // We might be unable to display a dialog here, e.g. because + // we're on the UI thread but dispatcher processing is disabled. + // In any case, we don't want to pump messages while the dialog is displaying, + // so we create a separate UI thread for the dialog: + bool debug = false; + var thread = new Thread(() => ShowAssertionDialog(message, detailMessage, stackTrace, ref debug)); + thread.SetApartmentState(ApartmentState.STA); + thread.Start(); + thread.Join(); + if (debug) + Debugger.Break(); } - void ShowAssertionDialog(string message, string detailMessage, string stackTrace, bool canDebug) + void ShowAssertionDialog(string message, string detailMessage, string stackTrace, ref bool debug) { message = message + Environment.NewLine + detailMessage + Environment.NewLine + stackTrace; - List buttonTexts = new List { "Show Stacktrace", "Debug", "Ignore", "Ignore All" }; - if (!canDebug) { - buttonTexts.RemoveAt(1); - } - CustomDialog inputBox = new CustomDialog("Assertion Failed", message.TakeStartEllipsis(750), -1, 2, buttonTexts.ToArray()); + string[] buttonTexts = { "Show Stacktrace", "Debug", "Ignore", "Ignore All" }; + CustomDialog inputBox = new CustomDialog("Assertion Failed", message.TakeStartEllipsis(750), -1, 2, buttonTexts); try { while (true) { // show the dialog repeatedly until an option other than 'Show Stacktrace' is selected - if (SD.MainThread.InvokeRequired) { - inputBox.ShowDialog(); - } else { - inputBox.ShowDialog(SD.WinForms.MainWin32Window); - } + inputBox.ShowDialog(); int result = inputBox.Result; - if (!canDebug && result >= 1) - result++; switch (result) { case 0: ExceptionBox.ShowErrorBox(null, message); break; // show the custom dialog again case 1: - Debugger.Break(); + debug = true; return; case 2: return; diff --git a/src/Main/SharpDevelop/Project/Solution.cs b/src/Main/SharpDevelop/Project/Solution.cs index c1a3071d5f..9728623ff3 100644 --- a/src/Main/SharpDevelop/Project/Solution.cs +++ b/src/Main/SharpDevelop/Project/Solution.cs @@ -194,7 +194,7 @@ namespace ICSharpCode.SharpDevelop.Project foreach (var project in removedItems) project.Dispose(); if (startupProjectWasRemoved || (solution.startupProject == null && addedItems.Contains(solution.AutoDetectStartupProject()))) - solution.StartupProjectChanged(this, EventArgs.Empty); + solution.StartupProjectChanged(solution, EventArgs.Empty); } }