예제 #1
0
        /// <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, ElementInfo> 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;
            }
        }
예제 #2
0
        /// <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)
        {
            var combined = new DefaultStyle();

            if (styles != null)
            {
                foreach (DefaultStyle style in styles)
                {
                    combined.Merge(style);
                }
            }

            return(combined);
        }
예제 #3
0
        /// <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)
        {
            var style = new DefaultStyle();
            var xaml  = File.ReadAllText(path);
            var root  = XElement.Parse(xaml, LoadOptions.PreserveWhitespace);

            style.DefaultStylePath = path;

            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;
                    string targetType;
                    string elementName;
                    string elementKey;

                    name = string.Empty;

                    if (element.Name.LocalName == "Style")
                    {
                        targetType  = GetAttribute(element, "TargetType");
                        elementName = GetAttribute(element, "Name");
                        elementKey  = GetAttribute(element, "Key");

                        name = "Style(";
                        if (targetType != null)
                        {
                            name += "TargetType=" + targetType;
                        }

                        if (elementName != null)
                        {
                            if (targetType != null)
                            {
                                name += ",";
                            }

                            name += "Name=" + name;
                        }

                        if (elementKey != null)
                        {
                            if (targetType != null || elementName != null)
                            {
                                name += ",";
                            }

                            name += "Key=" + elementKey;
                        }

                        name += ")";
                    }
                    else
                    {
                        elementName = GetAttribute(element, "Name");
                        elementKey  = GetAttribute(element, "Key");

                        if (elementName != null)
                        {
                            name += "Name=" + name;
                        }

                        if (elementKey != null)
                        {
                            if (elementName != null)
                            {
                                name += ",";
                            }

                            name += "Key=" + elementKey;
                        }
                    }

                    if (style.Resources.ContainsKey(name))
                    {
                        throw new InvalidOperationException(string.Format(
                                                                CultureInfo.InvariantCulture,
                                                                "Resource \"{0}\" is defined multiple times in: {1}",
                                                                name,
                                                                path));
                    }

                    style.Resources.Add(name, new ElementInfo(element, MergeDefaultStylesTask.Order++));
                    style.MergeHistory[name] = path;
                }
            }

            return(style);
        }
예제 #4
0
        public override bool Execute()
        {
            Order = 0;

            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.");

                try
                {
                    // Could interact with the source control system / TFS here
                    File.SetAttributes(originalPath, FileAttributes.Normal);
                    Log.LogMessage("Removed any read-only flag for generic.xaml.");

                    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);
        }