/// <summary> /// Merge with another DefaultStyle. /// </summary> /// <param name="other">Other DefaultStyle to merge.</param> private void Merge(DefaultStyle other) { // Merge or lower namespaces foreach (KeyValuePair <string, string> ns in other.Namespaces) { string value = null; if (!Namespaces.TryGetValue(ns.Key, out value)) { Namespaces.Add(ns.Key, ns.Value); } else if (value != ns.Value) { other.LowerNamespace(ns.Key); } } // Merge the resources foreach (KeyValuePair <string, XElement> resource in other.Resources) { if (Resources.ContainsKey(resource.Key)) { throw new InvalidOperationException(string.Format( CultureInfo.InvariantCulture, "Resource \"{0}\" is used by both {1} and {2}!", resource.Key, MergeHistory[resource.Key], other.DefaultStylePath)); } Resources[resource.Key] = resource.Value; MergeHistory[resource.Key] = other.DefaultStylePath; } }
/// <summary> /// Merge a sequence of DefaultStyles into a single style. /// </summary> /// <param name="styles">Sequence of DefaultStyles.</param> /// <returns>Merged DefaultStyle.</returns> public static DefaultStyle Merge(IEnumerable <DefaultStyle> styles) { DefaultStyle combined = new DefaultStyle(); if (styles != null) { foreach (DefaultStyle style in styles) { combined.Merge(style); } } return(combined); }
/// <summary> /// Load a DefaultStyle from the a project item. /// </summary> /// <param name="path"> /// Path of the default style which is used for reporting errors. /// </param> /// <returns>The DefaultStyle.</returns> public static DefaultStyle Load(string path) { DefaultStyle style = new DefaultStyle(); style.DefaultStylePath = path; string xaml = File.ReadAllText(path); XElement root = XElement.Parse(xaml, LoadOptions.PreserveWhitespace); if (root.Name.LocalName == RootElement) { // Get the namespaces foreach (XAttribute attribute in root.Attributes()) { if (attribute.Name.LocalName == "xmlns") { style.Namespaces.Add("", attribute.Value); } else if (attribute.Name.NamespaceName == XNamespace.Xmlns.NamespaceName) { style.Namespaces.Add(attribute.Name.LocalName, attribute.Value); } } // Get the styles and shared resources foreach (XElement element in root.Elements()) { string name = (element.Name.LocalName == "Style") ? GetAttribute(element, "TargetType", "Key", "Name") : GetAttribute(element, "Key", "Name"); if (style.Resources.ContainsKey(name)) { throw new InvalidOperationException(string.Format( CultureInfo.InvariantCulture, "Resource \"{0}\" is used multiple times in {1} (possibly as a Key, Name, or TargetType)!", name, path)); } style.Resources.Add(name, element); style.MergeHistory[name] = path; } } return(style); }
/// <summary> /// Load a DefaultStyle from the a project item. /// </summary> /// <param name="path"> /// Path of the default style which is used for reporting errors. /// </param> /// <returns>The DefaultStyle.</returns> public static DefaultStyle Load(string path) { DefaultStyle style = new DefaultStyle(); style.DefaultStylePath = path; string xaml = File.ReadAllText(path); XElement root = XElement.Parse(xaml, LoadOptions.PreserveWhitespace); if (root.Name.LocalName == RootElement) { // Get the namespaces foreach (XAttribute attribute in root.Attributes()) { if (attribute.Name.LocalName == "xmlns") { style.Namespaces.Add("", attribute.Value); } else if (attribute.Name.NamespaceName == XNamespace.Xmlns.NamespaceName) { style.Namespaces.Add(attribute.Name.LocalName, attribute.Value); } } // Get the styles and shared resources foreach (XElement element in root.Elements()) { string name = (element.Name.LocalName == "Style") ? GetAttribute(element, "TargetType", "Key", "Name") : GetAttribute(element, "Key", "Name"); if (style.Resources.ContainsKey(name)) { throw new InvalidOperationException(string.Format( CultureInfo.InvariantCulture, "Resource \"{0}\" is used multiple times in {1} (possibly as a Key, Name, or TargetType)!", name, path)); } style.Resources.Add(name, element); style.MergeHistory[name] = path; } } return style; }
public override bool Execute() { Log.LogMessage(MessageImportance.Low, "Merging default styles into Generic.xaml."); // Get the original generic.xaml string originalPath = Path.Combine(ProjectDirectory, Path.Combine("Themes", "Generic.xaml")); if (!File.Exists(originalPath)) { Log.LogError("{0} does not exist!", originalPath); return(false); } Log.LogMessage(MessageImportance.Low, "Found original Generic.xaml at {0}.", originalPath); string original = null; Encoding encoding = Encoding.Default; try { using (StreamReader reader = new StreamReader(File.Open(originalPath, FileMode.Open, FileAccess.Read))) { original = reader.ReadToEnd(); encoding = reader.CurrentEncoding; } } catch (Exception ex) { Log.LogErrorFromException(ex); return(false); } // Create the merged Generic.xaml List <DefaultStyle> styles = new List <DefaultStyle>(); foreach (ITaskItem item in DefaultStyles) { string path = Path.Combine(ProjectDirectory, item.ItemSpec); if (!File.Exists(path)) { Log.LogWarning("Ignoring missing DefaultStyle {0}.", path); continue; } try { Log.LogMessage(MessageImportance.Low, "Processing file {0}.", item.ItemSpec); styles.Add(DefaultStyle.Load(path)); } catch (Exception ex) { Log.LogErrorFromException(ex); } } string merged = null; try { merged = DefaultStyle.Merge(styles).GenerateXaml(); } catch (InvalidOperationException ex) { Log.LogErrorFromException(ex); return(false); } // Write the new generic.xaml if (original != merged) { Log.LogMessage(MessageImportance.Low, "Writing merged Generic.xaml."); if (EnableTfs && TryTfs.Checkout(originalPath)) { Log.LogMessage("Checked out Generic.xaml."); } else { // Remove read-only flag File.SetAttributes(originalPath, FileAttributes.Normal); } try { File.WriteAllText(originalPath, merged, encoding); Log.LogMessage("Successfully merged Generic.xaml."); } catch (Exception ex) { Log.LogErrorFromException(ex); return(false); } } else { Log.LogMessage("Existing Generic.xaml was up to date."); } return(true); }
/// <summary> /// Merge with another DefaultStyle. /// </summary> /// <param name="other">Other DefaultStyle to merge.</param> private void Merge(DefaultStyle other) { // Merge or lower namespaces foreach (KeyValuePair<string, string> ns in other.Namespaces) { string value = null; if (!Namespaces.TryGetValue(ns.Key, out value)) { Namespaces.Add(ns.Key, ns.Value); } else if (value != ns.Value) { other.LowerNamespace(ns.Key); } } // Merge the resources foreach (KeyValuePair<string, XElement> resource in other.Resources) { if (Resources.ContainsKey(resource.Key)) { throw new InvalidOperationException(string.Format( CultureInfo.InvariantCulture, "Resource \"{0}\" is used by both {1} and {2}!", resource.Key, MergeHistory[resource.Key], other.DefaultStylePath)); } Resources[resource.Key] = resource.Value; MergeHistory[resource.Key] = other.DefaultStylePath; } }
/// <summary> /// Merge a sequence of DefaultStyles into a single style. /// </summary> /// <param name="styles">Sequence of DefaultStyles.</param> /// <returns>Merged DefaultStyle.</returns> public static DefaultStyle Merge(IEnumerable<DefaultStyle> styles) { DefaultStyle combined = new DefaultStyle(); if (styles != null) { foreach (DefaultStyle style in styles) { combined.Merge(style); } } return combined; }