diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..4bb21ee --- /dev/null +++ b/.editorconfig @@ -0,0 +1,150 @@ +root = true +# EditorConfig is awesome:http://EditorConfig.org + +# top-most EditorConfig file + +# Don't use tabs for indentation. +[*] +indent_style = space +indent_size = 2 + +# Code files +[*.{cs, csx, vb, vbx}] +insert_final_newline = true +charset = utf-8-bom + +# ReSharper properties +resharper_csharp_extra_spaces = leave_multiple +resharper_csharp_naming_rule.private_constants = AaBb, AA_BB +resharper_csharp_space_within_array_access_brackets = true +resharper_space_around_arrow_op = true +resharper_space_within_array_rank_brackets = true +resharper_use_indent_from_vs = false +resharper_xml_attribute_style = first_attribute_on_single_line +resharper_xml_pi_attribute_style = first_attribute_on_single_line + +# Dotnet code style settings: +[*.{cs, vb}] +# Sort using and Import directives with System.* appearing first +dotnet_sort_system_directives_first = true +# Avoid "this." and "Me." if not necessary +dotnet_style_qualification_for_field = false : suggestion +dotnet_style_qualification_for_property = false : suggestion +dotnet_style_qualification_for_method = false : suggestion +dotnet_style_qualification_for_event = false : suggestion + +# Use language keywords instead of framework type names for type references +dotnet_style_predefined_type_for_locals_parameters_members = true : suggestion +dotnet_style_predefined_type_for_member_access = true : suggestion + +# Suggest more modern language features when available +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion + +# CSharp code style settings: +[*.cs] +# Prefer "var" everywhere +csharp_style_var_for_built_in_types = true : suggestion +csharp_style_var_when_type_is_apparent = true : suggestion +csharp_style_var_elsewhere = true : suggestion + +# Prefer method-like constructs to have a block body +csharp_style_expression_bodied_methods = false:none +csharp_style_expression_bodied_constructors = false:none +csharp_style_expression_bodied_operators = false:none + +# Prefer property-like constructs to have an expression-body +csharp_style_expression_bodied_properties = true:none +csharp_style_expression_bodied_indexers = true:none +csharp_style_expression_bodied_accessors = true:none + +# Suggest more modern language features when available +csharp_style_pattern_matching_over_is_with_cast_check = true : suggestion +csharp_style_pattern_matching_over_as_with_null_check = true : suggestion +csharp_style_inlined_variable_declaration = true : suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true : suggestion + +# Newline settings +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true + +spaces_around_brackets = inside +csharp_using_directive_placement = outside_namespace:silent +csharp_prefer_simple_using_statement = true:suggestion +csharp_prefer_braces = true:silent +csharp_style_namespace_declarations = block_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_top_level_statements = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_prefer_null_check_over_type_check = true:suggestion +csharp_indent_labels = one_less_than_current + +[*.{cs,vb}] +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion +dotnet_style_namespace_match_folder = true:suggestion +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 2 +end_of_line = crlf diff --git a/Directory.Build.props b/Directory.Build.props index d15da13..cfd1aeb 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -63,6 +63,7 @@ + diff --git a/xUnitRevit.sln b/xUnitRevit.sln index 3712a5a..0697209 100644 --- a/xUnitRevit.sln +++ b/xUnitRevit.sln @@ -19,6 +19,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "xUnitRevitUtils2022", "xUni EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{F5A2849D-7C58-4894-B9C5-8488E244B7CF}" ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig Directory.Build.props = Directory.Build.props EndProjectSection EndProject diff --git a/xUnitRevitUtils2019/xUnitRevitUtils2019.csproj b/xUnitRevitUtils2019/xUnitRevitUtils2019.csproj index 718399b..fd2d743 100644 --- a/xUnitRevitUtils2019/xUnitRevitUtils2019.csproj +++ b/xUnitRevitUtils2019/xUnitRevitUtils2019.csproj @@ -6,10 +6,6 @@ xUnitRevitUtils.2019 - - - - diff --git a/xUnitRevitUtils2020/xUnitRevitUtils2020.csproj b/xUnitRevitUtils2020/xUnitRevitUtils2020.csproj index 5215545..176555a 100644 --- a/xUnitRevitUtils2020/xUnitRevitUtils2020.csproj +++ b/xUnitRevitUtils2020/xUnitRevitUtils2020.csproj @@ -6,9 +6,6 @@ xUnitRevitUtils.2020 - - - diff --git a/xUnitRevitUtils2021/xUnitRevitUtils2021.csproj b/xUnitRevitUtils2021/xUnitRevitUtils2021.csproj index 5543811..027df3c 100644 --- a/xUnitRevitUtils2021/xUnitRevitUtils2021.csproj +++ b/xUnitRevitUtils2021/xUnitRevitUtils2021.csproj @@ -6,6 +6,7 @@ xUnitRevitUtils.2021 + diff --git a/xUnitRevitUtils2021/xru.cs b/xUnitRevitUtils2021/xru.cs deleted file mode 100644 index 4351a1e..0000000 --- a/xUnitRevitUtils2021/xru.cs +++ /dev/null @@ -1,159 +0,0 @@ -using Autodesk.Revit.DB; -using Autodesk.Revit.UI; -using Xunit; - -namespace xUnitRevitUtils { - /// - /// Utility class with methods and properties used by the xUnit Revit plugin - /// - public static class xru { - public static UIApplication Uiapp { get; set; } - - private static IList Queue { get; set; } - private static ExternalEvent EventHandler { get; set; } - - public static SynchronizationContext UiContext { get; set; } - - public static void Initialize(UIApplication uiapp, SynchronizationContext uiContext, ExternalEvent eventHandler, IList queue) { - Uiapp = uiapp; - UiContext = uiContext; - EventHandler = eventHandler; - Queue = queue; - } - - #region utility methods - - /// - /// Returns the selected elements in the active document - /// - /// - public static IList GetActiveSelection() { - Assert.NotNull(Uiapp); - - if (Uiapp.ActiveUIDocument != null) - return Uiapp.ActiveUIDocument.Selection.GetElementIds().Select(x => Uiapp.ActiveUIDocument.Document.GetElement(x)).ToList(); - return new List(); - } - /// - /// Opens and activates a document if not open already - /// - /// Path to the file to open - public static Document OpenDoc(string filePath) { - Assert.NotNull(Uiapp); - Document doc = null; - //OpenAndActivateDocument only works if run from the current context - UiContext.Send(x => { doc = Uiapp.OpenAndActivateDocument(filePath).Document; }, null); - Assert.NotNull(doc); - return doc; - } - - /// - /// Creates a new empty document - /// - /// Path to the project template - /// Path where to save the new doc - /// If true overwrites existing files with same name - /// - public static Document CreateNewDoc(string templatePath, string filePath, bool overwrite = true) { - Assert.NotNull(Uiapp); - Document doc = null; - - try { - if (overwrite && File.Exists(filePath)) - File.Delete(filePath); - } - catch { } - - //OpenAndActivateDocument only works if run from the current context - UiContext.Send(x => { - //if already open, just use it - if (!File.Exists(filePath)) { - doc = Uiapp.Application.NewProjectDocument(templatePath); - doc.SaveAs(filePath); - doc.Close(); - } - - doc = Uiapp.OpenAndActivateDocument(filePath).Document; - } - , null); - Assert.NotNull(doc); - return doc; - } - - /// - /// Runs an Action in a Revit transaction, uses TaskCompletionSource to communicate when done - /// - /// Action to run - /// Revit Document - /// Transaction Name - /// Enable to swallow all warnings generated by the transaction and prevent them from being raised within Revit - /// - public static Task RunInTransaction(Action action, Document doc, string transactionName = "transaction", bool ignoreWarnings = false) { - var tcs = new TaskCompletionSource(); - Queue.Add(new Action(() => { - try { - using (Transaction transaction = new Transaction(doc, transactionName)) { - transaction.Start(); - - if (ignoreWarnings) { - var options = transaction.GetFailureHandlingOptions(); - options.SetFailuresPreprocessor(new IgnoreAllWarnings()); - transaction.SetFailureHandlingOptions(options); - } - - action.Invoke(); - transaction.Commit(); - } - } - catch (Exception e) { - tcs.TrySetException(e); - } - tcs.TrySetResult(""); - })); - - EventHandler.Raise(); - - return tcs.Task; - } - - /// - /// Runs an Action, uses TaskCompletionSource to communicate when done - /// - /// Action to run - /// Revit Document - /// - public static Task Run(Action action, Document doc) { - var tcs = new TaskCompletionSource(); - Queue.Add(new Action(() => { - try { - action.Invoke(); - } - catch (Exception e) { - tcs.TrySetException(e); - } - tcs.TrySetResult(""); - })); - - EventHandler.Raise(); - - return tcs.Task; - } - - /// - /// A failures preprocesser that clears any failures that occur within a transaction - /// - internal class IgnoreAllWarnings : IFailuresPreprocessor { - public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor) { - var failList = failuresAccessor.GetFailureMessages(); - - foreach (FailureMessageAccessor failure in failList) { - failuresAccessor.DeleteWarning(failure); - } - - return FailureProcessingResult.Continue; - } - } - - #endregion - } -} diff --git a/xUnitRevitUtils2022/xUnitRevitUtils2022.csproj b/xUnitRevitUtils2022/xUnitRevitUtils2022.csproj index e369953..7a6968c 100644 --- a/xUnitRevitUtils2022/xUnitRevitUtils2022.csproj +++ b/xUnitRevitUtils2022/xUnitRevitUtils2022.csproj @@ -6,8 +6,9 @@ xUnitRevitUtils.2022 + - + diff --git a/xUnitRevitUtils2023/xUnitRevitUtils2023.csproj b/xUnitRevitUtils2023/xUnitRevitUtils2023.csproj index 05e9220..b27d4a4 100644 --- a/xUnitRevitUtils2023/xUnitRevitUtils2023.csproj +++ b/xUnitRevitUtils2023/xUnitRevitUtils2023.csproj @@ -6,8 +6,9 @@ xUnitRevitUtils.2023 + - + diff --git a/xUnitRevitUtils2023/xru.cs b/xUnitRevitUtils2023/xru.cs deleted file mode 100644 index 0c2869e..0000000 --- a/xUnitRevitUtils2023/xru.cs +++ /dev/null @@ -1,155 +0,0 @@ -using Autodesk.Revit.DB; -using Autodesk.Revit.UI; -using Xunit; - -namespace xUnitRevitUtils { - /// - /// Utility class with methods and properties used by the xUnit Revit plugin - /// - public static class xru { - public static UIApplication Uiapp { get; set; } - private static IList Queue { get; set; } - private static ExternalEvent EventHandler { get; set; } - public static SynchronizationContext UiContext { get; set; } - public static void Initialize(UIApplication uiapp, SynchronizationContext uiContext, ExternalEvent eventHandler, IList queue) { - Uiapp = uiapp; - UiContext = uiContext; - EventHandler = eventHandler; - Queue = queue; - } - - #region utility methods - - /// - /// Returns the selected elements in the active document - /// - /// - public static IList GetActiveSelection() { - Assert.NotNull(Uiapp); - - if (Uiapp.ActiveUIDocument != null) - return Uiapp.ActiveUIDocument.Selection.GetElementIds().Select(x => Uiapp.ActiveUIDocument.Document.GetElement(x)).ToList(); - return new List(); - } - /// - /// Opens and activates a document if not open already - /// - /// Path to the file to open - public static Document OpenDoc(string filePath) { - Assert.NotNull(Uiapp); - Document doc = null; - //OpenAndActivateDocument only works if run from the current context - UiContext.Send(x => { doc = Uiapp.OpenAndActivateDocument(filePath).Document; }, null); - Assert.NotNull(doc); - return doc; - } - - /// - /// Creates a new empty document - /// - /// Path to the project template - /// Path where to save the new doc - /// If true overwrites existing files with same name - /// - public static Document CreateNewDoc(string templatePath, string filePath, bool overwrite = true) { - Assert.NotNull(Uiapp); - Document doc = null; - - try { - if (overwrite && File.Exists(filePath)) - File.Delete(filePath); - } - catch { } - - //OpenAndActivateDocument only works if run from the current context - UiContext.Send(x => { - //if already open, just use it - if (!File.Exists(filePath)) { - doc = Uiapp.Application.NewProjectDocument(templatePath); - doc.SaveAs(filePath); - doc.Close(); - } - - doc = Uiapp.OpenAndActivateDocument(filePath).Document; - } - , null); - Assert.NotNull(doc); - return doc; - } - - /// - /// Runs an Action in a Revit transaction, uses TaskCompletionSource to communicate when done - /// - /// Action to run - /// Revit Document - /// Transaction Name - /// Enable to swallow all warnings generated by the transaction and prevent them from being raised within Revit - /// - public static Task RunInTransaction(Action action, Document doc, string transactionName = "transaction", bool ignoreWarnings = false) { - var tcs = new TaskCompletionSource(); - Queue.Add(new Action(() => { - try { - using (Transaction transaction = new Transaction(doc, transactionName)) { - transaction.Start(); - - if (ignoreWarnings) { - var options = transaction.GetFailureHandlingOptions(); - options.SetFailuresPreprocessor(new IgnoreAllWarnings()); - transaction.SetFailureHandlingOptions(options); - } - - action.Invoke(); - transaction.Commit(); - } - } - catch (Exception e) { - tcs.TrySetException(e); - } - tcs.TrySetResult(""); - })); - - EventHandler.Raise(); - - return tcs.Task; - } - - /// - /// Runs an Action, uses TaskCompletionSource to communicate when done - /// - /// Action to run - /// Revit Document - /// - public static Task Run(Action action, Document doc) { - var tcs = new TaskCompletionSource(); - Queue.Add(new Action(() => { - try { - action.Invoke(); - } - catch (Exception e) { - tcs.TrySetException(e); - } - tcs.TrySetResult(""); - })); - - EventHandler.Raise(); - - return tcs.Task; - } - - /// - /// A failures preprocesser that clears any failures that occur within a transaction - /// - internal class IgnoreAllWarnings : IFailuresPreprocessor { - public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor) { - var failList = failuresAccessor.GetFailureMessages(); - - foreach (FailureMessageAccessor failure in failList) { - failuresAccessor.DeleteWarning(failure); - } - - return FailureProcessingResult.Continue; - } - } - #endregion - } -} diff --git a/xUnitRevitUtils2022/xru.cs b/xUnitRevitUtilsShared/xru.cs similarity index 97% rename from xUnitRevitUtils2022/xru.cs rename to xUnitRevitUtilsShared/xru.cs index 0c2869e..66384ff 100644 --- a/xUnitRevitUtils2022/xru.cs +++ b/xUnitRevitUtilsShared/xru.cs @@ -1,155 +1,155 @@ -using Autodesk.Revit.DB; -using Autodesk.Revit.UI; -using Xunit; - -namespace xUnitRevitUtils { - /// - /// Utility class with methods and properties used by the xUnit Revit plugin - /// - public static class xru { - public static UIApplication Uiapp { get; set; } - private static IList Queue { get; set; } - private static ExternalEvent EventHandler { get; set; } - public static SynchronizationContext UiContext { get; set; } - public static void Initialize(UIApplication uiapp, SynchronizationContext uiContext, ExternalEvent eventHandler, IList queue) { - Uiapp = uiapp; - UiContext = uiContext; - EventHandler = eventHandler; - Queue = queue; - } - - #region utility methods - - /// - /// Returns the selected elements in the active document - /// - /// - public static IList GetActiveSelection() { - Assert.NotNull(Uiapp); - - if (Uiapp.ActiveUIDocument != null) - return Uiapp.ActiveUIDocument.Selection.GetElementIds().Select(x => Uiapp.ActiveUIDocument.Document.GetElement(x)).ToList(); - return new List(); - } - /// - /// Opens and activates a document if not open already - /// - /// Path to the file to open - public static Document OpenDoc(string filePath) { - Assert.NotNull(Uiapp); - Document doc = null; - //OpenAndActivateDocument only works if run from the current context - UiContext.Send(x => { doc = Uiapp.OpenAndActivateDocument(filePath).Document; }, null); - Assert.NotNull(doc); - return doc; - } - - /// - /// Creates a new empty document - /// - /// Path to the project template - /// Path where to save the new doc - /// If true overwrites existing files with same name - /// - public static Document CreateNewDoc(string templatePath, string filePath, bool overwrite = true) { - Assert.NotNull(Uiapp); - Document doc = null; - - try { - if (overwrite && File.Exists(filePath)) - File.Delete(filePath); - } - catch { } - - //OpenAndActivateDocument only works if run from the current context - UiContext.Send(x => { - //if already open, just use it - if (!File.Exists(filePath)) { - doc = Uiapp.Application.NewProjectDocument(templatePath); - doc.SaveAs(filePath); - doc.Close(); - } - - doc = Uiapp.OpenAndActivateDocument(filePath).Document; - } - , null); - Assert.NotNull(doc); - return doc; - } - - /// - /// Runs an Action in a Revit transaction, uses TaskCompletionSource to communicate when done - /// - /// Action to run - /// Revit Document - /// Transaction Name - /// Enable to swallow all warnings generated by the transaction and prevent them from being raised within Revit - /// - public static Task RunInTransaction(Action action, Document doc, string transactionName = "transaction", bool ignoreWarnings = false) { - var tcs = new TaskCompletionSource(); - Queue.Add(new Action(() => { - try { - using (Transaction transaction = new Transaction(doc, transactionName)) { - transaction.Start(); - - if (ignoreWarnings) { - var options = transaction.GetFailureHandlingOptions(); - options.SetFailuresPreprocessor(new IgnoreAllWarnings()); - transaction.SetFailureHandlingOptions(options); - } - - action.Invoke(); - transaction.Commit(); - } - } - catch (Exception e) { - tcs.TrySetException(e); - } - tcs.TrySetResult(""); - })); - - EventHandler.Raise(); - - return tcs.Task; - } - - /// - /// Runs an Action, uses TaskCompletionSource to communicate when done - /// - /// Action to run - /// Revit Document - /// - public static Task Run(Action action, Document doc) { - var tcs = new TaskCompletionSource(); - Queue.Add(new Action(() => { - try { - action.Invoke(); - } - catch (Exception e) { - tcs.TrySetException(e); - } - tcs.TrySetResult(""); - })); - - EventHandler.Raise(); - - return tcs.Task; - } - - /// - /// A failures preprocesser that clears any failures that occur within a transaction - /// - internal class IgnoreAllWarnings : IFailuresPreprocessor { - public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor) { - var failList = failuresAccessor.GetFailureMessages(); - - foreach (FailureMessageAccessor failure in failList) { - failuresAccessor.DeleteWarning(failure); - } - - return FailureProcessingResult.Continue; - } - } - #endregion - } -} +using Autodesk.Revit.DB; +using Autodesk.Revit.UI; +using Xunit; + +namespace xUnitRevitUtils { + /// + /// Utility class with methods and properties used by the xUnit Revit plugin + /// + public static class xru { + public static UIApplication Uiapp { get; set; } + private static IList Queue { get; set; } + private static ExternalEvent EventHandler { get; set; } + public static SynchronizationContext UiContext { get; set; } + public static void Initialize(UIApplication uiapp, SynchronizationContext uiContext, ExternalEvent eventHandler, IList queue) { + Uiapp = uiapp; + UiContext = uiContext; + EventHandler = eventHandler; + Queue = queue; + } + + #region utility methods + + /// + /// Returns the selected elements in the active document + /// + /// + public static IList GetActiveSelection() { + Assert.NotNull(Uiapp); + + if (Uiapp.ActiveUIDocument != null) + return Uiapp.ActiveUIDocument.Selection.GetElementIds().Select(x => Uiapp.ActiveUIDocument.Document.GetElement(x)).ToList(); + return new List(); + } + /// + /// Opens and activates a document if not open already + /// + /// Path to the file to open + public static Document OpenDoc(string filePath) { + Assert.NotNull(Uiapp); + Document doc = null; + //OpenAndActivateDocument only works if run from the current context + UiContext.Send(x => { doc = Uiapp.OpenAndActivateDocument(filePath).Document; }, null); + Assert.NotNull(doc); + return doc; + } + + /// + /// Creates a new empty document + /// + /// Path to the project template + /// Path where to save the new doc + /// If true overwrites existing files with same name + /// + public static Document CreateNewDoc(string templatePath, string filePath, bool overwrite = true) { + Assert.NotNull(Uiapp); + Document doc = null; + + try { + if (overwrite && File.Exists(filePath)) + File.Delete(filePath); + } + catch { } + + //OpenAndActivateDocument only works if run from the current context + UiContext.Send(x => { + //if already open, just use it + if (!File.Exists(filePath)) { + doc = Uiapp.Application.NewProjectDocument(templatePath); + doc.SaveAs(filePath); + doc.Close(); + } + + doc = Uiapp.OpenAndActivateDocument(filePath).Document; + } + , null); + Assert.NotNull(doc); + return doc; + } + + /// + /// Runs an Action in a Revit transaction, uses TaskCompletionSource to communicate when done + /// + /// Action to run + /// Revit Document + /// Transaction Name + /// Enable to swallow all warnings generated by the transaction and prevent them from being raised within Revit + /// + public static Task RunInTransaction(Action action, Document doc, string transactionName = "transaction", bool ignoreWarnings = false) { + var tcs = new TaskCompletionSource(); + Queue.Add(new Action(() => { + try { + using (Transaction transaction = new Transaction(doc, transactionName)) { + transaction.Start(); + + if (ignoreWarnings) { + var options = transaction.GetFailureHandlingOptions(); + options.SetFailuresPreprocessor(new IgnoreAllWarnings()); + transaction.SetFailureHandlingOptions(options); + } + + action.Invoke(); + transaction.Commit(); + } + } + catch (Exception e) { + tcs.TrySetException(e); + } + tcs.TrySetResult(""); + })); + + EventHandler.Raise(); + + return tcs.Task; + } + + /// + /// Runs an Action, uses TaskCompletionSource to communicate when done + /// + /// Action to run + /// Revit Document + /// + public static Task Run(Action action, Document doc) { + var tcs = new TaskCompletionSource(); + Queue.Add(new Action(() => { + try { + action.Invoke(); + } + catch (Exception e) { + tcs.TrySetException(e); + } + tcs.TrySetResult(""); + })); + + EventHandler.Raise(); + + return tcs.Task; + } + + /// + /// A failures preprocesser that clears any failures that occur within a transaction + /// + internal class IgnoreAllWarnings : IFailuresPreprocessor { + public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor) { + var failList = failuresAccessor.GetFailureMessages(); + + foreach (FailureMessageAccessor failure in failList) { + failuresAccessor.DeleteWarning(failure); + } + + return FailureProcessingResult.Continue; + } + } + #endregion + } +}