Beispiel #1
0
        internal void LoadWindowState(ToolsUIWindow mainWindow)
        {
            this.mainWindow = mainWindow;

            try
            {
                var defaultStateText         = GetDefaultWindowStateResourceText();
                var stateDoc                 = XElement.Parse(defaultStateText);
                var layoutDefinitionsElement = stateDoc.Element("LayoutDefinitions");

                this.defaultLayoutDefinitions = layoutDefinitionsElement.Elements("LayoutDefinition")
                                                .Select(e => LayoutDefinition.LoadFromState(e, this.viewCreators))
                                                .ToList();
            }
            catch (Exception)
            {
                this.defaultLayoutDefinitions = new List <LayoutDefinition>();
            }

            LoadWindowState();
        }
Beispiel #2
0
        void TryLoadWindowState()
        {
            if (!File.Exists(this.windowStateFileName))
            {
                // Load nothing.
                return;
            }

            XElement   windowStateRoot = XElement.Load(this.windowStateFileName);
            XAttribute versionAttr     = windowStateRoot.Attribute("Version");
            XElement   mainWindowState = windowStateRoot.Element("MainWindow");
            XElement   layoutState     = windowStateRoot.Element("LayoutDefinitions");
            int        version;

            if (versionAttr == null || !int.TryParse(versionAttr.Value, out version) || version != WindowStateVersion)
            {
                throw new VersionMismatchException();
            }

            var bumpedDocumentFactories = new HashSet <string>();
            var defaultLayoutVersions   = windowStateRoot.Element("DefaultLayoutVersions");

            if (defaultLayoutVersions != null)
            {
                foreach (var layoutVersion in defaultLayoutVersions.Elements("DefaultLayoutVersion"))
                {
                    var factory = this.ExtensionManager.LookupDocumentFactory(layoutVersion.Attribute("DocumentFactoryName").Value);

                    if (int.Parse(layoutVersion.Attribute("Version").Value) < factory.DefaultLayoutVersion)
                    {
                        bumpedDocumentFactories.Add(factory.Name);
                    }
                }
            }

            // Don't call clear here, instead remove one at a time.  Reason:  Calling Clear()
            // sends a "Reset" event, and the layout handling code in ToolsUIWindow gets mad at that.
            // Usually doesn't matter (at startup), but this also gets called as part of "Revert
            // to Default Window State".
            while (this.LayoutDefinitions.Count > 0)
            {
                this.LayoutDefinitions.RemoveAt(0);
            }

            var usedIds          = new HashSet <Guid>();
            var loadedLayoutDefs = new Dictionary <string, List <LayoutDefinition> >();

            foreach (var layoutDefElement in layoutState.Elements("LayoutDefinition"))
            {
                var layoutDef = LayoutDefinition.LoadFromState(layoutDefElement, this.viewCreators);

                if (layoutDef.Id.Equals(Guid.Empty))
                {
                    // Could be from a state format before layouts had ID's.  Match the name and document affinity to the
                    // default set, and if found, assume its ID.  Failing that, give it a fresh one.
                    var defaultLayoutDef = this.defaultLayoutDefinitions.FirstOrDefault(ld => ld.Header == layoutDef.Header && ld.DocumentFactoryName == layoutDef.DocumentFactoryName);

                    if (defaultLayoutDef != null && !usedIds.Contains(defaultLayoutDef.Id))
                    {
                        layoutDef.Id = defaultLayoutDef.Id;
                    }
                    else
                    {
                        layoutDef.Id = Guid.NewGuid();
                    }
                }

                // We only do this to guard against users having same-named layouts (affinitized with the same document factory).  We
                // trust that Guid.NewGuid actually creates unique values...
                usedIds.Add(layoutDef.Id);

                if (layoutDef.DocumentFactoryName == null)
                {
                    // This is a "global" (any-document) layout, so we can add it now.
                    this.LayoutDefinitions.Add(layoutDef);
                }
                else
                {
                    List <LayoutDefinition> list;

                    // Stage this for validation against layout version
                    if (!loadedLayoutDefs.TryGetValue(layoutDef.DocumentFactoryName, out list))
                    {
                        list = new List <LayoutDefinition>();
                        loadedLayoutDefs.Add(layoutDef.DocumentFactoryName, list);
                    }

                    list.Add(layoutDef);
                }
            }

            foreach (var kvp in loadedLayoutDefs)
            {
                if (bumpedDocumentFactories.Contains(kvp.Key))
                {
                    var oldSet = kvp.Value.ToDictionary(ld => ld.Id);

                    // These need to be updated/upgraded. We do that giving preference to the defaults by loading them first,
                    // but keep their names in case the user has changed them.  Then add the remaining loaded layouts.
                    foreach (var layout in this.defaultLayoutDefinitions.Where(ld => ld.DocumentFactoryName == kvp.Key))
                    {
                        LayoutDefinition existingLayout;

                        if (oldSet.TryGetValue(layout.Id, out existingLayout))
                        {
                            layout.Header = existingLayout.Header;
                            oldSet.Remove(layout.Id);
                        }

                        // Mark this layout as having been reverted to default.  This prevents the per-instance state data
                        // from being loaded, which would likely fail due to structure mismatch with the definition.
                        layout.RevertedToDefault = true;
                        this.LayoutDefinitions.Add(layout);
                    }

                    // Get the rest -- don't just iterate over the dictionary, use the list instead to
                    // preserve order (as much as possible).  Note that these are not reverted to default, as
                    // they do not have one.
                    foreach (var remainingLayout in kvp.Value.Where(ld => oldSet.ContainsKey(ld.Id)))
                    {
                        this.LayoutDefinitions.Add(remainingLayout);
                    }
                }
                else
                {
                    // These are good to go
                    foreach (var layout in kvp.Value)
                    {
                        this.LayoutDefinitions.Add(layout);
                    }
                }
            }

            if (mainWindowState != null)
            {
                this.mainWindow.LoadWindowState(mainWindowState);
            }

            var windowElements = windowStateRoot.Elements("Window");

            if (windowElements.Any())
            {
                if (this.mainWindow.IsLoaded)
                {
                    RecreateAuxiliaryWindows(windowElements);
                }
                else
                {
                    RoutedEventHandler handler = null;

                    handler = (s, e) =>
                    {
                        RecreateAuxiliaryWindows(windowElements);
                        this.mainWindow.Loaded -= handler;
                        this.mainWindow.Activate();
                    };
                    this.mainWindow.Loaded += handler;
                }
            }
        }