/// <summary> /// Save changes on exit if necessary /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { BaseContentEditor content; string state; if(cancellationTokenSource != null) { if(cancellationTokenSource.IsCancellationRequested) return; if(MessageBox.Show("A build is currently taking place. Do you want to abort it and exit?", Constants.AppName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) { e.Cancel = true; return; } miCancelBuild_Click(sender, e); return; } if(!projectExplorer.AskToSaveProject()) e.Cancel = true; else foreach(IDockContent dockContent in dockPanel.Contents) { content = dockContent as BaseContentEditor; if(content != null && !content.CanClose) { e.Cancel = true; break; } } if(!e.Cancel) { // Save the current window size and position if possible WINDOWPLACEMENT wp = new WINDOWPLACEMENT(); wp.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT)); UnsafeNativeMethods.GetWindowPlacement(this.Handle, out wp); Settings.Default.WindowPlacement = wp; // Save the content state. If open, hide some of the windows // so that they default to hidden when re-opened. if(outputWindow != null && outputWindow.Visible) outputWindow.Hide(); if(entityReferencesWindow != null && entityReferencesWindow.Visible) entityReferencesWindow.Hide(); // Dispose of the preview window to get rid of its temporary project and build files if(previewWindow != null) { previewWindow.Dispose(); previewWindow = null; } // Save the default window state using(MemoryStream ms = new MemoryStream()) { dockPanel.SaveAsXml(ms, Encoding.UTF8); state = Encoding.UTF8.GetString(ms.ToArray()); Settings.Default.ContentEditorDockState = state; } Settings.Default.Save(); this.KillWebServer(); // Save per user project state if wanted if(projectExplorer.CurrentProject != null && Settings.Default.PerUserProjectState) { // If hidden, unhide it so that DockPanel can write to it. We'll hide it again afterwards. bool isHidden = (File.Exists(projectExplorer.CurrentProject.Filename + WindowStateSuffix) && (File.GetAttributes(projectExplorer.CurrentProject.Filename + WindowStateSuffix) & FileAttributes.Hidden) != 0); try { Cursor.Current = Cursors.WaitCursor; if(isHidden) File.SetAttributes(projectExplorer.CurrentProject.Filename + WindowStateSuffix, FileAttributes.Normal); dockPanel.SaveAsXml(projectExplorer.CurrentProject.Filename + WindowStateSuffix); if(isHidden) File.SetAttributes(projectExplorer.CurrentProject.Filename + WindowStateSuffix, FileAttributes.Hidden); } finally { Cursor.Current = Cursors.Default; } } } }
/// <summary> /// Create a new project instance and connect it to the UI /// </summary> /// <param name="projectName">The project filename</param> /// <param name="mustExist">True if it must exist or false if it is a new, unnamed project</param> private void CreateProject(string projectName, bool mustExist) { List<string> values; project = new SandcastleProject(projectName, mustExist, false); projectExplorer.CurrentProject = projectProperties.CurrentProject = project; if(entityReferencesWindow != null) entityReferencesWindow.CurrentProject = project; this.UpdateFilenameInfo(); // Get the configuration and platform values values = project.MSBuildProject.ConditionedProperties["Configuration"]; tcbConfig.Items.Clear(); foreach(string value in values) tcbConfig.Items.Add(value); if(tcbConfig.Items.Count == 0) { tcbConfig.Items.Add("Debug"); tcbConfig.Items.Add("Release"); } values = project.MSBuildProject.ConditionedProperties["Platform"]; tcbPlatform.Items.Clear(); foreach(string value in values) tcbPlatform.Items.Add(value); if(tcbPlatform.Items.Count == 0) tcbPlatform.Items.Add("AnyCPU"); if(tcbConfig.Items.Contains(Settings.Default.LastConfig)) tcbConfig.SelectedItem = Settings.Default.LastConfig; else tcbConfig.SelectedIndex = 0; if(tcbPlatform.Items.Contains(Settings.Default.LastPlatform)) tcbPlatform.SelectedItem = Settings.Default.LastPlatform; else tcbPlatform.SelectedIndex = 0; miDocumentation.Visible = miCloseProject.Enabled = miClose.Enabled = miSave.Enabled = miSaveAs.Enabled = tsbSave.Enabled = tsbSaveAll.Enabled = miSaveAll.Enabled = miProjectExplorer.Visible = miExplorerSeparator.Visible = tsbBuildProject.Enabled = tsbViewHelpFile.Enabled = miPreviewTopic.Enabled = tsbPreviewTopic.Enabled = true; Directory.SetCurrentDirectory(Path.GetDirectoryName(Path.GetFullPath(project.Filename))); if(Settings.Default.PerUserProjectState && File.Exists(project.Filename + WindowStateSuffix)) { try { Cursor.Current = Cursors.WaitCursor; dockPanel.SuspendLayout(true); projectExplorer.DockPanel = null; projectProperties.DockPanel = null; if(outputWindow != null) outputWindow.DockPanel = null; if(entityReferencesWindow != null) entityReferencesWindow.DockPanel = null; if(previewWindow != null) { previewWindow.Dispose(); previewWindow = null; } dockPanel.LoadFromXml(project.Filename + WindowStateSuffix, DeserializeState); } catch(InvalidOperationException ) { // Ignore errors if the content settings don't load miViewProjectExplorer_Click(this, EventArgs.Empty); miViewProjectProperties_Click(this, EventArgs.Empty); } finally { Cursor.Current = Cursors.Default; dockPanel.ResumeLayout(true, true); } } else { miViewProjectExplorer_Click(this, EventArgs.Empty); miViewProjectProperties_Click(this, EventArgs.Empty); } }
/// <summary> /// Close the current project /// </summary> /// <returns>True if the project was closed, false if not</returns> private bool CloseProject() { BaseContentEditor content; IDockContent[] contents; if(projectExplorer.AskToSaveProject()) { miClearOutput_Click(this, EventArgs.Empty); this.KillWebServer(); // Dispose of the preview window as it doesn't make much sense to save its state if(previewWindow != null) { previewWindow.Dispose(); previewWindow = null; } if(outputWindow != null) { outputWindow.ResetLogViewer(); outputWindow.LogFile = null; } if(entityReferencesWindow != null) entityReferencesWindow.CurrentProject = null; if(projectExplorer.CurrentProject != null && Settings.Default.PerUserProjectState) { // If hidden, unhide it so that DockPanel can write to it. We'll hide it again afterwards. bool isHidden = (File.Exists(projectExplorer.CurrentProject.Filename + WindowStateSuffix) && (File.GetAttributes(projectExplorer.CurrentProject.Filename + WindowStateSuffix) & FileAttributes.Hidden) != 0); try { Cursor.Current = Cursors.WaitCursor; if(isHidden) File.SetAttributes(projectExplorer.CurrentProject.Filename + WindowStateSuffix, FileAttributes.Normal); dockPanel.SaveAsXml(projectExplorer.CurrentProject.Filename + WindowStateSuffix); if(isHidden) File.SetAttributes(projectExplorer.CurrentProject.Filename + WindowStateSuffix, FileAttributes.Hidden); } finally { Cursor.Current = Cursors.Default; } } // Close all content editors contents = new IDockContent[dockPanel.Contents.Count]; dockPanel.Contents.CopyTo(contents, 0); foreach(IDockContent dockContent in contents) { content = dockContent as BaseContentEditor; // If one can't close, don't close the project if(content != null && !content.CanClose) { projectExplorer.Activate(); return false; } if(dockContent.DockHandler.HideOnClose) dockContent.DockHandler.Hide(); else dockContent.DockHandler.Close(); } if(project != null) project.Dispose(); project = projectExplorer.CurrentProject = projectProperties.CurrentProject = null; this.UpdateFilenameInfo(); miDocumentation.Visible = miCloseProject.Enabled = miClose.Enabled = miCloseAll.Enabled = miCloseAllButCurrent.Enabled = miSave.Enabled = miSaveAs.Enabled = miSaveAll.Enabled = tsbSave.Enabled = tsbSaveAll.Enabled = miProjectExplorer.Visible = miExplorerSeparator.Visible = tsbBuildProject.Enabled = tsbViewHelpFile.Enabled = miPreviewTopic.Enabled = tsbPreviewTopic.Enabled = false; return true; } return false; }
/// <summary> /// Open or show the preview topic window /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void miPreviewTopic_Click(object sender, EventArgs e) { TopicEditorWindow editor; FileItem fileItem = null; dockPanel.CheckFocusedContent(); // HACK editor = dockPanel.ActiveDocument as TopicEditorWindow; // If we are in a topic editor, show it by default when the previewer opens if(editor == null) { foreach(IDockContent document in dockPanel.Contents) { editor = document as TopicEditorWindow; if(editor != null) break; } } if(editor != null) fileItem = project.FindFile(editor.Filename); try { Cursor.Current = Cursors.WaitCursor; if(previewWindow == null) { previewWindow = new PreviewTopicWindow(); previewWindow.Show(dockPanel); } previewWindow.PreviewTopic(project, (fileItem == null) ? null : fileItem.FullPath); previewWindow.Activate(); // When the state is restored and it's a document pane, it doesn't always become the active pane // unless this is called. previewWindow.Show(dockPanel, previewWindow.DockState); } finally { Cursor.Current = Cursors.Default; } }
/// <summary> /// Save changes on exit if necessary /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { BaseContentEditor content; string state; if(buildThread != null && buildThread.IsAlive) { if(MessageBox.Show("A build is currently taking place. Do " + "you want to abort it and exit?", Constants.AppName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) { e.Cancel = true; return; } miCancelBuild_Click(sender, e); } if(!projectExplorer.AskToSaveProject()) e.Cancel = true; else foreach(IDockContent dockContent in dockPanel.Contents) { content = dockContent as BaseContentEditor; if(content != null && !content.CanClose) { e.Cancel = true; break; } } if(!e.Cancel && previewWindow != null) e.Cancel = !previewWindow.CanClose; if(!e.Cancel) { // Save the current window size and position if possible WINDOWPLACEMENT wp = new WINDOWPLACEMENT(); wp.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT)); UnsafeNativeMethods.GetWindowPlacement(this.Handle, out wp); Settings.Default.WindowPlacement = wp; // Save the content state. If open, hide some of the windows // so that they default to hidden when re-opened. if(outputWindow != null && outputWindow.Visible) outputWindow.Hide(); if(entityReferencesWindow != null && entityReferencesWindow.Visible) entityReferencesWindow.Hide(); if(previewWindow != null && previewWindow.Visible) previewWindow.Hide(); using(MemoryStream ms = new MemoryStream()) { dockPanel.SaveAsXml(ms, Encoding.UTF8); state = Encoding.UTF8.GetString(ms.ToArray()); Settings.Default.ContentEditorDockState = state; } // Dispose of the preview window to get rid of its temporary // project and build files. if(previewWindow != null) { previewWindow.Close(); previewWindow = null; } Settings.Default.Save(); this.KillWebServer(); } }
//===================================================================== /// <summary> /// Deserialize the state of a content pane. /// </summary> /// <param name="persistString">The name of the item being deserialized</param> /// <returns>The dock content if deserialized or null if not.</returns> private IDockContent DeserializeState(string persistString) { if(persistString == typeof(ProjectExplorerWindow).FullName) return projectExplorer; if(persistString == typeof(ProjectPropertiesWindow).FullName) return projectProperties; if(persistString == typeof(OutputWindow).FullName) { outputWindow = new OutputWindow(); return outputWindow; } if(persistString == typeof(EntityReferenceWindow).FullName) { entityReferencesWindow = new EntityReferenceWindow(tsslStatusText); return entityReferencesWindow; } if(persistString == typeof(PreviewTopicWindow).FullName) { previewWindow = new PreviewTopicWindow(); return previewWindow; } return null; }
/// <summary> /// Close the current project /// </summary> /// <returns>True if the project was closed, false if not</returns> private bool CloseProject() { BaseContentEditor content; IDockContent[] contents = new IDockContent[dockPanel.Contents.Count]; dockPanel.Contents.CopyTo(contents, 0); if(projectExplorer.AskToSaveProject()) { // Close all content editors foreach(IDockContent dockContent in contents) { content = dockContent as BaseContentEditor; // If one can't close, don't close the project if(content != null && !content.CanClose) { projectExplorer.Activate(); return false; } if(dockContent.DockHandler.HideOnClose) dockContent.DockHandler.Hide(); else dockContent.DockHandler.Close(); } miClearOutput_Click(this, EventArgs.Empty); this.KillWebServer(); // Dispose of the preview window to get rid of its temporary // project and build files. if(previewWindow != null) { previewWindow.Close(); previewWindow = null; } if(outputWindow != null) { outputWindow.ResetLogViewer(); outputWindow.LogFile = null; } if(entityReferencesWindow != null) entityReferencesWindow.CurrentProject = null; project = projectExplorer.CurrentProject = projectProperties.CurrentProject = null; this.UpdateFilenameInfo(); miDocumentation.Visible = miCloseProject.Enabled = miClose.Enabled = miCloseAll.Enabled = miCloseAllButCurrent.Enabled = miSave.Enabled = miSaveAs.Enabled = miSaveAll.Enabled = tsbSave.Enabled = tsbSaveAll.Enabled = miProjectExplorer.Visible = miExplorerSeparator.Visible = tsbBuildProject.Enabled = tsbViewHelpFile.Enabled = miPreviewTopic.Enabled = tsbPreviewTopic.Enabled = false; return true; } return false; }
/// <summary> /// Open or show the preview topic window /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void miPreviewTopic_Click(object sender, EventArgs e) { TopicEditorWindow editor; FileItem fileItem; dockPanel.CheckFocusedContent(); // HACK editor = dockPanel.ActiveDocument as TopicEditorWindow; if(editor == null) { foreach(IDockContent document in dockPanel.Contents) { editor = document as TopicEditorWindow; if(editor != null) break; } if(editor == null) return; } if(!this.SaveBeforeBuild()) return; if(previewWindow == null) { previewWindow = new PreviewTopicWindow(); previewWindow.Show(dockPanel); } fileItem = project.FindFile(editor.Filename); if(fileItem != null) { // Save the editor to ensure it is current on disk. This has // to happen regardless of the BeforeBuild preference or the // content won't be current. if(!editor.Save()) return; previewWindow.PreviewTopic(project, fileItem); previewWindow.Activate(); // When the state is restored and it's a document pane, it // doesn't always become the active pane unless this is called. previewWindow.Show(dockPanel, previewWindow.DockState); } }