"Fossies" - the Fresh Open Source Software Archive

Member "PowerShell-7.2.6/src/Microsoft.Management.UI.Internal/ShowCommand/ViewModel/AllModulesViewModel.cs" (11 Aug 2022, 22497 Bytes) of package /linux/misc/PowerShell-7.2.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C# source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "AllModulesViewModel.cs" see the Fossies "Dox" file reference documentation.

    1 // Copyright (c) Microsoft Corporation.
    2 // Licensed under the MIT License.
    3 
    4 using System;
    5 using System.Collections.Generic;
    6 using System.ComponentModel;
    7 using System.Globalization;
    8 using System.Linq;
    9 using System.Management.Automation;
   10 using System.Windows;
   11 
   12 using Microsoft.Management.UI.Internal;
   13 using Microsoft.PowerShell.Commands.ShowCommandExtension;
   14 
   15 namespace Microsoft.PowerShell.Commands.ShowCommandInternal
   16 {
   17     /// <summary>
   18     /// Contains all Commands, Parameters, ParameterSet and Common Parameter.
   19     /// </summary>
   20     public class AllModulesViewModel : INotifyPropertyChanged
   21     {
   22         #region Private Fields
   23         /// <summary>
   24         /// Flag indicating a wait message is being displayed.
   25         /// </summary>
   26         private bool waitMessageDisplayed;
   27 
   28         /// <summary>
   29         /// True if this ViewModel is not supposed to show common parameters.
   30         /// </summary>
   31         private bool noCommonParameter;
   32 
   33         /// <summary>
   34         /// the filterName of command.
   35         /// </summary>
   36         private string commandNameFilter;
   37 
   38         /// <summary>
   39         /// Field used for the Modules property.
   40         /// </summary>
   41         private List<ModuleViewModel> modules;
   42 
   43         /// <summary>
   44         /// true if a command can be run.
   45         /// </summary>
   46         private bool canRun;
   47 
   48         /// <summary>
   49         /// true if a command can be copied.
   50         /// </summary>
   51         private bool canCopy;
   52 
   53         /// <summary>
   54         /// the selected module being displayed in the GUI.
   55         /// </summary>
   56         private ModuleViewModel selectedModule;
   57 
   58         /// <summary>
   59         /// the visibility of the refresh button.
   60         /// </summary>
   61         private Visibility refreshVisibility = Visibility.Collapsed;
   62 
   63         /// <summary>
   64         /// Provides an extra viewModel object that allows callers to control certain aspects of the GUI.
   65         /// </summary>
   66         private object extraViewModel;
   67 
   68         /// <summary>
   69         /// private property for ZoomLevel.
   70         /// </summary>
   71         private double zoomLevel = 1.0;
   72         #endregion
   73 
   74         #region Construction and Destructor
   75         /// <summary>
   76         /// Initializes a new instance of the AllModulesViewModel class.
   77         /// </summary>
   78         /// <param name="importedModules">The loaded modules.</param>
   79         /// <param name="commands">Commands to show.</param>
   80         public AllModulesViewModel(Dictionary<string, ShowCommandModuleInfo> importedModules, IEnumerable<ShowCommandCommandInfo> commands)
   81         {
   82             if (commands == null || !commands.GetEnumerator().MoveNext())
   83             {
   84                 throw new ArgumentNullException("commands");
   85             }
   86 
   87             this.Initialization(importedModules, commands, true);
   88         }
   89 
   90         /// <summary>
   91         /// Initializes a new instance of the AllModulesViewModel class.
   92         /// </summary>
   93         /// <param name="importedModules">The loaded modules.</param>
   94         /// <param name="commands">All PowerShell commands.</param>
   95         /// <param name="noCommonParameter">True not to show common parameters.</param>
   96         public AllModulesViewModel(Dictionary<string, ShowCommandModuleInfo> importedModules, IEnumerable<ShowCommandCommandInfo> commands, bool noCommonParameter)
   97         {
   98             if (commands == null)
   99             {
  100                 throw new ArgumentNullException("commands");
  101             }
  102 
  103             this.Initialization(importedModules, commands, noCommonParameter);
  104         }
  105 
  106         #endregion
  107 
  108         #region INotifyPropertyChanged Members
  109         /// <summary>
  110         /// PropertyChanged Event.
  111         /// </summary>
  112         public event PropertyChangedEventHandler PropertyChanged;
  113         #endregion
  114 
  115         /// <summary>
  116         /// Indicates the selected command in the selected module needs to display the help for a command.
  117         /// </summary>
  118         public event EventHandler<HelpNeededEventArgs> SelectedCommandInSelectedModuleNeedsHelp;
  119 
  120         /// <summary>
  121         /// Indicates the selected command in the selected module needs to import a module for a command.
  122         /// </summary>
  123         public event EventHandler<ImportModuleEventArgs> SelectedCommandInSelectedModuleNeedsImportModule;
  124 
  125         /// <summary>
  126         /// Indicates the selected command in the selected module should be run.
  127         /// </summary>
  128         public event EventHandler<CommandEventArgs> RunSelectedCommandInSelectedModule;
  129 
  130         /// <summary>
  131         /// Indicates we want to refresh the viewModel.
  132         /// </summary>
  133         public event EventHandler<EventArgs> Refresh;
  134 
  135         #region Public Properties
  136 
  137         /// <summary>
  138         /// Get or Sets Zoom level.
  139         /// </summary>
  140         public double ZoomLevel
  141         {
  142             get
  143             {
  144                 return this.zoomLevel;
  145             }
  146 
  147             set
  148             {
  149                 if (value > 0)
  150                 {
  151                     this.zoomLevel = value / 100.0;
  152                     this.OnNotifyPropertyChanged("ZoomLevel");
  153                 }
  154             }
  155         }
  156 
  157         /// <summary>
  158         /// Gets the tooltip for the refresh button.
  159         /// </summary>
  160         public static string RefreshTooltip
  161         {
  162             get { return string.Format(CultureInfo.CurrentUICulture, ShowCommandResources.RefreshShowCommandTooltipFormat, "import-module"); }
  163         }
  164 
  165         /// <summary>
  166         /// Gets or sets the visibility of the refresh button.
  167         /// </summary>
  168         public Visibility RefreshVisibility
  169         {
  170             get
  171             {
  172                 return this.refreshVisibility;
  173             }
  174 
  175             set
  176             {
  177                 if (this.refreshVisibility == value)
  178                 {
  179                     return;
  180                 }
  181 
  182                 this.refreshVisibility = value;
  183                 this.OnNotifyPropertyChanged("RefreshVisibility");
  184             }
  185         }
  186 
  187         /// <summary>
  188         /// Gets a value indicating whether common parameters are displayed.
  189         /// </summary>
  190         public bool NoCommonParameter
  191         {
  192             get { return this.noCommonParameter; }
  193         }
  194 
  195         /// <summary>
  196         /// Gets or sets the filterName of command.
  197         /// </summary>
  198         public string CommandNameFilter
  199         {
  200             get
  201             {
  202                 return this.commandNameFilter;
  203             }
  204 
  205             set
  206             {
  207                 if (this.CommandNameFilter == value)
  208                 {
  209                     return;
  210                 }
  211 
  212                 this.commandNameFilter = value;
  213                 if (this.selectedModule != null)
  214                 {
  215                     this.selectedModule.RefreshFilteredCommands(this.CommandNameFilter);
  216                     this.selectedModule.SelectedCommand = null;
  217                 }
  218 
  219                 this.OnNotifyPropertyChanged("CommandNameFilter");
  220             }
  221         }
  222 
  223         /// <summary>
  224         /// Gets or sets the selected module being displayed in the GUI.
  225         /// </summary>
  226         public ModuleViewModel SelectedModule
  227         {
  228             get
  229             {
  230                 return this.selectedModule;
  231             }
  232 
  233             set
  234             {
  235                 if (this.selectedModule == value)
  236                 {
  237                     return;
  238                 }
  239 
  240                 if (this.selectedModule != null)
  241                 {
  242                     this.selectedModule.SelectedCommandNeedsImportModule -= this.SelectedModule_SelectedCommandNeedsImportModule;
  243                     this.selectedModule.SelectedCommandNeedsHelp -= this.SelectedModule_SelectedCommandNeedsHelp;
  244                     this.selectedModule.RunSelectedCommand -= this.SelectedModule_RunSelectedCommand;
  245                     this.selectedModule.PropertyChanged -= this.SelectedModule_PropertyChanged;
  246                 }
  247 
  248                 this.selectedModule = value;
  249                 this.SetCanRun();
  250                 this.SetCanCopy();
  251 
  252                 if (this.selectedModule != null)
  253                 {
  254                     this.selectedModule.RefreshFilteredCommands(this.CommandNameFilter);
  255                     this.selectedModule.SelectedCommandNeedsImportModule += this.SelectedModule_SelectedCommandNeedsImportModule;
  256                     this.selectedModule.SelectedCommandNeedsHelp += this.SelectedModule_SelectedCommandNeedsHelp;
  257                     this.selectedModule.RunSelectedCommand += this.SelectedModule_RunSelectedCommand;
  258                     this.selectedModule.PropertyChanged += this.SelectedModule_PropertyChanged;
  259                     this.selectedModule.SelectedCommand = null;
  260                 }
  261 
  262                 this.OnNotifyPropertyChanged("SelectedModule");
  263             }
  264         }
  265 
  266         /// <summary>
  267         /// Gets a value indicating whether we can run a command.
  268         /// </summary>
  269         public bool CanRun
  270         {
  271             get
  272             {
  273                 return this.canRun;
  274             }
  275         }
  276 
  277         /// <summary>
  278         /// Gets a value indicating whether we can copy a command.
  279         /// </summary>
  280         public bool CanCopy
  281         {
  282             get
  283             {
  284                 return this.canCopy;
  285             }
  286         }
  287 
  288         /// <summary>
  289         /// Gets the Modules parameter.
  290         /// </summary>
  291         public List<ModuleViewModel> Modules
  292         {
  293             get { return this.modules; }
  294         }
  295 
  296         /// <summary>
  297         /// Gets the visibility of the wait message.
  298         /// </summary>
  299         public Visibility WaitMessageVisibility
  300         {
  301             get
  302             {
  303                 return this.waitMessageDisplayed ? Visibility.Visible : Visibility.Hidden;
  304             }
  305         }
  306 
  307         /// <summary>
  308         /// Gets the visibility of the main grid.
  309         /// </summary>
  310         public Visibility MainGridVisibility
  311         {
  312             get
  313             {
  314                 return this.waitMessageDisplayed ? Visibility.Hidden : Visibility.Visible;
  315             }
  316         }
  317 
  318         /// <summary>
  319         /// Gets a value indicating whether the main grid is displayed.
  320         /// </summary>
  321         public bool MainGridDisplayed
  322         {
  323             get
  324             {
  325                 return !this.waitMessageDisplayed;
  326             }
  327         }
  328 
  329         /// <summary>
  330         /// Gets or sets a value indicating whether the wait message is displayed.
  331         /// </summary>
  332         public bool WaitMessageDisplayed
  333         {
  334             get
  335             {
  336                 return this.waitMessageDisplayed;
  337             }
  338 
  339             set
  340             {
  341                 if (this.waitMessageDisplayed == value)
  342                 {
  343                     return;
  344                 }
  345 
  346                 this.waitMessageDisplayed = value;
  347                 this.SetCanCopy();
  348                 this.SetCanRun();
  349                 this.OnNotifyPropertyChanged("WaitMessageDisplayed");
  350                 this.OnNotifyPropertyChanged("WaitMessageVisibility");
  351                 this.OnNotifyPropertyChanged("MainGridDisplayed");
  352                 this.OnNotifyPropertyChanged("MainGridVisibility");
  353             }
  354         }
  355 
  356         /// <summary>
  357         /// Gets or sets an extra viewModel object that allows callers to control certain aspects of the GUI.
  358         /// </summary>
  359         public object ExtraViewModel
  360         {
  361             get
  362             {
  363                 return this.extraViewModel;
  364             }
  365 
  366             set
  367             {
  368                 if (this.extraViewModel == value)
  369                 {
  370                     return;
  371                 }
  372 
  373                 this.extraViewModel = value;
  374                 this.OnNotifyPropertyChanged("ExtraViewModel");
  375             }
  376         }
  377         #endregion
  378 
  379         /// <summary>
  380         /// Returns the selected script.
  381         /// </summary>
  382         /// <returns>The selected script.</returns>
  383         public string GetScript()
  384         {
  385             if (this.SelectedModule == null)
  386             {
  387                 return null;
  388             }
  389 
  390             if (this.SelectedModule.SelectedCommand == null)
  391             {
  392                 return null;
  393             }
  394 
  395             return this.SelectedModule.SelectedCommand.GetScript();
  396         }
  397 
  398         /// <summary>
  399         /// Triggers Refresh.
  400         /// </summary>
  401         internal void OnRefresh()
  402         {
  403             EventHandler<EventArgs> handler = this.Refresh;
  404             if (handler != null)
  405             {
  406                 handler(this, new EventArgs());
  407             }
  408         }
  409 
  410         #region Private Methods
  411         /// <summary>
  412         /// If current modules name is ALL, then return true.
  413         /// </summary>
  414         /// <param name="name">The modules name.</param>
  415         /// <returns>Return true is the module name is ALLModulesViewModel.</returns>
  416         private static bool IsAll(string name)
  417         {
  418             return name.Equals(ShowCommandResources.All, StringComparison.Ordinal);
  419         }
  420 
  421         /// <summary>
  422         /// Monitors property changes in the selected module to call:
  423         ///     SetCanRun for IsThereASelectedImportedCommandWhereAllMandatoryParametersHaveValues
  424         ///     SetCanCopy for SetCanCopy
  425         /// </summary>
  426         /// <param name="sender">Event sender.</param>
  427         /// <param name="e">Event arguments.</param>
  428         private void SelectedModule_PropertyChanged(object sender, PropertyChangedEventArgs e)
  429         {
  430             if (e.PropertyName == "IsThereASelectedImportedCommandWhereAllMandatoryParametersHaveValues")
  431             {
  432                 this.SetCanRun();
  433             }
  434             else if (e.PropertyName == "IsThereASelectedCommand")
  435             {
  436                 this.SetCanCopy();
  437             }
  438         }
  439 
  440         /// <summary>
  441         /// Called to set this.CanRun when:
  442         ///     The SelectedModule changes, since there will be no selected command in the new module, and CanRun should be false
  443         ///     WaitMessageDisplayedMessage changes since this being true will cause this.MainGridDisplayed to be false and CanRun should be false
  444         ///     IsThereASelectedImportedCommandWhereAllMandatoryParametersHaveValues changes in the selected module
  445         /// </summary>
  446         private void SetCanRun()
  447         {
  448             bool newValue = this.selectedModule != null && this.MainGridDisplayed &&
  449                 this.selectedModule.IsThereASelectedImportedCommandWhereAllMandatoryParametersHaveValues;
  450 
  451             if (this.canRun == newValue)
  452             {
  453                 return;
  454             }
  455 
  456             this.canRun = newValue;
  457             this.OnNotifyPropertyChanged("CanRun");
  458         }
  459 
  460         /// <summary>
  461         /// Called to set this.CanCopy when:
  462         ///     The SelectedModule changes, since there will be no selected command in the new module, and CanCopy should be false
  463         ///     WaitMessageDisplayedMessage changes since this being true will cause this.MainGridDisplayed to be false and CanCopy should be false
  464         ///     IsThereASelectedCommand changes in the selected module
  465         /// </summary>
  466         private void SetCanCopy()
  467         {
  468             bool newValue = this.selectedModule != null && this.MainGridDisplayed && this.selectedModule.IsThereASelectedCommand;
  469 
  470             if (this.canCopy == newValue)
  471             {
  472                 return;
  473             }
  474 
  475             this.canCopy = newValue;
  476             this.OnNotifyPropertyChanged("CanCopy");
  477         }
  478 
  479         /// <summary>
  480         /// Initialize AllModulesViewModel.
  481         /// </summary>
  482         /// <param name="importedModules">All loaded modules.</param>
  483         /// <param name="commands">List of commands in all modules.</param>
  484         /// <param name="noCommonParameterInModel">Whether showing common parameter.</param>
  485         private void Initialization(Dictionary<string, ShowCommandModuleInfo> importedModules, IEnumerable<ShowCommandCommandInfo> commands, bool noCommonParameterInModel)
  486         {
  487             if (commands == null)
  488             {
  489                 return;
  490             }
  491 
  492             Dictionary<string, ModuleViewModel> rawModuleViewModels = new Dictionary<string, ModuleViewModel>();
  493 
  494             this.noCommonParameter = noCommonParameterInModel;
  495 
  496             // separates commands in their Modules
  497             foreach (ShowCommandCommandInfo command in commands)
  498             {
  499                 ModuleViewModel moduleViewModel;
  500                 if (!rawModuleViewModels.TryGetValue(command.ModuleName, out moduleViewModel))
  501                 {
  502                     moduleViewModel = new ModuleViewModel(command.ModuleName, importedModules);
  503                     rawModuleViewModels.Add(command.ModuleName, moduleViewModel);
  504                 }
  505 
  506                 CommandViewModel commandViewModel;
  507 
  508                 try
  509                 {
  510                     commandViewModel = CommandViewModel.GetCommandViewModel(moduleViewModel, command, noCommonParameterInModel);
  511                 }
  512                 catch (RuntimeException)
  513                 {
  514                     continue;
  515                 }
  516 
  517                 moduleViewModel.Commands.Add(commandViewModel);
  518                 moduleViewModel.SetAllModules(this);
  519             }
  520 
  521             // populates this.modules
  522             this.modules = new List<ModuleViewModel>();
  523 
  524             // if there is just one module then use only it
  525             if (rawModuleViewModels.Values.Count == 1)
  526             {
  527                 this.modules.Add(rawModuleViewModels.Values.First());
  528                 this.modules[0].SortCommands(false);
  529                 this.SelectedModule = this.modules[0];
  530                 return;
  531             }
  532 
  533             // If there are more modules, create an additional module to agregate all commands
  534             ModuleViewModel allCommandsModule = new ModuleViewModel(ShowCommandResources.All, null);
  535             this.modules.Add(allCommandsModule);
  536             allCommandsModule.SetAllModules(this);
  537 
  538             if (rawModuleViewModels.Values.Count > 0)
  539             {
  540                 foreach (ModuleViewModel module in rawModuleViewModels.Values)
  541                 {
  542                     module.SortCommands(false);
  543                     this.modules.Add(module);
  544 
  545                     allCommandsModule.Commands.AddRange(module.Commands);
  546                 }
  547             }
  548 
  549             allCommandsModule.SortCommands(true);
  550 
  551             this.modules.Sort(this.Compare);
  552             this.SelectedModule = this.modules.Count == 0 ? null : this.modules[0];
  553         }
  554 
  555         /// <summary>
  556         /// Compare two ModuleViewModel target and source.
  557         /// </summary>
  558         /// <param name="source">The source ModuleViewModel.</param>
  559         /// <param name="target">The target ModuleViewModel.</param>
  560         /// <returns>Compare result.</returns>
  561         private int Compare(ModuleViewModel source, ModuleViewModel target)
  562         {
  563             if (AllModulesViewModel.IsAll(source.Name) && !AllModulesViewModel.IsAll(target.Name))
  564             {
  565                 return -1;
  566             }
  567 
  568             if (!AllModulesViewModel.IsAll(source.Name) && AllModulesViewModel.IsAll(target.Name))
  569             {
  570                 return 1;
  571             }
  572 
  573             return string.Compare(source.Name, target.Name, StringComparison.OrdinalIgnoreCase);
  574         }
  575 
  576         /// <summary>
  577         /// Called when the SelectedCommandNeedsHelp event is triggered in the Selected Module.
  578         /// </summary>
  579         /// <param name="sender">Event sender.</param>
  580         /// <param name="e">Event arguments.</param>
  581         private void SelectedModule_SelectedCommandNeedsHelp(object sender, HelpNeededEventArgs e)
  582         {
  583             this.OnSelectedCommandInSelectedModuleNeedsHelp(e);
  584         }
  585 
  586         /// <summary>
  587         /// Called when the SelectedCommandNeedsImportModule event is triggered in the Selected Module.
  588         /// </summary>
  589         /// <param name="sender">Event sender.</param>
  590         /// <param name="e">Event arguments.</param>
  591         private void SelectedModule_SelectedCommandNeedsImportModule(object sender, ImportModuleEventArgs e)
  592         {
  593             this.OnSelectedCommandInSelectedModuleNeedsImportModule(e);
  594         }
  595 
  596         /// <summary>
  597         /// Triggers SelectedCommandInSelectedModuleNeedsHelp.
  598         /// </summary>
  599         /// <param name="e">Event arguments.</param>
  600         private void OnSelectedCommandInSelectedModuleNeedsHelp(HelpNeededEventArgs e)
  601         {
  602             EventHandler<HelpNeededEventArgs> handler = this.SelectedCommandInSelectedModuleNeedsHelp;
  603             if (handler != null)
  604             {
  605                 handler(this, e);
  606             }
  607         }
  608 
  609         /// <summary>
  610         /// Triggers SelectedCommandInSelectedModuleNeedsImportModule.
  611         /// </summary>
  612         /// <param name="e">Event arguments.</param>
  613         private void OnSelectedCommandInSelectedModuleNeedsImportModule(ImportModuleEventArgs e)
  614         {
  615             EventHandler<ImportModuleEventArgs> handler = this.SelectedCommandInSelectedModuleNeedsImportModule;
  616             if (handler != null)
  617             {
  618                 handler(this, e);
  619             }
  620         }
  621 
  622         /// <summary>
  623         /// Called when the RunSelectedCommand is triggered in the selected module.
  624         /// </summary>
  625         /// <param name="sender">Event sender.</param>
  626         /// <param name="e">Event arguments.</param>
  627         private void SelectedModule_RunSelectedCommand(object sender, CommandEventArgs e)
  628         {
  629             this.OnRunSelectedCommandInSelectedModule(e);
  630         }
  631 
  632         /// <summary>
  633         /// Triggers RunSelectedCommandInSelectedModule.
  634         /// </summary>
  635         /// <param name="e">Event arguments.</param>
  636         private void OnRunSelectedCommandInSelectedModule(CommandEventArgs e)
  637         {
  638             EventHandler<CommandEventArgs> handler = this.RunSelectedCommandInSelectedModule;
  639             if (handler != null)
  640             {
  641                 handler(this, e);
  642             }
  643         }
  644 
  645         /// <summary>
  646         /// If property changed will be notify.
  647         /// </summary>
  648         /// <param name="propertyName">The changed property.</param>
  649         private void OnNotifyPropertyChanged(string propertyName)
  650         {
  651             PropertyChangedEventHandler handler = this.PropertyChanged;
  652             if (handler != null)
  653             {
  654                 handler(this, new PropertyChangedEventArgs(propertyName));
  655             }
  656         }
  657         #endregion
  658     }
  659 }