void ResetLayoutDefinitionVisibility() { LayoutDefinition mostRecentlyActiveLayout = null; foreach (var layoutDef in this.EditableLayoutDefinitions) { bool isVisible = layoutDef.DocumentFactoryName == null || StringComparer.OrdinalIgnoreCase.Equals(layoutDef.DocumentFactoryName, this.SelectedDocumentCategory.DocumentFactoryName); ViewLayoutEditor.SetIsLayoutVisible(layoutDef, isVisible); if (isVisible) { if (mostRecentlyActiveLayout == null || mostRecentlyActiveLayout.ActivationIndex < layoutDef.ActivationIndex) { mostRecentlyActiveLayout = layoutDef; } } } if ((mostRecentlyActiveLayout == null) && (this.tabControl != null)) { this.tabControl.SelectedIndex = -1; } else if (this.tabControl != null) { this.tabControl.SelectedItem = mostRecentlyActiveLayout; } foreach (var category in this.DocumentCategories) { SetIsCategorySelected(category, category == this.SelectedDocumentCategory); } }
public ViewSource(LayoutDefinition parent, int id, string slotName, IViewCreationCommand creator) { this.Parent = parent; this.Id = id; this.SlotName = slotName; this.ViewCreator = creator; this.Title = this.ViewCreator.DisplayName; }
public ViewSource(LayoutDefinition parent, int id, string slotName, IViewCreationCommand creator) { this.Parent = parent; this.Id = id; this.SlotName = slotName; this.ViewCreator = creator; this.Title = this.ViewCreator.DisplayName; }
static void OnHeaderChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { LayoutDefinition layoutDef = obj as LayoutDefinition; if (layoutDef != null) { var handler = layoutDef.HeaderChanged; if (handler != null) { handler(layoutDef, EventArgs.Empty); } } }
void AddPlaceholder(string documentFactoryName) { var layoutDef = new LayoutDefinition { Header = "", Id = Guid.NewGuid(), DocumentFactoryName = documentFactoryName, IsNewPlaceholder = true }; layoutDef.PlaceholderModified += OnPlaceholderModified; InsertLayoutDefinition(this.EditableLayoutDefinitions, layoutDef); }
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(); }
public static LayoutDefinition LoadFromState(XElement state, IDictionary <string, IViewCreationCommand> viewCreators) { var page = new LayoutDefinition(); page.Header = state.Attribute("Name").Value; page.ReadState(state, viewCreators); var docKindAttr = state.Attribute("DocumentFactoryName"); if (docKindAttr != null) { page.DocumentFactoryName = docKindAttr.Value; } var idAttr = state.Attribute("Id"); if (idAttr != null) { page.Id = Guid.Parse(idAttr.Value); } page.RecomputeViewShortcutKeys(); return(page); }
public static LayoutDefinition LoadFromState(XElement state, IDictionary<string, IViewCreationCommand> viewCreators) { var page = new LayoutDefinition(); page.Header = state.Attribute("Name").Value; page.ReadState(state, viewCreators); var docKindAttr = state.Attribute("DocumentFactoryName"); if (docKindAttr != null) { page.DocumentFactoryName = docKindAttr.Value; } var idAttr = state.Attribute("Id"); if (idAttr != null) { page.Id = Guid.Parse(idAttr.Value); } page.RecomputeViewShortcutKeys(); return page; }
void AddPlaceholder(string documentFactoryName) { var layoutDef = new LayoutDefinition { Header = "", Id = Guid.NewGuid(), DocumentFactoryName = documentFactoryName, IsNewPlaceholder = true }; layoutDef.PlaceholderModified += OnPlaceholderModified; InsertLayoutDefinition(this.EditableLayoutDefinitions, layoutDef); }
void InsertLayoutDefinition(ObservableCollection<LayoutDefinition> list, LayoutDefinition layoutDef) { list.Insert(FindInsertIndexForDocumentFactory(list, layoutDef.DocumentFactoryName), layoutDef); }
void InsertLayoutDefinition(ObservableCollection <LayoutDefinition> list, LayoutDefinition layoutDef) { list.Insert(FindInsertIndexForDocumentFactory(list, layoutDef.DocumentFactoryName), layoutDef); }
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; } } }
public LayoutInstance(IServiceProvider serviceProvider, IActivationSite parentSite, LayoutDefinition layoutDefinition, bool isInEditMode) { this.LayoutDefinition = layoutDefinition; this.LayoutDefinition.SlotDefinition.Changed += OnRootSlotChanged; this.LayoutDefinition.ViewSources.CollectionChanged += OnLayoutDefinitionViewSourcesChanged; this.ParentSite = parentSite; this.IsInEditMode = isInEditMode; this.serviceContainer = new ServiceContainer(serviceProvider); this.serviceContainer.AddService(typeof(IViewBindingService), this); this.ServiceProvider = serviceContainer; this.LayoutControl = new LayoutControl(this); this.LayoutControl.SlotDefinition = isInEditMode ? this.LayoutDefinition.SlotDefinition : this.LayoutDefinition.SlotDefinition.Clone(); this.singleViewContentTemplate = this.LayoutControl.FindResource(isInEditMode ? "EditModeSingleViewContentTemplate" : "SingleViewContentTemplate") as DataTemplate; this.tabbedViewContentTemplate = this.LayoutControl.FindResource(isInEditMode ? "EditModeTabbedViewContentTemplate" : "TabbedViewContentTemplate") as DataTemplate; this.ourWindow = serviceProvider.GetService(typeof(ToolsUIWindow)) as ToolsUIWindow; object stateObject; // We do this trick (storing our activation state in our window per layout definition) so that // the layout editor can create an instance that matches the "real" layout states. if (!this.ourWindow.StateTable.TryGetValue(this.LayoutDefinition, out stateObject)) { stateObject = new LayoutInstanceState(); this.ourWindow.StateTable[this.LayoutDefinition] = stateObject; } this.state = (LayoutInstanceState)stateObject; EnsureSlotContentPopulation(); }
public void ReadState(XElement element) { if (this.LayoutDefinition.RevertedToDefault) { // This layout was reverted to default at startup, so ignore the saved instance state (it probably doesn't map). return; } var activationIndexAttr = element.Attribute("ActivationIndex"); if (activationIndexAttr != null) { int index; if (int.TryParse(activationIndexAttr.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out index)) { this.ActivationIndex = index; nextActivationIndex = Math.Max(index + 1, nextActivationIndex); } } var slotElement = element.Element("Slot"); if (slotElement != null) { this.LayoutControl.SlotDefinition = LayoutDefinition.LoadSlotFromState(element.Element("Slot")); try { var viewElementTable = element.Elements("View").ToDictionary(e => int.Parse(e.Attribute("Id").Value)); foreach (var site in this.existingSlotContents.Values.SelectMany(sc => sc.ViewSites)) { XElement viewElement; if (viewElementTable.TryGetValue(site.ViewSource.Id, out viewElement)) { Debug.Assert(viewElement.Attribute("RegisteredName").Value == site.View.ViewCreationCommand.RegisteredName); Debug.Assert(viewElement.Attribute("SlotName").Value == site.ViewSource.SlotName); var titleAttr = viewElement.Attribute("Title"); if (titleAttr != null) { site.ViewSource.Title = titleAttr.Value; } var viewStateElement = viewElement.Element("ViewState"); if (viewStateElement != null && viewStateElement.Elements().Any()) { site.View.LoadViewState(viewStateElement.Elements().First()); } if (viewElement.Attribute("IsSelected") != null) { var slotContent = site.FindParentSite <SlotContent>(); if (slotContent != null) { slotContent.TopmostViewSite = site; } } } } } catch (Exception) { // Ignore } } }
public void WriteState(XElement element) { element.Add(new XAttribute("ActivationIndex", this.ActivationIndex)); element.Add(LayoutDefinition.BuildSlotElement(this.LayoutControl.SlotDefinition)); element.Add(this.existingSlotContents.Values.SelectMany(s => BuildViewStateElements(s))); }