284 lines
8.4 KiB
C#
284 lines
8.4 KiB
C#
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
using System;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.Management.Automation;
|
|
using System.Windows.Documents;
|
|
|
|
namespace Microsoft.Management.UI.Internal
|
|
{
|
|
/// <summary>
|
|
/// ViewModel for the Help Dialog used to:
|
|
/// build the help document
|
|
/// search the help document
|
|
/// offer text for labels.
|
|
/// </summary>
|
|
internal class HelpViewModel : INotifyPropertyChanged
|
|
{
|
|
/// <summary>
|
|
/// The builder for the help FlowDocument Paragraph used in a RichEditText control.
|
|
/// </summary>
|
|
private readonly HelpParagraphBuilder helpBuilder;
|
|
|
|
/// <summary>
|
|
/// Searcher for selecting current matches in paragraph text.
|
|
/// </summary>
|
|
private readonly ParagraphSearcher searcher;
|
|
|
|
/// <summary>
|
|
/// Title of the help window.
|
|
/// </summary>
|
|
private readonly string helpTitle;
|
|
|
|
/// <summary>
|
|
/// the zoom bound to the zoom slider value.
|
|
/// </summary>
|
|
private double zoom = 100;
|
|
|
|
/// <summary>
|
|
/// Text to be found. This is bound to the find TextBox.
|
|
/// </summary>
|
|
private string findText;
|
|
|
|
/// <summary>
|
|
/// text for the number of matches found.
|
|
/// </summary>
|
|
private string matchesLabel;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the HelpViewModel class.
|
|
/// </summary>
|
|
/// <param name="psObj">Object containing help.</param>
|
|
/// <param name="documentParagraph">Paragraph in which help text is built/searched.</param>
|
|
internal HelpViewModel(PSObject psObj, Paragraph documentParagraph)
|
|
{
|
|
Debug.Assert(psObj != null, "ensured by caller");
|
|
Debug.Assert(documentParagraph != null, "ensured by caller");
|
|
|
|
this.helpBuilder = new HelpParagraphBuilder(documentParagraph, psObj);
|
|
this.helpBuilder.BuildParagraph();
|
|
this.searcher = new ParagraphSearcher();
|
|
this.helpBuilder.PropertyChanged += new PropertyChangedEventHandler(this.HelpBuilder_PropertyChanged);
|
|
this.helpTitle = string.Format(
|
|
CultureInfo.CurrentCulture,
|
|
HelpWindowResources.HelpTitleFormat,
|
|
HelpParagraphBuilder.GetPropertyString(psObj, "name"));
|
|
}
|
|
|
|
#region INotifyPropertyChanged Members
|
|
/// <summary>
|
|
/// Used to notify of property changes.
|
|
/// </summary>
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Gets or sets the Zoom bound to the zoom slider value.
|
|
/// </summary>
|
|
public double Zoom
|
|
{
|
|
get
|
|
{
|
|
return this.zoom;
|
|
}
|
|
|
|
set
|
|
{
|
|
this.zoom = value;
|
|
this.OnNotifyPropertyChanged("Zoom");
|
|
this.OnNotifyPropertyChanged("ZoomLabel");
|
|
this.OnNotifyPropertyChanged("ZoomLevel");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the value bound to the RichTextEdit zoom, which is calculated based on the zoom.
|
|
/// </summary>
|
|
public double ZoomLevel
|
|
{
|
|
get
|
|
{
|
|
return this.zoom / 100.0;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the label to be displayed for the zoom.
|
|
/// </summary>
|
|
public string ZoomLabel
|
|
{
|
|
get
|
|
{
|
|
return string.Format(CultureInfo.CurrentCulture, HelpWindowResources.ZoomLabelTextFormat, this.zoom);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the text to be found.
|
|
/// </summary>
|
|
public string FindText
|
|
{
|
|
get
|
|
{
|
|
return this.findText;
|
|
}
|
|
|
|
set
|
|
{
|
|
this.findText = value;
|
|
this.Search();
|
|
this.SetMatchesLabel();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the title of the window.
|
|
/// </summary>
|
|
public string HelpTitle
|
|
{
|
|
get
|
|
{
|
|
return this.helpTitle;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the label for current matches.
|
|
/// </summary>
|
|
public string MatchesLabel
|
|
{
|
|
get
|
|
{
|
|
return this.matchesLabel;
|
|
}
|
|
|
|
set
|
|
{
|
|
this.matchesLabel = value;
|
|
this.OnNotifyPropertyChanged("MatchesLabel");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a value indicating whether there are matches to go to.
|
|
/// </summary>
|
|
public bool CanGoToNextOrPrevious
|
|
{
|
|
get
|
|
{
|
|
return this.HelpBuilder.HighlightCount != 0;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the searcher for selecting current matches in paragraph text.
|
|
/// </summary>
|
|
internal ParagraphSearcher Searcher
|
|
{
|
|
get { return this.searcher; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the paragraph builder used to write help content.
|
|
/// </summary>
|
|
internal HelpParagraphBuilder HelpBuilder
|
|
{
|
|
get { return this.helpBuilder; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Highlights all matches to this.findText
|
|
/// Called when findText changes or whenever the search has to be refreshed
|
|
/// </summary>
|
|
internal void Search()
|
|
{
|
|
this.HelpBuilder.HighlightAllInstancesOf(this.findText, HelpWindowSettings.Default.HelpSearchMatchCase, HelpWindowSettings.Default.HelpSearchWholeWord);
|
|
this.searcher.ResetSearch();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Increases Zoom if not above maximum.
|
|
/// </summary>
|
|
internal void ZoomIn()
|
|
{
|
|
if (this.Zoom + HelpWindow.ZoomInterval <= HelpWindow.MaximumZoom)
|
|
{
|
|
this.Zoom += HelpWindow.ZoomInterval;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Decreases Zoom if not below minimum.
|
|
/// </summary>
|
|
internal void ZoomOut()
|
|
{
|
|
if (this.Zoom - HelpWindow.ZoomInterval >= HelpWindow.MinimumZoom)
|
|
{
|
|
this.Zoom -= HelpWindow.ZoomInterval;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called to update the matches label.
|
|
/// </summary>
|
|
/// <param name="sender">Event sender.</param>
|
|
/// <param name="e">Event arguments.</param>
|
|
private void HelpBuilder_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
|
{
|
|
if (e.PropertyName == "HighlightCount")
|
|
{
|
|
this.SetMatchesLabel();
|
|
this.OnNotifyPropertyChanged("CanGoToNextOrPrevious");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the current matches label.
|
|
/// </summary>
|
|
private void SetMatchesLabel()
|
|
{
|
|
if (this.findText == null || this.findText.Trim().Length == 0)
|
|
{
|
|
this.MatchesLabel = string.Empty;
|
|
}
|
|
else
|
|
{
|
|
if (this.HelpBuilder.HighlightCount == 0)
|
|
{
|
|
this.MatchesLabel = HelpWindowResources.NoMatches;
|
|
}
|
|
else
|
|
{
|
|
if (this.HelpBuilder.HighlightCount == 1)
|
|
{
|
|
this.MatchesLabel = HelpWindowResources.OneMatch;
|
|
}
|
|
else
|
|
{
|
|
this.MatchesLabel = string.Format(
|
|
CultureInfo.CurrentCulture,
|
|
HelpWindowResources.SomeMatchesFormat,
|
|
this.HelpBuilder.HighlightCount);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called internally to notify when a proiperty changed.
|
|
/// </summary>
|
|
/// <param name="propertyName">Property name.</param>
|
|
private void OnNotifyPropertyChanged(string propertyName)
|
|
{
|
|
PropertyChangedEventHandler handler = this.PropertyChanged;
|
|
if (handler != null)
|
|
{
|
|
handler(this, new PropertyChangedEventArgs(propertyName));
|
|
}
|
|
}
|
|
}
|
|
}
|