/// <summary> /// Load the topic and display it when selected /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void tvContent_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e) { TocEntry t = tvContent.SelectedItem as TocEntry; if (t != null) { try { Mouse.OverrideCursor = Cursors.Wait; // If the file is open in an editor, use its current content var args = new TopicContentNeededEventArgs(TopicContentNeededEvent, this, t.SourceFile); if (!String.IsNullOrEmpty(t.SourceFile)) { base.RaiseEvent(args); } txtTitle.Text = t.PreviewerTitle; fdViewer.Document = converter.ToFlowDocument(t.SourceFile, args.TopicContent); this.AdjustPageWidth(); // Scroll to the top if not the first time shown DependencyObject child = fdViewer; if (VisualTreeHelper.GetChildrenCount(child) != 0) { while (!(child is ScrollViewer)) { child = VisualTreeHelper.GetChild(child as Visual, 0); } ((ScrollViewer)child).ScrollToHome(); } } catch (Exception ex) { // If we get here, something went really wrong MessageBox.Show("Unable to convert topic. Possible converter error. Reason: " + ex.Message, Constants.AppName, MessageBoxButton.OK, MessageBoxImage.Error); } finally { Mouse.OverrideCursor = null; } if (!isNavigating && !String.IsNullOrEmpty(t.Id)) { this.RecordHistory(new Uri("link://" + t.Id)); } } else { txtTitle.Text = null; fdViewer.Document = null; } }
/// <summary> /// Load the topic and display it when selected /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void tvContent_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) { TocEntry t = tvContent.SelectedItem as TocEntry; if(t != null) { try { Mouse.OverrideCursor = Cursors.Wait; // If the file is open in an editor, use its current content var args = new TopicContentNeededEventArgs(TopicContentNeededEvent, this, t.SourceFile); if(!String.IsNullOrEmpty(t.SourceFile)) base.RaiseEvent(args); txtTitle.Text = t.PreviewerTitle; fdViewer.Document = converter.ToFlowDocument(t.SourceFile, args.TopicContent); this.AdjustPageWidth(); // Scroll to the top if not the first time shown DependencyObject child = fdViewer; if(VisualTreeHelper.GetChildrenCount(child) != 0) { while(!(child is ScrollViewer)) child = VisualTreeHelper.GetChild(child as Visual, 0); ((ScrollViewer)child).ScrollToHome(); } } catch(Exception ex) { // If we get here, something went really wrong MessageBox.Show("Unable to convert topic. Possible converter error. Reason: " + ex.Message, Constants.AppName, MessageBoxButton.OK, MessageBoxImage.Error); } finally { Mouse.OverrideCursor = null; } if(!isNavigating && !String.IsNullOrEmpty(t.Id)) this.RecordHistory(new Uri("link://" + t.Id)); } else { txtTitle.Text = null; fdViewer.Document = null; } }
/// <summary> /// This is used to get the content of a specific topic file if it is open in an editor so that the /// current content is displayed for it in the topic previewer control. /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void ucTopicPreviewer_TopicContentNeeded(object sender, TopicContentNeededEventArgs e) { IVsHierarchy hier; IVsPersistDocData persistDocData; IVsTextStream srpStream; IntPtr docData = IntPtr.Zero; uint itemid, cookie = 0; int hr = VSConstants.E_FAIL; IVsRunningDocumentTable rdt = Utility.GetServiceFromPackage<IVsRunningDocumentTable, SVsRunningDocumentTable>(true); if(rdt == null) return; try { // Getting a read lock on the document. This must be released later. hr = rdt.FindAndLockDocument((uint)_VSRDTFLAGS.RDT_ReadLock, e.TopicFilename, out hier, out itemid, out docData, out cookie); if(ErrorHandler.Failed(hr) || docData == IntPtr.Zero) return; persistDocData = Marshal.GetObjectForIUnknown(docData) as IVsPersistDocData; // Try to get the Text lines IVsTextLines srpTextLines = persistDocData as IVsTextLines; if(srpTextLines == null) { // Try getting a text buffer provider first IVsTextBufferProvider srpTextBufferProvider = persistDocData as IVsTextBufferProvider; if(srpTextBufferProvider != null) hr = srpTextBufferProvider.GetTextBuffer(out srpTextLines); } if(ErrorHandler.Succeeded(hr)) { srpStream = srpTextLines as IVsTextStream; if(srpStream != null) { IVsBatchUpdate srpBatchUpdate = srpStream as IVsBatchUpdate; if(srpBatchUpdate != null) ErrorHandler.ThrowOnFailure(srpBatchUpdate.FlushPendingUpdates(0)); int lBufferSize = 0; hr = srpStream.GetSize(out lBufferSize); if(ErrorHandler.Succeeded(hr)) { IntPtr dest = IntPtr.Zero; try { // GetStream() returns Unicode data so we need to double the buffer size dest = Marshal.AllocCoTaskMem((lBufferSize + 1) * 2); ErrorHandler.ThrowOnFailure(srpStream.GetStream(0, lBufferSize, dest)); // Get the contents e.TopicContent = Marshal.PtrToStringUni(dest); } finally { if(dest != IntPtr.Zero) Marshal.FreeCoTaskMem(dest); } } } } } finally { if(docData != IntPtr.Zero) Marshal.Release(docData); if(cookie != 0) ErrorHandler.ThrowOnFailure(rdt.UnlockDocument((uint)_VSRDTFLAGS.RDT_ReadLock, cookie)); } }
/// <summary> /// This is used to get the content of a specific topic file if it is open in an editor so that the /// current content is displayed for it in the topic previewer control. /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void ucTopicPreviewer_TopicContentNeeded(object sender, TopicContentNeededEventArgs e) { TopicEditorWindow topicEditor; foreach(IDockContent content in this.DockPanel.Documents) { topicEditor = content as TopicEditorWindow; if(topicEditor != null && topicEditor.Filename.Equals(e.TopicFilename, StringComparison.OrdinalIgnoreCase)) e.TopicContent = topicEditor.FileContent; } }