From 2726a38520296cae32b9c9c9668e0292e1b5c5ee Mon Sep 17 00:00:00 2001 From: PowerShell Team Date: Tue, 21 Jun 2016 12:54:12 -0700 Subject: [PATCH] Copy Microsoft.PowerShell.GraphicalHost from [SD:715912] commit 570d318 --- .../CommonHelper.cs | 74 + .../HelpWindow/HelpParagraphBuilder.cs | 983 ++++++++++++ .../HelpWindow/HelpViewModel.cs | 289 ++++ .../HelpWindow/HelpWindow.xaml.cs | 309 ++++ .../HelpWindow/HelpWindowSettings.Designer.cs | 248 +++ .../HelpWindow/ParagraphBuilder.cs | 383 +++++ .../HelpWindow/ParagraphSearcher.cs | 247 +++ .../HelpWindow/SettingsDialog.xaml.cs | 64 + .../Common/AutomationTextBlock.cs | 50 + .../AutomationTextBlockAutomationPeer.cs | 62 + .../ManagementList/Common/BooleanBoxes.cs | 47 + .../ManagementList/Common/CommandHelper.cs | 57 + .../Common/CustomTypeComparer.cs | 77 + .../Common/DataRoutedEventArgs.cs | 44 + .../Common/DateTimeApproximationComparer.cs | 71 + .../Common/DismissiblePopup.Generated.cs | 283 ++++ .../ManagementList/Common/DismissiblePopup.cs | 154 ++ .../ExtendedFrameworkElementAutomationPeer.cs | 109 ++ .../ManagementList/Common/IAsyncProgress.cs | 45 + .../Common/IStateDescriptorFactory.cs | 27 + .../Common/IntegralConverter.cs | 90 ++ .../Common/InverseBooleanConverter.cs | 51 + .../ManagementList/Common/IsEqualConverter.cs | 80 + .../Common/IsNotNullConverter.cs | 48 + .../ManagementList/Common/KeyboardHelp.cs | 152 ++ .../Common/ListOrganizer.Generated.cs | 490 ++++++ .../ManagementList/Common/ListOrganizer.cs | 67 + .../Common/ListOrganizerItem.Generated.cs | 154 ++ .../Common/ListOrganizerItem.cs | 263 ++++ .../Common/MessageTextBox.Generated.cs | 158 ++ .../ManagementList/Common/MessageTextBox.cs | 65 + .../Common/PickerBase.Generated.cs | 271 ++++ .../ManagementList/Common/PickerBase.cs | 137 ++ .../Common/PopupControlButton.Generated.cs | 93 ++ .../Common/PopupControlButton.cs | 126 ++ .../Common/PropertyChangedEventArgs.cs | 46 + .../ReadOnlyObservableAsyncCollection.cs | 136 ++ .../Common/ScalableImage.Generated.cs | 105 ++ .../ManagementList/Common/ScalableImage.cs | 128 ++ .../Common/ScalableImageSource.Generated.cs | 238 +++ .../Common/ScalableImageSource.cs | 57 + .../ManagementList/Common/StateDescriptor.cs | 87 ++ .../Common/StringFormatConverter.cs | 60 + .../Common/TextBlockService.Generated.cs | 182 +++ .../ManagementList/Common/TextBlockService.cs | 95 ++ .../Common/TextTrimConverter.cs | 72 + .../ManagementList/Common/Utilities.cs | 199 +++ .../Common/VisualToAncestorDataConverter.cs | 70 + .../Common/WeakEventListener.cs | 52 + .../ManagementList/Common/WpfHelp.cs | 613 ++++++++ .../CommonControls/AutomationGroup.cs | 27 + .../ExpanderButton.Generated.cs | 44 + .../CommonControls/ExpanderButton.cs | 65 + .../ExpanderButtonAutomationPeer.cs | 121 ++ .../CommonControls/Resizer.Generated.cs | 426 ++++++ .../ManagementList/CommonControls/Resizer.cs | 231 +++ .../ResizerGripThicknessConverter.cs | 75 + .../UIElementAdorner.Generated.cs | 91 ++ .../CommonControls/UIElementAdorner.cs | 108 ++ .../DefaultFilterRuleCustomizationFactory.cs | 353 +++++ .../FilterCore/FilterEvaluator.cs | 247 +++ .../FilterCore/FilterExceptionEventArgs.cs | 46 + .../FilterExpressionAndOperatorNode.cs | 101 ++ .../FilterExpressionNode.cs | 75 + .../FilterExpressionOperandNode.cs | 75 + .../FilterExpressionOrOperatorNode.cs | 101 ++ .../FilterRuleCustomizationFactory.cs | 112 ++ .../FilterRules/ComparableValueFilterRule.cs | 81 + .../FilterRules/DoesNotEqualFilterRule.cs | 45 + .../FilterRules/EqualsFilterRule.cs | 48 + .../FilterCore/FilterRules/FilterRule.cs | 82 + .../FilterRules/FilterRuleExtensions.cs | 59 + .../FilterRules/IsBetweenFilterRule.cs | 123 ++ .../FilterRules/IsEmptyFilterRule.cs | 52 + .../FilterRules/IsGreaterThanFilterRule.cs | 48 + .../FilterRules/IsLessThanFilterRule.cs | 48 + .../FilterRules/IsNotEmptyFilterRule.cs | 40 + .../FilterRules/IsNotEmptyValidationRule.cs | 65 + .../PropertiesTextContainsFilterRule.cs | 133 ++ .../PropertyValueSelectorFilterRule.cs | 153 ++ .../FilterRules/SelectorFilterRule.cs | 122 ++ .../SingleValueComparableValueFilterRule.cs | 75 + .../FilterRules/TextContainsFilterRule.cs | 48 + .../TextDoesNotContainFilterRule.cs | 42 + .../FilterRules/TextDoesNotEqualFilterRule.cs | 42 + .../FilterRules/TextEndsWithFilterRule.cs | 47 + .../FilterRules/TextEqualsFilterRule.cs | 46 + .../FilterCore/FilterRules/TextFilterRule.cs | 170 +++ .../FilterRules/TextStartsWithFilterRule.cs | 48 + .../ManagementList/FilterCore/FilterStatus.cs | 32 + .../FilterCore/FilterUtilities.cs | 50 + .../ManagementList/FilterCore/IEvaluate.cs | 29 + .../FilterCore/IFilterExpressionProvider.cs | 41 + .../FilterCore/ItemsControlFilterEvaluator.cs | 146 ++ .../FilterCore/ValidatingSelectorValue.cs | 252 +++ .../FilterCore/ValidatingValue.cs | 219 +++ .../FilterCore/ValidatingValueBase.cs | 329 ++++ .../DataErrorInfoValidationResult.cs | 81 + .../DataErrorInfoValidationRule.cs | 32 + .../AddFilterRulePicker.Generated.cs | 272 ++++ .../FilterProviders/AddFilterRulePicker.cs | 107 ++ .../AddFilterRulePickerItem.cs | 86 ++ .../FilterRulePanel.Generated.cs | 114 ++ .../FilterProviders/FilterRulePanel.cs | 387 +++++ .../FilterRulePanelContentPresenter.cs | 57 + .../FilterRulePanelController.cs | 284 ++++ .../FilterProviders/FilterRulePanelItem.cs | 121 ++ .../FilterRulePanelItemType.cs | 34 + .../FilterRuleTemplateSelector.cs | 78 + .../FilterRuleToDisplayNameConverter.cs | 79 + .../InputFieldBackgroundTextConverter.cs | 114 ++ .../IsValidatingValueValidConverter.cs | 58 + .../FilterProviders/SearchBox.Generated.cs | 200 +++ .../FilterProviders/SearchBox.cs | 152 ++ .../FilterProviders/SearchTextParseResult.cs | 48 + .../FilterProviders/SearchTextParser.cs | 268 ++++ ...tingSelectorValueToDisplayNameConverter.cs | 94 ++ ...ingValueToGenericParameterTypeConverter.cs | 72 + .../ManagementList/ColumnPicker.xaml.cs | 380 +++++ .../ManagementList/DefaultStringConverter.cs | 101 ++ .../ManagementList/IPropertyValueGetter.cs | 30 + .../ManagementList/InnerList.Generated.cs | 235 +++ .../InnerListColumn.Generated.cs | 218 +++ .../ManagementList/InnerListGridView.cs | 306 ++++ .../ManagementList/Innerlist.cs | 722 +++++++++ .../ManagementList.Generated.cs | 860 +++++++++++ .../ManagementListStateDescriptor.cs | 609 ++++++++ .../ManagementListStateDescriptorFactory.cs | 27 + .../ManagementListTitle.Generated.cs | 267 ++++ .../ManagementList/ManagementListTitle.cs | 25 + .../ManagementList/PropertyValueComparer.cs | 155 ++ .../ManagementList/PropertyValueGetter.cs | 134 ++ .../UIPropertyGroupDescription.cs | 133 ++ .../ViewGroupToStringConverter.cs | 69 + .../ManagementList/ManagementList/WaitRing.cs | 40 + .../ManagementList/innerlistcolumn.cs | 183 +++ .../ManagementList/managementlist.cs | 428 ++++++ .../Controls/AllModulesControl.xaml.cs | 45 + .../Controls/CmdletControl.xaml.cs | 104 ++ .../Controls/ImageButton/ImageButton.xaml.cs | 44 + .../Controls/ImageButton/ImageButtonBase.cs | 70 + .../ImageButtonTooltipConverter.cs | 79 + .../ImageButton/ImageToggleButton.xaml.cs | 60 + .../Controls/MultipleSelectionControl.xaml.cs | 60 + .../Controls/NotImportedCmdletControl.xaml.cs | 26 + .../Controls/ParameterSetControl.xaml.cs | 379 +++++ .../Controls/ShowModuleControl.xaml.cs | 89 ++ .../ShowCommandSettings.Designer.cs | 146 ++ .../ViewModel/AllModulesViewModel.cs | 660 ++++++++ .../ShowCommand/ViewModel/CommandEventArgs.cs | 38 + .../ShowCommand/ViewModel/CommandViewModel.cs | 651 ++++++++ .../ViewModel/HelpNeededEventArgs.cs | 38 + .../ViewModel/ImportModuleEventArgs.cs | 73 + .../ShowCommand/ViewModel/ModuleViewModel.cs | 532 +++++++ .../ViewModel/ParameterSetViewModel.cs | 397 +++++ .../ViewModel/ParameterViewModel.cs | 279 ++++ .../Windows/MultipleSelectionDialog.xaml.cs | 46 + .../Windows/ShowAllModulesWindow.xaml.cs | 203 +++ .../Windows/ShowCommandWindow.xaml.cs | 72 + .../commandHelpers/HelpWindowHelper.cs | 60 + .../commandHelpers/ShowCommandHelper.cs | 1349 +++++++++++++++++ .../commandHelpers/outgridview.cs | 601 ++++++++ .../resources/GraphicalHostResources.resx | 123 ++ .../resources/HelpWindowResources.resx | 230 +++ .../resources/InvariantResources.resx | 148 ++ .../resources/ShowCommandResources.resx | 239 +++ .../resources/UICultureResources.resx | 230 +++ .../resources/XamlLocalizableResources.resx | 414 +++++ .../xamls/AllModulesControl.xaml | 47 + .../xamls/CmdletControl.xaml | 56 + .../xamls/ColumnPicker.xaml | 204 +++ .../xamls/HelpWindow.xaml | 70 + .../xamls/ImageButton.xaml | 21 + .../xamls/ImageButtonCommon.xaml | 71 + .../xamls/ImageToggleButton.xaml | 24 + .../xamls/MultipleSelectionControl.xaml | 21 + .../xamls/MultipleSelectionDialog.xaml | 26 + .../xamls/NotImportedCmdletControl.xaml | 22 + .../xamls/ParameterSetControl.xaml | 17 + .../xamls/SettingsDialog.xaml | 57 + .../xamls/ShowAllModulesWindow.xaml | 33 + .../xamls/ShowCommandWindow.xaml | 26 + .../xamls/ShowModuleControl.xaml | 27 + 183 files changed, 28888 insertions(+) create mode 100644 src/Microsoft.PowerShell.GraphicalHost/CommonHelper.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpParagraphBuilder.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpViewModel.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpWindow.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpWindowSettings.Designer.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/HelpWindow/ParagraphBuilder.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/HelpWindow/ParagraphSearcher.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/HelpWindow/SettingsDialog.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/AutomationTextBlock.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/AutomationTextBlockAutomationPeer.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/BooleanBoxes.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/CommandHelper.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/CustomTypeComparer.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DataRoutedEventArgs.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DateTimeApproximationComparer.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DismissiblePopup.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DismissiblePopup.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ExtendedFrameworkElementAutomationPeer.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IAsyncProgress.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IStateDescriptorFactory.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IntegralConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/InverseBooleanConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IsEqualConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IsNotNullConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/KeyboardHelp.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ListOrganizer.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ListOrganizer.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ListOrganizerItem.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ListOrganizerItem.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/MessageTextBox.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/MessageTextBox.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/PickerBase.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/PickerBase.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/PopupControlButton.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/PopupControlButton.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/PropertyChangedEventArgs.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ReadOnlyObservableAsyncCollection.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ScalableImage.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ScalableImage.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ScalableImageSource.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ScalableImageSource.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/StateDescriptor.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/StringFormatConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/TextBlockService.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/TextBlockService.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/TextTrimConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/Utilities.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/VisualToAncestorDataConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/WeakEventListener.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/WpfHelp.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/CommonControls/AutomationGroup.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/CommonControls/ExpanderButton.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/CommonControls/ExpanderButton.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/CommonControls/ExpanderButtonAutomationPeer.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/CommonControls/Resizer.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/CommonControls/Resizer.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/CommonControls/ResizerGripThicknessConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/CommonControls/UIElementAdorner.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/CommonControls/UIElementAdorner.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/DefaultFilterRuleCustomizationFactory.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterEvaluator.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterExceptionEventArgs.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterExpressionNodes/FilterExpressionAndOperatorNode.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterExpressionNodes/FilterExpressionNode.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterExpressionNodes/FilterExpressionOperandNode.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterExpressionNodes/FilterExpressionOrOperatorNode.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRuleCustomizationFactory.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/ComparableValueFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/DoesNotEqualFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/EqualsFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/FilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/FilterRuleExtensions.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/IsBetweenFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/IsEmptyFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/IsGreaterThanFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/IsLessThanFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/IsNotEmptyFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/IsNotEmptyValidationRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/PropertiesTextContainsFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/PropertyValueSelectorFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/SelectorFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/SingleValueComparableValueFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/TextContainsFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/TextDoesNotContainFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/TextDoesNotEqualFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/TextEndsWithFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/TextEqualsFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/TextFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterRules/TextStartsWithFilterRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterStatus.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/FilterUtilities.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/IEvaluate.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/IFilterExpressionProvider.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/ItemsControlFilterEvaluator.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/ValidatingSelectorValue.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/ValidatingValue.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/ValidatingValueBase.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/ValidationRules/DataErrorInfoValidationResult.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterCore/ValidationRules/DataErrorInfoValidationRule.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/AddFilterRulePicker.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/AddFilterRulePicker.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/AddFilterRulePickerItem.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/FilterRulePanel.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/FilterRulePanel.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/FilterRulePanelContentPresenter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/FilterRulePanelController.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/FilterRulePanelItem.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/FilterRulePanelItemType.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/FilterRuleTemplateSelector.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/FilterRuleToDisplayNameConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/InputFieldBackgroundTextConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/IsValidatingValueValidConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/SearchBox.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/SearchBox.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/SearchTextParseResult.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/SearchTextParser.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/ValidatingSelectorValueToDisplayNameConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/FilterProviders/ValidatingValueToGenericParameterTypeConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/ColumnPicker.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/DefaultStringConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/IPropertyValueGetter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/InnerList.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/InnerListColumn.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/InnerListGridView.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/Innerlist.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/ManagementList.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/ManagementListStateDescriptor.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/ManagementListStateDescriptorFactory.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/ManagementListTitle.Generated.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/ManagementListTitle.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/PropertyValueComparer.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/PropertyValueGetter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/UIPropertyGroupDescription.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/ViewGroupToStringConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/WaitRing.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/innerlistcolumn.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ManagementList/ManagementList/managementlist.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Controls/AllModulesControl.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Controls/CmdletControl.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Controls/ImageButton/ImageButton.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Controls/ImageButton/ImageButtonBase.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Controls/ImageButton/ImageButtonTooltipConverter.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Controls/ImageButton/ImageToggleButton.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Controls/MultipleSelectionControl.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Controls/NotImportedCmdletControl.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Controls/ParameterSetControl.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Controls/ShowModuleControl.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/ShowCommandSettings.Designer.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/ViewModel/AllModulesViewModel.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/ViewModel/CommandEventArgs.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/ViewModel/CommandViewModel.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/ViewModel/HelpNeededEventArgs.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/ViewModel/ImportModuleEventArgs.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/ViewModel/ModuleViewModel.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/ViewModel/ParameterSetViewModel.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/ViewModel/ParameterViewModel.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Windows/MultipleSelectionDialog.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Windows/ShowAllModulesWindow.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/ShowCommand/Windows/ShowCommandWindow.xaml.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/commandHelpers/HelpWindowHelper.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/commandHelpers/ShowCommandHelper.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/commandHelpers/outgridview.cs create mode 100644 src/Microsoft.PowerShell.GraphicalHost/resources/GraphicalHostResources.resx create mode 100644 src/Microsoft.PowerShell.GraphicalHost/resources/HelpWindowResources.resx create mode 100644 src/Microsoft.PowerShell.GraphicalHost/resources/InvariantResources.resx create mode 100644 src/Microsoft.PowerShell.GraphicalHost/resources/ShowCommandResources.resx create mode 100644 src/Microsoft.PowerShell.GraphicalHost/resources/UICultureResources.resx create mode 100644 src/Microsoft.PowerShell.GraphicalHost/resources/XamlLocalizableResources.resx create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/AllModulesControl.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/CmdletControl.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/ColumnPicker.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/HelpWindow.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/ImageButton.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/ImageButtonCommon.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/ImageToggleButton.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/MultipleSelectionControl.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/MultipleSelectionDialog.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/NotImportedCmdletControl.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/ParameterSetControl.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/SettingsDialog.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/ShowAllModulesWindow.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/ShowCommandWindow.xaml create mode 100644 src/Microsoft.PowerShell.GraphicalHost/xamls/ShowModuleControl.xaml diff --git a/src/Microsoft.PowerShell.GraphicalHost/CommonHelper.cs b/src/Microsoft.PowerShell.GraphicalHost/CommonHelper.cs new file mode 100644 index 000000000..37066d70b --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/CommonHelper.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Implements HelpWindow. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI +{ + using System.Windows; + + /// + /// Utilities in common in this assembly + /// + internal static class CommonHelper + { + /// + /// Restore the values from the settings to the actual window position, size and state. + /// + /// the window we are setting position and size of + /// the value for top from the user settings + /// the value for left from the user settings + /// the value for width from the user settings + /// the value for height from the user settings + /// the with used if is not valid + /// the height used if is not valid + /// true if the window is maximized in the user setting + internal static void SetStartingPositionAndSize(Window target, double userSettingTop, double userSettingLeft, double userSettingWidth, double userSettingHeight, double defaultWidth, double defaultHeight, bool userSettingMaximized) + { + bool leftInvalid = userSettingLeft < System.Windows.SystemParameters.VirtualScreenLeft || + userSettingWidth > System.Windows.SystemParameters.VirtualScreenLeft + + System.Windows.SystemParameters.VirtualScreenWidth; + + bool topInvalid = userSettingTop < System.Windows.SystemParameters.VirtualScreenTop || + userSettingTop > System.Windows.SystemParameters.VirtualScreenTop + + System.Windows.SystemParameters.VirtualScreenHeight; + + bool widthInvalid = userSettingWidth < 0 || + userSettingWidth > System.Windows.SystemParameters.VirtualScreenWidth; + + bool heightInvalid = userSettingHeight < 0 || + userSettingHeight > System.Windows.SystemParameters.VirtualScreenHeight; + + if (leftInvalid || topInvalid) + { + target.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen; + } + else + { + target.Left = userSettingLeft; + target.Top = userSettingTop; + } + + // If any saved coordinate is invalid, we set the window to the default position + if (widthInvalid || heightInvalid) + { + target.Width = defaultWidth; + target.Height = defaultHeight; + } + else + { + target.Width = userSettingWidth; + target.Height = userSettingHeight; + } + + if (userSettingMaximized) + { + target.WindowState = WindowState.Maximized; + } + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpParagraphBuilder.cs b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpParagraphBuilder.cs new file mode 100644 index 000000000..49c2b87c5 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpParagraphBuilder.cs @@ -0,0 +1,983 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Implements HelpParagraphBuilder. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Diagnostics; + using System.Globalization; + using System.Management.Automation; + using System.Text; + using System.Windows.Documents; + + /// + /// Builds a help paragraph for a cmdlet + /// + internal class HelpParagraphBuilder : ParagraphBuilder + { + /// + /// Indentation size + /// + internal const int IndentSize = 4; + + /// + /// new line separators + /// + private static readonly string[] Separators = new string[] { "\r\n", "\n" }; + + /// + /// Object with the cmdelt + /// + private PSObject psObj; + + /// + /// Initializes a new instance of the HelpParagraphBuilder class + /// + /// paragraph being built + /// object with help information + internal HelpParagraphBuilder(Paragraph paragraph, PSObject psObj) + : base(paragraph) + { + this.psObj = psObj; + this.AddTextToParagraphBuilder(); + } + + /// + /// Enum for category of Help. + /// + private enum HelpCategory { Default, DscResource, Class }; + + /// + /// Gets the string value of a property or null if it could not be retrieved + /// + /// object with the property + /// property name + /// the string value of a property or null if it could not be retrieved + internal static string GetPropertyString(PSObject psObj, string propertyName) + { + Debug.Assert(psObj != null, "ensured by caller"); + object value = GetPropertyObject(psObj, propertyName); + + if (value == null) + { + return null; + } + + return value.ToString(); + } + + /// + /// Adds the help text to the paragraph + /// + internal void AddTextToParagraphBuilder() + { + this.ResetAllText(); + + string strCategory = (HelpParagraphBuilder.GetProperty(this.psObj, "Category")).Value.ToString(); + + HelpCategory category = HelpCategory.Default; + + if (String.Compare(strCategory, "DscResource", StringComparison.OrdinalIgnoreCase) == 0) + { + category = HelpCategory.DscResource; + } + else if (String.Compare(strCategory, "Class", StringComparison.OrdinalIgnoreCase) == 0) + { + category = HelpCategory.Class; + } + + if (HelpParagraphBuilder.GetProperty(this.psObj, "Syntax") == null) + { + if(category == HelpCategory.Default) + { + // if there is no syntax, this is not the standard help + // it might be an about page + this.AddText(this.psObj.ToString(), false); + return; + } + } + + switch (category) + { + case HelpCategory.Class: + this.AddDescription(HelpWindowSettings.Default.HelpSynopsysDisplayed, HelpWindowResources.SynopsisTitle, "Introduction"); + this.AddMembers(HelpWindowSettings.Default.HelpParametersDisplayed, HelpWindowResources.PropertiesTitle); + this.AddMembers(HelpWindowSettings.Default.HelpParametersDisplayed, HelpWindowResources.MethodsTitle); + break; + case HelpCategory.DscResource: + this.AddStringSection(HelpWindowSettings.Default.HelpSynopsysDisplayed, "Synopsis", HelpWindowResources.SynopsisTitle); + this.AddDescription(HelpWindowSettings.Default.HelpDescriptionDisplayed, HelpWindowResources.DescriptionTitle, "Description"); + this.AddParameters(HelpWindowSettings.Default.HelpParametersDisplayed, HelpWindowResources.PropertiesTitle, "Properties", HelpCategory.DscResource); + break; + default: + this.AddStringSection(HelpWindowSettings.Default.HelpSynopsysDisplayed, "Synopsis", HelpWindowResources.SynopsisTitle); + this.AddDescription(HelpWindowSettings.Default.HelpDescriptionDisplayed, HelpWindowResources.DescriptionTitle, "Description"); + this.AddParameters(HelpWindowSettings.Default.HelpParametersDisplayed, HelpWindowResources.ParametersTitle, "Parameters", HelpCategory.Default); + this.AddSyntax(HelpWindowSettings.Default.HelpSyntaxDisplayed, HelpWindowResources.SyntaxTitle); + break; + } + + this.AddInputOrOutputEntries(HelpWindowSettings.Default.HelpInputsDisplayed, HelpWindowResources.InputsTitle, "inputTypes", "inputType"); + this.AddInputOrOutputEntries(HelpWindowSettings.Default.HelpOutputsDisplayed, HelpWindowResources.OutputsTitle, "returnValues", "returnValue"); + this.AddNotes(HelpWindowSettings.Default.HelpNotesDisplayed, HelpWindowResources.NotesTitle); + this.AddExamples(HelpWindowSettings.Default.HelpExamplesDisplayed, HelpWindowResources.ExamplesTitle); + this.AddNavigationLink(HelpWindowSettings.Default.HelpRelatedLinksDisplayed, HelpWindowResources.RelatedLinksTitle); + this.AddStringSection(HelpWindowSettings.Default.HelpRemarksDisplayed, "Remarks", HelpWindowResources.RemarksTitle); + } + + /// + /// Gets the object property or null if it could not be retrieved + /// + /// object with the property + /// property name + /// the object property or null if it could not be retrieved + private static PSPropertyInfo GetProperty(PSObject psObj, string propertyName) + { + Debug.Assert(psObj != null, "ensured by caller"); + return psObj.Properties[propertyName]; + } + + /// + /// Gets a PSObject and then a value from it or null if the value could not be retrieved + /// + /// PSObject that contains another PSObject as a property + /// property name that contains the PSObject + /// property name in thye inner PSObject + /// the string from the inner psObject property or null if it could not be retrieved + private static string GetInnerPSObjectPropertyString(PSObject psObj, string psObjectName, string propertyName) + { + Debug.Assert(psObj != null, "ensured by caller"); + PSObject innerPsObj = GetPropertyObject(psObj, psObjectName) as PSObject; + + if (innerPsObj == null) + { + return null; + } + + object value = GetPropertyObject(innerPsObj, propertyName); + + if (value == null) + { + return null; + } + + return value.ToString(); + } + + /// + /// Gets the value of a property or null if the value could not be retrieved + /// + /// object with the property + /// property name + /// the value of a property or null if the value could not be retrieved + private static object GetPropertyObject(PSObject psObj, string propertyName) + { + Debug.Assert(psObj != null, "ensured by caller"); + PSPropertyInfo property = HelpParagraphBuilder.GetProperty(psObj, propertyName); + if (property == null) + { + return null; + } + + object value = null; + try + { + value = property.Value; + } + catch (ExtendedTypeSystemException) + { + } + + return value; + } + + /// + /// Gets the text from a property of type PSObject[] where the first object has a text property + /// + /// objhect to get text from + /// property with PSObject[] containing text + /// the text from a property of type PSObject[] where the first object has a text property + private static string GetTextFromArray(PSObject psObj, string propertyText) + { + PSObject[] introductionObjects = HelpParagraphBuilder.GetPropertyObject(psObj, propertyText) as PSObject[]; + if (introductionObjects != null && introductionObjects.Length > 0) + { + return GetPropertyString(introductionObjects[0], "text"); + } + + return null; + } + + /// + /// Returns the largest size of a group of strings + /// + /// strings to evaluate the largest size from + /// the largest size of a group of strings + private static int LargestSize(params string[] strs) + { + int returnValue = 0; + + foreach (string str in strs) + { + if (str != null && str.Length > returnValue) + { + returnValue = str.Length; + } + } + + return returnValue; + } + + /// + /// Splits the string adding indentation before each line + /// + /// string to add indentation to + /// the string indented + private static string AddIndent(string str) + { + return HelpParagraphBuilder.AddIndent(str, 1); + } + + /// + /// Splits the string adding indentation before each line + /// + /// string to add indentation to + /// number of indentations + /// the string indented + private static string AddIndent(string str, int numberOfIdents) + { + StringBuilder indent = new StringBuilder(); + indent.Append(' ', numberOfIdents * HelpParagraphBuilder.IndentSize); + return HelpParagraphBuilder.AddIndent(str, indent.ToString()); + } + + /// + /// Splits the string adding indentation before each line + /// + /// string to add indentation to + /// indentation string + /// the string indented + private static string AddIndent(string str, string indentString) + { + if (str == null) + { + return String.Empty; + } + + string[] lines = str.Split(Separators, StringSplitOptions.None); + + StringBuilder returnValue = new StringBuilder(); + foreach (string line in lines) + { + // Indentation is not localized + returnValue.AppendFormat("{0}{1}\r\n", indentString, line); + } + + if (returnValue.Length > 2) + { + // remove the last \r\n + returnValue.Remove(returnValue.Length - 2, 2); + } + + return returnValue.ToString(); + } + + /// + /// Get the object array value of a property + /// + /// object containing the property + /// property with the array value + /// the object array value of a property + private static object[] GetPropertyObjectArray(PSObject obj, string propertyName) + { + object innerObject; + if ((innerObject = HelpParagraphBuilder.GetPropertyObject(obj, propertyName)) == null) + { + return null; + } + + if (innerObject is PSObject) + { + return new object[] { innerObject }; + } + + object[] innerObjectArray = innerObject as object[]; + if (innerObject == null) + { + return null; + } + + return innerObjectArray; + } + + + /// + /// Adds a section that contains only a string + /// + /// true if it should add the segment + /// name of the section to add + /// title of the section + private void AddStringSection(bool setting, string sectionName, string sectionTitle) + { + string propertyValue; + if (!setting || (propertyValue = HelpParagraphBuilder.GetPropertyString(this.psObj, sectionName)) == null) + { + return; + } + + this.AddText(sectionTitle, true); + this.AddText("\r\n", false); + this.AddText(HelpParagraphBuilder.AddIndent(propertyValue), false); + this.AddText("\r\n\r\n", false); + } + + /// + /// Adds the help syntax segment + /// + /// true if it should add the segment + /// title of the section + private void AddSyntax(bool setting, string sectionTitle) + { + PSObject syntaxObject; + if (!setting || (syntaxObject = HelpParagraphBuilder.GetPropertyObject(this.psObj, "Syntax") as PSObject) == null) + { + return; + } + + object[] syntaxItemsObj = HelpParagraphBuilder.GetPropertyObjectArray(syntaxObject, "syntaxItem"); + if (syntaxItemsObj == null || syntaxItemsObj.Length == 0) + { + return; + } + + this.AddText(sectionTitle, true); + this.AddText("\r\n", false); + + foreach (object syntaxItemObj in syntaxItemsObj) + { + PSObject syntaxItem = syntaxItemObj as PSObject; + if (syntaxItem == null) + { + continue; + } + + string commandName = GetPropertyString(syntaxItem, "name"); + + object[] parameterObjs = HelpParagraphBuilder.GetPropertyObjectArray(syntaxItem, "parameter"); + if (commandName == null || parameterObjs == null || parameterObjs.Length == 0) + { + continue; + } + + string commandStart = String.Format(CultureInfo.CurrentCulture, "{0} ", commandName); + this.AddText(HelpParagraphBuilder.AddIndent(commandStart), false); + + foreach (object parameterObj in parameterObjs) + { + PSObject parameter = parameterObj as PSObject; + if (parameter == null) + { + continue; + } + + string parameterValue = GetPropertyString(parameter, "parameterValue"); + string position = GetPropertyString(parameter, "position"); + string required = GetPropertyString(parameter, "required"); + string parameterName = GetPropertyString(parameter, "name"); + if (position == null || required == null || parameterName == null) + { + continue; + } + + string parameterType = parameterValue == null ? String.Empty : String.Format(CultureInfo.CurrentCulture, "<{0}>", parameterValue); + + string parameterOptionalOpenBrace, parameterOptionalCloseBrace; + + if (String.Equals(required, "true", StringComparison.OrdinalIgnoreCase)) + { + parameterOptionalOpenBrace = parameterOptionalCloseBrace = String.Empty; + } + else + { + parameterOptionalOpenBrace = "["; + parameterOptionalCloseBrace = "]"; + } + + string parameterNameOptionalOpenBrace, parameterNameOptionalCloseBrace; + + if (String.Equals(position, "named", StringComparison.OrdinalIgnoreCase)) + { + parameterNameOptionalOpenBrace = parameterNameOptionalCloseBrace = String.Empty; + } + else + { + parameterNameOptionalOpenBrace = "["; + parameterNameOptionalCloseBrace = "]"; + } + + string paramterPrefix = String.Format( + CultureInfo.CurrentCulture, + "{0}{1}-", + parameterOptionalOpenBrace, + parameterNameOptionalOpenBrace); + + this.AddText(paramterPrefix, false); + this.AddText(parameterName, true); + + string paramterSuffix = String.Format( + CultureInfo.CurrentCulture, + "{0} {1}{2} ", + parameterNameOptionalCloseBrace, + parameterType, + parameterOptionalCloseBrace); + this.AddText(paramterSuffix, false); + } + + string commonParametersText = String.Format( + CultureInfo.CurrentCulture, + "[<{0}>]\r\n\r\n", + HelpWindowResources.CommonParameters); + + this.AddText(commonParametersText, false); + } + + this.AddText("\r\n", false); + } + + /// + /// Adds the help description segment + /// + /// true if it should add the segment + /// title of the section + /// propertyName that has description + private void AddDescription(bool setting, string sectionTitle, string propertyName) + { + PSObject[] descriptionObjects; + if (!setting || + (descriptionObjects = HelpParagraphBuilder.GetPropertyObject(this.psObj, propertyName) as PSObject[]) == null || + descriptionObjects.Length == 0) + { + return; + } + + this.AddText(sectionTitle, true); + this.AddText("\r\n", false); + + foreach (PSObject description in descriptionObjects) + { + string descriptionText = GetPropertyString(description, "text"); + this.AddText(HelpParagraphBuilder.AddIndent(descriptionText), false); + this.AddText("\r\n", false); + } + + this.AddText("\r\n\r\n", false); + } + + /// + /// Adds the help examples segment + /// + /// true if it should add the segment + /// title of the section + private void AddExamples(bool setting, string sectionTitle) + { + if (!setting) + { + return; + } + + PSObject exampleRootObject = HelpParagraphBuilder.GetPropertyObject(this.psObj, "Examples") as PSObject; + if (exampleRootObject == null) + { + return; + } + + object[] exampleObjects = HelpParagraphBuilder.GetPropertyObjectArray(exampleRootObject, "example"); + if (exampleObjects == null || exampleObjects.Length == 0) + { + return; + } + + this.AddText(sectionTitle, true); + this.AddText("\r\n", false); + + foreach (object exampleObj in exampleObjects) + { + PSObject example = exampleObj as PSObject; + if (example == null) + { + continue; + } + + string introductionText = null; + introductionText = GetTextFromArray(example, "introduction"); + + string codeText = GetPropertyString(example, "code"); + string title = GetPropertyString(example, "title"); + + if (codeText == null) + { + continue; + } + + if (title != null) + { + this.AddText(HelpParagraphBuilder.AddIndent(title), false); + this.AddText("\r\n", false); + } + + string codeLine = String.Format( + CultureInfo.CurrentCulture, + "{0}{1}\r\n\r\n", + introductionText, + codeText); + + this.AddText(HelpParagraphBuilder.AddIndent(codeLine), false); + + PSObject[] remarks = HelpParagraphBuilder.GetPropertyObject(example, "remarks") as PSObject[]; + if (remarks == null) + { + continue; + } + + foreach (PSObject remark in remarks) + { + string remarkText = GetPropertyString(remark, "text"); + if (remarkText == null) + { + continue; + } + + this.AddText(remarkText, false); + this.AddText("\r\n", false); + } + } + + this.AddText("\r\n\r\n", false); + } + + private void AddMembers(bool setting, string sectionTitle) + { + if(!setting || String.IsNullOrEmpty(sectionTitle)) + return; + + PSObject memberRootObject = HelpParagraphBuilder.GetPropertyObject(this.psObj, "Members") as PSObject; + if (memberRootObject == null) + return; + + object[] memberObjects = HelpParagraphBuilder.GetPropertyObjectArray(memberRootObject, "member"); + + if (memberObjects == null) + return; + + this.AddText(sectionTitle, true); + this.AddText("\r\n", false); + + foreach (object memberObj in memberObjects) + { + string description = null; + string memberText = null; + + PSObject member = memberObj as PSObject; + if (member == null) + continue; + + string name = GetPropertyString(member, "title"); + string type = GetPropertyString(member, "type"); + string propertyType = null; + + if (String.Compare("field", type, StringComparison.OrdinalIgnoreCase) == 0) + { + PSObject fieldData = HelpParagraphBuilder.GetPropertyObject(member, "fieldData") as PSObject; + + if (fieldData != null) + { + PSObject propertyTypeObject = HelpParagraphBuilder.GetPropertyObject(fieldData, "type") as PSObject; + if (propertyTypeObject != null) + { + propertyType = GetPropertyString(propertyTypeObject, "name"); + description = GetPropertyString(propertyTypeObject, "description"); + } + + memberText = String.Format(CultureInfo.CurrentCulture, " [{0}] {1}\r\n", propertyType, name); + } + } + else if (String.Compare("method", type, StringComparison.OrdinalIgnoreCase) == 0) + { + FormatMethodData(member, name, out memberText, out description); + } + + if (!String.IsNullOrEmpty(memberText)) + { + this.AddText(HelpParagraphBuilder.AddIndent(""), false); + this.AddText(memberText, true); + + if (description != null) + { + this.AddText(HelpParagraphBuilder.AddIndent(description, 2), false); + this.AddText("\r\n", false); + } + + this.AddText("\r\n", false); + } + } + } + + private void FormatMethodData(PSObject member, string name, out string memberText, out string description) + { + memberText = null; + description = null; + + if (member == null || String.IsNullOrEmpty(name)) + { + return; + } + + string returnType = null; + StringBuilder parameterText = new StringBuilder(); + + //Get method return type + PSObject returnTypeObject = HelpParagraphBuilder.GetPropertyObject(member, "returnValue") as PSObject; + if (returnTypeObject != null) + { + PSObject returnTypeData = HelpParagraphBuilder.GetPropertyObject(returnTypeObject, "type") as PSObject; + if (returnTypeData != null) + returnType = GetPropertyString(returnTypeData, "name"); + } + + //Get method description. + PSObject[] methodDescriptions = HelpParagraphBuilder.GetPropertyObject(member, "introduction") as PSObject[]; + if (methodDescriptions != null) + { + foreach (var methodDescription in methodDescriptions) + { + description = GetPropertyString(methodDescription, "Text"); + + //If we get an text we do not need to iterate more. + if (!String.IsNullOrEmpty(description)) + break; + } + } + + //Get method parameters. + PSObject parametersObject = HelpParagraphBuilder.GetPropertyObject(member, "parameters") as PSObject; + if (parametersObject != null) + { + PSObject[] paramObject = HelpParagraphBuilder.GetPropertyObject(parametersObject, "parameter") as PSObject[]; + + if (paramObject != null) + { + foreach (var param in paramObject) + { + string parameterName = GetPropertyString(param, "name"); + string parameterType = null; + + PSObject parameterTypeData = HelpParagraphBuilder.GetPropertyObject(param, "type") as PSObject; + + if (parameterTypeData != null) + { + parameterType = GetPropertyString(parameterTypeData, "name"); + + //If there is no type for the paramter, we expect it is System.Object + if (String.IsNullOrEmpty(parameterType)) + parameterType = "object"; + } + + string paramString = String.Format(CultureInfo.CurrentCulture, "[{0}] ${1},", parameterType, parameterName); + + parameterText.Append(paramString); + } + + if (String.Compare(parameterText[parameterText.Length - 1].ToString(), ",", StringComparison.OrdinalIgnoreCase) == 0) + { + parameterText = parameterText.Remove(parameterText.Length - 1, 1); + } + } + } + + memberText = String.Format(CultureInfo.CurrentCulture, " [{0}] {1}({2})\r\n", returnType, name, parameterText.ToString()); + } + + /// + /// Adds the help parameters segment + /// + /// true if it should add the segment + /// title of the section + /// name of the property which has properties + /// category of help + private void AddParameters(bool setting, string sectionTitle, string paramPropertyName, HelpCategory helpCategory) + { + if (!setting) + { + return; + } + + PSObject parameterRootObject = HelpParagraphBuilder.GetPropertyObject(this.psObj, paramPropertyName) as PSObject; + if (parameterRootObject == null) + { + return; + } + + object[] parameterObjects = null; + + //Root object for Class has members not parameters. + if (helpCategory != HelpCategory.Class) + { + parameterObjects = HelpParagraphBuilder.GetPropertyObjectArray(parameterRootObject, "parameter"); + } + + if (parameterObjects == null || parameterObjects.Length == 0) + { + return; + } + + this.AddText(sectionTitle, true); + this.AddText("\r\n", false); + + foreach (object parameterObj in parameterObjects) + { + PSObject parameter = parameterObj as PSObject; + if (parameter == null) + { + continue; + } + + string parameterValue = GetPropertyString(parameter, "parameterValue"); + string name = GetPropertyString(parameter, "name"); + string description = GetTextFromArray(parameter, "description"); + string required = GetPropertyString(parameter, "required"); + string position = GetPropertyString(parameter, "position"); + string pipelineinput = GetPropertyString(parameter, "pipelineInput"); + string defaultValue = GetPropertyString(parameter, "defaultValue"); + string acceptWildcard = GetPropertyString(parameter, "globbing"); + + if (String.IsNullOrEmpty(name)) + { + continue; + } + + // This syntax string is not localized + + if (helpCategory == HelpCategory.DscResource) + this.AddText(HelpParagraphBuilder.AddIndent(""), false); + else + this.AddText(HelpParagraphBuilder.AddIndent("-"), false); + + this.AddText(name, true); + string parameterText = String.Format( + CultureInfo.CurrentCulture, + " <{0}>\r\n", + parameterValue); + + this.AddText(parameterText, false); + + if (description != null) + { + this.AddText(HelpParagraphBuilder.AddIndent(description, 2), false); + this.AddText("\r\n", false); + } + + this.AddText("\r\n", false); + + int largestSize = HelpParagraphBuilder.LargestSize( + HelpWindowResources.ParameterRequired, + HelpWindowResources.ParameterPosition, + HelpWindowResources.ParameterDefautValue, + HelpWindowResources.ParameterPipelineInput, + HelpWindowResources.ParameterAcceptWildcard); + + // justification of parameter values is not localized + string formatString = String.Format( + CultureInfo.CurrentCulture, + "{{0,-{0}}}{{1}}", + largestSize + 2); + + string tableLine; + + tableLine = String.Format( + CultureInfo.CurrentCulture, + formatString, + HelpWindowResources.ParameterRequired, + required); + this.AddText(HelpParagraphBuilder.AddIndent(tableLine, 2), false); + this.AddText("\r\n", false); + + //these are not applicable for Dsc Resource help + if (helpCategory != HelpCategory.DscResource) + { + tableLine = String.Format( + CultureInfo.CurrentCulture, + formatString, + HelpWindowResources.ParameterPosition, + position); + this.AddText(HelpParagraphBuilder.AddIndent(tableLine, 2), false); + this.AddText("\r\n", false); + + tableLine = String.Format( + CultureInfo.CurrentCulture, + formatString, + HelpWindowResources.ParameterDefautValue, + defaultValue); + this.AddText(HelpParagraphBuilder.AddIndent(tableLine, 2), false); + this.AddText("\r\n", false); + + tableLine = String.Format( + CultureInfo.CurrentCulture, + formatString, + HelpWindowResources.ParameterPipelineInput, + pipelineinput); + this.AddText(HelpParagraphBuilder.AddIndent(tableLine, 2), false); + this.AddText("\r\n", false); + + tableLine = String.Format( + CultureInfo.CurrentCulture, + formatString, + HelpWindowResources.ParameterAcceptWildcard, + acceptWildcard); + this.AddText(HelpParagraphBuilder.AddIndent(tableLine, 2), false); + } + + this.AddText("\r\n\r\n", false); + } + + this.AddText("\r\n\r\n", false); + } + + /// + /// Adds the help navigation links segment + /// + /// true if it should add the segment + /// title of the section + private void AddNavigationLink(bool setting, string sectionTitle) + { + if (!setting) + { + return; + } + + PSObject linkRootObject = HelpParagraphBuilder.GetPropertyObject(this.psObj, "RelatedLinks") as PSObject; + if (linkRootObject == null) + { + return; + } + + PSObject[] linkObjects; + + if ((linkObjects = HelpParagraphBuilder.GetPropertyObject(linkRootObject, "navigationLink") as PSObject[]) == null || + linkObjects.Length == 0) + { + return; + } + + this.AddText(sectionTitle, true); + this.AddText("\r\n", false); + + foreach (PSObject linkObject in linkObjects) + { + string text = GetPropertyString(linkObject, "linkText"); + string uri = GetPropertyString(linkObject, "uri"); + + string linkLine = String.IsNullOrEmpty(uri) ? text : String.Format( + CultureInfo.CurrentCulture, + HelpWindowResources.LinkTextFormat, + text, + uri); + + this.AddText(HelpParagraphBuilder.AddIndent(linkLine), false); + this.AddText("\r\n", false); + } + + this.AddText("\r\n\r\n", false); + } + + /// + /// Adds the help input or output segment + /// + /// true if it should add the segment + /// title of the section + /// property with the outter object + /// property with the inner object + private void AddInputOrOutputEntries(bool setting, string sectionTitle, string inputOrOutputProperty, string inputOrOutputInnerProperty) + { + if (!setting) + { + return; + } + + PSObject rootObject = HelpParagraphBuilder.GetPropertyObject(this.psObj, inputOrOutputProperty) as PSObject; + if (rootObject == null) + { + return; + } + + object[] inputOrOutputObjs; + inputOrOutputObjs = HelpParagraphBuilder.GetPropertyObjectArray(rootObject, inputOrOutputInnerProperty); + + if (inputOrOutputObjs == null || inputOrOutputObjs.Length == 0) + { + return; + } + + this.AddText(sectionTitle, true); + this.AddText("\r\n", false); + + foreach (object inputOrOutputObj in inputOrOutputObjs) + { + PSObject inputOrOutput = inputOrOutputObj as PSObject; + if (inputOrOutput == null) + { + continue; + } + + string type = HelpParagraphBuilder.GetInnerPSObjectPropertyString(inputOrOutput, "type", "name"); + string description = GetTextFromArray(inputOrOutput, "description"); + + this.AddText(HelpParagraphBuilder.AddIndent(type), false); + this.AddText("\r\n", false); + if (description != null) + { + this.AddText(HelpParagraphBuilder.AddIndent(description), false); + this.AddText("\r\n", false); + } + } + + this.AddText("\r\n", false); + } + + /// + /// Adds the help notes segment + /// + /// true if it should add the segment + /// title of the section + private void AddNotes(bool setting, string sectionTitle) + { + if (!setting) + { + return; + } + + PSObject rootObject = HelpParagraphBuilder.GetPropertyObject(this.psObj, "alertSet") as PSObject; + if (rootObject == null) + { + return; + } + + string note = GetTextFromArray(rootObject, "alert"); + + if (note == null) + { + return; + } + + this.AddText(sectionTitle, true); + this.AddText("\r\n", false); + this.AddText(HelpParagraphBuilder.AddIndent(note), false); + this.AddText("\r\n\r\n", false); + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpViewModel.cs b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpViewModel.cs new file mode 100644 index 000000000..91f44fc4e --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpViewModel.cs @@ -0,0 +1,289 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Implements HelpViewModel. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.ComponentModel; + using System.Diagnostics; + using System.Globalization; + using System.Management.Automation; + using System.Windows.Documents; + + /// + /// 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 HelpParagraphBuilder helpBuilder; + + /// + /// Searcher for selecting current matches in paragraph text + /// + private ParagraphSearcher searcher; + + /// + /// Title of the help window + /// + private 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)); + } + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpWindow.xaml.cs b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpWindow.xaml.cs new file mode 100644 index 000000000..a858d26c8 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpWindow.xaml.cs @@ -0,0 +1,309 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Implements HelpWindow. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI +{ + using System.Globalization; + using System.Management.Automation; + using System.Windows; + using System.Windows.Documents; + using System.Windows.Input; + using Microsoft.Management.UI.Internal; + + /// + /// A window displaying help content and allowing search + /// + public partial class HelpWindow : Window + { + /// + /// Minimum zoom in the slider + /// + public const double MinimumZoom = 20; + + /// + /// Maximum zoom in the slider + /// + public const double MaximumZoom = 300; + + /// + /// Zoom interval + /// + public const double ZoomInterval = 10; + + /// + /// The ViewModel for the dialog + /// + private HelpViewModel viewModel; + + /// + /// Initializes a new instance of the HelpWindow class + /// + /// the object with help information + public HelpWindow(PSObject helpObject) + { + InitializeComponent(); + this.viewModel = new HelpViewModel(helpObject, this.DocumentParagraph); + CommonHelper.SetStartingPositionAndSize( + this, + HelpWindowSettings.Default.HelpWindowTop, + HelpWindowSettings.Default.HelpWindowLeft, + HelpWindowSettings.Default.HelpWindowWidth, + HelpWindowSettings.Default.HelpWindowHeight, + double.Parse((string)HelpWindowSettings.Default.Properties["HelpWindowWidth"].DefaultValue, CultureInfo.InvariantCulture.NumberFormat), + double.Parse((string)HelpWindowSettings.Default.Properties["HelpWindowHeight"].DefaultValue, CultureInfo.InvariantCulture.NumberFormat), + HelpWindowSettings.Default.HelpWindowMaximized); + + this.ReadZoomUserSetting(); + + this.viewModel.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(this.ViewModel_PropertyChanged); + this.DataContext = this.viewModel; + + this.Loaded += new RoutedEventHandler(this.HelpDialog_Loaded); + this.Closed += new System.EventHandler(this.HelpDialog_Closed); + } + + /// + /// Handles the mouse wheel to zoom in/out + /// + /// event arguments + protected override void OnPreviewMouseWheel(MouseWheelEventArgs e) + { + if (Keyboard.Modifiers != ModifierKeys.Control) + { + return; + } + + if (e.Delta > 0) + { + this.viewModel.ZoomIn(); + e.Handled = true; + } + else + { + this.viewModel.ZoomOut(); + e.Handled = true; + } + } + + /// + /// Handles key down to fix the Page/Douwn going to end of help issue + /// And to implement some additional shortcuts like Ctrl+F and ZoomIn/ZoomOut + /// + /// event arguments + protected override void OnPreviewKeyDown(KeyEventArgs e) + { + if (Keyboard.Modifiers == ModifierKeys.None) + { + if (e.Key == Key.PageUp) + { + this.Scroll.PageUp(); + e.Handled = true; + return; + } + + if (e.Key == Key.PageDown) + { + this.Scroll.PageDown(); + e.Handled = true; + return; + } + } + + if (Keyboard.Modifiers == ModifierKeys.Control) + { + this.HandleZoomInAndZoomOut(e); + if (e.Handled) + { + return; + } + + if (e.Key == Key.F) + { + this.Find.Focus(); + e.Handled = true; + return; + } + } + + if (Keyboard.Modifiers == (ModifierKeys.Control | ModifierKeys.Shift)) + { + this.HandleZoomInAndZoomOut(e); + if (e.Handled) + { + return; + } + } + } + + /// + /// Reads the zoom part of the user settings + /// + private void ReadZoomUserSetting() + { + if (HelpWindowSettings.Default.HelpZoom < HelpWindow.MinimumZoom || HelpWindowSettings.Default.HelpZoom > HelpWindow.MaximumZoom) + { + HelpWindowSettings.Default.HelpZoom = 100; + } + + this.viewModel.Zoom = HelpWindowSettings.Default.HelpZoom; + } + + /// + /// Handles Zoom in and Zoom out keys + /// + /// event arguments + private void HandleZoomInAndZoomOut(KeyEventArgs e) + { + if (e.Key == Key.OemPlus || e.Key == Key.Add) + { + this.viewModel.ZoomIn(); + e.Handled = true; + } + + if (e.Key == Key.OemMinus || e.Key == Key.Subtract) + { + this.viewModel.ZoomOut(); + e.Handled = true; + } + } + + /// + /// Listens to changes in the zoom in order to update the user settings + /// + /// event sender + /// event arguments + private void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if (e.PropertyName == "Zoom") + { + HelpWindowSettings.Default.HelpZoom = this.viewModel.Zoom; + } + } + + /// + /// Saves the user settings + /// + /// event sender + /// event arguments + private void HelpDialog_Closed(object sender, System.EventArgs e) + { + HelpWindowSettings.Default.Save(); + } + + /// + /// Updates the user setting with window state + /// + /// event sender + /// event arguments + private void HelpDialog_StateChanged(object sender, System.EventArgs e) + { + HelpWindowSettings.Default.HelpWindowMaximized = this.WindowState == WindowState.Maximized; + } + + /// + /// Sets the positions from user settings and start monitoring position changes + /// + /// event sender + /// event arguments + private void HelpDialog_Loaded(object sender, RoutedEventArgs e) + { + this.StateChanged += new System.EventHandler(this.HelpDialog_StateChanged); + this.LocationChanged += new System.EventHandler(this.HelpDialog_LocationChanged); + this.SizeChanged += new SizeChangedEventHandler(this.HelpDialog_SizeChanged); + } + + /// + /// Saves size changes in user settings + /// + /// event sender + /// event arguments + private void HelpDialog_SizeChanged(object sender, SizeChangedEventArgs e) + { + HelpWindowSettings.Default.HelpWindowWidth = this.Width; + HelpWindowSettings.Default.HelpWindowHeight = this.Height; + } + + /// + /// Saves position changes in user settings + /// + /// event sender + /// event arguments + private void HelpDialog_LocationChanged(object sender, System.EventArgs e) + { + HelpWindowSettings.Default.HelpWindowTop = this.Top; + HelpWindowSettings.Default.HelpWindowLeft = this.Left; + } + + /// + /// Called when the settings button is clicked + /// + /// event sender + /// event arguments + private void Settings_Click(object sender, RoutedEventArgs e) + { + SettingsDialog settings = new SettingsDialog(); + settings.Owner = this; + + settings.ShowDialog(); + + if (settings.DialogResult == true) + { + this.viewModel.HelpBuilder.AddTextToParagraphBuilder(); + this.viewModel.Search(); + } + } + + /// + /// Called when the Previous button is clicked + /// + /// event sender + /// event arguments + private void PreviousMatch_Click(object sender, RoutedEventArgs e) + { + this.MoveToNextMatch(false); + } + + /// + /// Called when the Next button is clicked + /// + /// event sender + /// event arguments + private void NextMatch_Click(object sender, RoutedEventArgs e) + { + this.MoveToNextMatch(true); + } + + /// + /// Moves to the previous or next match + /// + /// true for forward false for backwards + private void MoveToNextMatch(bool forward) + { + TextPointer caretPosition = this.HelpText.CaretPosition; + Run nextRun = this.viewModel.Searcher.MoveAndHighlightNextNextMatch(forward, caretPosition); + this.MoveToRun(nextRun); + } + + /// + /// Moves to the caret and brings the view to the + /// + /// run to move to + private void MoveToRun(Run run) + { + if (run == null) + { + return; + } + + run.BringIntoView(); + this.HelpText.CaretPosition = run.ElementEnd; + this.HelpText.Focus(); + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpWindowSettings.Designer.cs b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpWindowSettings.Designer.cs new file mode 100644 index 000000000..6306c28bf --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/HelpWindowSettings.Designer.cs @@ -0,0 +1,248 @@ +// +// Copyright (C) Microsoft. All rights reserved. +// +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.16598 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.Management.UI.Internal { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class HelpWindowSettings : global::System.Configuration.ApplicationSettingsBase { + + private static HelpWindowSettings defaultInstance = ((HelpWindowSettings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new HelpWindowSettings()))); + + public static HelpWindowSettings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool HelpRemarksDisplayed + { + get + { + return ((bool)(this["HelpRemarksDisplayed"])); + } + set + { + this["HelpRemarksDisplayed"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool HelpSyntaxDisplayed { + get { + return ((bool)(this["HelpSyntaxDisplayed"])); + } + set { + this["HelpSyntaxDisplayed"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool HelpExamplesDisplayed { + get { + return ((bool)(this["HelpExamplesDisplayed"])); + } + set { + this["HelpExamplesDisplayed"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool HelpSynopsysDisplayed { + get { + return ((bool)(this["HelpSynopsysDisplayed"])); + } + set { + this["HelpSynopsysDisplayed"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool HelpDescriptionDisplayed { + get { + return ((bool)(this["HelpDescriptionDisplayed"])); + } + set { + this["HelpDescriptionDisplayed"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool HelpParametersDisplayed { + get { + return ((bool)(this["HelpParametersDisplayed"])); + } + set { + this["HelpParametersDisplayed"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool HelpInputsDisplayed { + get { + return ((bool)(this["HelpInputsDisplayed"])); + } + set { + this["HelpInputsDisplayed"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool HelpOutputsDisplayed { + get { + return ((bool)(this["HelpOutputsDisplayed"])); + } + set { + this["HelpOutputsDisplayed"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool HelpNotesDisplayed { + get { + return ((bool)(this["HelpNotesDisplayed"])); + } + set { + this["HelpNotesDisplayed"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool HelpRelatedLinksDisplayed { + get { + return ((bool)(this["HelpRelatedLinksDisplayed"])); + } + set { + this["HelpRelatedLinksDisplayed"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool HelpSearchMatchCase { + get { + return ((bool)(this["HelpSearchMatchCase"])); + } + set { + this["HelpSearchMatchCase"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool HelpSearchWholeWord { + get { + return ((bool)(this["HelpSearchWholeWord"])); + } + set { + this["HelpSearchWholeWord"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("400")] + public double HelpWindowHeight { + get { + return ((double)(this["HelpWindowHeight"])); + } + set { + this["HelpWindowHeight"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("600")] + public double HelpWindowWidth { + get { + return ((double)(this["HelpWindowWidth"])); + } + set { + this["HelpWindowWidth"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("-1")] + public double HelpWindowTop { + get { + return ((double)(this["HelpWindowTop"])); + } + set { + this["HelpWindowTop"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("-1")] + public double HelpWindowLeft { + get { + return ((double)(this["HelpWindowLeft"])); + } + set { + this["HelpWindowLeft"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool HelpWindowMaximized { + get { + return ((bool)(this["HelpWindowMaximized"])); + } + set { + this["HelpWindowMaximized"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("100")] + public double HelpZoom { + get { + return ((double)(this["HelpZoom"])); + } + set { + this["HelpZoom"] = value; + } + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/ParagraphBuilder.cs b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/ParagraphBuilder.cs new file mode 100644 index 000000000..3704b2eb9 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/ParagraphBuilder.cs @@ -0,0 +1,383 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Implements ParagraphBuilder. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Text; + using System.Windows.Documents; + using System.Windows.Media; + + /// + /// Builds a paragraph based on Text + Bold + Highlight information. + /// Bold are the segments of thexct that should be bold, and Highlight are + /// the segments of thext that should be highlighted (like search results). + /// + internal class ParagraphBuilder : INotifyPropertyChanged + { + /// + /// The text spans that should be bold + /// + private List boldSpans; + + /// + /// The text spans that should be highlighted + /// + private List highlighedSpans; + + /// + /// The text displayed + /// + private StringBuilder textBuilder; + + /// + /// Paragraph built in BuildParagraph + /// + private Paragraph paragraph; + + /// + /// Initializes a new instance of the ParagraphBuilder class + /// + /// paragraph we will be adding lines to in BuildParagraph + internal ParagraphBuilder(Paragraph paragraph) + { + if (paragraph == null) + { + throw new ArgumentNullException("paragraph"); + } + + this.paragraph = paragraph; + this.boldSpans = new List(); + this.highlighedSpans = new List(); + this.textBuilder = new StringBuilder(); + } + + #region INotifyPropertyChanged Members + /// + /// Used to notify of property changes + /// + public event PropertyChangedEventHandler PropertyChanged; + #endregion + + /// + /// Gets the number of highlights. + /// + internal int HighlightCount + { + get { return this.highlighedSpans.Count; } + } + + /// + /// Gets the paragraph built in BuildParagraph + /// + internal Paragraph Paragraph + { + get { return this.paragraph; } + } + + /// + /// Called after all the AddText calls have been made to build the paragraph + /// based on the current text. + /// This method goes over 3 collections simultaneouslly: + /// 1) characters in this.textBuilder + /// 2) spans in this.boldSpans + /// 3) spans in this.highlightedSpans + /// And adds the minimal number of Inlines to the paragraph so that all + /// characters that should be bold and/or highlighed are. + /// + internal void BuildParagraph() + { + this.paragraph.Inlines.Clear(); + + int currentBoldIndex = 0; + TextSpan? currentBoldSpan = this.boldSpans.Count == 0 ? (TextSpan?)null : this.boldSpans[0]; + int currentHighlightedIndex = 0; + TextSpan? currentHighlightedSpan = this.highlighedSpans.Count == 0 ? (TextSpan?)null : this.highlighedSpans[0]; + + bool currentBold = false; + bool currentHighlighted = false; + + StringBuilder sequence = new StringBuilder(); + int i = 0; + foreach (char c in this.textBuilder.ToString()) + { + bool newBold = false; + bool newHighlighted = false; + + ParagraphBuilder.MoveSpanToPosition(ref currentBoldIndex, ref currentBoldSpan, i, this.boldSpans); + newBold = currentBoldSpan == null ? false : currentBoldSpan.Value.Contains(i); + + ParagraphBuilder.MoveSpanToPosition(ref currentHighlightedIndex, ref currentHighlightedSpan, i, this.highlighedSpans); + newHighlighted = currentHighlightedSpan == null ? false : currentHighlightedSpan.Value.Contains(i); + + if (newBold != currentBold || newHighlighted != currentHighlighted) + { + ParagraphBuilder.AddInline(this.paragraph, currentBold, currentHighlighted, sequence); + } + + sequence.Append(c); + + currentHighlighted = newHighlighted; + currentBold = newBold; + i++; + } + + ParagraphBuilder.AddInline(this.paragraph, currentBold, currentHighlighted, sequence); + } + + /// + /// Highlights all ocurrences of . + /// This is called after all calls to AddText have been made + /// + /// search string + /// true if search should be case sensitive + /// true if we should search whole word only + internal void HighlightAllInstancesOf(string search, bool caseSensitive, bool wholeWord) + { + this.highlighedSpans.Clear(); + + if (search == null || search.Trim().Length == 0) + { + this.BuildParagraph(); + this.OnNotifyPropertyChanged("HighlightCount"); + return; + } + + string text = this.textBuilder.ToString(); + StringComparison comparison = caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; + int start = 0; + int match; + while ((match = text.IndexOf(search, start, comparison)) != -1) + { + // false loop + do + { + if (wholeWord) + { + if (match > 0 && Char.IsLetterOrDigit(text[match - 1])) + { + break; + } + + if ((match + search.Length <= text.Length - 1) && Char.IsLetterOrDigit(text[match + search.Length])) + { + break; + } + } + + this.AddHighlight(match, search.Length); + } + while (false); + + start = match + search.Length; + } + + this.BuildParagraph(); + this.OnNotifyPropertyChanged("HighlightCount"); + } + + /// + /// Adds text to the paragraph later build with BuildParagraph + /// + /// text to be added + /// true if the text should be bold + internal void AddText(string str, bool bold) + { + if (str == null) + { + throw new ArgumentNullException("str"); + } + + if (str.Length == 0) + { + return; + } + + if (bold) + { + this.boldSpans.Add(new TextSpan(this.textBuilder.Length, str.Length)); + } + + this.textBuilder.Append(str); + } + + /// + /// Called before a derived class starts adding text + /// to reset the current content + /// + internal void ResetAllText() + { + this.boldSpans.Clear(); + this.highlighedSpans.Clear(); + this.textBuilder.Clear(); + } + + /// + /// Adds an inline to based on the remaining parameters. + /// + /// paragraph to add Inline to + /// true if text should be added in bold + /// true if the text should be added with highlight + /// the text to add and clear + private static void AddInline(Paragraph currentParagraph, bool currentBold, bool currentHighlighted, StringBuilder sequence) + { + if (sequence.Length == 0) + { + return; + } + + Run run = new Run(sequence.ToString()); + if (currentHighlighted) + { + run.Background = ParagraphSearcher.HighlightBrush; + } + + Inline inline = currentBold ? (Inline)new Bold(run) : run; + currentParagraph.Inlines.Add(inline); + sequence.Clear(); + } + + /// + /// This is an auxiliar method in BuildParagraph to move the current bold or highlighed spans + /// according to the + /// The current bold and higlighed span should be ending ahead of the current position. + /// Moves and to the + /// propper span in according to the + /// This is an auxiliar method in BuildParagraph. + /// + /// current index within + /// current span within + /// caracter position. This comes from a position within this.textBuilder + /// the collection of spans. This is either this.boldSpans or this.highlightedSpans + private static void MoveSpanToPosition(ref int currentSpanIndex, ref TextSpan? currentSpan, int caracterPosition, List allSpans) + { + if (currentSpan == null || caracterPosition <= currentSpan.Value.End) + { + return; + } + + for (int newBoldIndex = currentSpanIndex + 1; newBoldIndex < allSpans.Count; newBoldIndex++) + { + TextSpan newBoldSpan = allSpans[newBoldIndex]; + if (caracterPosition <= newBoldSpan.End) + { + currentSpanIndex = newBoldIndex; + currentSpan = newBoldSpan; + return; + } + } + + // there is no span ending ahead of current position, so + // we set the current span to null to prevent unecessary comparisons against the currentSpan + currentSpan = null; + } + + /// + /// Adds one individual text highlight + /// This is called after all calls to AddText have been made + /// + /// highlight start + /// highlight length + private void AddHighlight(int start, int length) + { + if (start < 0) + { + throw new ArgumentOutOfRangeException("start"); + } + + if (start + length > this.textBuilder.Length) + { + throw new ArgumentOutOfRangeException("length"); + } + + this.highlighedSpans.Add(new TextSpan(start, length)); + } + + /// + /// 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)); + } + } + + /// + /// A text span used to mark bold and highlighed segments + /// + internal struct TextSpan + { + /// + /// Index of the first character in the span + /// + private int start; + + /// + /// Index of the last character in the span + /// + private int end; + + /// + /// Initializes a new instance of the TextSpan struct + /// + /// Index of the first character in the span + /// Index of the last character in the span + internal TextSpan(int start, int length) + { + if (start < 0) + { + throw new ArgumentOutOfRangeException("start"); + } + + if (length < 1) + { + throw new ArgumentOutOfRangeException("length"); + } + + this.start = start; + this.end = start + length - 1; + } + + /// + /// Gets the index of the first character in the span + /// + internal int Start + { + get { return this.start; } + } + + /// + /// Gets the index of the first character in the span + /// + internal int End + { + get + { + return this.end; + } + } + + /// + /// Returns true if the is between start and end (inclusive) + /// + /// position to verify if is in the span + /// true if the is between start and end (inclusive) + internal bool Contains(int position) + { + return (position >= this.start) && (position <= this.end); + } + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/ParagraphSearcher.cs b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/ParagraphSearcher.cs new file mode 100644 index 000000000..c6337f7fb --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/ParagraphSearcher.cs @@ -0,0 +1,247 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Implements ParagraphSearcher. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System.Diagnostics; + using System.Windows.Documents; + using System.Windows.Media; + + /// + /// Moves through search highlights built in a ParagraphBuilder + /// changing the color of the current highlight + /// + internal class ParagraphSearcher + { + /// + /// Highlight for all matches except the current + /// + internal static readonly Brush HighlightBrush = Brushes.Yellow; + + /// + /// Highlight for the current match + /// + private static readonly Brush CurrentHighlightBrush = Brushes.Cyan; + + /// + /// Current match being highlighted in search + /// + private Run currentHighlightedMatch; + + /// + /// Initializes a new instance of the ParagraphSearcher class + /// + internal ParagraphSearcher() + { + } + + /// + /// Move to the next highlight starting at the + /// + /// true for next false for previous + /// caret position + /// the next highlight starting at the + internal Run MoveAndHighlightNextNextMatch(bool forward, TextPointer caretPosition) + { + Debug.Assert(caretPosition != null, "a caret position is allways valid"); + Debug.Assert(caretPosition.Parent != null && caretPosition.Parent is Run, "a caret PArent is allways a valid Run"); + Run caretRun = (Run)caretPosition.Parent; + + Run currentRun; + + if (this.currentHighlightedMatch != null) + { + // restore the curent highlighted background to plain highlighted + this.currentHighlightedMatch.Background = ParagraphSearcher.HighlightBrush; + } + + // If the caret is in the end of a highlight we move to the adjacent run + // It has to be in the end because if there is a match at the begining of the file + // and the caret has not been touched (so it is in the beginning of the file too) + // we want to highlight this first match. + // Considering the caller allways set the caret to the end of the highlight + // The condition below works well for successive searchs + // We also need to move to the adjacent run if the caret is at the first run and we + // are moving backwards so that a search backwards when the first run is highlighted + // and the caret is at the beginning will wrap to the end + if ((!forward && IsFirstRun(caretRun)) || + ((caretPosition.GetOffsetToPosition(caretRun.ContentEnd) == 0) && ParagraphSearcher.Ishighlighted(caretRun))) + { + currentRun = ParagraphSearcher.GetNextRun(caretRun, forward); + } + else + { + currentRun = caretRun; + } + + currentRun = ParagraphSearcher.GetNextMatch(currentRun, forward); + + if (currentRun == null) + { + // if we could not find a next highlight wrap arround + currentRun = ParagraphSearcher.GetFirstOrLastRun(caretRun, forward); + currentRun = ParagraphSearcher.GetNextMatch(currentRun, forward); + } + + this.currentHighlightedMatch = currentRun; + if (this.currentHighlightedMatch != null) + { + // restore the curent highligthed background to current highlighted + this.currentHighlightedMatch.Background = ParagraphSearcher.CurrentHighlightBrush; + } + + return currentRun; + } + + /// + /// Resets the search for fresh calls to MoveAndHighlightNextNextMatch + /// + internal void ResetSearch() + { + this.currentHighlightedMatch = null; + } + + /// + /// Returns true if is highlighted + /// + /// run to check if is highlighted + /// true if is highlighted + private static bool Ishighlighted(Run run) + { + if (run == null) + { + return false; + } + + SolidColorBrush background = run.Background as SolidColorBrush; + if (background != null && background == ParagraphSearcher.HighlightBrush) + { + return true; + } + + return false; + } + + /// + /// Get the next or previous run according to + /// + /// the current run + /// true for next false for previous + /// the next or previous run according to + private static Run GetNextRun(Run currentRun, bool forward) + { + Bold parentBold = currentRun.Parent as Bold; + + Inline nextInline; + + if (forward) + { + nextInline = parentBold != null ? ((Inline)parentBold).NextInline : currentRun.NextInline; + } + else + { + nextInline = parentBold != null ? ((Inline)parentBold).PreviousInline : currentRun.PreviousInline; + } + + return GetRun(nextInline); + } + + /// + /// Gets the run of an inline. Inlines in a ParagrahBuilder are either a Run or a Bold + /// which contains a Run + /// + /// inline to get the run from + /// the run of the inline + private static Run GetRun(Inline inline) + { + Bold inlineBold = inline as Bold; + if (inlineBold != null) + { + return (Run)inlineBold.Inlines.FirstInline; + } + + return (Run)inline; + } + + /// + /// Gets the next highlighted run starting and including + /// according to the direction specified in + /// + /// the current run + /// true for next false for previous + /// + /// the next highlighted run starting and including + /// according to the direction specified in + /// + private static Run GetNextMatch(Run currentRun, bool forward) + { + while (currentRun != null) + { + if (ParagraphSearcher.Ishighlighted(currentRun)) + { + return currentRun; + } + + currentRun = ParagraphSearcher.GetNextRun(currentRun, forward); + } + + return currentRun; + } + + /// + /// Gets the run's paragraph + /// + /// run to get the paragraph from + /// the run's paragraph + private static Paragraph GetParagraph(Run run) + { + Bold parentBold = run.Parent as Bold; + Paragraph parentParagraph = (parentBold != null ? parentBold.Parent : run.Parent) as Paragraph; + Debug.Assert(parentParagraph != null, "the documents we are saerching are built with ParagraphBuilder, which builds the document like this"); + return parentParagraph; + } + + /// + /// Returns true if the run is the fiorst run of the paragraph + /// + /// run to check + /// true if the run is the fiorst run of the paragraph + private static bool IsFirstRun(Run run) + { + Paragraph paragraph = GetParagraph(run); + Run firstRun = ParagraphSearcher.GetRun(paragraph.Inlines.FirstInline); + return run == firstRun; + } + + /// + /// Gets the first or lasr run in the paragraph containing + /// + /// run containing the caret + /// true for first false for last + /// the first or last run in the paragraph containing + private static Run GetFirstOrLastRun(Run caretRun, bool forward) + { + Debug.Assert(caretRun != null, "a caret run is allways valid"); + + Paragraph paragraph = GetParagraph(caretRun); + + Inline firstOrLastInline; + if (forward) + { + firstOrLastInline = paragraph.Inlines.FirstInline; + } + else + { + firstOrLastInline = paragraph.Inlines.LastInline; + } + + return GetRun(firstOrLastInline); + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/SettingsDialog.xaml.cs b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/SettingsDialog.xaml.cs new file mode 100644 index 000000000..538540bd5 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/HelpWindow/SettingsDialog.xaml.cs @@ -0,0 +1,64 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Implements SettingsDialog. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI +{ + using System.Windows; + using Microsoft.Management.UI.Internal; + + /// + /// Dialog with settings for the help dialog + /// + public partial class SettingsDialog : Window + { + /// + /// Initializes a new instance of the SettingsDialog class + /// + public SettingsDialog() + { + InitializeComponent(); + this.Description.IsChecked = HelpWindowSettings.Default.HelpDescriptionDisplayed; + this.Examples.IsChecked = HelpWindowSettings.Default.HelpExamplesDisplayed; + this.Inputs.IsChecked = HelpWindowSettings.Default.HelpInputsDisplayed; + this.Notes.IsChecked = HelpWindowSettings.Default.HelpNotesDisplayed; + this.Outputs.IsChecked = HelpWindowSettings.Default.HelpOutputsDisplayed; + this.Parameters.IsChecked = HelpWindowSettings.Default.HelpParametersDisplayed; + this.RelatedLinks.IsChecked = HelpWindowSettings.Default.HelpRelatedLinksDisplayed; + this.Remarks.IsChecked = HelpWindowSettings.Default.HelpRemarksDisplayed; + this.Synopsys.IsChecked = HelpWindowSettings.Default.HelpSynopsysDisplayed; + this.Syntax.IsChecked = HelpWindowSettings.Default.HelpSyntaxDisplayed; + this.CaseSensitive.IsChecked = HelpWindowSettings.Default.HelpSearchMatchCase; + this.WholeWord.IsChecked = HelpWindowSettings.Default.HelpSearchWholeWord; + } + + /// + /// Called when the OK button has been clicked + /// + /// event sender + /// event arguments + private void OK_Click(object sender, RoutedEventArgs e) + { + HelpWindowSettings.Default.HelpDescriptionDisplayed = this.Description.IsChecked == true; + HelpWindowSettings.Default.HelpExamplesDisplayed = this.Examples.IsChecked == true; + HelpWindowSettings.Default.HelpInputsDisplayed = this.Inputs.IsChecked == true; + HelpWindowSettings.Default.HelpOutputsDisplayed = this.Outputs.IsChecked == true; + HelpWindowSettings.Default.HelpNotesDisplayed = this.Notes.IsChecked == true; + HelpWindowSettings.Default.HelpParametersDisplayed = this.Parameters.IsChecked == true; + HelpWindowSettings.Default.HelpRelatedLinksDisplayed = this.RelatedLinks.IsChecked == true; + HelpWindowSettings.Default.HelpRemarksDisplayed = this.Remarks.IsChecked == true; + HelpWindowSettings.Default.HelpSynopsysDisplayed = this.Synopsys.IsChecked == true; + HelpWindowSettings.Default.HelpSyntaxDisplayed = this.Syntax.IsChecked == true; + HelpWindowSettings.Default.HelpSearchMatchCase = this.CaseSensitive.IsChecked == true; + HelpWindowSettings.Default.HelpSearchWholeWord = this.WholeWord.IsChecked == true; + HelpWindowSettings.Default.Save(); + this.DialogResult = true; + this.Close(); + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/AutomationTextBlock.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/AutomationTextBlock.cs new file mode 100644 index 000000000..ccbdff12d --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/AutomationTextBlock.cs @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + #region Using Directives + + using System.ComponentModel; + using System.Diagnostics.CodeAnalysis; + using System.Windows.Automation.Peers; + using System.Windows.Controls; + + #endregion + + /// + /// Provides a control that is always visible in the automation tree. + /// + [SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + [Description("Provides a System.Windows.Controls.TextBlock control that is always visible in the automation tree.")] + public class AutomationTextBlock : TextBlock + { + #region Structors + + /// + /// Initializes a new instance of the class. + /// + public AutomationTextBlock() + { + // This constructor intentionally left blank + } + + #endregion + + #region Overides + + /// + /// Returns the implementations for this control. + /// + /// The implementations for this control. + protected override AutomationPeer OnCreateAutomationPeer() + { + return new AutomationTextBlockAutomationPeer(this); + } + + #endregion + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/AutomationTextBlockAutomationPeer.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/AutomationTextBlockAutomationPeer.cs new file mode 100644 index 000000000..ac171da6e --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/AutomationTextBlockAutomationPeer.cs @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Provides an automation peer for AutomationTextBlock. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + #region Using Directives + + using System.Diagnostics.CodeAnalysis; + using System.Windows.Automation.Peers; + using System.Windows.Controls; + + #endregion + + /// + /// Provides an automation peer for AutomationTextBlock. + /// + [SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + internal class AutomationTextBlockAutomationPeer : TextBlockAutomationPeer + { + #region Structors + + /// + /// Initializes a new instance of the class. + /// + /// The owner of the automation peer. + public AutomationTextBlockAutomationPeer(TextBlock owner) + : base(owner) + { + // This constructor intentionally left blank + } + + #endregion + + #region Overrides + + /// + /// Gets a value that indicates whether the element is understood by the user as interactive or as contributing to the logical structure of the control in the GUI. Called by IsControlElement(). + /// + /// This method always returns true. + protected override bool IsControlElementCore() + { + return true; + } + + /// + /// Gets the class name. + /// + /// The class name. + protected override string GetClassNameCore() + { + return this.Owner.GetType().Name; + } + + #endregion + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/BooleanBoxes.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/BooleanBoxes.cs new file mode 100644 index 000000000..28dbe8e7d --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/BooleanBoxes.cs @@ -0,0 +1,47 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// ----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + + /// + /// A class which returns the same boxed bool values. + /// + internal static class BooleanBoxes + { + private static object trueBox = true; + private static object falseBox = false; + + internal static object TrueBox + { + get + { + return trueBox; + } + } + + internal static object FalseBox + { + get + { + return falseBox; + } + } + + internal static object Box(bool value) + { + if (value) + { + return TrueBox; + } + else + { + return FalseBox; + } + } + } + +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/CommandHelper.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/CommandHelper.cs new file mode 100644 index 000000000..04737d141 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/CommandHelper.cs @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Helper routines for executing commands. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Collections.Generic; + using System.Text; + using System.Windows; + using System.Windows.Input; + using System.Security; + + internal static class CommandHelper + { + internal static void ExecuteCommand(ICommand command, object parameter, IInputElement target) + { + RoutedCommand command2 = command as RoutedCommand; + if (command2 != null) + { + if (command2.CanExecute(parameter, target)) + { + command2.Execute(parameter, target); + } + } + else if (command.CanExecute(parameter)) + { + command.Execute(parameter); + } + } + + internal static bool CanExecuteCommand(ICommand command, object parameter, IInputElement target) + { + if (command == null) + { + return false; + } + + RoutedCommand command2 = command as RoutedCommand; + + if (command2 != null) + { + return command2.CanExecute(parameter, target); + } + else + { + return command.CanExecute(parameter); + } + } + } +} + diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/CustomTypeComparer.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/CustomTypeComparer.cs new file mode 100644 index 000000000..3efb3af14 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/CustomTypeComparer.cs @@ -0,0 +1,77 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + + /// + /// The CustomTypeComparer is responsible for holding custom comparers + /// for different types, which are in turn used to perform comparison + /// operations instead of the default IComparable comparison. + /// with a custom comparer + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + public static class CustomTypeComparer + { + private static Dictionary comparers = new Dictionary(); + + /// + /// The static constructor. + /// + static CustomTypeComparer() + { + comparers.Add(typeof(DateTime), new DateTimeApproximationComparer()); + } + + /// + /// Compares two objects and returns a value indicating + /// whether one is less than, equal to, or greater than the other. + /// + /// + /// The first object to compare. + /// + /// + /// The second object to compare. + /// + /// + /// A type implementing IComparable. + /// + /// + /// If value1 is less than value2, then a value less than zero is returned. + /// If value1 equals value2, than zero is returned. + /// If value1 is greater than value2, then a value greater than zero is returned. + /// + public static int Compare(T value1, T value2) where T : IComparable + { + IComparer comparer; + if (false == TryGetCustomComparer(out comparer)) + { + return value1.CompareTo(value2); + } + + return comparer.Compare(value1, value2); + } + + private static bool TryGetCustomComparer(out IComparer comparer) where T : IComparable + { + comparer = null; + + object uncastComparer = null; + if (false == comparers.TryGetValue(typeof(T), out uncastComparer)) + { + return false; + } + + Debug.Assert(uncastComparer is IComparer); + comparer = (IComparer)uncastComparer; + + return true; + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DataRoutedEventArgs.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DataRoutedEventArgs.cs new file mode 100644 index 000000000..3594dba22 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DataRoutedEventArgs.cs @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Collections.Generic; + using System.Text; + using System.Windows; + using System.Diagnostics.CodeAnalysis; + + /// + /// Routed event args which provide the ability to attach an + /// arbitrary peice of data. + /// + /// There are no restrictions on type T. + [SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + public class DataRoutedEventArgs : RoutedEventArgs + { + private T data; + + /// + /// Constructs a new instance of the DataRoutedEventArgs class. + /// + /// The data payload to be stored. + /// The routed event. + public DataRoutedEventArgs(T data, RoutedEvent routedEvent) + { + this.data = data; + this.RoutedEvent = routedEvent; + } + + /// + /// Gets a value containing the data being stored. + /// + public T Data + { + get { return this.data; } + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DateTimeApproximationComparer.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DateTimeApproximationComparer.cs new file mode 100644 index 000000000..e49ab1dcb --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DateTimeApproximationComparer.cs @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Collections.Generic; + + /// + /// The DateTimeApproximationComparer is responsible for comparing two + /// DateTime objects at a level of precision determined by + /// the first object. The comparison either compares at the + /// date level or the date and time (down to Seconds precision). + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + public class DateTimeApproximationComparer : IComparer + { + /// + /// Compares two objects and returns a value indicating + /// whether one is less than, equal to, or greater than the other. + /// + /// + /// The first object to compare. + /// + /// + /// The second object to compare. + /// + /// + /// If value1 is less than value2, then a value less than zero is returned. + /// If value1 equals value2, than zero is returned. + /// If value1 is greater than value2, then a value greater than zero is returned. + /// + public int Compare(DateTime value1, DateTime value2) + { + DateTime roundedX; + DateTime roundedY; + GetRoundedValues(value1, value2, out roundedX, out roundedY); + + return roundedX.CompareTo(roundedY); + } + + private static void GetRoundedValues(DateTime value1, DateTime value2, out DateTime roundedValue1, out DateTime roundedValue2) + { + roundedValue1 = value1; + roundedValue2 = value2; + + bool hasTimeComponent = HasTimeComponent(value1); + + int hour = hasTimeComponent ? value1.Hour : value2.Hour; + int minute = hasTimeComponent ? value1.Minute : value2.Minute; + int second = hasTimeComponent ? value1.Second : value2.Second; + + roundedValue1 = new DateTime(value1.Year, value1.Month, value1.Day, hour, minute, second); + roundedValue2 = new DateTime(value2.Year, value2.Month, value2.Day, value2.Hour, value2.Minute, value2.Second); + } + + private static bool HasTimeComponent(DateTime value) + { + bool hasNoTimeComponent = true + && 0 == value.Hour + && 0 == value.Minute + && 0 == value.Second + && 0 == value.Millisecond; + + return (!hasNoTimeComponent); + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DismissiblePopup.Generated.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DismissiblePopup.Generated.cs new file mode 100644 index 000000000..d680283f4 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DismissiblePopup.Generated.cs @@ -0,0 +1,283 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// +// This code was generated by a tool. DO NOT EDIT +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ----------------------------------------------------------------------- + +#region StyleCop Suppression - generated code +using System; +using System.ComponentModel; +using System.Windows; +using System.Windows.Input; + +namespace Microsoft.Management.UI.Internal +{ + + /// + /// A popup which child controls can signal to be dimissed. + /// + /// + /// If a control wants to dismiss the popup then they should execute the DismissPopupCommand on a target in the popup window. + /// + [Localizability(LocalizationCategory.None)] + partial class DismissiblePopup + { + // + // DismissPopup routed command + // + /// + /// A command which child controls can use to tell the popup to close. + /// + public static readonly RoutedCommand DismissPopupCommand = new RoutedCommand("DismissPopup",typeof(DismissiblePopup)); + + static private void DismissPopupCommand_CommandExecuted(object sender, ExecutedRoutedEventArgs e) + { + DismissiblePopup obj = (DismissiblePopup) sender; + obj.OnDismissPopupExecuted( e ); + } + + /// + /// Called when DismissPopup executes. + /// + /// + /// A command which child controls can use to tell the popup to close. + /// + protected virtual void OnDismissPopupExecuted(ExecutedRoutedEventArgs e) + { + OnDismissPopupExecutedImplementation(e); + } + + partial void OnDismissPopupExecutedImplementation(ExecutedRoutedEventArgs e); + + // + // CloseOnEscape dependency property + // + /// + /// Identifies the CloseOnEscape dependency property. + /// + public static readonly DependencyProperty CloseOnEscapeProperty = DependencyProperty.Register( "CloseOnEscape", typeof(bool), typeof(DismissiblePopup), new PropertyMetadata( BooleanBoxes.TrueBox, CloseOnEscapeProperty_PropertyChanged) ); + + /// + /// Gets or sets a value indicating whether the popup closes when ESC is pressed. + /// + [Bindable(true)] + [Category("Common Properties")] + [Description("Gets or sets a value indicating whether the popup closes when ESC is pressed.")] + [Localizability(LocalizationCategory.None)] + public bool CloseOnEscape + { + get + { + return (bool) GetValue(CloseOnEscapeProperty); + } + set + { + SetValue(CloseOnEscapeProperty,BooleanBoxes.Box(value)); + } + } + + static private void CloseOnEscapeProperty_PropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + DismissiblePopup obj = (DismissiblePopup) o; + obj.OnCloseOnEscapeChanged( new PropertyChangedEventArgs((bool)e.OldValue, (bool)e.NewValue) ); + } + + /// + /// Occurs when CloseOnEscape property changes. + /// + public event EventHandler> CloseOnEscapeChanged; + + /// + /// Called when CloseOnEscape property changes. + /// + protected virtual void OnCloseOnEscapeChanged(PropertyChangedEventArgs e) + { + OnCloseOnEscapeChangedImplementation(e); + RaisePropertyChangedEvent(CloseOnEscapeChanged, e); + } + + partial void OnCloseOnEscapeChangedImplementation(PropertyChangedEventArgs e); + + // + // FocusChildOnOpen dependency property + // + /// + /// Identifies the FocusChildOnOpen dependency property. + /// + public static readonly DependencyProperty FocusChildOnOpenProperty = DependencyProperty.Register( "FocusChildOnOpen", typeof(bool), typeof(DismissiblePopup), new PropertyMetadata( BooleanBoxes.TrueBox, FocusChildOnOpenProperty_PropertyChanged) ); + + /// + /// Gets or sets a value indicating whether focus should be set on the child when the popup opens. + /// + [Bindable(true)] + [Category("Common Properties")] + [Description("Gets or sets a value indicating whether focus should be set on the child when the popup opens.")] + [Localizability(LocalizationCategory.None)] + public bool FocusChildOnOpen + { + get + { + return (bool) GetValue(FocusChildOnOpenProperty); + } + set + { + SetValue(FocusChildOnOpenProperty,BooleanBoxes.Box(value)); + } + } + + static private void FocusChildOnOpenProperty_PropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + DismissiblePopup obj = (DismissiblePopup) o; + obj.OnFocusChildOnOpenChanged( new PropertyChangedEventArgs((bool)e.OldValue, (bool)e.NewValue) ); + } + + /// + /// Occurs when FocusChildOnOpen property changes. + /// + public event EventHandler> FocusChildOnOpenChanged; + + /// + /// Called when FocusChildOnOpen property changes. + /// + protected virtual void OnFocusChildOnOpenChanged(PropertyChangedEventArgs e) + { + OnFocusChildOnOpenChangedImplementation(e); + RaisePropertyChangedEvent(FocusChildOnOpenChanged, e); + } + + partial void OnFocusChildOnOpenChangedImplementation(PropertyChangedEventArgs e); + + // + // SetFocusOnClose dependency property + // + /// + /// Identifies the SetFocusOnClose dependency property. + /// + public static readonly DependencyProperty SetFocusOnCloseProperty = DependencyProperty.Register( "SetFocusOnClose", typeof(bool), typeof(DismissiblePopup), new PropertyMetadata( BooleanBoxes.FalseBox, SetFocusOnCloseProperty_PropertyChanged) ); + + /// + /// Indicates whether the focus returns to either a defined by the FocusOnCloseTarget dependency property UIElement or PlacementTarget or not. + /// + [Bindable(true)] + [Category("Common Properties")] + [Description("Indicates whether the focus returns to either a defined by the FocusOnCloseTarget dependency property UIElement or PlacementTarget or not.")] + [Localizability(LocalizationCategory.None)] + public bool SetFocusOnClose + { + get + { + return (bool) GetValue(SetFocusOnCloseProperty); + } + set + { + SetValue(SetFocusOnCloseProperty,BooleanBoxes.Box(value)); + } + } + + static private void SetFocusOnCloseProperty_PropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + DismissiblePopup obj = (DismissiblePopup) o; + obj.OnSetFocusOnCloseChanged( new PropertyChangedEventArgs((bool)e.OldValue, (bool)e.NewValue) ); + } + + /// + /// Occurs when SetFocusOnClose property changes. + /// + public event EventHandler> SetFocusOnCloseChanged; + + /// + /// Called when SetFocusOnClose property changes. + /// + protected virtual void OnSetFocusOnCloseChanged(PropertyChangedEventArgs e) + { + OnSetFocusOnCloseChangedImplementation(e); + RaisePropertyChangedEvent(SetFocusOnCloseChanged, e); + } + + partial void OnSetFocusOnCloseChangedImplementation(PropertyChangedEventArgs e); + + // + // SetFocusOnCloseElement dependency property + // + /// + /// Identifies the SetFocusOnCloseElement dependency property. + /// + public static readonly DependencyProperty SetFocusOnCloseElementProperty = DependencyProperty.Register( "SetFocusOnCloseElement", typeof(UIElement), typeof(DismissiblePopup), new PropertyMetadata( null, SetFocusOnCloseElementProperty_PropertyChanged) ); + + /// + /// If the SetFocusOnClose property is set True and this property is set to a valid UIElement, focus returns to this UIElement after the DismissiblePopup is closed. + /// + [Bindable(true)] + [Category("Common Properties")] + [Description("If the SetFocusOnClose property is set True and this property is set to a valid UIElement, focus returns to this UIElement after the DismissiblePopup is closed.")] + [Localizability(LocalizationCategory.None)] + public UIElement SetFocusOnCloseElement + { + get + { + return (UIElement) GetValue(SetFocusOnCloseElementProperty); + } + set + { + SetValue(SetFocusOnCloseElementProperty,value); + } + } + + static private void SetFocusOnCloseElementProperty_PropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + DismissiblePopup obj = (DismissiblePopup) o; + obj.OnSetFocusOnCloseElementChanged( new PropertyChangedEventArgs((UIElement)e.OldValue, (UIElement)e.NewValue) ); + } + + /// + /// Occurs when SetFocusOnCloseElement property changes. + /// + public event EventHandler> SetFocusOnCloseElementChanged; + + /// + /// Called when SetFocusOnCloseElement property changes. + /// + protected virtual void OnSetFocusOnCloseElementChanged(PropertyChangedEventArgs e) + { + OnSetFocusOnCloseElementChangedImplementation(e); + RaisePropertyChangedEvent(SetFocusOnCloseElementChanged, e); + } + + partial void OnSetFocusOnCloseElementChangedImplementation(PropertyChangedEventArgs e); + + /// + /// Called when a property changes. + /// + private void RaisePropertyChangedEvent(EventHandler> eh, PropertyChangedEventArgs e) + { + if(eh != null) + { + eh(this,e); + } + } + + // + // Static constructor + // + + /// + /// Called when the type is initialized. + /// + static DismissiblePopup() + { + CommandManager.RegisterClassCommandBinding( typeof(DismissiblePopup), new CommandBinding( DismissiblePopup.DismissPopupCommand, DismissPopupCommand_CommandExecuted )); + StaticConstructorImplementation(); + } + + static partial void StaticConstructorImplementation(); + + } +} +#endregion diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DismissiblePopup.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DismissiblePopup.cs new file mode 100644 index 000000000..f67079529 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/DismissiblePopup.cs @@ -0,0 +1,154 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// ----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Diagnostics; + using System.Windows; + using System.Windows.Automation; + using System.Windows.Controls.Primitives; + using System.Windows.Input; + using System.Windows.Media; + using System.Windows.Data; + + /// + /// Partial class implementation for DismissiblePopup control. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + public partial class DismissiblePopup : Popup + { + /// + /// Constructs an instance of DismissablePopup. + /// + public DismissiblePopup() : base() + { + // nothing + } + + private delegate void FocusChildDelegate(); + + /// + /// Responds to the condition in which the value of the IsOpen property changes from false to true. + /// + /// The event arguments. + protected override void OnOpened(EventArgs e) + { + base.OnOpened(e); + + if (this.FocusChildOnOpen) + { + this.Dispatcher.BeginInvoke( + System.Windows.Threading.DispatcherPriority.Loaded, + new FocusChildDelegate(this.FocusChild)); + } + + this.SetupAutomationIdBinding(); + } + + + /// + /// Responds when the value of the IsOpen property changes from to true to false. + /// + /// The event arguments. + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + + if (this.SetFocusOnClose) + { + // Find a control to set focus on. + if (this.SetFocusOnCloseElement != null) + { + // The focus target is set explicitly. + this.SetFocus(this.SetFocusOnCloseElement); + } + else if (this.PlacementTarget != null) + { + // Use PlacementTarget as a first chance option. + this.SetFocus(this.PlacementTarget); + } + else + { + // Use parent UIObject when neither FocusOnCloseTarget nor PlacementTarget is set. + UIElement parent = this.Parent as UIElement; + if (parent != null) + { + this.SetFocus(parent); + } + } + } + } + + private void SetFocus(UIElement element) + { + if (element.Focusable) + { + element.Focus(); + } + else + { + element.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); + } + } + + private void SetupAutomationIdBinding() + { + var popupRoot = this.FindPopupRoot(); + + var binding = new Binding(); + binding.Source = this; + binding.Path = new PropertyPath(AutomationProperties.AutomationIdProperty); + popupRoot.SetBinding(AutomationProperties.AutomationIdProperty, binding); + } + + private FrameworkElement FindPopupRoot() + { + DependencyObject element = this.Child; + + while (false == element.GetType().Name.Equals("PopupRoot", StringComparison.Ordinal)) + { + element = VisualTreeHelper.GetParent( element ); + } + + Debug.Assert(element != null ); + + return (FrameworkElement) element; + } + + /// + /// Provides class handling for the KeyDown routed event that occurs when the user presses a key while this control has focus. + /// + /// The event data. + protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e) + { + //// + // Close the popup if ESC is pressed + //// + if (e.Key == System.Windows.Input.Key.Escape && this.CloseOnEscape) + { + this.IsOpen = false; + } + else + { + base.OnKeyDown(e); + } + } + + partial void OnDismissPopupExecutedImplementation(ExecutedRoutedEventArgs e) + { + this.IsOpen = false; + } + + private void FocusChild() + { + if (this.Child != null) + { + this.Child.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); + } + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ExtendedFrameworkElementAutomationPeer.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ExtendedFrameworkElementAutomationPeer.cs new file mode 100644 index 000000000..10ac0f006 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ExtendedFrameworkElementAutomationPeer.cs @@ -0,0 +1,109 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Provides a base automation peer for FrameworkElement controls. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + #region Using Directives + + using System.Diagnostics.CodeAnalysis; + using System.Windows; + using System.Windows.Automation.Peers; + using System.Windows.Controls; + + #endregion + + /// + /// Provides a base automation peer for FrameworkElement controls. + /// + [SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + public class ExtendedFrameworkElementAutomationPeer : FrameworkElementAutomationPeer + { + #region Fields + + /// + /// Gets or sets the control type of the element that is associated with this automation peer. + /// + private AutomationControlType controlType = AutomationControlType.Custom; + + /// + /// Gets or sets a value that indicates whether the control should show in the logical tree. + /// + private bool isControlElement = true; + + #endregion + + #region Structors + + /// + /// Initializes a new instance of the class. + /// + /// The owner of the automation peer. + public ExtendedFrameworkElementAutomationPeer(FrameworkElement owner) + : base(owner) + { + // This constructor intentionally left blank + } + + /// + /// Initializes a new instance of the class. + /// + /// The owner of the automation peer. + /// The control type of the element that is associated with the automation peer. + public ExtendedFrameworkElementAutomationPeer(FrameworkElement owner, AutomationControlType controlType) + : this(owner) + { + this.controlType = controlType; + } + + /// + /// Initializes a new instance of the class. + /// + /// The owner of the automation peer. + /// The control type of the element that is associated with the automation peer. + /// Whether the element should show in the logical tree. + public ExtendedFrameworkElementAutomationPeer(FrameworkElement owner, AutomationControlType controlType, bool isControlElement) + : this(owner, controlType) + { + this.isControlElement = isControlElement; + } + + #endregion + + #region Overrides + + /// + /// Gets the class name. + /// + /// The class name. + protected override string GetClassNameCore() + { + return this.Owner.GetType().Name; + } + + /// + /// Gets the control type of the element that is associated with the automation peer. + /// + /// Returns the control type of the element that is associated with the automation peer. + protected override AutomationControlType GetAutomationControlTypeCore() + { + return this.controlType; + } + + /// + /// Gets a value that indicates whether the element is understood by the user as interactive or as contributing to the logical structure of the control in the GUI. Called by IsControlElement(). + /// + /// This method always returns true. + protected override bool IsControlElementCore() + { + return this.isControlElement; + } + + #endregion + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IAsyncProgress.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IAsyncProgress.cs new file mode 100644 index 000000000..a776dd43c --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IAsyncProgress.cs @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + #region Using Directives + + using System; + using System.Diagnostics.CodeAnalysis; + using System.Collections.Generic; + using System.Text; + using System.Windows; + + #endregion + + /// + /// An interface designed to provide updates about an asynchronous operation. + /// If the UI is data bound to the properties in this interface then INotifyPropertyChanged should + /// be implemented by the type implementing IAsyncProgress so the UI can get notification of the properties + /// being changed. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + public interface IAsyncProgress + { + /// + /// Gets a value indicating whether the async operation is currently running. + /// + bool OperationInProgress + { + get; + } + + /// + /// Gets a the error for the async operation. This field is only valid if + /// OperationInProgress is false. null indicates there was no error. + /// + Exception OperationError + { + get; + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IStateDescriptorFactory.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IStateDescriptorFactory.cs new file mode 100644 index 000000000..24ed5f442 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IStateDescriptorFactory.cs @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Diagnostics.CodeAnalysis; + + /// + /// Defines an interface for a factory that creates + /// StateDescriptors. + /// + /// The type T used by the StateDescriptor. + [SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + public interface IStateDescriptorFactory + { + /// + /// Creates a new StateDescriptor based upon custom + /// logic. + /// + /// A new StateDescriptor. + StateDescriptor Create(); + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IntegralConverter.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IntegralConverter.cs new file mode 100644 index 000000000..7c01b5a0f --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IntegralConverter.cs @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Collections.Generic; + using System.Text; + using System.Windows.Data; + using System.Diagnostics.CodeAnalysis; + using System.Windows; + using System.Globalization; + + /// + /// Takes a value and returns the largest value which is a integral amount of the second value. + /// + [SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + public class IntegralConverter : IMultiValueConverter + { + /// + /// Takes a value and returns the largest value which is a integral amount of the second value. + /// + /// + /// The first value is the source. The second is the factor. + /// + /// The parameter is not used. + /// The padding to subtract from the first value. + /// The parameter is not used. + /// + /// The integral value. + /// + public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (values == null) + { + throw new ArgumentNullException("values"); + } + + if (2 != values.Length) + { + throw new ArgumentException("Two values expected", "values"); + } + + if (values[0] == DependencyProperty.UnsetValue || + values[1] == DependencyProperty.UnsetValue) + { + return DependencyProperty.UnsetValue; + } + + var source = (double) values[0]; + var factor = (double)values[1]; + + double padding = 0; + + if (parameter != null) + { + padding = Double.Parse((string)parameter, CultureInfo.InvariantCulture); + } + + var newSource = source - padding; + + if (newSource < factor) + { + return source; + } + + var remainder = newSource % factor; + var result = newSource - remainder; + + return result; + + } + + /// + /// This method is not used. + /// + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/InverseBooleanConverter.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/InverseBooleanConverter.cs new file mode 100644 index 000000000..33cfb8b3c --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/InverseBooleanConverter.cs @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Windows.Data; + + /// + /// Takes a bool value and returns the inverse. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + public class InverseBooleanConverter : IValueConverter + { + /// + /// Converts a boolean value to be it's inverse. + /// + /// The source value. + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + /// The inverted boolean value. + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + var boolValue = (bool)value; + + return !boolValue; + } + + /// + /// This method is not used. + /// + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IsEqualConverter.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IsEqualConverter.cs new file mode 100644 index 000000000..6fb0d52e1 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IsEqualConverter.cs @@ -0,0 +1,80 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Used to determine whether two objects are equal. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Collections.Generic; + using System.Text; + using System.Windows.Data; + using System.Diagnostics.CodeAnalysis; + using System.Windows; + + /// + /// Takes two objects and determines whether they are equal. + /// + [SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + public class IsEqualConverter : IMultiValueConverter + { + /// + /// Takes two items and determines whether they are equal. + /// + /// + /// Two objects of any type. + /// + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + /// + /// True if-and-only-if the two objects are equal per Object.Equals(). + /// Null is equal only to null. + /// + public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (values == null) + { + throw new ArgumentNullException("values"); + } + + if (2 != values.Length) + { + throw new ArgumentException("Two values expected", "values"); + } + + object item1 = values[0]; + object item2 = values[1]; + + if (null == item1) + { + return (null == item2); + } + + if (null == item2) + { + return false; + } + + bool equal = item1.Equals(item2); + return equal; + } + + /// + /// This method is not used. + /// + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IsNotNullConverter.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IsNotNullConverter.cs new file mode 100644 index 000000000..ba8825426 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/IsNotNullConverter.cs @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//----------------------------------------------------------------------- +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Windows.Data; + + /// + /// The IsNotNullConverter is responsible for converting a value into + /// a boolean indicting whether the value is not null. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")] + public class IsNotNullConverter : IValueConverter + { + #region IValueConverter Members + + /// + /// Determines if value is not null. + /// + /// The object to check. + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + /// Returns true if value is not null, false otherwise. + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + return (null != value); + } + + /// + /// This method is not used. + /// + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + /// The parameter is not used. + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + throw new NotSupportedException(); + } + + #endregion + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/KeyboardHelp.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/KeyboardHelp.cs new file mode 100644 index 000000000..dded7361d --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/KeyboardHelp.cs @@ -0,0 +1,152 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace Microsoft.Management.UI.Internal +{ + using System; + using System.Collections.Generic; + using System.Text; + using System.Windows.Input; + using System.Diagnostics; + using System.Windows; + + internal enum LogicalDirection + { + None, + Left, + Right + } + + internal static class KeyboardHelp + { + /// + /// Gets the logical direction for a key, taking into account RTL settings. + /// + /// The element to get FlowDirection from. + /// The key pressed. + /// The logical direction. + public static LogicalDirection GetLogicalDirection(DependencyObject element, Key key) + { + Debug.Assert(element != null); + + bool rightToLeft = IsElementRightToLeft(element); + + switch (key) + { + case Key.Right: + if (rightToLeft) + { + return LogicalDirection.Left; + } + else + { + return LogicalDirection.Right; + } + + case Key.Left: + if (rightToLeft) + { + return LogicalDirection.Right; + } + else + { + return LogicalDirection.Left; + } + + default: + return LogicalDirection.None; + } + } + + /// + /// Gets the focus direction for a key, taking into account RTL settings. + /// + /// The element to get FlowDirection from. + /// The key pressed. + /// The focus direction. + public static FocusNavigationDirection GetNavigationDirection(DependencyObject element, Key key) + { + Debug.Assert(element != null); + Debug.Assert(IsFlowDirectionKey(key)); + + bool rightToLeft = IsElementRightToLeft(element); + + switch (key) + { + case Key.Right: + if (rightToLeft) + { + return FocusNavigationDirection.Left; + } + else + { + return FocusNavigationDirection.Right; + } + + case Key.Left: + if (rightToLeft) + { + return FocusNavigationDirection.Right; + } + else + { + return FocusNavigationDirection.Left; + } + + case Key.Down: + return FocusNavigationDirection.Down; + case Key.Up: + return FocusNavigationDirection.Up; + default: + Debug.Fail("Non-direction key specified"); + return FocusNavigationDirection.First; + } + } + + /// + /// Determines if the control key is pressed. + /// + /// True if a control is is pressed. + public static bool IsControlPressed() + { + if (ModifierKeys.Control == (Keyboard.Modifiers & ModifierKeys.Control)) + { + return true; + } + else + { + return false; + } + } + + /// + /// Determines if the key is a navigation key. + /// + /// The key pressed. + /// True if the key is a navigation key. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + private static bool IsFlowDirectionKey(Key key) + { + switch (key) + { + case Key.Right: + case Key.Left: + case Key.Down: + case Key.Up: + return true; + default: + return false; + } + } + + private static bool IsElementRightToLeft(DependencyObject element) + { + FlowDirection flowDirection = FrameworkElement.GetFlowDirection(element); + bool rightToLeft = (flowDirection == FlowDirection.RightToLeft); + return rightToLeft; + } + } +} diff --git a/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ListOrganizer.Generated.cs b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ListOrganizer.Generated.cs new file mode 100644 index 000000000..7dc0cbc24 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/ManagementList/Common/ListOrganizer.Generated.cs @@ -0,0 +1,490 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// +// This code was generated by a tool. DO NOT EDIT +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ----------------------------------------------------------------------- + +#region StyleCop Suppression - generated code +using System; +using System.Collections; +using System.ComponentModel; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Input; + +namespace Microsoft.Management.UI.Internal +{ + + /// + /// This control presents a dropdown listbox with associated organizing actions that can be performed on it. + /// + /// + /// + /// + /// If a custom template is provided for this control, then the template MUST provide the following template parts: + /// + /// PART_Picker - A required template part which must be of type PickerBase. This control provides basic functionality for Picker-like controls. + /// + /// + [TemplatePart(Name="PART_Picker", Type=typeof(PickerBase))] + [Localizability(LocalizationCategory.None)] + partial class ListOrganizer + { + // + // Fields + // + private PickerBase picker; + + // + // ItemDeleted RoutedEvent + // + /// + /// Identifies the ItemDeleted RoutedEvent. + /// + public static readonly RoutedEvent ItemDeletedEvent = EventManager.RegisterRoutedEvent("ItemDeleted",RoutingStrategy.Bubble,typeof(EventHandler>),typeof(ListOrganizer)); + + /// + /// Occurs when an item is deleted from the list. + /// + public event EventHandler> ItemDeleted + { + add + { + AddHandler(ItemDeletedEvent,value); + } + remove + { + RemoveHandler(ItemDeletedEvent,value); + } + } + + // + // ItemSelected RoutedEvent + // + /// + /// Identifies the ItemSelected RoutedEvent. + /// + public static readonly RoutedEvent ItemSelectedEvent = EventManager.RegisterRoutedEvent("ItemSelected",RoutingStrategy.Bubble,typeof(EventHandler>),typeof(ListOrganizer)); + + /// + /// Occurs when an item is selected in the list. + /// + public event EventHandler> ItemSelected + { + add + { + AddHandler(ItemSelectedEvent,value); + } + remove + { + RemoveHandler(ItemSelectedEvent,value); + } + } + + // + // DeleteItem routed command + // + /// + /// Informs the ListOrganizer that it should delete the item passed. + /// + public static readonly RoutedCommand DeleteItemCommand = new RoutedCommand("DeleteItem",typeof(ListOrganizer)); + + static private void DeleteItemCommand_CommandExecuted(object sender, ExecutedRoutedEventArgs e) + { + ListOrganizer obj = (ListOrganizer) sender; + obj.OnDeleteItemExecuted( e ); + } + + /// + /// Called when DeleteItem executes. + /// + /// + /// Informs the ListOrganizer that it should delete the item passed. + /// + protected virtual void OnDeleteItemExecuted(ExecutedRoutedEventArgs e) + { + OnDeleteItemExecutedImplementation(e); + } + + partial void OnDeleteItemExecutedImplementation(ExecutedRoutedEventArgs e); + + // + // SelectItem routed command + // + /// + /// Informs the ListOrganizer that it should select the item passed. + /// + public static readonly RoutedCommand SelectItemCommand = new RoutedCommand("SelectItem",typeof(ListOrganizer)); + + static private void SelectItemCommand_CommandExecuted(object sender, ExecutedRoutedEventArgs e) + { + ListOrganizer obj = (ListOrganizer) sender; + obj.OnSelectItemExecuted( e ); + } + + /// + /// Called when SelectItem executes. + /// + /// + /// Informs the ListOrganizer that it should select the item passed. + /// + protected virtual void OnSelectItemExecuted(ExecutedRoutedEventArgs e) + { + OnSelectItemExecutedImplementation(e); + } + + partial void OnSelectItemExecutedImplementation(ExecutedRoutedEventArgs e); + + // + // DropDownButtonTemplate dependency property + // + /// + /// Identifies the DropDownButtonTemplate dependency property. + /// + public static readonly DependencyProperty DropDownButtonTemplateProperty = DependencyProperty.Register( "DropDownButtonTemplate", typeof(ControlTemplate), typeof(ListOrganizer), new PropertyMetadata( null, DropDownButtonTemplateProperty_PropertyChanged) ); + + /// + /// Gets or sets a value that controls the visual tree of the DropDown button. + /// + [Bindable(true)] + [Category("Common Properties")] + [Description("Gets or sets a value that controls the visual tree of the DropDown button.")] + [Localizability(LocalizationCategory.None)] + public ControlTemplate DropDownButtonTemplate + { + get + { + return (ControlTemplate) GetValue(DropDownButtonTemplateProperty); + } + set + { + SetValue(DropDownButtonTemplateProperty,value); + } + } + + static private void DropDownButtonTemplateProperty_PropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + ListOrganizer obj = (ListOrganizer) o; + obj.OnDropDownButtonTemplateChanged( new PropertyChangedEventArgs((ControlTemplate)e.OldValue, (ControlTemplate)e.NewValue) ); + } + + /// + /// Occurs when DropDownButtonTemplate property changes. + /// + public event EventHandler> DropDownButtonTemplateChanged; + + /// + /// Called when DropDownButtonTemplate property changes. + /// + protected virtual void OnDropDownButtonTemplateChanged(PropertyChangedEventArgs e) + { + OnDropDownButtonTemplateChangedImplementation(e); + RaisePropertyChangedEvent(DropDownButtonTemplateChanged, e); + } + + partial void OnDropDownButtonTemplateChangedImplementation(PropertyChangedEventArgs e); + + // + // DropDownStyle dependency property + // + /// + /// Identifies the DropDownStyle dependency property. + /// + public static readonly DependencyProperty DropDownStyleProperty = DependencyProperty.Register( "DropDownStyle", typeof(Style), typeof(ListOrganizer), new PropertyMetadata( null, DropDownStyleProperty_PropertyChanged) ); + + /// + /// Gets or sets the style of the drop-down. + /// + [Bindable(true)] + [Category("Common Properties")] + [Description("Gets or sets the style of the drop-down.")] + [Localizability(LocalizationCategory.None)] + public Style DropDownStyle + { + get + { + return (Style) GetValue(DropDownStyleProperty); + } + set + { + SetValue(DropDownStyleProperty,value); + } + } + + static private void DropDownStyleProperty_PropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + ListOrganizer obj = (ListOrganizer) o; + obj.OnDropDownStyleChanged( new PropertyChangedEventArgs + + + + + + + + + + diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/CmdletControl.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/CmdletControl.xaml new file mode 100644 index 000000000..240e697d3 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/CmdletControl.xaml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/ColumnPicker.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/ColumnPicker.xaml new file mode 100644 index 000000000..2a4934e90 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/ColumnPicker.xaml @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/HelpWindow.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/HelpWindow.xaml new file mode 100644 index 000000000..a002684f9 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/HelpWindow.xaml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/ImageButton.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/ImageButton.xaml new file mode 100644 index 000000000..a31f9b2e4 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/ImageButton.xaml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/ImageButtonCommon.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/ImageButtonCommon.xaml new file mode 100644 index 000000000..8c3c1d08b --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/ImageButtonCommon.xaml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/ImageToggleButton.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/ImageToggleButton.xaml new file mode 100644 index 000000000..034f534ee --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/ImageToggleButton.xaml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/MultipleSelectionControl.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/MultipleSelectionControl.xaml new file mode 100644 index 000000000..73b5656e8 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/MultipleSelectionControl.xaml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/MultipleSelectionDialog.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/MultipleSelectionDialog.xaml new file mode 100644 index 000000000..e757a0d1e --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/MultipleSelectionDialog.xaml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/NotImportedCmdletControl.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/NotImportedCmdletControl.xaml new file mode 100644 index 000000000..d0d627a9d --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/NotImportedCmdletControl.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/ParameterSetControl.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/ParameterSetControl.xaml new file mode 100644 index 000000000..a1f714e45 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/ParameterSetControl.xaml @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/SettingsDialog.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/SettingsDialog.xaml new file mode 100644 index 000000000..34e40a6f1 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/SettingsDialog.xaml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/ShowAllModulesWindow.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/ShowAllModulesWindow.xaml new file mode 100644 index 000000000..c8713ba5c --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/ShowAllModulesWindow.xaml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/ShowCommandWindow.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/ShowCommandWindow.xaml new file mode 100644 index 000000000..dfc2a8e1e --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/ShowCommandWindow.xaml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/Microsoft.PowerShell.GraphicalHost/xamls/ShowModuleControl.xaml b/src/Microsoft.PowerShell.GraphicalHost/xamls/ShowModuleControl.xaml new file mode 100644 index 000000000..edc43d926 --- /dev/null +++ b/src/Microsoft.PowerShell.GraphicalHost/xamls/ShowModuleControl.xaml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + +