// 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
{
///
/// ViewModel for the Help Dialog used to:
/// build the help document
/// search the help document
/// offer text for labels.
///
internal class HelpViewModel : INotifyPropertyChanged
{
///
/// The builder for the help FlowDocument Paragraph used in a RichEditText control.
///
private readonly HelpParagraphBuilder helpBuilder;
///
/// Searcher for selecting current matches in paragraph text.
///
private readonly ParagraphSearcher searcher;
///
/// Title of the help window.
///
private readonly string helpTitle;
///
/// the zoom bound to the zoom slider value.
///
private double zoom = 100;
///
/// Text to be found. This is bound to the find TextBox.
///
private string findText;
///
/// text for the number of matches found.
///
private string matchesLabel;
///
/// Initializes a new instance of the HelpViewModel class.
///
/// Object containing help.
/// Paragraph in which help text is built/searched.
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
///
/// Used to notify of property changes.
///
public event PropertyChangedEventHandler PropertyChanged;
#endregion
///
/// Gets or sets the Zoom bound to the zoom slider value.
///
public double Zoom
{
get
{
return this.zoom;
}
set
{
this.zoom = value;
this.OnNotifyPropertyChanged("Zoom");
this.OnNotifyPropertyChanged("ZoomLabel");
this.OnNotifyPropertyChanged("ZoomLevel");
}
}
///
/// Gets the value bound to the RichTextEdit zoom, which is calculated based on the zoom.
///
public double ZoomLevel
{
get
{
return this.zoom / 100.0;
}
}
///
/// Gets the label to be displayed for the zoom.
///
public string ZoomLabel
{
get
{
return string.Format(CultureInfo.CurrentCulture, HelpWindowResources.ZoomLabelTextFormat, this.zoom);
}
}
///
/// Gets or sets the text to be found.
///
public string FindText
{
get
{
return this.findText;
}
set
{
this.findText = value;
this.Search();
this.SetMatchesLabel();
}
}
///
/// Gets the title of the window.
///
public string HelpTitle
{
get
{
return this.helpTitle;
}
}
///
/// Gets or sets the label for current matches.
///
public string MatchesLabel
{
get
{
return this.matchesLabel;
}
set
{
this.matchesLabel = value;
this.OnNotifyPropertyChanged("MatchesLabel");
}
}
///
/// Gets a value indicating whether there are matches to go to.
///
public bool CanGoToNextOrPrevious
{
get
{
return this.HelpBuilder.HighlightCount != 0;
}
}
///
/// Gets the searcher for selecting current matches in paragraph text.
///
internal ParagraphSearcher Searcher
{
get { return this.searcher; }
}
///
/// Gets the paragraph builder used to write help content.
///
internal HelpParagraphBuilder HelpBuilder
{
get { return this.helpBuilder; }
}
///
/// Highlights all matches to this.findText
/// Called when findText changes or whenever the search has to be refreshed
///
internal void Search()
{
this.HelpBuilder.HighlightAllInstancesOf(this.findText, HelpWindowSettings.Default.HelpSearchMatchCase, HelpWindowSettings.Default.HelpSearchWholeWord);
this.searcher.ResetSearch();
}
///
/// Increases Zoom if not above maximum.
///
internal void ZoomIn()
{
if (this.Zoom + HelpWindow.ZoomInterval <= HelpWindow.MaximumZoom)
{
this.Zoom += HelpWindow.ZoomInterval;
}
}
///
/// Decreases Zoom if not below minimum.
///
internal void ZoomOut()
{
if (this.Zoom - HelpWindow.ZoomInterval >= HelpWindow.MinimumZoom)
{
this.Zoom -= HelpWindow.ZoomInterval;
}
}
///
/// Called to update the matches label.
///
/// Event sender.
/// Event arguments.
private void HelpBuilder_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "HighlightCount")
{
this.SetMatchesLabel();
this.OnNotifyPropertyChanged("CanGoToNextOrPrevious");
}
}
///
/// Sets the current matches label.
///
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);
}
}
}
}
///
/// Called internally to notify when a proiperty changed.
///
/// Property name.
private void OnNotifyPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}