From 7a9db456c0f8f023bb0d2b58c125d1ccd935aed8 Mon Sep 17 00:00:00 2001 From: Steve Cadwallader Date: Sat, 9 Apr 2016 07:08:40 -0400 Subject: [PATCH] #268: Add an option to prompt the user about whether or not reorganization should run in the presence of preprocessor conditionals. Follows pattern of cleanup external files. --- .../CodeReorganizationAvailabilityLogic.cs | 85 ++++++++++++++++++- .../Reorganizing/CodeReorganizationManager.cs | 2 +- CodeMaid/Properties/Settings.Designer.cs | 12 +++ CodeMaid/Properties/Settings.settings | 3 + .../ReorganizingGeneralDataTemplate.xaml | 12 ++- .../ReorganizingGeneralViewModel.cs | 11 +++ CodeMaid/app.config | 4 + 7 files changed, 125 insertions(+), 4 deletions(-) diff --git a/CodeMaid/Logic/Reorganizing/CodeReorganizationAvailabilityLogic.cs b/CodeMaid/Logic/Reorganizing/CodeReorganizationAvailabilityLogic.cs index 003aa22c..f599f9ae 100644 --- a/CodeMaid/Logic/Reorganizing/CodeReorganizationAvailabilityLogic.cs +++ b/CodeMaid/Logic/Reorganizing/CodeReorganizationAvailabilityLogic.cs @@ -1,5 +1,9 @@ using EnvDTE; using SteveCadwallader.CodeMaid.Helpers; +using SteveCadwallader.CodeMaid.Properties; +using SteveCadwallader.CodeMaid.UI.Dialogs.Prompts; +using SteveCadwallader.CodeMaid.UI.Enumerations; +using System; namespace SteveCadwallader.CodeMaid.Logic.Reorganizing { @@ -57,20 +61,54 @@ internal bool IsReorganizationEnvironmentAvailable() /// Determines if the specified document can be reorganized. /// /// The document. + /// A flag indicating if user prompts should be allowed. /// True if item can be reorganized, otherwise false. - internal bool CanReorganize(Document document) + internal bool CanReorganize(Document document, bool allowUserPrompts = false) { return IsReorganizationEnvironmentAvailable() && document != null && document.GetCodeLanguage() == CodeLanguage.CSharp && !document.IsExternal() && - !HasPreprocessorConditionalCompilationDirectives(document); + !IsDocumentExcludedBecausePreprocessorConditionals(document, allowUserPrompts); } #endregion Internal Methods #region Private Methods + /// + /// Determines whether the specified document should be excluded because it contains + /// preprocessor conditionals. Conditionally includes prompting the user. + /// + /// The document. + /// A flag indicating if user prompts should be allowed. + /// + /// True if document should be excluded because of preprocessor conditionals, otherwise false. + /// + private bool IsDocumentExcludedBecausePreprocessorConditionals(Document document, bool allowUserPrompts) + { + if (!HasPreprocessorConditionalCompilationDirectives(document)) return false; + + switch ((AskYesNo)Settings.Default.Reorganizing_PerformWhenPreprocessorConditionals) + { + case AskYesNo.Ask: + if (allowUserPrompts) + { + return !PromptUserAboutReorganizingPreprocessorConditionals(document); + } + break; + + case AskYesNo.Yes: + return false; + + case AskYesNo.No: + return true; + } + + // If unresolved, assume exclusion. + return true; + } + /// /// Determines if the specified document contains preprocessor conditional compilation directives. /// @@ -93,6 +131,49 @@ private bool HasPreprocessorConditionalCompilationDirectives(Document document) return false; } + /// + /// Prompts the user about reorganizing files with preprocessor conditionals. + /// + /// The document. + /// True if files with preprocessor conditionals should be reorganized, otherwise false. + private static bool PromptUserAboutReorganizingPreprocessorConditionals(Document document) + { + try + { + var viewModel = new YesNoPromptViewModel + { + Title = @"CodeMaid: Reorganize Preprocessor Conditionals", + Message = document.Name + " contains preprocessor conditionals (e.g. #if, #pragma) which reorganization does not currently support." + + Environment.NewLine + Environment.NewLine + + "Do you want to reorganize anyways (DANGEROUS)?", + CanRemember = true + }; + + var window = new YesNoPromptWindow { DataContext = viewModel }; + var response = window.ShowModal(); + + if (!response.HasValue) + { + return false; + } + + if (viewModel.Remember) + { + var preference = (int)(response.Value ? AskYesNo.Yes : AskYesNo.No); + + Settings.Default.Reorganizing_PerformWhenPreprocessorConditionals = preference; + Settings.Default.Save(); + } + + return response.Value; + } + catch (Exception ex) + { + OutputWindowHelper.ExceptionWriteLine("Unable to prompt user about reorganizing preprocessor conditionals", ex); + return false; + } + } + #endregion Private Methods } } \ No newline at end of file diff --git a/CodeMaid/Logic/Reorganizing/CodeReorganizationManager.cs b/CodeMaid/Logic/Reorganizing/CodeReorganizationManager.cs index d660c453..ada6b3ce 100644 --- a/CodeMaid/Logic/Reorganizing/CodeReorganizationManager.cs +++ b/CodeMaid/Logic/Reorganizing/CodeReorganizationManager.cs @@ -105,7 +105,7 @@ internal void MoveItemIntoBase(BaseCodeItem itemToMove, ICodeItemParent baseItem /// The document for reorganizing. internal void Reorganize(Document document) { - if (!_codeReorganizationAvailabilityLogic.CanReorganize(document)) return; + if (!_codeReorganizationAvailabilityLogic.CanReorganize(document, true)) return; new UndoTransactionHelper(_package, $"CodeMaid Reorganize for '{document.Name}'").Run( delegate diff --git a/CodeMaid/Properties/Settings.Designer.cs b/CodeMaid/Properties/Settings.Designer.cs index ea334c17..2493a67e 100644 --- a/CodeMaid/Properties/Settings.Designer.cs +++ b/CodeMaid/Properties/Settings.Designer.cs @@ -1835,6 +1835,18 @@ public string Reorganizing_MemberTypeStructs { } } + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0")] + public int Reorganizing_PerformWhenPreprocessorConditionals { + get { + return ((int)(this["Reorganizing_PerformWhenPreprocessorConditionals"])); + } + set { + this["Reorganizing_PerformWhenPreprocessorConditionals"] = value; + } + } + [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] diff --git a/CodeMaid/Properties/Settings.settings b/CodeMaid/Properties/Settings.settings index 45ee48cd..19b6b12e 100644 --- a/CodeMaid/Properties/Settings.settings +++ b/CodeMaid/Properties/Settings.settings @@ -455,6 +455,9 @@ Structs||11||Structs + + 0 + False diff --git a/CodeMaid/UI/Dialogs/Options/Reorganizing/ReorganizingGeneralDataTemplate.xaml b/CodeMaid/UI/Dialogs/Options/Reorganizing/ReorganizingGeneralDataTemplate.xaml index a5a9a2ec..35be5d31 100644 --- a/CodeMaid/UI/Dialogs/Options/Reorganizing/ReorganizingGeneralDataTemplate.xaml +++ b/CodeMaid/UI/Dialogs/Options/Reorganizing/ReorganizingGeneralDataTemplate.xaml @@ -1,7 +1,8 @@ + xmlns:cnv="clr-namespace:SteveCadwallader.CodeMaid.UI.Converters" + xmlns:enums="clr-namespace:SteveCadwallader.CodeMaid.UI.Enumerations"> @@ -19,6 +20,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/CodeMaid/UI/Dialogs/Options/Reorganizing/ReorganizingGeneralViewModel.cs b/CodeMaid/UI/Dialogs/Options/Reorganizing/ReorganizingGeneralViewModel.cs index 39e7aa58..3fc76ba5 100644 --- a/CodeMaid/UI/Dialogs/Options/Reorganizing/ReorganizingGeneralViewModel.cs +++ b/CodeMaid/UI/Dialogs/Options/Reorganizing/ReorganizingGeneralViewModel.cs @@ -1,4 +1,5 @@ using SteveCadwallader.CodeMaid.Properties; +using SteveCadwallader.CodeMaid.UI.Enumerations; namespace SteveCadwallader.CodeMaid.UI.Dialogs.Options.Reorganizing { @@ -21,6 +22,7 @@ public ReorganizingGeneralViewModel(CodeMaidPackage package, Settings activeSett { new SettingToOptionMapping(x => ActiveSettings.Reorganizing_AlphabetizeMembersOfTheSameGroup, x => AlphabetizeMembersOfTheSameGroup), new SettingToOptionMapping(x => ActiveSettings.Reorganizing_KeepMembersWithinRegions, x => KeepMembersWithinRegions), + new SettingToOptionMapping(x => ActiveSettings.Reorganizing_PerformWhenPreprocessorConditionals, x => PerformWhenPreprocessorConditionals), new SettingToOptionMapping(x => ActiveSettings.Reorganizing_PrimaryOrderByAccessLevel, x => PrimaryOrderByAccessLevel), new SettingToOptionMapping(x => ActiveSettings.Reorganizing_RunAtStartOfCleanup, x => RunAtStartOfCleanup) }; @@ -57,6 +59,15 @@ public bool KeepMembersWithinRegions set { SetPropertyValue(value); } } + /// + /// Gets or sets the options for performing reorganization when preprocessor conditionals are present. + /// + public AskYesNo PerformWhenPreprocessorConditionals + { + get { return GetPropertyValue(); } + set { SetPropertyValue(value); } + } + /// /// Gets or sets the flag indicating if primary ordering should be by access level. /// diff --git a/CodeMaid/app.config b/CodeMaid/app.config index fc708ece..b0fe87db 100644 --- a/CodeMaid/app.config +++ b/CodeMaid/app.config @@ -508,6 +508,10 @@ Structs||11||Structs + + 0 + False