diff --git a/.editorconfig b/.editorconfig index 654123bb..6c05deba 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,138 +1,116 @@ -# editorconfig.org - -# top-most EditorConfig file -root = true - -# Default settings: -# A newline ending every file -# Use 4 spaces as indentation -[*] -insert_final_newline = true -indent_style = space -indent_size = 4 - -# C# files -[*.cs] - -# "This." and "Me." Qualification -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 - -# Language keywords (int, string, etc.) vs 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 -dotnet_style_object_initializer = true:suggestion -dotnet_style_collection_initializer = true:suggestion -dotnet_style_explicit_tuple_names = true:warning -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_null_propagation true:warning - -# "var" and Explicit Types -csharp_style_var_for_built_in_types = true:suggestion -csharp_style_var_when_type_is_apparent = true:suggestion -csharp_style_var_elsewhere = true:suggestion - -# Expression-bodied Members -csharp_style_expression_bodied_methods = false:none -csharp_style_expression_bodied_constructors = false:none -csharp_style_expression_bodied_operators = false:none -csharp_style_expression_bodied_properties = true:none -csharp_style_expression_bodied_indexers = true:none -csharp_style_expression_bodied_accessors = true:none - -# Pattern matching -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 - -# Expression-level Preferences -csharp_prefer_simple_default_expression = true:suggestion - -# "Null" Checking Preferences -csharp_style_throw_expression = true:suggestion -csharp_style_conditional_delegate_call = true:suggestion - -# Code Block Preferences -csharp_prefer_braces = false:suggestion - -# Organize Usings -dotnet_sort_system_directives_first = true - -# Newline Options -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 -csharp_new_line_between_query_expression_clauses = true - -# Indentation Options -csharp_indent_case_contents = true -csharp_indent_switch_labels = true -csharp_indent_labels = no_change - -# Spacing Options -csharp_space_after_cast = true -csharp_space_between_method_declaration_parameter_list_parentheses = false -csharp_space_between_method_call_parameter_list_parentheses = false -csharp_space_between_parentheses = false - -# Wrapping Options -csharp_preserve_single_line_statements = false -csharp_preserve_single_line_blocks = true - -##### -# Naming Convention (Custom) -##### - -## Name all private fields with camelCase -dotnet_naming_symbols.private_field_symbol.applicable_kinds = field -dotnet_naming_symbols.private_field_symbol.applicable_accessibilities = private -dotnet_naming_style.private_field_style.capitalization = camel_case -dotnet_naming_rule.private_fields_are_camel_case.severity = warning -dotnet_naming_rule.private_fields_are_camel_case.symbols = private_field_symbol -dotnet_naming_rule.private_fields_are_camel_case.style = private_field_style - -## Name all non-private fields with PascalCase -dotnet_naming_symbols.non_private_field_symbol.applicable_kinds = field -dotnet_naming_symbols.non_private_field_symbol.applicable_accessibilities = public,internal,friend,protected,protected_internal,protected_friend -dotnet_naming_style.non_private_field_style.capitalization = pascal_case -dotnet_naming_rule.non_private_fields_are_pascal_case.severity = error -dotnet_naming_rule.non_private_fields_are_pascal_case.symbols = non_private_field_symbol -dotnet_naming_rule.non_private_fields_are_pascal_case.style = non_private_field_style - -## Names of parameters must be CamelCase -dotnet_naming_symbols.parameter_symbol.applicable_kinds = parameter -dotnet_naming_style.parameter_style.capitalization = camel_case -dotnet_naming_rule.parameters_are_camel_case.severity = error -dotnet_naming_rule.parameters_are_camel_case.symbols = parameter_symbol -dotnet_naming_rule.parameters_are_camel_case.style = parameter_style - -## Non-interface types must use PascalCase -dotnet_naming_symbols.non_interface_type_symbol.applicable_kinds = class,struct,enum,delegate -dotnet_naming_style.non_interface_type_style.capitalization = pascal_case -dotnet_naming_rule.non_interface_types_are_pascal_case.severity = error -dotnet_naming_rule.non_interface_types_are_pascal_case.symbols = non_interface_type_symbol -dotnet_naming_rule.non_interface_types_are_pascal_case.style = non_interface_type_style - -## Interfaces must use PascalCase and start with a prefix of 'I' -dotnet_naming_symbols.interface_type_symbol.applicable_kinds = interface -dotnet_naming_style.interface_type_style.capitalization = pascal_case -dotnet_naming_style.interface_type_style.required_prefix = I -dotnet_naming_rule.interface_types_must_be_prefixed_with_I.severity = error -dotnet_naming_rule.interface_types_must_be_prefixed_with_I.symbols = interface_type_symbol -dotnet_naming_rule.interface_types_must_be_prefixed_with_I.style = interface_type_style - -## Methods, Properties, and Events must use PascalCase -dotnet_naming_symbols.member_symbol.applicable_kinds = method,property,event -dotnet_naming_style.member_style.capitalization = pascal_case -dotnet_naming_rule.members_are_pascal_case.severity = error -dotnet_naming_rule.members_are_pascal_case.symbols = member_symbol -dotnet_naming_rule.members_are_pascal_case.style = member_style - -# Xml project files -[*.{csproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}] -indent_size = 2 +# To learn more about .editorconfig see https://aka.ms/editorconfigdocs +############################### +# Core EditorConfig Options # +############################### +# All files +[*] +indent_style = space +# Code files +[*.{cs,csx,vb,vbx}] +indent_size = 4 +insert_final_newline = true +charset = utf-8-bom +############################### +# .NET Coding Conventions # +############################### +[*.{cs,vb}] +# Organize usings +dotnet_sort_system_directives_first = true +# this. preferences +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 +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent +dotnet_style_readonly_field = true:suggestion +# Expression-level preferences +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_prefer_inferred_tuple_names = true:suggestion +dotnet_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_return = true:suggestion +############################### +# Naming Conventions # +############################### +# Style Definitions +dotnet_naming_style.pascal_case_style.capitalization = pascal_case +# Use PascalCase for constant fields +dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = warning +dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields +dotnet_naming_symbols.constant_fields.applicable_kinds = field +dotnet_naming_symbols.constant_fields.applicable_accessibilities = * +dotnet_naming_symbols.constant_fields.required_modifiers = const +############################### +# C# Coding Conventions # +############################### +[*.cs] +# var preferences +csharp_style_var_for_built_in_types = true:silent +csharp_style_var_when_type_is_apparent = true:suggestion +csharp_style_var_elsewhere = true:silent +# Expression-bodied members +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +# Pattern matching preferences +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +# Null-checking preferences +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion +# Modifier preferences +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion +# Expression-level preferences +csharp_prefer_braces = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +############################### +# C# Formatting Rules # +############################### +# New line preferences +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 +csharp_new_line_between_query_expression_clauses = true +# Indentation preferences +csharp_indent_case_contents = true +csharp_indent_switch_labels = true +csharp_indent_labels = flush_left +# Space preferences +csharp_space_after_cast = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_around_binary_operators = before_and_after +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +# Wrapping preferences +csharp_preserve_single_line_statements = true +csharp_preserve_single_line_blocks = true diff --git a/BuildVision.sln b/BuildVision.sln index d7427501..11426b07 100644 --- a/BuildVision.sln +++ b/BuildVision.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.136 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28803.202 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{A8C25F90-8847-4EBE-A66B-02E5D1B42EC0}" ProjectSection(SolutionItems) = preProject @@ -19,48 +19,84 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AE904AFF-1B2 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildVision", "src\BuildVision\BuildVision.csproj", "{9925A635-1827-4BB4-9C31-FE0FC87A6265}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildVision.Common", "src\BuildVision.Common\BuildVision.Common.csproj", "{848412D1-95BF-4E56-A9EF-2926AF5C6D67}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildVision.Common", "src\BuildVision.Common\BuildVision.Common.csproj", "{848412D1-95BF-4E56-A9EF-2926AF5C6D67}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildVision.Contracts", "src\BuildVision.Contracts\BuildVision.Contracts.csproj", "{13D64A57-5DB3-4CC7-AC2B-9034E767D754}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildVision.Contracts", "src\BuildVision.Contracts\BuildVision.Contracts.csproj", "{13D64A57-5DB3-4CC7-AC2B-9034E767D754}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildVision.UI", "src\BuildVision.UI\BuildVision.UI.csproj", "{84E8BA65-9A4B-4C50-A115-6EF3208E4058}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{1DE272AA-D641-45F2-AEB9-934B3BAA6FBD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildVision.IntegrationTests", "test\BuildVision.IntegrationTests\BuildVision.IntegrationTests.csproj", "{FBB4F3ED-B1B8-4401-8667-5180194BAA54}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildVision.IntegrationTests", "test\BuildVision.IntegrationTests\BuildVision.IntegrationTests.csproj", "{FBB4F3ED-B1B8-4401-8667-5180194BAA54}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildVision.UnitTests", "test\BuildVision.UnitTests\BuildVision.UnitTests.csproj", "{2A7DE186-A1FA-4BA8-B393-3CA9ECBF444F}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildVision.Exports", "src\BuildVision.Exports\BuildVision.Exports.csproj", "{F16E6593-DDF9-4E9E-A2F8-56A3C43A643E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Marketplace|Any CPU = Marketplace|Any CPU Release|Any CPU = Release|Any CPU + VsixGallery|Any CPU = VsixGallery|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {9925A635-1827-4BB4-9C31-FE0FC87A6265}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9925A635-1827-4BB4-9C31-FE0FC87A6265}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9925A635-1827-4BB4-9C31-FE0FC87A6265}.Marketplace|Any CPU.ActiveCfg = Marketplace|Any CPU + {9925A635-1827-4BB4-9C31-FE0FC87A6265}.Marketplace|Any CPU.Build.0 = Marketplace|Any CPU {9925A635-1827-4BB4-9C31-FE0FC87A6265}.Release|Any CPU.ActiveCfg = Release|Any CPU {9925A635-1827-4BB4-9C31-FE0FC87A6265}.Release|Any CPU.Build.0 = Release|Any CPU + {9925A635-1827-4BB4-9C31-FE0FC87A6265}.VsixGallery|Any CPU.ActiveCfg = VsixGallery|Any CPU + {9925A635-1827-4BB4-9C31-FE0FC87A6265}.VsixGallery|Any CPU.Build.0 = VsixGallery|Any CPU {848412D1-95BF-4E56-A9EF-2926AF5C6D67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {848412D1-95BF-4E56-A9EF-2926AF5C6D67}.Debug|Any CPU.Build.0 = Debug|Any CPU + {848412D1-95BF-4E56-A9EF-2926AF5C6D67}.Marketplace|Any CPU.ActiveCfg = Marketplace|Any CPU + {848412D1-95BF-4E56-A9EF-2926AF5C6D67}.Marketplace|Any CPU.Build.0 = Marketplace|Any CPU {848412D1-95BF-4E56-A9EF-2926AF5C6D67}.Release|Any CPU.ActiveCfg = Release|Any CPU {848412D1-95BF-4E56-A9EF-2926AF5C6D67}.Release|Any CPU.Build.0 = Release|Any CPU + {848412D1-95BF-4E56-A9EF-2926AF5C6D67}.VsixGallery|Any CPU.ActiveCfg = VsixGallery|Any CPU + {848412D1-95BF-4E56-A9EF-2926AF5C6D67}.VsixGallery|Any CPU.Build.0 = VsixGallery|Any CPU {13D64A57-5DB3-4CC7-AC2B-9034E767D754}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {13D64A57-5DB3-4CC7-AC2B-9034E767D754}.Debug|Any CPU.Build.0 = Debug|Any CPU + {13D64A57-5DB3-4CC7-AC2B-9034E767D754}.Marketplace|Any CPU.ActiveCfg = Marketplace|Any CPU + {13D64A57-5DB3-4CC7-AC2B-9034E767D754}.Marketplace|Any CPU.Build.0 = Marketplace|Any CPU {13D64A57-5DB3-4CC7-AC2B-9034E767D754}.Release|Any CPU.ActiveCfg = Release|Any CPU {13D64A57-5DB3-4CC7-AC2B-9034E767D754}.Release|Any CPU.Build.0 = Release|Any CPU + {13D64A57-5DB3-4CC7-AC2B-9034E767D754}.VsixGallery|Any CPU.ActiveCfg = VsixGallery|Any CPU + {13D64A57-5DB3-4CC7-AC2B-9034E767D754}.VsixGallery|Any CPU.Build.0 = VsixGallery|Any CPU {84E8BA65-9A4B-4C50-A115-6EF3208E4058}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {84E8BA65-9A4B-4C50-A115-6EF3208E4058}.Debug|Any CPU.Build.0 = Debug|Any CPU + {84E8BA65-9A4B-4C50-A115-6EF3208E4058}.Marketplace|Any CPU.ActiveCfg = Marketplace|Any CPU + {84E8BA65-9A4B-4C50-A115-6EF3208E4058}.Marketplace|Any CPU.Build.0 = Marketplace|Any CPU {84E8BA65-9A4B-4C50-A115-6EF3208E4058}.Release|Any CPU.ActiveCfg = Release|Any CPU {84E8BA65-9A4B-4C50-A115-6EF3208E4058}.Release|Any CPU.Build.0 = Release|Any CPU + {84E8BA65-9A4B-4C50-A115-6EF3208E4058}.VsixGallery|Any CPU.ActiveCfg = VsixGallery|Any CPU + {84E8BA65-9A4B-4C50-A115-6EF3208E4058}.VsixGallery|Any CPU.Build.0 = VsixGallery|Any CPU {FBB4F3ED-B1B8-4401-8667-5180194BAA54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FBB4F3ED-B1B8-4401-8667-5180194BAA54}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FBB4F3ED-B1B8-4401-8667-5180194BAA54}.Marketplace|Any CPU.ActiveCfg = Marketplace|Any CPU + {FBB4F3ED-B1B8-4401-8667-5180194BAA54}.Marketplace|Any CPU.Build.0 = Marketplace|Any CPU {FBB4F3ED-B1B8-4401-8667-5180194BAA54}.Release|Any CPU.ActiveCfg = Release|Any CPU {FBB4F3ED-B1B8-4401-8667-5180194BAA54}.Release|Any CPU.Build.0 = Release|Any CPU + {FBB4F3ED-B1B8-4401-8667-5180194BAA54}.VsixGallery|Any CPU.ActiveCfg = VsixGallery|Any CPU + {FBB4F3ED-B1B8-4401-8667-5180194BAA54}.VsixGallery|Any CPU.Build.0 = VsixGallery|Any CPU {2A7DE186-A1FA-4BA8-B393-3CA9ECBF444F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2A7DE186-A1FA-4BA8-B393-3CA9ECBF444F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A7DE186-A1FA-4BA8-B393-3CA9ECBF444F}.Marketplace|Any CPU.ActiveCfg = Marketplace|Any CPU + {2A7DE186-A1FA-4BA8-B393-3CA9ECBF444F}.Marketplace|Any CPU.Build.0 = Marketplace|Any CPU {2A7DE186-A1FA-4BA8-B393-3CA9ECBF444F}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A7DE186-A1FA-4BA8-B393-3CA9ECBF444F}.Release|Any CPU.Build.0 = Release|Any CPU + {2A7DE186-A1FA-4BA8-B393-3CA9ECBF444F}.VsixGallery|Any CPU.ActiveCfg = VsixGallery|Any CPU + {2A7DE186-A1FA-4BA8-B393-3CA9ECBF444F}.VsixGallery|Any CPU.Build.0 = VsixGallery|Any CPU + {F16E6593-DDF9-4E9E-A2F8-56A3C43A643E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F16E6593-DDF9-4E9E-A2F8-56A3C43A643E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F16E6593-DDF9-4E9E-A2F8-56A3C43A643E}.Marketplace|Any CPU.ActiveCfg = Marketplace|Any CPU + {F16E6593-DDF9-4E9E-A2F8-56A3C43A643E}.Marketplace|Any CPU.Build.0 = Marketplace|Any CPU + {F16E6593-DDF9-4E9E-A2F8-56A3C43A643E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F16E6593-DDF9-4E9E-A2F8-56A3C43A643E}.Release|Any CPU.Build.0 = Release|Any CPU + {F16E6593-DDF9-4E9E-A2F8-56A3C43A643E}.VsixGallery|Any CPU.ActiveCfg = VsixGallery|Any CPU + {F16E6593-DDF9-4E9E-A2F8-56A3C43A643E}.VsixGallery|Any CPU.Build.0 = VsixGallery|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -72,6 +108,7 @@ Global {84E8BA65-9A4B-4C50-A115-6EF3208E4058} = {AE904AFF-1B2B-4D8F-9826-57BC13DC4AC5} {FBB4F3ED-B1B8-4401-8667-5180194BAA54} = {1DE272AA-D641-45F2-AEB9-934B3BAA6FBD} {2A7DE186-A1FA-4BA8-B393-3CA9ECBF444F} = {1DE272AA-D641-45F2-AEB9-934B3BAA6FBD} + {F16E6593-DDF9-4E9E-A2F8-56A3C43A643E} = {AE904AFF-1B2B-4D8F-9826-57BC13DC4AC5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1485240E-4A28-4FA4-8D69-3D8151C3E1F6} diff --git a/Directory.Build.props b/Directory.Build.props index 19922ea1..f8117bd5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,8 +2,16 @@ - 2.2.33 + 2.3.138 all + + + $(DefineConstants);VSIXGallery + $(DefineConstants);MARKETPLACE + $(DefineConstants);VSIX + $(DefineConstants);VSIX + + \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt index 34f2aaa5..8371b4bf 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ - Copyright © 2017 Aleksey Nagovitsyn, Stefan Kert and Tom Schmiedlechner + Copyright © 2019 Stefan Kert Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ac693dce..61b79f0b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -2,60 +2,78 @@ trigger: branches: include: - master - - develop pr: branches: include: - master - - develop - -pool: - vmImage: 'VS2017-Win2016' variables: BuildPlatform: 'Any CPU' BuildConfiguration: 'Release' -steps: -- task: DotNetCoreCLI@2 - inputs: - command: custom - custom: tool - arguments: install --tool-path . nbgv - displayName: Install NBGV tool - -- script: nbgv cloud -a - displayName: Set Version - -- task: NuGetToolInstaller@0 - -- task: NuGetCommand@2 - inputs: - restoreSolution: BuildVision.sln - -- task: MSBuild@1 - displayName: Build BuildVision.sln - inputs: - solution: BuildVision.sln - platform: $(BuildPlatform) - configuration: $(BuildConfiguration) - -- task: CopyFiles@2 - inputs: - contents: '**/bin/$(BuildConfiguration)/*.vsix' - targetFolder: $(Build.ArtifactStagingDirectory)/artifacts - flattenFolders: true - -- task: DotNetCoreCLI@2 - inputs: - command: test - projects: 'test/**/*.csproj' - arguments: -c $(BuildConfiguration) --no-build --no-restore - displayName: Run Tests - -- task: PublishBuildArtifacts@1 - inputs: - PathtoPublish: $(Build.ArtifactStagingDirectory)/artifacts - ArtifactName: artifacts - publishLocation: Container +jobs: + - job: Build + pool: + vmImage: vs2017-win2016 + strategy: + matrix: + Config_Release: + BuildConfiguration: Release + BuildOutputDirectory: Vsix + Config_Marketplace: + BuildConfiguration: Marketplace + BuildOutputDirectory: Marketplace + Config_VSIXGallery: + BuildConfiguration: VsixGallery + BuildOutputDirectory: VsixGallery + + steps: + - task: DotNetCoreCLI@2 + inputs: + command: custom + custom: tool + arguments: install --tool-path . nbgv + displayName: Install NBGV tool + continueOnError: true + + - powershell: | + mkdir $(Build.ArtifactStagingDirectory)\$(BuildOutputDirectory) + + - script: nbgv cloud -a + displayName: Set Version + + - task: VisualStudioTestPlatformInstaller@1 + displayName: VsTest Platform Installer + + - task: NuGetToolInstaller@0 + + - task: NuGetCommand@2 + inputs: + restoreSolution: BuildVision.sln + + - task: MSBuild@1 + displayName: Build BuildVision.sln + inputs: + solution: BuildVision.sln + platform: $(BuildPlatform) + configuration: $(BuildConfiguration) + + - task: CopyFiles@2 + inputs: + contents: '**/bin/$(BuildConfiguration)/*.vsix' + targetFolder: $(Build.ArtifactStagingDirectory)/$(BuildOutputDirectory) + flattenFolders: true + + - task: DotNetCoreCLI@2 + inputs: + command: test + projects: 'test/**/BuildVision.UnitTests.csproj' + arguments: -c $(BuildConfiguration) --no-build --no-restore + displayName: Run Unittests + + - task: PublishBuildArtifacts@1 + inputs: + PathtoPublish: $(Build.ArtifactStagingDirectory)/$(BuildOutputDirectory) + ArtifactName: $(BuildOutputDirectory) + publishLocation: Container \ No newline at end of file diff --git a/libs/2017/Microsoft.VSSDK.TestHostFramework.dll b/libs/2017/Microsoft.VSSDK.TestHostFramework.dll new file mode 100644 index 00000000..9ad0b181 Binary files /dev/null and b/libs/2017/Microsoft.VSSDK.TestHostFramework.dll differ diff --git a/libs/2017/Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll b/libs/2017/Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll new file mode 100644 index 00000000..4f1fa2e7 Binary files /dev/null and b/libs/2017/Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll differ diff --git a/libs/2017/Microsoft.VisualStudioTools.VSTestHost.15.0.dll b/libs/2017/Microsoft.VisualStudioTools.VSTestHost.15.0.dll new file mode 100644 index 00000000..03fdd043 Binary files /dev/null and b/libs/2017/Microsoft.VisualStudioTools.VSTestHost.15.0.dll differ diff --git a/src/BuildVision.Common/AppVersionInfo.cs b/src/BuildVision.Common/AppVersionInfo.cs index 1b98f9c5..b5707524 100644 --- a/src/BuildVision.Common/AppVersionInfo.cs +++ b/src/BuildVision.Common/AppVersionInfo.cs @@ -1,6 +1,8 @@ -using System; +using System; +using System.Diagnostics; using System.IO; using System.Reflection; +using System.Runtime.InteropServices; namespace BuildVision.Common { @@ -8,47 +10,14 @@ public class AppVersionInfo { public string AppVersion { get; set; } public string BuildVersion { get; set; } - public DateTime BuildDateTime { get; set; } public AppVersionInfo() { - Assembly assembly = Assembly.GetExecutingAssembly(); - AssemblyName assemblyName = assembly.GetName(); - Version version = assemblyName.Version; + var assembly = Assembly.GetExecutingAssembly(); + var versionInfo = FileVersionInfo.GetVersionInfo(assembly.Location); - AppVersion = version.ToString(3); - BuildVersion = version.ToString(4); - BuildDateTime = RetrieveLinkerTimestamp(assembly); - } - - /// - /// Get last build datetime. - /// - private static DateTime RetrieveLinkerTimestamp(Assembly assembly) - { - string filePath = assembly.Location; - const int PeHeaderOffset = 60; - const int LinkerTimestampOffset = 8; - var buffer = new byte[2048]; - Stream stream = null; - - try - { - stream = new FileStream(filePath, FileMode.Open, FileAccess.Read); - stream.Read(buffer, 0, 2048); - } - finally - { - if (stream != null) - stream.Close(); - } - - int i = BitConverter.ToInt32(buffer, PeHeaderOffset); - int secondsSince1970 = BitConverter.ToInt32(buffer, i + LinkerTimestampOffset); - var dt = new DateTime(1970, 1, 1, 0, 0, 0); - dt = dt.AddSeconds(secondsSince1970); - dt = dt.AddHours(TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours); - return dt; + AppVersion = versionInfo.ProductVersion.ToString(); + BuildVersion = new Version(versionInfo.FileVersion).ToString(); } } } diff --git a/src/BuildVision.Common/ApplicationInfo.cs b/src/BuildVision.Common/ApplicationInfo.cs new file mode 100644 index 00000000..78e92de3 --- /dev/null +++ b/src/BuildVision.Common/ApplicationInfo.cs @@ -0,0 +1,28 @@ +using System; +using System.Diagnostics; +using System.Reflection; + +namespace BuildVision.Common +{ + public static class ApplicationInfo + { + public const string ApplicationName = "BuildVision"; + + public static FileVersionInfo GetHostVersionInfo() + { + return Process.GetCurrentProcess().MainModule.FileVersionInfo; + } + + public static string GetPackageVersion(object package) + { + var versionInfo = FileVersionInfo.GetVersionInfo(package.GetType().Assembly.Location); + return versionInfo.ProductVersion; + } + + public static string GetProductVersion() + { + var versionInfo = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location); + return versionInfo.ProductVersion; + } + } +} diff --git a/src/BuildVision.Common/BindableBase.cs b/src/BuildVision.Common/BindableBase.cs index 5efa5848..5d2ecec8 100644 --- a/src/BuildVision.Common/BindableBase.cs +++ b/src/BuildVision.Common/BindableBase.cs @@ -11,7 +11,9 @@ public abstract class BindableBase : INotifyPropertyChanged public virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null) { if (Equals(storage, value)) + { return false; + } storage = value; OnPropertyChanged(propertyName); @@ -19,12 +21,14 @@ public virtual bool SetProperty(ref T storage, T value, [CallerMemberName] st return true; } - public virtual bool SetProperty(Func storage, Action set, T value, [CallerMemberName] string propertyName = null) + public virtual bool SetProperty(Func storage, Action setAction, T value, [CallerMemberName] string propertyName = null) { if (Equals(storage(), value)) + { return false; + } - set(value); + setAction(value); OnPropertyChanged(propertyName); return true; diff --git a/src/BuildVision.Common/BuildVision.Common.csproj b/src/BuildVision.Common/BuildVision.Common.csproj index 4f779ccd..de2843bf 100644 --- a/src/BuildVision.Common/BuildVision.Common.csproj +++ b/src/BuildVision.Common/BuildVision.Common.csproj @@ -1,80 +1,35 @@ - - - + - Debug - AnyCPU - {848412D1-95BF-4E56-A9EF-2926AF5C6D67} - Library - Properties - BuildVision.Common - BuildVision.Common - v4.7.2 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - true + net472 + Debug;Release;Marketplace;VsixGallery + Key.snk + true + - - - - - - - - - - - + + - - - - - - - - - - - - - - - - + + + + + + + + - + + + - - {13D64A57-5DB3-4CC7-AC2B-9034E767D754} - BuildVision.Contracts - + - + \ No newline at end of file diff --git a/src/BuildVision.Common/CustomStringFormatProvider.cs b/src/BuildVision.Common/CustomStringFormatProvider.cs index 73909163..0703ede6 100644 --- a/src/BuildVision.Common/CustomStringFormatProvider.cs +++ b/src/BuildVision.Common/CustomStringFormatProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace BuildVision.Common { @@ -19,11 +19,13 @@ public object GetFormat(Type formatType) public string Format(string format, object arg, IFormatProvider formatProvider) { if (arg == null) + { return null; + } if (format != null && arg is string) { - var strArg = (string) arg; + var strArg = (string)arg; switch (format.ToUpper()) { case "U": @@ -34,7 +36,7 @@ public string Format(string format, object arg, IFormatProvider formatProvider) } return arg is IFormattable - ? ((IFormattable) arg).ToString(format, formatProvider) + ? ((IFormattable)arg).ToString(format, formatProvider) : arg.ToString(); } } diff --git a/src/BuildVision.Common/Diagnostics/DiagnosticsClient.cs b/src/BuildVision.Common/Diagnostics/DiagnosticsClient.cs new file mode 100644 index 00000000..1ab889ff --- /dev/null +++ b/src/BuildVision.Common/Diagnostics/DiagnosticsClient.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using Microsoft.ApplicationInsights; +using Microsoft.ApplicationInsights.Extensibility; + +namespace BuildVision.Common.Diagnostics +{ + public static class DiagnosticsClient + { + private static bool _initialized; + private static TelemetryClient _client; + + public static bool ParticipateInTelemetry { get; set; } = true; + + public static void Initialize(string edition, string vsVersion, string apiKey) + { + if (!string.IsNullOrWhiteSpace(apiKey)) + { + TelemetryConfiguration.Active.InstrumentationKey = apiKey; + TelemetryConfiguration.Active.TelemetryChannel.DeveloperMode = Debugger.IsAttached; + TelemetryConfiguration.Active.TelemetryInitializers.Add(new VersionTelemetry()); + TelemetryConfiguration.Active.TelemetryInitializers.Add(new SessionTelemetry(vsVersion, edition)); + + _initialized = true; + _client = new TelemetryClient(); + } + } + + public static void Flush() + { + if (!_initialized || !ParticipateInTelemetry) + { + return; + } + + _client.Flush(); + // Allow time for flushing: + System.Threading.Thread.Sleep(1000); + } + + public static void TrackEvent(string eventName, IDictionary properties = null, IDictionary metrics = null) + { + if (!_initialized || !ParticipateInTelemetry) + { + return; + } + + _client.TrackEvent(eventName, properties, metrics); + } + + public static void TrackTrace(string trace) + { + if (!_initialized || !ParticipateInTelemetry) + { + return; + } + + _client.TrackTrace(trace); + } + + public static void TrackException(Exception exception) + { + if (!_initialized || !ParticipateInTelemetry) + { + return; + } + + _client.TrackException(exception); + } + + public static void TrackPageView(string pageName) + { + if (!_initialized || !ParticipateInTelemetry) + { + return; + } + + _client.TrackPageView(pageName); + } + } +} diff --git a/src/BuildVision.Common/Diagnostics/SessionTelemetry.cs b/src/BuildVision.Common/Diagnostics/SessionTelemetry.cs new file mode 100644 index 00000000..fc4fac9b --- /dev/null +++ b/src/BuildVision.Common/Diagnostics/SessionTelemetry.cs @@ -0,0 +1,70 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Security.Cryptography; +using System.Text; +using Microsoft.ApplicationInsights.Channel; +using Microsoft.ApplicationInsights.Extensibility; + +namespace BuildVision.Common.Diagnostics +{ + class SessionTelemetry : ITelemetryInitializer + { + private readonly string _userName; + private readonly string _operatingSystem = RuntimeInformation.OSDescription?.Replace("Microsoft ", ""); // Shorter description + private readonly string _session = Guid.NewGuid().ToString(); + private readonly string _vsVersion; + private readonly string _dteEdition; + +#if VSIXGallery + private const string Channel = "vsixgallery"; +#elif MARKETPLACE + private const string Channel = "marketplace"; +#elif VSIX + private const string Channel = "vsix"; +#else + private const string Channel = "vsix"; +#endif + + public SessionTelemetry(string vsVersion, string dteEdition) + { + try + { + using (var hash = SHA256.Create()) + { + var hashBytes = hash.ComputeHash(Encoding.UTF8.GetBytes(Environment.MachineName + Environment.UserDomainName + Environment.UserName)); + _userName = Convert.ToBase64String(hashBytes); + } + } + catch + { + // No user id + } + + _vsVersion = vsVersion; + _dteEdition = dteEdition; + } + + public void Initialize(ITelemetry telemetry) + { + telemetry.Context.GlobalProperties["Environment"] = Channel; + // Always default to development if we're in the debugger + if (Debugger.IsAttached) + { + telemetry.Context.GlobalProperties["Environment"] = "development"; + } + + if (_userName != null) + { + telemetry.Context.User.Id = _userName; + } + + telemetry.Context.Session.Id = _session; + telemetry.Context.Device.OperatingSystem = _operatingSystem; + telemetry.Context.Cloud.RoleInstance = ""; + telemetry.Context.Cloud.RoleName = ""; + telemetry.Context.Device.Model = _vsVersion; + telemetry.Context.Device.Type = _dteEdition; + } + } +} diff --git a/src/BuildVision.Common/Diagnostics/VersionTelemetry.cs b/src/BuildVision.Common/Diagnostics/VersionTelemetry.cs new file mode 100644 index 00000000..1fcc320f --- /dev/null +++ b/src/BuildVision.Common/Diagnostics/VersionTelemetry.cs @@ -0,0 +1,27 @@ +using System; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using Microsoft.ApplicationInsights.Channel; +using Microsoft.ApplicationInsights.Extensibility; + +namespace BuildVision.Common.Diagnostics +{ + class VersionTelemetry : ITelemetryInitializer + { + private readonly string _appVersion; + + public VersionTelemetry() + { + var assembly = Assembly.GetExecutingAssembly(); + var versionInfo = FileVersionInfo.GetVersionInfo(assembly.Location); + + _appVersion = versionInfo.ProductVersion.ToString(); + } + + public void Initialize(ITelemetry telemetry) + { + telemetry.Context.Component.Version = _appVersion; + } + } +} diff --git a/src/BuildVision.Common/Extensions/DateTimeExtensions.cs b/src/BuildVision.Common/Extensions/DateTimeExtensions.cs index 6d15ea35..6d789e96 100644 --- a/src/BuildVision.Common/Extensions/DateTimeExtensions.cs +++ b/src/BuildVision.Common/Extensions/DateTimeExtensions.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BuildVision.Common.Extensions { @@ -10,9 +6,7 @@ public static class DateTimeExtensions { public static DateTime Truncate(this DateTime dateTime, TimeSpan timeSpan) { - if (timeSpan <= TimeSpan.Zero) - return dateTime; - return dateTime.AddTicks(-(dateTime.Ticks % timeSpan.Ticks)); + return timeSpan <= TimeSpan.Zero ? dateTime : dateTime.AddTicks(-(dateTime.Ticks % timeSpan.Ticks)); } } } diff --git a/src/BuildVision.Common/FilePathHelper.cs b/src/BuildVision.Common/FilePathHelper.cs index d7c52811..12e72f8c 100644 --- a/src/BuildVision.Common/FilePathHelper.cs +++ b/src/BuildVision.Common/FilePathHelper.cs @@ -120,7 +120,7 @@ public static string ShortenPath(string path, int maxLength) } } - if (lastPart == "") + if (string.IsNullOrEmpty(lastPart)) { //the filename (and root path) in itself was longer than maxLength, shorten it lastPart = pathParts[pathParts.Length - 1];//"pathParts[pathParts.Length -1]" is the equivalent of "Path.GetFileName(pathToShorten)" diff --git a/src/BuildVision.Common/GenericXmlSerializer.cs b/src/BuildVision.Common/GenericXmlSerializer.cs index 49e70b00..c0a2ea2a 100644 --- a/src/BuildVision.Common/GenericXmlSerializer.cs +++ b/src/BuildVision.Common/GenericXmlSerializer.cs @@ -1,5 +1,4 @@ -using System; -using System.IO; +using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; diff --git a/src/BuildVision.Common/GithubHelper.cs b/src/BuildVision.Common/GithubHelper.cs index feb9821e..b6679ac6 100644 --- a/src/BuildVision.Common/GithubHelper.cs +++ b/src/BuildVision.Common/GithubHelper.cs @@ -1,15 +1,12 @@ -using BuildVision.Common; -using System; -using System.Collections.Generic; +using System; using System.Diagnostics; -using System.Linq; +using System.Globalization; using System.Net; -using System.Text; -using System.Threading.Tasks; +using BuildVision.Common; namespace BuildVision.Helpers { - public class GithubHelper + public static class GithubHelper { const string ASSIGNEE = "stefankert"; const string URL_TEMPLATE = "https://github.com/StefanKert/BuildVision/issues/new?labels={0}&title={1}&assignee={2}&body={3}"; @@ -28,13 +25,13 @@ public static void OpenBrowserWithPrefilledIssue() { var appVersion = new AppVersionInfo(); - var url = GetUrlForNewBug(string.Format(template, VsVersion.FullVersion, appVersion.BuildVersion, Environment.OSVersion)); - Process.Start(new ProcessStartInfo(url)); + var url = GetUrlForNewBug(string.Format(CultureInfo.CurrentCulture, template, VsVersion.FullVersion, appVersion.BuildVersion, Environment.OSVersion)); + Process.Start(new ProcessStartInfo(url.ToString())); } - public static string GetUrlForNewBug(string body) + public static Uri GetUrlForNewBug(string body) { - return string.Format(URL_TEMPLATE, "Bug", "", ASSIGNEE, WebUtility.UrlEncode(body)); + return new Uri(string.Format(CultureInfo.CurrentCulture, URL_TEMPLATE, "Bug", "", ASSIGNEE, WebUtility.UrlEncode(body))); } } } diff --git a/src/BuildVision.Common/Logging/ILoggerExtensions.cs b/src/BuildVision.Common/Logging/ILoggerExtensions.cs new file mode 100644 index 00000000..7e5490e1 --- /dev/null +++ b/src/BuildVision.Common/Logging/ILoggerExtensions.cs @@ -0,0 +1,64 @@ +using System; +using System.Globalization; +using System.Threading.Tasks; +using Serilog; + +namespace BuildVision.Common.Logging +{ + public static class ILoggerExtensions + { + public static void Assert(this ILogger logger, bool condition, string messageTemplate) + { + if (!condition) + { + messageTemplate = "Assertion Failed: " + messageTemplate; +#pragma warning disable Serilog004 // propertyValues might not be strings + logger.Warning(messageTemplate); +#pragma warning restore Serilog004 + } + } + + public static void Assert(this ILogger logger, bool condition, string messageTemplate, params object[] propertyValues) + { + if (!condition) + { + messageTemplate = "Assertion Failed: " + messageTemplate; +#pragma warning disable Serilog004 // propertyValues might not be strings + logger.Warning(messageTemplate, propertyValues); +#pragma warning restore Serilog004 + } + } + + public static void Time(this ILogger logger, string name, Action method) + { + var startTime = DateTime.Now; + method(); + logger.Verbose("{Name} took {Seconds} seconds", name, FormatSeconds(DateTime.Now - startTime)); + } + + public static T Time(this ILogger logger, string name, Func method) + { + var startTime = DateTime.Now; + var value = method(); + logger.Verbose("{Name} took {Seconds} seconds", name, FormatSeconds(DateTime.Now - startTime)); + return value; + } + + public static async Task TimeAsync(this ILogger logger, string name, Func methodAsync) + { + var startTime = DateTime.Now; + await methodAsync().ConfigureAwait(false); + logger.Verbose("{Name} took {Seconds} seconds", name, FormatSeconds(DateTime.Now - startTime)); + } + + public static async Task TimeAsync(this ILogger logger, string name, Func> methodAsync) + { + var startTime = DateTime.Now; + var value = await methodAsync().ConfigureAwait(false); + logger.Verbose("{Name} took {Seconds} seconds", name, FormatSeconds(DateTime.Now - startTime)); + return value; + } + + static string FormatSeconds(TimeSpan timeSpan) => timeSpan.TotalSeconds.ToString("0.##", CultureInfo.InvariantCulture); + } +} diff --git a/src/BuildVision.Common/Logging/LogManager.cs b/src/BuildVision.Common/Logging/LogManager.cs new file mode 100644 index 00000000..c224f6a6 --- /dev/null +++ b/src/BuildVision.Common/Logging/LogManager.cs @@ -0,0 +1,56 @@ +using System; +using System.IO; +using Serilog; +using Serilog.Core; +using Serilog.Events; + +namespace BuildVision.Common.Logging +{ + public static class LogManager + { +#if DEBUG + private static LogEventLevel DefaultLoggingLevel = LogEventLevel.Debug; +#else + private static LogEventLevel DefaultLoggingLevel = LogEventLevel.Information; +#endif + + private static LoggingLevelSwitch LoggingLevelSwitch = new LoggingLevelSwitch(DefaultLoggingLevel); + + static Logger CreateLogger() + { + var logPath = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + ApplicationInfo.ApplicationName, + "extension.log"); + + const string outputTemplate = + "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{ProcessId:00000}] {Level:u4} [{ThreadId:00}] {ShortSourceContext,-25} {Message:lj}{NewLine}{Exception}"; + + return new LoggerConfiguration() + .Enrich.WithProcessId() + .Enrich.WithThreadId() + .MinimumLevel.ControlledBy(LoggingLevelSwitch) + .WriteTo.File(logPath, + fileSizeLimitBytes: null, + outputTemplate: outputTemplate, + shared: true) + .CreateLogger(); + } + + public static void EnableTraceLogging(bool enable) + { + var logEventLevel = enable ? LogEventLevel.Verbose : DefaultLoggingLevel; + if (LoggingLevelSwitch.MinimumLevel != logEventLevel) + { + ForContext(typeof(LogManager)).Information("Set Logging Level: {LogEventLevel}", logEventLevel); + LoggingLevelSwitch.MinimumLevel = logEventLevel; + } + } + + static Lazy Logger { get; } = new Lazy(CreateLogger); + + public static ILogger ForContext() => ForContext(typeof(T)); + + public static ILogger ForContext(Type type) => Logger.Value.ForContext(type).ForContext("ShortSourceContext", type.Name); + } +} diff --git a/src/BuildVision.Common/ObservableCollectionExtensions.cs b/src/BuildVision.Common/ObservableCollectionExtensions.cs deleted file mode 100644 index 98f2b01a..00000000 --- a/src/BuildVision.Common/ObservableCollectionExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Collections.Generic; -using System.Collections.ObjectModel; - -namespace BuildVision.Common -{ - public static class ObservableCollectionExtensions - { - public static void AddRange(this ObservableCollection collection, IEnumerable range) - { - foreach (T item in range) - { - collection.Add(item); - } - } - } -} diff --git a/src/BuildVision.Common/Properties/AssemblyInfo.cs b/src/BuildVision.Common/Properties/AssemblyInfo.cs deleted file mode 100644 index 4d3afc79..00000000 --- a/src/BuildVision.Common/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using BuildVision; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("BuildVision.Common")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("BuildVision.Common")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("848412d1-95bf-4e56-a9ef-2926af5c6d67")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] diff --git a/src/BuildVision.Common/Properties/GlobalSuppressions.cs b/src/BuildVision.Common/Properties/GlobalSuppressions.cs new file mode 100644 index 00000000..f29fc8c0 --- /dev/null +++ b/src/BuildVision.Common/Properties/GlobalSuppressions.cs @@ -0,0 +1,6 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.Common.FilePathHelper.ShortenPath(System.String,System.Int32)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:BuildVision.Common.Diagnostics.SessionTelemetry.#ctor")] diff --git a/src/BuildVision.Common/PropertyColumnSorter.cs b/src/BuildVision.Common/PropertyColumnSorter.cs deleted file mode 100644 index f5c69e67..00000000 --- a/src/BuildVision.Common/PropertyColumnSorter.cs +++ /dev/null @@ -1,44 +0,0 @@ -using BuildVision.Contracts; -using System; -using System.Collections; -using System.ComponentModel; -using System.Reflection; - -namespace BuildVision.Common -{ - public class PropertyColumnSorter : IComparer - where T : class - { - private readonly int _direction; - private readonly PropertyInfo _propertyInfo; - - public PropertyColumnSorter(ListSortDirection direction, string propertyName) - { - _direction = (direction == ListSortDirection.Ascending) ? 1 : -1; - _propertyInfo = typeof(T).GetProperty(propertyName); - - if (_propertyInfo == null) - throw new PropertyNotFoundException(propertyName, typeof(T)); - } - - int IComparer.Compare(object x, object y) - { - return Compare((T) x, (T) y); - } - - protected int Compare(T x, T y) - { - var x1 = _propertyInfo.GetValue(x, null) as IComparable; - var y1 = _propertyInfo.GetValue(y, null) as IComparable; - - if (x1 != null && y1 != null) - return x1.CompareTo(y1) * _direction; - - if (x1 == null && y1 == null) - return 0; - - // Null values always in the bottom. - return (x1 == null) ? 1 : -1; - } - } -} diff --git a/src/BuildVision.Common/RelayCommand.cs b/src/BuildVision.Common/RelayCommand.cs index cec77435..3d8c3080 100644 --- a/src/BuildVision.Common/RelayCommand.cs +++ b/src/BuildVision.Common/RelayCommand.cs @@ -32,10 +32,7 @@ public RelayCommand(Action execute) /// The execution status logic. public RelayCommand(Action execute, Predicate canExecute) { - if (execute == null) - throw new ArgumentNullException("execute"); - - _execute = execute; + _execute = execute ?? throw new ArgumentNullException(nameof(execute)); _canExecute = canExecute; } diff --git a/src/BuildVision.Common/SettingsBase.cs b/src/BuildVision.Common/SettingsBase.cs index da0a4cb9..ec4f5e96 100644 --- a/src/BuildVision.Common/SettingsBase.cs +++ b/src/BuildVision.Common/SettingsBase.cs @@ -14,7 +14,9 @@ public void InitFrom(T source) where T : SettingsBase { PropertyInfo[] properties = typeof(T).GetProperties(); foreach (var property in properties) + { property.SetValue(this, property.GetValue(source, null), null); + } } } } diff --git a/src/BuildVision.Common/VSVersion.cs b/src/BuildVision.Common/VSVersion.cs index 79bccd8f..47bd2d92 100644 --- a/src/BuildVision.Common/VSVersion.cs +++ b/src/BuildVision.Common/VSVersion.cs @@ -8,7 +8,6 @@ public static class VsVersion { static readonly object mLock = new object(); static Version mVsVersion; - static Version mOsVersion; public static Version FullVersion { @@ -37,28 +36,14 @@ public static Version FullVersion mVsVersion = new Version(verName); } else + { mVsVersion = new Version(0, 0); // Not running inside Visual Studio! + } } } return mVsVersion; } } - - public static Version OSVersion => mOsVersion ?? (mOsVersion = Environment.OSVersion.Version); - - public static bool VS2012OrLater => FullVersion >= new Version(11, 0); - - public static bool VS2010OrLater => FullVersion >= new Version(10, 0); - - public static bool VS2008OrOlder => FullVersion < new Version(9, 0); - - public static bool VS2005 => FullVersion.Major == 8; - - public static bool VS2008 => FullVersion.Major == 9; - - public static bool VS2010 => FullVersion.Major == 10; - - public static bool VS2012 => FullVersion.Major == 11; } } diff --git a/src/BuildVision.Common/ViewCommandEventArgs.cs b/src/BuildVision.Common/ViewCommandEventArgs.cs deleted file mode 100644 index 62aa45bc..00000000 --- a/src/BuildVision.Common/ViewCommandEventArgs.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace BuildVision.Common -{ - public class ViewCommandEventArgs : EventArgs - { - public string Command { get; } - - public object Response { get; set; } - - public ViewCommandEventArgs(string command) - { - Command = command; - } - } -} diff --git a/src/BuildVision.Contracts/BaseGridColumnSettings.cs b/src/BuildVision.Contracts/BaseGridColumnSettings.cs deleted file mode 100644 index 81e58925..00000000 --- a/src/BuildVision.Contracts/BaseGridColumnSettings.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace BuildVision.Contracts -{ - public abstract class BaseGridColumnSettingsAttribute : Attribute - { - public string Header { get; set; } - - public bool Visible { get; set; } - - /// - /// -1 for auto. - /// - public int DisplayIndex { get; set; } - - /// - /// double.NaN for auto. - /// - public double Width { get; set; } - - public string ValueStringFormat { get; set; } - - protected BaseGridColumnSettingsAttribute() - { - Width = double.NaN; - DisplayIndex = -1; - Visible = true; - } - } -} diff --git a/src/BuildVision.Contracts/BuildErrorRaisedEventArgs.cs b/src/BuildVision.Contracts/BuildErrorRaisedEventArgs.cs index 95112bcc..9b837ba5 100644 --- a/src/BuildVision.Contracts/BuildErrorRaisedEventArgs.cs +++ b/src/BuildVision.Contracts/BuildErrorRaisedEventArgs.cs @@ -1,16 +1,17 @@ -using System; +using System; +using BuildVision.UI.Models; namespace BuildVision.Contracts { public class BuildErrorRaisedEventArgs : EventArgs { public ErrorLevel ErrorLevel { get; private set; } - public BuildedProject ProjectInfo { get; private set; } + public IProjectItem ProjectInfo { get; private set; } - public BuildErrorRaisedEventArgs(ErrorLevel errorLevel, BuildedProject projectInfo) + public BuildErrorRaisedEventArgs(ErrorLevel errorLevel, IProjectItem projectInfo) { ErrorLevel = errorLevel; ProjectInfo = projectInfo; } } -} \ No newline at end of file +} diff --git a/src/BuildVision.Contracts/BuildOutputFileTypes.cs b/src/BuildVision.Contracts/BuildOutputFileTypes.cs index 73f4f4f6..64e8e0f5 100644 --- a/src/BuildVision.Contracts/BuildOutputFileTypes.cs +++ b/src/BuildVision.Contracts/BuildOutputFileTypes.cs @@ -1,70 +1,62 @@ -using System.Runtime.Serialization; - -namespace BuildVision.Contracts +namespace BuildVision.Contracts { - /// - /// See https://msdn.microsoft.com/en-us/library/Microsoft.VisualStudio.Shell.Interop.BuildOutputGroup.aspx - /// - public class BuildOutputFileTypes - { - /// - /// Represents localized resource DLLs in an output group. - /// - public bool LocalizedResourceDlls { get; set; } - - /// - /// XML-serializer assemblies. - /// - public bool XmlSerializer { get; set; } - - /// - /// Represents content files in an output group. - /// - public bool ContentFiles { get; set; } - - /// - /// Represents built files in an output group. - /// - public bool Built { get; set; } - - /// - /// Represents source code files in an output group. - /// - public bool SourceFiles { get; set; } - - /// - /// Represents a list of symbols in an output group. - /// - public bool Symbols { get; set; } - - /// - /// Represents documentation files in an output group. - /// - public bool Documentation { get; set; } - - /// - /// Checks whether all properties is false. - /// - public bool IsEmpty - { - get - { - return !(LocalizedResourceDlls - || XmlSerializer - || ContentFiles - || Built - || SourceFiles - || Symbols - || Documentation); - } - } - - public BuildOutputFileTypes() + /// + /// See https://msdn.microsoft.com/en-us/library/Microsoft.VisualStudio.Shell.Interop.BuildOutputGroup.aspx + /// + public class BuildOutputFileTypes { - LocalizedResourceDlls = true; - Built = true; - Symbols = true; - Documentation = true; + /// + /// Represents localized resource DLLs in an output group. + /// + public bool LocalizedResourceDlls { get; set; } + + /// + /// XML-serializer assemblies. + /// + public bool XmlSerializer { get; set; } + + /// + /// Represents content files in an output group. + /// + public bool ContentFiles { get; set; } + + /// + /// Represents built files in an output group. + /// + public bool Built { get; set; } + + /// + /// Represents source code files in an output group. + /// + public bool SourceFiles { get; set; } + + /// + /// Represents a list of symbols in an output group. + /// + public bool Symbols { get; set; } + + /// + /// Represents documentation files in an output group. + /// + public bool Documentation { get; set; } + + /// + /// Checks whether all properties is false. + /// + public bool IsEmpty => !(LocalizedResourceDlls + || XmlSerializer + || ContentFiles + || Built + || SourceFiles + || Symbols + || Documentation); + + public BuildOutputFileTypes() + { + LocalizedResourceDlls = true; + Built = true; + Symbols = true; + Documentation = true; + } } - } -} \ No newline at end of file +} diff --git a/src/BuildVision.Contracts/BuildVision.Contracts.csproj b/src/BuildVision.Contracts/BuildVision.Contracts.csproj index ae2b2b0f..2d804ff4 100644 --- a/src/BuildVision.Contracts/BuildVision.Contracts.csproj +++ b/src/BuildVision.Contracts/BuildVision.Contracts.csproj @@ -1,74 +1,25 @@ - - - + - Debug - AnyCPU - {13D64A57-5DB3-4CC7-AC2B-9034E767D754} - Library - Properties - BuildVision.Contracts - BuildVision.Contracts - v4.7.2 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - true + net472 + Debug;Release;Marketplace;VsixGallery + Key.snk + true + - - - - - - - - - + + - - - - - - - - - - - - - - - - - - + + - + + - + \ No newline at end of file diff --git a/src/BuildVision.Contracts/BuildedProject.cs b/src/BuildVision.Contracts/BuildedProject.cs deleted file mode 100644 index 6b52d106..00000000 --- a/src/BuildVision.Contracts/BuildedProject.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace BuildVision.Contracts -{ - public class BuildedProject - { - public string UniqueName { get; set; } - - public string FileName { get; set; } - - public string Configuration { get; set; } - - public string Platform { get; set; } - - public bool? Success { get; set; } - - public ErrorsBox ErrorsBox { get; set; } - - public ProjectState ProjectState { get; set; } - - public BuildedProject(string uniqueProjectName, string fileName, string configuration, string platform) - { - UniqueName = uniqueProjectName; - FileName = fileName; - Configuration = configuration; - Platform = platform; - Success = null; - ErrorsBox = new ErrorsBox(); - } - } -} diff --git a/src/BuildVision.Contracts/BuildedSolution.cs b/src/BuildVision.Contracts/BuildedSolution.cs deleted file mode 100644 index 6c31ffac..00000000 --- a/src/BuildVision.Contracts/BuildedSolution.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.IO; - -namespace BuildVision.Contracts -{ - public class BuildedSolution - { - public string FullName { get; set; } - - public string Name { get; set; } - - public BuildedSolution(string fullName, string fileName) - { - FullName = fullName; - Name = Path.GetFileNameWithoutExtension(fileName); - } - } -} \ No newline at end of file diff --git a/src/BuildVision.Contracts/Enums/BuildActions.cs b/src/BuildVision.Contracts/Enums/BuildActions.cs index 943ab442..b1078a2e 100644 --- a/src/BuildVision.Contracts/Enums/BuildActions.cs +++ b/src/BuildVision.Contracts/Enums/BuildActions.cs @@ -1,16 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BuildVision.Contracts +namespace BuildVision.Contracts { - public enum BuildActions + public enum BuildAction { - BuildActionBuild = 1, - BuildActionRebuildAll = 2, - BuildActionClean = 3, - BuildActionDeploy = 4 + Build = 1, + RebuildAll = 2, + Clean = 3, + Deploy = 4, + Unknown = 5 } } diff --git a/src/BuildVision.Contracts/Enums/BuildResultState.cs b/src/BuildVision.Contracts/Enums/BuildResultState.cs new file mode 100644 index 00000000..dd6ba1c2 --- /dev/null +++ b/src/BuildVision.Contracts/Enums/BuildResultState.cs @@ -0,0 +1,22 @@ +namespace BuildVision.Contracts +{ + public enum BuildResultState + { + Unknown, + + RebuildDone, + RebuildErrorDone, + RebuildFailed, + RebuildCancelled, + + BuildDone, + BuildErrorDone, + BuildFailed, + BuildCancelled, + + CleanDone, + CleanErrorDone, + CleanFailed, + CleanCancelled + } +} diff --git a/src/BuildVision.Contracts/Enums/BuildScopes.cs b/src/BuildVision.Contracts/Enums/BuildScopes.cs index 304f2bc8..0a762b7f 100644 --- a/src/BuildVision.Contracts/Enums/BuildScopes.cs +++ b/src/BuildVision.Contracts/Enums/BuildScopes.cs @@ -1,9 +1,10 @@ namespace BuildVision.Contracts { - public enum BuildScopes + public enum BuildScope { - BuildScopeSolution = 1, - BuildScopeBatch = 2, - BuildScopeProject = 3 + Solution = 1, + Batch = 2, + Project = 3, + Unknown = 4 } } diff --git a/src/BuildVision.Contracts/Enums/BuildState.cs b/src/BuildVision.Contracts/Enums/BuildState.cs index cda71fff..8d06213e 100644 --- a/src/BuildVision.Contracts/Enums/BuildState.cs +++ b/src/BuildVision.Contracts/Enums/BuildState.cs @@ -4,6 +4,9 @@ public enum BuildState { NotStarted = 0, InProgress = 1, - Done = 2 + Done = 2, + Cancelled = 3, + Failed = 4, + ErrorDone = 5 } -} \ No newline at end of file +} diff --git a/src/BuildVision.Contracts/Enums/ProjectState.cs b/src/BuildVision.Contracts/Enums/ProjectState.cs index 145b7c61..bf3677da 100644 --- a/src/BuildVision.Contracts/Enums/ProjectState.cs +++ b/src/BuildVision.Contracts/Enums/ProjectState.cs @@ -2,6 +2,7 @@ { public enum ProjectState { + None, Pending, Skipped, BuildCancelled, @@ -14,4 +15,4 @@ public enum ProjectState CleanError, BuildWarning } -} \ No newline at end of file +} diff --git a/src/BuildVision.Contracts/ErrorItem.cs b/src/BuildVision.Contracts/ErrorItem.cs deleted file mode 100644 index 9b95c7f2..00000000 --- a/src/BuildVision.Contracts/ErrorItem.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; - -namespace BuildVision.Contracts -{ - public class ErrorItem - { - public const string DefaultSortPropertyName = "Number"; - private readonly List _invalidFileNames = new List { "CSC", "MSBUILD", "LINK" }; - - public bool CanNavigateTo { get; set; } - - public int? Number { get; set; } - - public ErrorLevel Level { get; set; } - - public string Code { get; set; } - - public string File { get; set; } - - public string FileName - { - get - { - try - { - return Path.GetFileName(File); - } - catch (ArgumentException) - { - return File; - } - } - } - - public string ProjectFile { get; set; } - - public int LineNumber { get; set; } - public int ColumnNumber { get; set; } - - public int EndLineNumber { get; set; } - - public int EndColumnNumber { get; set; } - - public string Subcategory { get; set; } - - public string Message { get; set; } - - public Action GoToError { get; } - - public ErrorItem(ErrorLevel errorLevel, Action goToError) - { - Level = errorLevel; - GoToError = () => goToError(this); - } - - public ErrorItem() { } - - // 1. EnvDTE.TextSelection.MoveToLineAndOffset requires line and offset numbers beginning at one. - // BuildErrorEventArgs.LineNumber and BuildErrorEventArgs.ColumnNumber may be uninitialized. - // 2. BuildErrorEventArgs.EndLineNumber and BuildErrorEventArgs.EndColumnNumber may be uninitialized, - // regardless of BuildErrorEventArgs.LineNumber and BuildErrorEventArgs.ColumnNumber. - public void VerifyValues() - { - if (_invalidFileNames.Contains(File) && LineNumber == 0 && ColumnNumber == 0) - { - CanNavigateTo = false; - return; - } - - if (LineNumber < 1) - LineNumber = 1; - - if (ColumnNumber < 1) - ColumnNumber = 1; - - if (EndLineNumber == 0 && EndColumnNumber == 0) - { - EndLineNumber = LineNumber; - EndColumnNumber = ColumnNumber; - } - - CanNavigateTo = true; - } - } -} diff --git a/src/BuildVision.Contracts/ErrorsBox.cs b/src/BuildVision.Contracts/ErrorsBox.cs deleted file mode 100644 index 32901fbf..00000000 --- a/src/BuildVision.Contracts/ErrorsBox.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace BuildVision.Contracts -{ - public class ErrorsBox : IEnumerable - { - private readonly List _errors = new List(); - - private readonly List _warnings = new List(); - - private readonly List _messages = new List(); - - public int ErrorsCount { get; private set; } - public int WarningsCount { get; private set; } - public int MessagesCount { get; private set; } - - public bool IsEmpty => _errors.Count == 0 && _warnings.Count == 0 && _messages.Count == 0; - public IList Errors => _errors; - - public void Add(ErrorItem errorItem) - { - switch (errorItem.Level) - { - case ErrorLevel.Message: - MessagesCount++; - break; - case ErrorLevel.Warning: - WarningsCount++; - break; - case ErrorLevel.Error: - ErrorsCount++; - break; - default: - throw new ArgumentOutOfRangeException("errorLevel"); - } - - if (errorItem.Level != ErrorLevel.Error) - return; - - int errorNumber = _errors.Count + _warnings.Count + _messages.Count + 1; - errorItem.Number = errorNumber; - switch (errorItem.Level) - { - case ErrorLevel.Message: - _messages.Add(errorItem); - break; - - case ErrorLevel.Warning: - _warnings.Add(errorItem); - break; - - case ErrorLevel.Error: - _errors.Add(errorItem); - break; - - default: - throw new ArgumentOutOfRangeException("errorLevel"); - } - } - - public IEnumerator GetEnumerator() - { - foreach (var error in _errors) - yield return error; - - foreach (var warning in _warnings) - yield return warning; - - foreach (var message in _messages) - yield return message; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} diff --git a/src/BuildVision.Contracts/ProjectNotFoundException.cs b/src/BuildVision.Contracts/Exceptions/ProjectNotFoundException.cs similarity index 92% rename from src/BuildVision.Contracts/ProjectNotFoundException.cs rename to src/BuildVision.Contracts/Exceptions/ProjectNotFoundException.cs index 7258f749..6b63566c 100644 --- a/src/BuildVision.Contracts/ProjectNotFoundException.cs +++ b/src/BuildVision.Contracts/Exceptions/ProjectNotFoundException.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.Serialization; -namespace BuildVision.Contracts +namespace BuildVision.Contracts.Exceptions { [Serializable] public class ProjectNotFoundException : Exception @@ -22,4 +22,4 @@ protected ProjectNotFoundException(SerializationInfo info, StreamingContext cont { } } -} \ No newline at end of file +} diff --git a/src/BuildVision.Contracts/Exceptions/PropertyNotFoundException.cs b/src/BuildVision.Contracts/Exceptions/PropertyNotFoundException.cs new file mode 100644 index 00000000..0420d0d5 --- /dev/null +++ b/src/BuildVision.Contracts/Exceptions/PropertyNotFoundException.cs @@ -0,0 +1,20 @@ +using System; + +namespace BuildVision.Contracts.Exceptions +{ + [Serializable] + public class PropertyNotFoundException : Exception + { + public string PropertyName { get; } + + public Type PropertyType { get; } + + public override string Message => string.Format("Property '{0}' not found in '{1}' type.", PropertyName, PropertyType); + + public PropertyNotFoundException(string propertyName, Type type) + { + PropertyName = propertyName; + PropertyType = type; + } + } +} diff --git a/src/BuildVision.Contracts/Models/BuildProjectContextEntry.cs b/src/BuildVision.Contracts/Models/BuildProjectContextEntry.cs new file mode 100644 index 00000000..64f8528a --- /dev/null +++ b/src/BuildVision.Contracts/Models/BuildProjectContextEntry.cs @@ -0,0 +1,22 @@ +using BuildVision.UI.Models; +using System.Collections.Generic; + +namespace BuildVision.UI.Contracts +{ + public class BuildProjectContextEntry + { + public string ProjectFile { get; set; } + + public IDictionary Properties { get; } + + public IProjectItem ProjectItem { get; set; } + + public bool IsInvalid { get; set; } + + public BuildProjectContextEntry(string fileName, IDictionary properties) + { + ProjectFile = fileName; + Properties = properties; + } + } +} diff --git a/src/BuildVision.Contracts/Models/ErrorItem.cs b/src/BuildVision.Contracts/Models/ErrorItem.cs new file mode 100644 index 00000000..1b320c2b --- /dev/null +++ b/src/BuildVision.Contracts/Models/ErrorItem.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.Build.Framework; + +namespace BuildVision.Contracts +{ + public class ErrorItem + { + public const string DefaultSortPropertyName = "Number"; + private readonly List _invalidFileNames = new List { "CSC", "MSBUILD", "LINK" }; + + public bool CanNavigateTo { get; set; } + + public int? Number { get; set; } + + public ErrorLevel Level { get; set; } + + public string Code { get; set; } + + public string File { get; set; } + + public string FileName + { + get + { + try + { + return Path.GetFileName(File); + } + catch (ArgumentException) + { + return File; + } + } + } + + public string ProjectFile { get; set; } + + public int LineNumber { get; set; } + public int ColumnNumber { get; set; } + + public int EndLineNumber { get; set; } + + public int EndColumnNumber { get; set; } + + public string Subcategory { get; set; } + + public string Message { get; set; } + + public ErrorItem(ErrorLevel errorLevel) + { + Level = errorLevel; + } + + public ErrorItem() { } + + public void Init(BuildErrorEventArgs e) + { + Code = e.Code; + File = e.File; + ProjectFile = e.ProjectFile; + LineNumber = e.LineNumber; + ColumnNumber = e.ColumnNumber; + EndLineNumber = e.EndLineNumber; + EndColumnNumber = e.EndColumnNumber; + Subcategory = e.Subcategory; + Message = e.Message; + } + + public void Init(BuildWarningEventArgs e) + { + Code = e.Code; + File = e.File; + ProjectFile = e.ProjectFile; + LineNumber = e.LineNumber; + ColumnNumber = e.ColumnNumber; + EndLineNumber = e.EndLineNumber; + EndColumnNumber = e.EndColumnNumber; + Subcategory = e.Subcategory; + Message = e.Message; + } + + public void Init(BuildMessageEventArgs e) + { + Code = e.Code; + File = e.File; + ProjectFile = e.ProjectFile; + LineNumber = e.LineNumber; + ColumnNumber = e.ColumnNumber; + EndLineNumber = e.EndLineNumber; + EndColumnNumber = e.EndColumnNumber; + Subcategory = e.Subcategory; + Message = e.Message; + } + + // 1. EnvDTE.TextSelection.MoveToLineAndOffset requires line and offset numbers beginning at one. + // BuildErrorEventArgs.LineNumber and BuildErrorEventArgs.ColumnNumber may be uninitialized. + // 2. BuildErrorEventArgs.EndLineNumber and BuildErrorEventArgs.EndColumnNumber may be uninitialized, + // regardless of BuildErrorEventArgs.LineNumber and BuildErrorEventArgs.ColumnNumber. + public void VerifyValues() + { + if (_invalidFileNames.Contains(File) && LineNumber == 0 && ColumnNumber == 0) + { + CanNavigateTo = false; + return; + } + + if (LineNumber < 1) + { + LineNumber = 1; + } + + if (ColumnNumber < 1) + { + ColumnNumber = 1; + } + + if (EndLineNumber == 0 && EndColumnNumber == 0) + { + EndLineNumber = LineNumber; + EndColumnNumber = ColumnNumber; + } + + CanNavigateTo = true; + } + } +} diff --git a/src/BuildVision.Contracts/Models/IBuildInformationModel.cs b/src/BuildVision.Contracts/Models/IBuildInformationModel.cs new file mode 100644 index 00000000..4e35f442 --- /dev/null +++ b/src/BuildVision.Contracts/Models/IBuildInformationModel.cs @@ -0,0 +1,32 @@ +using System; +using System.ComponentModel; +using System.Windows.Controls; +using BuildVision.UI.Models; + +namespace BuildVision.Contracts.Models +{ + public interface IBuildInformationModel : INotifyPropertyChanged + { + Guid BuildId { get; set; } + BuildAction BuildAction { get; set; } + DateTime? BuildFinishTime { get; set; } + BuildScope BuildScope { get; set; } + DateTime? BuildStartTime { get; set; } + BuildState CurrentBuildState { get; set; } + int ErrorCount { get; set; } + int FailedProjectsCount { get; set; } + int MessagesCount { get; set; } + string StateMessage { get; set; } + int SucceededProjectsCount { get; set; } + int UpToDateProjectsCount { get; set; } + int WarnedProjectsCount { get; set; } + int WarningsCount { get; set; } + + BuildResultState ResultState { get; } + string StateIconKey { get; } + IProjectItem CurrentProject { get; set; } + + int GetFinishedProjectsCount(); + void ResetState(); + } +} diff --git a/src/BuildVision.Contracts/Models/IProjectItem.cs b/src/BuildVision.Contracts/Models/IProjectItem.cs new file mode 100644 index 00000000..1b28cbf7 --- /dev/null +++ b/src/BuildVision.Contracts/Models/IProjectItem.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.ObjectModel; +using System.Windows.Controls; +using BuildVision.Contracts; + +namespace BuildVision.UI.Models +{ + public interface IProjectItem + { + TimeSpan? BuildElapsedTime { get; } + DateTime? BuildFinishTime { get; set; } + int? BuildOrder { get; set; } + DateTime? BuildStartTime { get; set; } + string CommonType { get; set; } + string Configuration { get; set; } + string ExtenderNames { get; set; } + string FlavourType { get; set; } + string Framework { get; set; } + string FullName { get; set; } + string FullPath { get; set; } + bool IsBatchBuildProject { get; set; } + string Language { get; set; } + string MainFlavourType { get; set; } + string Name { get; set; } + string OutputType { get; set; } + string Platform { get; set; } + string RootNamespace { get; set; } + string SolutionFolder { get; set; } + ProjectState State { get; set; } + ControlTemplate StateBitmap { get; } + bool Success { get; set; } + string UniqueName { get; set; } + int MessagesCount { get; set; } + int ErrorsCount { get; set; } + int WarningsCount { get; set; } + ObservableCollection Errors { get; } + ObservableCollection Warnings { get; } + ObservableCollection Messages { get; } + + void RaiseBuildElapsedTimeChanged(); + void AddErrorItem(ErrorItem errorItem); + } +} diff --git a/src/BuildVision.Contracts/Models/ISolutionModel.cs b/src/BuildVision.Contracts/Models/ISolutionModel.cs new file mode 100644 index 00000000..3eb65d4d --- /dev/null +++ b/src/BuildVision.Contracts/Models/ISolutionModel.cs @@ -0,0 +1,10 @@ +namespace BuildVision.Contracts.Models +{ + public interface ISolutionModel + { + string FileName { get; set; } + string FullName { get; set; } + bool IsEmpty { get; set; } + string Name { get; set; } + } +} diff --git a/src/BuildVision.Contracts/Properties/AssemblyInfo.cs b/src/BuildVision.Contracts/Properties/AssemblyInfo.cs deleted file mode 100644 index 6cc21777..00000000 --- a/src/BuildVision.Contracts/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("BuildVision.Contracts")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("BuildVision.Contracts")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("13d64a57-5db3-4cc7-ac2b-9034e767d754")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] diff --git a/src/BuildVision.Contracts/Properties/GlobalSuppressions.cs b/src/BuildVision.Contracts/Properties/GlobalSuppressions.cs new file mode 100644 index 00000000..c860c334 --- /dev/null +++ b/src/BuildVision.Contracts/Properties/GlobalSuppressions.cs @@ -0,0 +1,5 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~P:BuildVision.Contracts.Exceptions.PropertyNotFoundException.Message")] diff --git a/src/BuildVision.Contracts/PropertyNotFoundException.cs b/src/BuildVision.Contracts/PropertyNotFoundException.cs deleted file mode 100644 index 5d43f387..00000000 --- a/src/BuildVision.Contracts/PropertyNotFoundException.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; - -namespace BuildVision.Contracts -{ - public class PropertyNotFoundException : Exception - { - private readonly string _propertyName; - private readonly Type _type; - - public PropertyNotFoundException(string propertyName, Type type) - { - _propertyName = propertyName; - _type = type; - } - - public string PropertyName - { - get { return _propertyName; } - } - - public Type Type - { - get { return _type; } - } - - public override string Message - { - get { return string.Format("Property '{0}' not found in '{1}' type.", _propertyName, _type); } - } - } -} \ No newline at end of file diff --git a/src/BuildVision.Contracts/VisualStudioProject.cs b/src/BuildVision.Contracts/VisualStudioProject.cs index 08029294..70f3c4a3 100644 --- a/src/BuildVision.Contracts/VisualStudioProject.cs +++ b/src/BuildVision.Contracts/VisualStudioProject.cs @@ -26,4 +26,4 @@ public class VisualStudioProject public DateTime? BuildFinishTime { get; set; } public TimeSpan? BuildElapsedTime { get; set; } } -} \ No newline at end of file +} diff --git a/src/BuildVision.Exports/BuildVision.Exports.csproj b/src/BuildVision.Exports/BuildVision.Exports.csproj new file mode 100644 index 00000000..5662c57a --- /dev/null +++ b/src/BuildVision.Exports/BuildVision.Exports.csproj @@ -0,0 +1,18 @@ + + + + net472 + true + Key.snk + Debug;Release;Marketplace;VsixGallery + + + + + + + + + + + diff --git a/src/BuildVision.Exports/Factories/IBuildMessagesFactory.cs b/src/BuildVision.Exports/Factories/IBuildMessagesFactory.cs new file mode 100644 index 00000000..068131b1 --- /dev/null +++ b/src/BuildVision.Exports/Factories/IBuildMessagesFactory.cs @@ -0,0 +1,11 @@ +using BuildVision.Contracts.Models; + +namespace BuildVision.Exports.Factories +{ + public interface IBuildMessagesFactory + { + string GetBuildBeginExtraMessage(IBuildInformationModel buildInformationModel); + string GetBuildBeginMajorMessage(IBuildInformationModel buildInformationModel); + string GetBuildDoneMessage(IBuildInformationModel buildInformationModel); + } +} diff --git a/src/BuildVision.Exports/IBuildOutputLogger.cs b/src/BuildVision.Exports/IBuildOutputLogger.cs new file mode 100644 index 00000000..bd1a363c --- /dev/null +++ b/src/BuildVision.Exports/IBuildOutputLogger.cs @@ -0,0 +1,16 @@ +using System; +using BuildVision.Contracts; +using BuildVision.UI.Contracts; +using BuildVision.UI.Models; + +namespace BuildVision.Exports +{ + public interface IBuildOutputLogger + { + bool IsProjectUpToDate(IProjectItem projectItem); + + void Attach(); + + event Action OnErrorRaised; + } +} diff --git a/src/BuildVision.Exports/Key.snk b/src/BuildVision.Exports/Key.snk new file mode 100644 index 00000000..8bf0d557 Binary files /dev/null and b/src/BuildVision.Exports/Key.snk differ diff --git a/src/BuildVision.Exports/Providers/IBuildInformationProvider.cs b/src/BuildVision.Exports/Providers/IBuildInformationProvider.cs new file mode 100644 index 00000000..ed69e19c --- /dev/null +++ b/src/BuildVision.Exports/Providers/IBuildInformationProvider.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using BuildVision.Contracts; +using BuildVision.Contracts.Models; +using BuildVision.UI.Models; + +namespace BuildVision.Exports.Providers +{ + public interface IBuildInformationProvider + { + IBuildInformationModel BuildInformationModel { get; } + ObservableCollection Projects { get; } + + void ProjectBuildStarted(IProjectItem projectItem, BuildAction buildAction); + void ProjectBuildFinished(BuildAction buildAction, string projectIdentifier, bool succeess, bool canceled); + void ReloadCurrentProjects(); + void ResetCurrentProjects(); + void BuildFinished(bool success, bool canceled); + void BuildStarted(BuildAction currentBuildAction, BuildScope scope); + void ResetBuildInformationModel(); + + event Action BuildStateChanged; + } +} diff --git a/src/BuildVision.Exports/Providers/ISolutionProvider.cs b/src/BuildVision.Exports/Providers/ISolutionProvider.cs new file mode 100644 index 00000000..b63f43e5 --- /dev/null +++ b/src/BuildVision.Exports/Providers/ISolutionProvider.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using BuildVision.Contracts.Models; +using BuildVision.UI.Models; + +namespace BuildVision.Exports.Providers +{ + public interface ISolutionProvider + { + ISolutionModel GetSolutionModel(); + void ReloadSolution(); + IEnumerable GetProjects(); + } +} diff --git a/src/BuildVision.Exports/Sevices/IBuildService.cs b/src/BuildVision.Exports/Sevices/IBuildService.cs new file mode 100644 index 00000000..8695f752 --- /dev/null +++ b/src/BuildVision.Exports/Sevices/IBuildService.cs @@ -0,0 +1,14 @@ +using BuildVision.UI.Models; + +namespace BuildVision.Exports.Services +{ + public interface IBuildService + { + void BuildSolution(); + void CleanSolution(); + void RebuildSolution(); + void CancelBuildSolution(); + void ProjectCopyBuildOutputFilesToClipBoard(IProjectItem projItem); + void RaiseCommandForSelectedProject(IProjectItem projectItem, int command); + } +} diff --git a/src/BuildVision.Exports/Sevices/IErrorNavigationService.cs b/src/BuildVision.Exports/Sevices/IErrorNavigationService.cs new file mode 100644 index 00000000..55f48e8c --- /dev/null +++ b/src/BuildVision.Exports/Sevices/IErrorNavigationService.cs @@ -0,0 +1,9 @@ +using BuildVision.Contracts; + +namespace BuildVision.Exports.Services +{ + public interface IErrorNavigationService + { + void NavigateToErrorItem(ErrorItem errorItem); + } +} diff --git a/src/BuildVision.Exports/Sevices/IStatusBarNotificationService.cs b/src/BuildVision.Exports/Sevices/IStatusBarNotificationService.cs new file mode 100644 index 00000000..a2d5ab6d --- /dev/null +++ b/src/BuildVision.Exports/Sevices/IStatusBarNotificationService.cs @@ -0,0 +1,8 @@ +namespace BuildVision.Exports.Services +{ + public interface IStatusBarNotificationService + { + void ShowText(string str); + void ShowTextWithFreeze(string str); + } +} diff --git a/src/BuildVision.Exports/Sevices/ITaskBarInfoService.cs b/src/BuildVision.Exports/Sevices/ITaskBarInfoService.cs new file mode 100644 index 00000000..d46ca586 --- /dev/null +++ b/src/BuildVision.Exports/Sevices/ITaskBarInfoService.cs @@ -0,0 +1,10 @@ +using BuildVision.Contracts; + +namespace BuildVision.Exports.Services +{ + public interface ITaskBarInfoService + { + void ResetTaskBarInfo(bool ifTaskBarProgressEnabled = true); + void UpdateTaskBarInfo(BuildState buildState, BuildScope buildScope, int projectsCount, int finishedProjects); + } +} diff --git a/src/BuildVision.Exports/ViewModels/IBuildVisionPaneViewModel.cs b/src/BuildVision.Exports/ViewModels/IBuildVisionPaneViewModel.cs new file mode 100644 index 00000000..d417c5ba --- /dev/null +++ b/src/BuildVision.Exports/ViewModels/IBuildVisionPaneViewModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BuildVision.Exports.ViewModels; + +namespace BuildVision.Exports.ViewModels +{ + public interface IBuildVisionPaneViewModel : IViewModel + { + } +} diff --git a/src/BuildVision.Exports/ViewModels/IViewModel.cs b/src/BuildVision.Exports/ViewModels/IViewModel.cs new file mode 100644 index 00000000..2a41720b --- /dev/null +++ b/src/BuildVision.Exports/ViewModels/IViewModel.cs @@ -0,0 +1,9 @@ +using System; +using System.ComponentModel; + +namespace BuildVision.Exports.ViewModels +{ + public interface IViewModel : INotifyPropertyChanged + { + } +} diff --git a/src/BuildVision.UI/App.xaml b/src/BuildVision.UI/App.xaml index 8de566f6..a6f67004 100644 --- a/src/BuildVision.UI/App.xaml +++ b/src/BuildVision.UI/App.xaml @@ -6,6 +6,7 @@ + diff --git a/src/BuildVision.UI/App.xaml.cs b/src/BuildVision.UI/App.xaml.cs index 7d50245b..33db04d2 100644 --- a/src/BuildVision.UI/App.xaml.cs +++ b/src/BuildVision.UI/App.xaml.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; +using System.Diagnostics; using System.Windows; namespace BuildVision.UI diff --git a/src/BuildVision.UI/Helpers/DisplayStringAttribute.cs b/src/BuildVision.UI/Attributes/DisplayStringAttribute.cs similarity index 89% rename from src/BuildVision.UI/Helpers/DisplayStringAttribute.cs rename to src/BuildVision.UI/Attributes/DisplayStringAttribute.cs index 93f017b8..348e512a 100644 --- a/src/BuildVision.UI/Helpers/DisplayStringAttribute.cs +++ b/src/BuildVision.UI/Attributes/DisplayStringAttribute.cs @@ -1,5 +1,4 @@ -using BuildVision.UI; -using System; +using System; namespace BuildVision.UI.Helpers { @@ -31,15 +30,15 @@ public class DisplayStringAttribute : Attribute public static readonly DisplayStringAttribute Default = new DisplayStringAttribute(); private string _resourceName; - /// - /// The value of this attribute. - /// - public string DisplayString { get; private set; } + /// + /// The value of this attribute. + /// + public string DisplayString { get; private set; } - public string ResourceName + public string ResourceName { - get { return _resourceName; } - set + get => _resourceName; + set { _resourceName = value; DisplayString = Resources.ResourceManager.GetString(value, Resources.Culture); @@ -67,7 +66,9 @@ public override bool Equals(object obj) { var dsaObj = obj as DisplayStringAttribute; if (dsaObj == null) + { return false; + } return DisplayString.Equals(dsaObj.DisplayString); } diff --git a/src/BuildVision.UI/Models/GridColumnAttribute.cs b/src/BuildVision.UI/Attributes/GridColumnAttribute.cs similarity index 65% rename from src/BuildVision.UI/Models/GridColumnAttribute.cs rename to src/BuildVision.UI/Attributes/GridColumnAttribute.cs index 160856fd..eec2abc2 100644 --- a/src/BuildVision.UI/Models/GridColumnAttribute.cs +++ b/src/BuildVision.UI/Attributes/GridColumnAttribute.cs @@ -1,6 +1,5 @@ +using System; using BuildVision.Contracts; -using BuildVision.UI; -using System; namespace BuildVision.UI.Modelss { @@ -13,23 +12,23 @@ public class GridColumnAttribute : BaseGridColumnSettingsAttribute public string ImageDictionaryUri { get; set; } - public object ExampleValue { get; set; } + public object ExampleValue { get; set; } - public string TimeSpanExampleValue + public string TimeSpanExampleValue { - get { return ""; } - set { ExampleValue = TimeSpan.Parse(value); } + get => ""; + set => ExampleValue = TimeSpan.Parse(value); } public string DateTimeExampleValue { - get { return ""; } - set { ExampleValue = DateTime.Parse(value); } + get => ""; + set => ExampleValue = DateTime.Parse(value); } public GridColumnAttribute( - string headerResourceName, - ColumnsOrder displayOrder, + string headerResourceName, + ColumnsOrder displayOrder, bool visible) { Header = Resources.ResourceManager.GetString(headerResourceName, Resources.Culture); diff --git a/src/BuildVision.UI/BuildVision.UI.csproj b/src/BuildVision.UI/BuildVision.UI.csproj index de0f3ae3..03c964d2 100644 --- a/src/BuildVision.UI/BuildVision.UI.csproj +++ b/src/BuildVision.UI/BuildVision.UI.csproj @@ -40,9 +40,30 @@ Key.snk + + bin\Marketplace\ + TRACE + true + pdbonly + AnyCPU + prompt + MinimumRecommendedRules.ruleset + true + + + bin\VsixGallery\ + TRACE + true + pdbonly + AnyCPU + prompt + MinimumRecommendedRules.ruleset + true + + @@ -72,22 +93,47 @@ App.xaml Code - - - - ControlHeader.xaml + + + ProjectGrid.xaml + + + BuildVisionProgressBar.xaml + + + + + + + + + + + + + + + + + + + + + + + + ErrorsGrid.xaml - - - + + + + + - - - - + ControlView.xaml @@ -103,46 +149,19 @@ - MainWindow.xaml - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - + Resources.resx True @@ -166,8 +185,11 @@ WindowSettingsControl.xaml - - + + + + + @@ -178,11 +200,8 @@ - - - @@ -225,10 +244,6 @@ - - Designer - MSBuild:Compile - MSBuild:Compile Designer @@ -237,13 +252,17 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + MSBuild:Compile Designer - - MSBuild:Compile + Designer + MSBuild:Compile Designer @@ -254,7 +273,7 @@ Designer Always - + MSBuild:Compile Designer Always @@ -283,7 +302,7 @@ Designer Always - + MSBuild:Compile Designer Always @@ -350,6 +369,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + @@ -360,14 +383,22 @@ {13d64a57-5db3-4cc7-ac2b-9034e767d754} BuildVision.Contracts + + {F16E6593-DDF9-4E9E-A2F8-56A3C43A643E} + BuildVision.Exports + - - 12.0.4 + + 2.10.34-preview + + + 14.3.81-pre - - 12.0.4 + + 2.9.2 + \ No newline at end of file diff --git a/src/BuildVision.UI/Common/Logging/BindingErrorListener.cs b/src/BuildVision.UI/Common/Logging/BindingErrorListener.cs deleted file mode 100644 index 515d9249..00000000 --- a/src/BuildVision.UI/Common/Logging/BindingErrorListener.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Diagnostics; - -namespace BuildVision.UI.Common.Logging -{ - public class BindingErrorListener : TraceListener - { - public override void Write(string message) - { - } - - public override void WriteLine(string message) - { - TraceManager.Trace("Binding error: " + message, EventLogEntryType.Warning); - } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Common/Logging/TraceManager.cs b/src/BuildVision.UI/Common/Logging/TraceManager.cs deleted file mode 100644 index edb06b2e..00000000 --- a/src/BuildVision.UI/Common/Logging/TraceManager.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Text; -using System.Windows; - -using Microsoft.VisualStudio.Shell; - -namespace BuildVision.UI.Common.Logging -{ - public static class TraceManager - { -#if DEBUG - static TraceManager() - { - string logDirectoryPath = Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - Resources.ProductName, - "log"); - string logFilePath = Path.Combine( - logDirectoryPath, - string.Format("log_{0}.svclog", Guid.NewGuid())); - - if (!Directory.Exists(logDirectoryPath)) - Directory.CreateDirectory(logDirectoryPath); - - var traceListener = new XmlWriterTraceListener(logFilePath) - { - TraceOutputOptions = TraceOptions.DateTime - }; - - System.Diagnostics.Trace.AutoFlush = true; - System.Diagnostics.Trace.Listeners.Add(traceListener); - - // Tracing binding errors - PresentationTraceSources.DataBindingSource.Listeners.Add(new BindingErrorListener()); - PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.Error; - } -#endif - - public static void TraceUnknownException(this Exception ex) - { - Trace(ex, Resources.UnknownExceptionMsg); - } - - public static void TraceError(string message) - { - Trace(message, EventLogEntryType.Error); - } - - public static void Trace(this Exception ex, string message, EventLogEntryType type = EventLogEntryType.Error) - { - TraceAction(ex.ToLogString(message), type); - } - - public static void Trace(string message, EventLogEntryType type) - { - TraceAction(message, type); - } - - private static void TraceAction(string message, EventLogEntryType type) - { - System.Threading.Tasks.Task.Run(() => - { - - // ActivityLog works if devenv.exe started with /log switch. - // Read more https://msdn.microsoft.com/en-us/library/ms241272.aspx. - switch (type) - { - case EventLogEntryType.Error: - ActivityLog.LogError(Resources.ProductName, message); -#if DEBUG - System.Diagnostics.Trace.TraceError(message); - MessageBox.Show(message, Resources.ProductName + " error", MessageBoxButton.OK, MessageBoxImage.Error); -#endif - break; - - case EventLogEntryType.Warning: - case EventLogEntryType.FailureAudit: - ActivityLog.LogWarning(Resources.ProductName, message); -#if DEBUG - System.Diagnostics.Trace.TraceWarning(message); -#endif - break; - - case EventLogEntryType.Information: - case EventLogEntryType.SuccessAudit: - ActivityLog.LogInformation(Resources.ProductName, message); -#if DEBUG - System.Diagnostics.Trace.TraceInformation(message); -#endif - break; - - default: - throw new ArgumentOutOfRangeException(nameof(type)); - } - }); - } - - public static string ToLogString(this Exception ex, string additionalMessage) - { - var msg = new StringBuilder(); - if (!string.IsNullOrEmpty(additionalMessage)) - msg.AppendLine(additionalMessage); - - if (ex == null) - return msg.ToString(); - - Exception orgEx = ex; - msg.AppendLine("Exception:"); - while (orgEx != null) - { - msg.AppendLine(orgEx.Message); - orgEx = orgEx.InnerException; - } - - AddDataEntries(ex, msg); - AddStackTrace(ex, msg); - AddSource(ex, msg); - AddTargetSite(ex, msg); - AddBaseExcception(ex, msg); - return msg.ToString(); - } - - private static void AddBaseExcception(Exception ex, StringBuilder msg) - { - Exception baseException = ex.GetBaseException(); - if (baseException != null) - { - msg.AppendLine("BaseException:"); - msg.Append(ex.GetBaseException()); - } - } - - private static void AddTargetSite(Exception ex, StringBuilder msg) - { - if (ex.TargetSite != null) - { - msg.AppendLine("TargetSite:"); - msg.AppendLine(ex.TargetSite.ToString()); - } - } - - private static void AddSource(Exception ex, StringBuilder msg) - { - if (ex.Source != null) - { - msg.AppendLine("Source:"); - msg.AppendLine(ex.Source.ToString()); - } - } - - private static void AddStackTrace(Exception ex, StringBuilder msg) - { - if (ex.StackTrace != null) - { - msg.AppendLine("StackTrace:"); - msg.AppendLine(ex.StackTrace); - } - } - - private static void AddDataEntries(Exception ex, StringBuilder msg) - { - if (ex.Data != null && ex.Data.Count > 0) - { - msg.AppendLine("Data:"); - foreach (System.Collections.DictionaryEntry dataEntry in ex.Data) - { - msg.AppendLine(string.Format("Key='{0}';Value='{1}'", dataEntry.Key, dataEntry.Value)); - } - } - } - } -} diff --git a/src/BuildVision.UI/Components/ControlHeader.xaml b/src/BuildVision.UI/Components/ControlHeader.xaml deleted file mode 100644 index 23caf0ad..00000000 --- a/src/BuildVision.UI/Components/ControlHeader.xaml +++ /dev/null @@ -1,359 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/BuildVision.UI/Components/ControlHeader.xaml.cs b/src/BuildVision.UI/Components/ControlHeader.xaml.cs deleted file mode 100644 index b6047453..00000000 --- a/src/BuildVision.UI/Components/ControlHeader.xaml.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; - -namespace BuildVision.UI.Components -{ - /// - /// Interaction logic for ControlHeader.xaml - /// - public partial class ControlHeader : UserControl - { - public ControlHeader() - { - InitializeComponent(); - } - } -} diff --git a/src/BuildVision.UI/Components/ControlView.xaml b/src/BuildVision.UI/Components/ControlView.xaml index 01c02f0b..382c0850 100644 --- a/src/BuildVision.UI/Components/ControlView.xaml +++ b/src/BuildVision.UI/Components/ControlView.xaml @@ -3,23 +3,23 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:res="clr-namespace:BuildVision.UI" - xmlns:views="clr-namespace:BuildVision.UI" - xmlns:components="clr-namespace:BuildVision.UI.Components" xmlns:viewModels="clr-namespace:BuildVision.UI.ViewModels" xmlns:extensions="clr-namespace:BuildVision.UI.Extensions" xmlns:helpers="clr-namespace:BuildVision.UI.Helpers" - xmlns:contracts="clr-namespace:BuildVision.Contracts;assembly=BuildVision.Contracts" + xmlns:customButtons="clr-namespace:BuildVision.UI.Controls.Buttons" + xmlns:indicators="clr-namespace:BuildVision.UI.Controls.Indicators" + xmlns:controls="clr-namespace:BuildVision.UI.Controls" + xmlns:components="clr-namespace:BuildVision.UI.Components" + xmlns:res="clr-namespace:BuildVision.UI" + xmlns:converters="clr-namespace:BuildVision.UI.Converters" mc:Ignorable="d" Name="OwnerUserControl" Background="{DynamicResource ToolWindowBackgroundKey}" - DataContextChanged="OnDataContextChanged" SnapsToDevicePixels="True" UseLayoutRounding="True" d:DesignHeight="148" d:DesignWidth="697" - d:DataContext="{Binding Source={StaticResource DesignViewModel}}"> - + d:DataContext="{d:DesignInstance viewModels:BuildVisionPaneViewModel, IsDesignTimeCreatable=True}"> @@ -28,321 +28,131 @@ + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + \ No newline at end of file diff --git a/src/BuildVision.UI/Components/ControlView.xaml.cs b/src/BuildVision.UI/Components/ControlView.xaml.cs index 5a764caf..4d0338ea 100644 --- a/src/BuildVision.UI/Components/ControlView.xaml.cs +++ b/src/BuildVision.UI/Components/ControlView.xaml.cs @@ -1,21 +1,8 @@ -using BuildVision.UI.Converters; -using BuildVision.UI.DataGrid; -using BuildVision.UI.Helpers; -using BuildVision.UI.Models; -using BuildVision.UI.ViewModels; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Diagnostics; +using System.ComponentModel; using System.Globalization; -using System.Linq; -using System.Windows; using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Input; using System.Windows.Markup; -using System.Windows.Media; +using BuildVision.UI.ViewModels; namespace BuildVision.UI { @@ -24,116 +11,22 @@ namespace BuildVision.UI /// public partial class ControlView : UserControl { - private ControlViewModel _viewModel; + public BuildVisionPaneViewModel ViewModel + { + get => (BuildVisionPaneViewModel)DataContext; + set => DataContext = value; + } public ControlView() { InitializeComponent(); - // Ensure the current culture passed into bindings is the OS culture. // By default, WPF uses en-US as the culture, regardless of the system settings. Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag); - Grid.TargetUpdated += GridOnTargetUpdated; - } - - private void GridOnTargetUpdated(object sender, DataTransferEventArgs e) - { - if (e.Property.Name == "ItemsSource") - RefreshSortDirectionInGrid(); - } - - private void RefreshSortDirectionInGrid() - { - DataGridColumn dataGridColumn = Grid.Columns.FirstOrDefault(col => col.GetBindedProperty() == _viewModel.GridSortDescription.Property); - if (dataGridColumn != null) - dataGridColumn.SortDirection = _viewModel.GridSortDescription.Order.ToSystem(); - } - - private void GridOnSorting(object sender, DataGridSortingEventArgs e) - { - if (_viewModel.GridSorting.CanExecute(e)) - _viewModel.GridSorting.Execute(e); - } - - private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) - { - Debug.Assert(DataContext != null); - - _viewModel = (ControlViewModel)DataContext; - _viewModel.SetGridColumnsRef(Grid.Columns); - _viewModel.PropertyChanged += ViewModelOnPropertyChanged; - } - - private void ViewModelOnPropertyChanged(object sender, PropertyChangedEventArgs e) - { - if (_viewModel.CurrentProject != null && e.PropertyName == "CurrentProject") - { - // TODO: Remove SelectedIndex = -1 and implement Unselect row feature by clicking on selected row. - Grid.SelectedIndex = -1; - - if (Grid.SelectedIndex == -1) - Grid.ScrollIntoView(_viewModel.CurrentProject); - } - } - - private void DataGridExpanderOnExpanded(object sender, RoutedEventArgs e) - { - ExpanderIsExpandedConverter.SaveState( - (Expander)sender, - false, - _viewModel.ControlSettings.GridSettings.CollapsedGroups); - e.Handled = true; - } - - private void DataGridExpanderOnCollapsed(object sender, RoutedEventArgs e) - { - ExpanderIsExpandedConverter.SaveState( - (Expander)sender, - true, - _viewModel.ControlSettings.GridSettings.CollapsedGroups); - e.Handled = true; - } - - // Send scrolling to the DataGrid. - private void DataGridExpanderOnPreviewMouseWheel(object sender, MouseWheelEventArgs e) - { - e.Handled = true; - var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta) - { - RoutedEvent = MouseWheelEvent, - Source = sender - }; - - var parent = (UIElement)VisualTreeHelper.GetParent((DependencyObject)sender); - parent.RaiseEvent(eventArg); - } - - private void DataGridRowDetailsOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) - { - // http://stackoverflow.com/questions/6279724/mousedoubleclick-events-dont-bubble/6326181#6326181) - if (e.ClickCount == 2) - e.Handled = true; - } - - // Autofocus for RowDetails (without extra mouse click). - private void DataGridRowOnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) - { - var row = (DataGridRow)sender; - if (!row.IsSelected && e.Source is DataGridDetailsPresenter) + if (DesignerProperties.GetIsInDesignMode(new System.Windows.DependencyObject())) { - row.Focusable = true; - row.Focus(); - - // Gets the element with keyboard focus. - var elementWithFocus = Keyboard.FocusedElement as UIElement; - - // Change keyboard focus. - if (elementWithFocus != null) - { - var request = new TraversalRequest(FocusNavigationDirection.Next); - elementWithFocus.MoveFocus(request); - } + ViewModel = new BuildVisionPaneViewModel(); } } } diff --git a/src/BuildVision.UI/Components/ErrorsGrid.xaml b/src/BuildVision.UI/Components/ErrorsGrid.xaml index 83da37c2..dd2e0f4e 100644 --- a/src/BuildVision.UI/Components/ErrorsGrid.xaml +++ b/src/BuildVision.UI/Components/ErrorsGrid.xaml @@ -1,13 +1,19 @@  + xmlns:contracts="clr-namespace:BuildVision.Contracts;assembly=BuildVision.Contracts" + xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase" + xmlns:models="clr-namespace:BuildVision.UI.Models" + xmlns:vsfx="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.14.0" + mc:Ignorable="d" + d:DesignHeight="300" + d:DesignWidth="300" + Loaded="ErrorsGridLoaded" + Name="Control" + d:DataContext="{Binding Source={StaticResource DesignViewModel}}"> @@ -16,13 +22,16 @@ - + + + + - - + + diff --git a/src/BuildVision.UI/Components/ErrorsGrid.xaml.cs b/src/BuildVision.UI/Components/ErrorsGrid.xaml.cs index 83d53d86..ed4074c4 100644 --- a/src/BuildVision.UI/Components/ErrorsGrid.xaml.cs +++ b/src/BuildVision.UI/Components/ErrorsGrid.xaml.cs @@ -1,13 +1,13 @@ -using BuildVision.Contracts; -using BuildVision.UI.Common.Logging; -using BuildVision.UI.Extensions; -using BuildVision.UI.Models; -using System; +using System; using System.Diagnostics; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; +using BuildVision.Common.Logging; +using BuildVision.Contracts; +using BuildVision.UI.Extensions; +using BuildVision.UI.Models; namespace BuildVision.UI { @@ -16,6 +16,9 @@ namespace BuildVision.UI /// public partial class ErrorsGrid : UserControl { + public static readonly DependencyProperty ProjectItemProperty = DependencyProperty.Register(nameof(ProjectItem), typeof(ProjectItem), typeof(ErrorsGrid)); + public static DependencyProperty NavigateToErrorCommandProperty = DependencyProperty.Register(nameof(NavigateToErrorCommand), typeof(ICommand), typeof(ErrorsGrid)); + private ScrollViewer _errorsGridScrollViewer; public ErrorsGrid() @@ -23,7 +26,6 @@ public ErrorsGrid() InitializeComponent(); } - public static readonly DependencyProperty ProjectItemProperty = DependencyProperty.Register(nameof(ProjectItem), typeof(ProjectItem), typeof(ErrorsGrid)); public ProjectItem ProjectItem { @@ -31,18 +33,24 @@ public ProjectItem ProjectItem set => SetValue(ProjectItemProperty, value); } + public ICommand NavigateToErrorCommand + { + get => (ICommand)GetValue(NavigateToErrorCommandProperty); + set => SetValue(NavigateToErrorCommandProperty, value); + } + private void ErrorsGridRowOnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { try { var row = (DataGridRow)sender; var errorItem = (ErrorItem)row.Item; - errorItem.GoToError(); + NavigateToErrorCommand.Execute(errorItem); e.Handled = true; } catch (Exception ex) { - ex.Trace("Navigate to error item exception."); + LogManager.ForContext().Error(ex, "Navigate to error item exception."); } } @@ -50,7 +58,9 @@ private void ErrorsGridRowOnMouseLeftButtonUp(object sender, MouseButtonEventArg private void ErrorsGridOnPreviewMouseWheel(object sender, MouseWheelEventArgs e) { if (_errorsGridScrollViewer.ComputedVerticalScrollBarVisibility == Visibility.Visible) + { return; + } e.Handled = true; var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta) @@ -62,7 +72,6 @@ private void ErrorsGridOnPreviewMouseWheel(object sender, MouseWheelEventArgs e) parent.RaiseEvent(eventArg); } - private void ErrorsGridLoaded(object sender, RoutedEventArgs e) { _errorsGridScrollViewer = VisualHelper.FindVisualChild(this); diff --git a/src/BuildVision.UI/Components/ProjectGrid.xaml b/src/BuildVision.UI/Components/ProjectGrid.xaml new file mode 100644 index 00000000..d22a9f44 --- /dev/null +++ b/src/BuildVision.UI/Components/ProjectGrid.xaml @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/BuildVision.UI/Components/ProjectGrid.xaml.cs b/src/BuildVision.UI/Components/ProjectGrid.xaml.cs new file mode 100644 index 00000000..823dc06c --- /dev/null +++ b/src/BuildVision.UI/Components/ProjectGrid.xaml.cs @@ -0,0 +1,136 @@ +using System.ComponentModel; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Input; +using System.Windows.Markup; +using System.Windows.Media; +using BuildVision.UI.Converters; +using BuildVision.UI.DataGrid; +using BuildVision.UI.Helpers; +using BuildVision.UI.ViewModels; + +namespace BuildVision.UI.Components +{ + public partial class ProjectGrid : UserControl + { + public BuildVisionPaneViewModel ViewModel + { + get => (BuildVisionPaneViewModel)DataContext; + set => DataContext = value; + } + + public ProjectGrid() + { + InitializeComponent(); + // Ensure the current culture passed into bindings is the OS culture. + // By default, WPF uses en-US as the culture, regardless of the system settings. + Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag); + Grid.TargetUpdated += GridOnTargetUpdated; + } + + private void GridOnTargetUpdated(object sender, DataTransferEventArgs e) + { + if (e.Property.Name == nameof(Grid.ItemsSource)) + { + RefreshSortDirectionInGrid(); + } + } + + private void RefreshSortDirectionInGrid() + { + Debug.Assert(Grid.Columns != null); + var dataGridColumn = Grid.Columns.FirstOrDefault(col => col.GetBindedProperty() == ViewModel.GridSortDescription.Property); + if (dataGridColumn != null) + { + dataGridColumn.SortDirection = ViewModel.GridSortDescription.Order.ToSystem(); + } + } + + private void GridOnSorting(object sender, DataGridSortingEventArgs e) + { + if (ViewModel.GridSorting.CanExecute(e)) + { + ViewModel.GridSorting.Execute(e); + } + } + + private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) + { + Debug.Assert(ViewModel != null); + ViewModel = (BuildVisionPaneViewModel)DataContext; + ViewModel.SetGridColumnsRef(Grid.Columns); + ViewModel.PropertyChanged += ViewModelOnPropertyChanged; + } + + private void ViewModelOnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + //TODO implement logic for scrolling tu currentproject + if (ViewModel.BuildInformationModel.CurrentProject != null && e.PropertyName == "CurrentProject") + { + // TODO: Remove SelectedIndex = -1 and implement Unselect row feature by clicking on selected row. + Grid.SelectedIndex = -1; + + if (Grid.SelectedIndex == -1) + { + Grid.ScrollIntoView(ViewModel.BuildInformationModel.CurrentProject); + } + } + } + + private void DataGridExpanderOnExpanded(object sender, RoutedEventArgs e) + { + ExpanderIsExpandedConverter.SaveState((Expander)sender, false, ViewModel.ControlSettings.GridSettings.CollapsedGroups); + e.Handled = true; + } + + private void DataGridExpanderOnCollapsed(object sender, RoutedEventArgs e) + { + ExpanderIsExpandedConverter.SaveState((Expander)sender, true, ViewModel.ControlSettings.GridSettings.CollapsedGroups); + e.Handled = true; + } + + // Send scrolling to the DataGrid. + private void DataGridExpanderOnPreviewMouseWheel(object sender, MouseWheelEventArgs e) + { + e.Handled = true; + var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta) + { + RoutedEvent = MouseWheelEvent, + Source = sender + }; + + var parent = (UIElement)VisualTreeHelper.GetParent((DependencyObject)sender); + parent.RaiseEvent(eventArg); + } + + private void DataGridRowDetailsOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + // http://stackoverflow.com/questions/6279724/mousedoubleclick-events-dont-bubble/6326181#6326181) + if (e.ClickCount == 2) + { + e.Handled = true; + } + } + + // Autofocus for RowDetails (without extra mouse click). + private void DataGridRowOnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + var row = (DataGridRow)sender; + if (!row.IsSelected && e.Source is DataGridDetailsPresenter) + { + row.Focusable = true; + row.Focus(); + if (Keyboard.FocusedElement is UIElement elementWithFocus) + { + var request = new TraversalRequest(FocusNavigationDirection.Next); + elementWithFocus.MoveFocus(request); + } + } + } + } +} diff --git a/src/BuildVision.UI/Components/SpinnerControl.xaml.cs b/src/BuildVision.UI/Components/SpinnerControl.xaml.cs index 15836e2a..839a2888 100644 --- a/src/BuildVision.UI/Components/SpinnerControl.xaml.cs +++ b/src/BuildVision.UI/Components/SpinnerControl.xaml.cs @@ -1,11 +1,11 @@ -using BuildVision.UI.Extensions; -using System; +using System; using System.ComponentModel; using System.Globalization; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; +using BuildVision.UI.Extensions; namespace BuildVision.UI.Components { @@ -48,13 +48,7 @@ static SpinnerControl() /// Returns the formatted version of the value, with the specified /// number of DecimalPlaces. /// - public string FormattedValue - { - get - { - return (string)GetValue(FormattedValueProperty); - } - } + public string FormattedValue => (string)GetValue(FormattedValueProperty); /// /// Update the formatted value. @@ -80,8 +74,8 @@ protected void UpdateFormattedValue(decimal newValue) [Category("SpinnerControl")] public decimal Value { - get { return (decimal)GetValue(ValueProperty); } - set { SetValue(ValueProperty, value); } + get => (decimal)GetValue(ValueProperty); + set => SetValue(ValueProperty, value); } private static readonly DependencyProperty ValueProperty = @@ -156,8 +150,8 @@ private static object CoerceValue(DependencyObject obj, object value) [Category("SpinnerControl")] public decimal Minimum { - get { return (decimal)GetValue(MinimumValueProperty); } - set { SetValue(MinimumValueProperty, value); } + get => (decimal)GetValue(MinimumValueProperty); + set => SetValue(MinimumValueProperty, value); } private static readonly DependencyProperty MinimumValueProperty = @@ -173,8 +167,8 @@ public decimal Minimum [Category("SpinnerControl")] public decimal Maximum { - get { return (decimal)GetValue(MaximumValueProperty); } - set { SetValue(MaximumValueProperty, value); } + get => (decimal)GetValue(MaximumValueProperty); + set => SetValue(MaximumValueProperty, value); } private static readonly DependencyProperty MaximumValueProperty = @@ -191,8 +185,8 @@ public decimal Maximum [Category("SpinnerControl")] public int DecimalPlaces { - get { return (int)GetValue(DecimalPlacesProperty); } - set { SetValue(DecimalPlacesProperty, value); } + get => (int)GetValue(DecimalPlacesProperty); + set => SetValue(DecimalPlacesProperty, value); } private static readonly DependencyProperty DecimalPlacesProperty = @@ -209,8 +203,8 @@ public int DecimalPlaces [Category("SpinnerControl")] public decimal Change { - get { return (decimal)GetValue(ChangeProperty); } - set { SetValue(ChangeProperty, value); } + get => (decimal)GetValue(ChangeProperty); + set => SetValue(ChangeProperty, value); } private static readonly DependencyProperty ChangeProperty = @@ -246,7 +240,9 @@ protected static void OnIncreaseCommand(Object sender, ExecutedRoutedEventArgs e { var control = sender as SpinnerControl; if (control != null) + { control.OnIncrease(); + } } protected void OnIncrease() @@ -262,7 +258,9 @@ protected static void OnDecreaseCommand(Object sender, ExecutedRoutedEventArgs e { var control = sender as SpinnerControl; if (control != null) + { control.OnDecrease(); + } } protected void OnDecrease() @@ -320,8 +318,7 @@ private void TextBox_TextChanged(object sender, TextChangedEventArgs e) { var textBox = (TextBox)sender; - decimal val; - if (!string.IsNullOrEmpty(textBox.Text) && decimal.TryParse(textBox.Text, out val)) + if (!string.IsNullOrEmpty(textBox.Text) && decimal.TryParse(textBox.Text, out var val)) { Value = val; BorderBrush = _defaultBorderBrush; diff --git a/src/BuildVision.UI/Components/UserControl_ForTesting.xaml b/src/BuildVision.UI/Components/UserControl_ForTesting.xaml deleted file mode 100644 index 3ca36881..00000000 --- a/src/BuildVision.UI/Components/UserControl_ForTesting.xaml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/src/BuildVision.UI/Contracts/BuildInfo.cs b/src/BuildVision.UI/Contracts/BuildInfo.cs deleted file mode 100644 index 159a449e..00000000 --- a/src/BuildVision.UI/Contracts/BuildInfo.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using BuildVision.Contracts; -using BuildVision.UI.Models; - -namespace BuildVision.UI.Contracts -{ - public interface IBuildInfo - { - BuildActions? BuildAction { get; } - - BuildScopes? BuildScope { get; } - - BuildState CurrentBuildState { get; } - - bool BuildIsCancelled { get; } - - DateTime? BuildStartTime { get; } - - DateTime? BuildFinishTime { get; } - - BuildedProjectsCollection BuildedProjects { get; } - - IList BuildingProjects { get; } - - BuildedSolution BuildedSolution { get; } - - void OverrideBuildProperties(BuildActions? buildAction = null, BuildScopes? buildScope = null); - - ProjectItem BuildScopeProject { get; } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Contracts/BuildProjectContextEntry.cs b/src/BuildVision.UI/Contracts/BuildProjectContextEntry.cs deleted file mode 100644 index c7ef7bc6..00000000 --- a/src/BuildVision.UI/Contracts/BuildProjectContextEntry.cs +++ /dev/null @@ -1,28 +0,0 @@ -using BuildVision.UI.Models; -using System.Collections.Generic; - -namespace BuildVision.UI.Contracts -{ - public class BuildProjectContextEntry - { - public int InstanceId { get; set; } - - public int ContextId { get; set; } - - public string FileName { get; set; } - - public IDictionary Properties { get; set; } - - public ProjectItem ProjectItem { get; set; } - - public bool IsInvalid { get; set; } - - public BuildProjectContextEntry(int instanceId, int contextId, string fileName, IDictionary properties) - { - InstanceId = instanceId; - ContextId = contextId; - FileName = fileName; - Properties = properties; - } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Contracts/BuildProjectEventArgs.cs b/src/BuildVision.UI/Contracts/BuildProjectEventArgs.cs deleted file mode 100644 index 77144067..00000000 --- a/src/BuildVision.UI/Contracts/BuildProjectEventArgs.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using BuildVision.Contracts; -using BuildVision.UI.Models; - -namespace BuildVision.UI.Contracts -{ - public class BuildProjectEventArgs : EventArgs - { - public ProjectItem ProjectItem { get; private set; } - public ProjectState ProjectState { get; private set; } - public DateTime EventTime { get; private set; } - public BuildedProject BuildedProjectInfo { get; private set; } - - public BuildProjectEventArgs(ProjectItem projectItem, ProjectState projectState, DateTime eventTime, BuildedProject buildedProjectInfo) - { - ProjectItem = projectItem; - ProjectState = projectState; - EventTime = eventTime; - BuildedProjectInfo = buildedProjectInfo; - } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Contracts/BuildedProjectsCollection.cs b/src/BuildVision.UI/Contracts/BuildedProjectsCollection.cs deleted file mode 100644 index f6406220..00000000 --- a/src/BuildVision.UI/Contracts/BuildedProjectsCollection.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -using BuildVision.Contracts; -using BuildVision.UI.Models; - -namespace BuildVision.UI.Contracts -{ - // TODO: thread-safety. - public class BuildedProjectsCollection : List - { - public int BuildSuccessCount => this.Count(p => p.Success == true && p.ProjectState != ProjectState.BuildWarning && p.ProjectState != ProjectState.UpToDate); - public int BuildErrorCount => this.Count(p => p.Success == false); - public int BuildWarningsCount => this.Count(p => p.ProjectState == ProjectState.BuildWarning); - - public int BuildUpToDateCount => this.Count(p => p.ProjectState == ProjectState.UpToDate); - - public bool BuildWithoutErrors => this.All(p => p.Success == null || p.Success == true); - - /// - /// Get by . - /// If not exists, it has been created and added to the collection. - /// - public BuildedProject this[ProjectItem pi] - { - get - { - var proj = Find(p => p.UniqueName == pi.UniqueName && p.Configuration == pi.Configuration && p.Platform == pi.Platform); - if (proj == null) - { - proj = new BuildedProject(pi.UniqueName, pi.FullName, pi.Configuration, pi.Platform); - Add(proj); - } - - return proj; - } - } - } -} diff --git a/src/BuildVision.UI/Contracts/IBuildDistributor.cs b/src/BuildVision.UI/Contracts/IBuildDistributor.cs deleted file mode 100644 index e2d7ea6e..00000000 --- a/src/BuildVision.UI/Contracts/IBuildDistributor.cs +++ /dev/null @@ -1,18 +0,0 @@ -using BuildVision.Contracts; -using System; - -namespace BuildVision.UI.Contracts -{ - public interface IBuildDistributor - { - event EventHandler OnBuildBegin; - event EventHandler OnBuildProcess; - event EventHandler OnBuildDone; - event EventHandler OnBuildCancelled; - event EventHandler OnBuildProjectBegin; - event EventHandler OnBuildProjectDone; - event EventHandler OnErrorRaised; - - void CancelBuild(); - } -} diff --git a/src/BuildVision.UI/Controls/BuildVisionProgressBar.xaml b/src/BuildVision.UI/Controls/BuildVisionProgressBar.xaml new file mode 100644 index 00000000..7fb6e891 --- /dev/null +++ b/src/BuildVision.UI/Controls/BuildVisionProgressBar.xaml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/BuildVision.UI/Controls/BuildVisionProgressBar.xaml.cs b/src/BuildVision.UI/Controls/BuildVisionProgressBar.xaml.cs new file mode 100644 index 00000000..86f96aa3 --- /dev/null +++ b/src/BuildVision.UI/Controls/BuildVisionProgressBar.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace BuildVision.UI.Controls +{ + /// + /// Interaction logic for BuildVisionProgressBar.xaml + /// + public partial class BuildVisionProgressBar : UserControl + { + public BuildVisionProgressBar() + { + InitializeComponent(); + } + } +} diff --git a/src/BuildVision.UI/Controls/Buttons/BuildActionButton.cs b/src/BuildVision.UI/Controls/Buttons/BuildActionButton.cs new file mode 100644 index 00000000..872f0fbd --- /dev/null +++ b/src/BuildVision.UI/Controls/Buttons/BuildActionButton.cs @@ -0,0 +1,13 @@ +using System.Windows; +using System.Windows.Controls; + +namespace BuildVision.UI.Controls.Buttons +{ + public class BuildActionButton : Button + { + static BuildActionButton() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(BuildActionButton), new FrameworkPropertyMetadata(typeof(BuildActionButton))); + } + } +} diff --git a/src/BuildVision.UI/Controls/Indicators/ErrorProjectsIndicator.cs b/src/BuildVision.UI/Controls/Indicators/ErrorProjectsIndicator.cs new file mode 100644 index 00000000..9e5b9963 --- /dev/null +++ b/src/BuildVision.UI/Controls/Indicators/ErrorProjectsIndicator.cs @@ -0,0 +1,22 @@ +using System.Windows; + +namespace BuildVision.UI.Controls.Indicators +{ + public class ErrorProjectsIndicator : ValueIndicator + { + static ErrorProjectsIndicator() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ErrorProjectsIndicator), new FrameworkPropertyMetadata(typeof(ErrorProjectsIndicator))); + } + + public ErrorProjectsIndicator() + { + Header = UI.Resources.ErrorProjectsIndicator_Header; + } + + static void OnValueChange(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + d.SetValue(ValueProperty, (long)e.NewValue); + } + } +} diff --git a/src/BuildVision.UI/Controls/Indicators/ErrorsIndicator.cs b/src/BuildVision.UI/Controls/Indicators/ErrorsIndicator.cs new file mode 100644 index 00000000..fe5e3692 --- /dev/null +++ b/src/BuildVision.UI/Controls/Indicators/ErrorsIndicator.cs @@ -0,0 +1,22 @@ +using System.Windows; + +namespace BuildVision.UI.Controls.Indicators +{ + public class ErrorsIndicator : ValueIndicator + { + static ErrorsIndicator() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ErrorsIndicator), new FrameworkPropertyMetadata(typeof(ErrorsIndicator))); + } + + public ErrorsIndicator() + { + Header = UI.Resources.ErrorsIndicator_Header; + } + + static void OnValueChange(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + d.SetValue(ValueProperty, (long)e.NewValue); + } + } +} diff --git a/src/BuildVision.UI/Controls/Indicators/MessagesIndicator.cs b/src/BuildVision.UI/Controls/Indicators/MessagesIndicator.cs new file mode 100644 index 00000000..ec96368a --- /dev/null +++ b/src/BuildVision.UI/Controls/Indicators/MessagesIndicator.cs @@ -0,0 +1,22 @@ +using System.Windows; + +namespace BuildVision.UI.Controls.Indicators +{ + public class MessagesIndicator : ValueIndicator + { + static MessagesIndicator() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(MessagesIndicator), new FrameworkPropertyMetadata(typeof(MessagesIndicator))); + } + + public MessagesIndicator() + { + Header = UI.Resources.MessagesIndicator_Header; + } + + static void OnValueChange(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + d.SetValue(ValueProperty, (long)e.NewValue); + } + } +} diff --git a/src/BuildVision.UI/Controls/Indicators/SuccessProjectsIndicator.cs b/src/BuildVision.UI/Controls/Indicators/SuccessProjectsIndicator.cs new file mode 100644 index 00000000..c799dc35 --- /dev/null +++ b/src/BuildVision.UI/Controls/Indicators/SuccessProjectsIndicator.cs @@ -0,0 +1,22 @@ +using System.Windows; + +namespace BuildVision.UI.Controls.Indicators +{ + public class SuccessProjectsIndicator : ValueIndicator + { + static SuccessProjectsIndicator() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(SuccessProjectsIndicator), new FrameworkPropertyMetadata(typeof(SuccessProjectsIndicator))); + } + + public SuccessProjectsIndicator() + { + Header = UI.Resources.SuccessProjectsIndicator_Header; + } + + static void OnValueChange(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + d.SetValue(ValueProperty, (long)e.NewValue); + } + } +} diff --git a/src/BuildVision.UI/Controls/Indicators/UpToDateProjectsIndicator.cs b/src/BuildVision.UI/Controls/Indicators/UpToDateProjectsIndicator.cs new file mode 100644 index 00000000..a3e8be66 --- /dev/null +++ b/src/BuildVision.UI/Controls/Indicators/UpToDateProjectsIndicator.cs @@ -0,0 +1,22 @@ +using System.Windows; + +namespace BuildVision.UI.Controls.Indicators +{ + public class UpToDateProjectsIndicator : ValueIndicator + { + static UpToDateProjectsIndicator() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(UpToDateProjectsIndicator), new FrameworkPropertyMetadata(typeof(UpToDateProjectsIndicator))); + } + + public UpToDateProjectsIndicator() + { + Header = UI.Resources.UpToDateProjectsIndicator_Header; + } + + static void OnValueChange(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + d.SetValue(ValueProperty, (long)e.NewValue); + } + } +} diff --git a/src/BuildVision.UI/Controls/Indicators/ValueIndicator.cs b/src/BuildVision.UI/Controls/Indicators/ValueIndicator.cs new file mode 100644 index 00000000..943dceaf --- /dev/null +++ b/src/BuildVision.UI/Controls/Indicators/ValueIndicator.cs @@ -0,0 +1,60 @@ +using System.Windows; +using System.Windows.Controls; +using BuildVision.UI.Extensions; + +namespace BuildVision.UI.Controls.Indicators +{ + public class ValueIndicator : Control + { + public const string ResourcesUri = @"Resources/ValueIndicator.Resources.xaml"; + + public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(nameof(Header), typeof(string), typeof(ValueIndicator)); + + public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon), typeof(ControlTemplate), typeof(ValueIndicator), new PropertyMetadata(null)); + + public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( + nameof(Value), + typeof(long), + typeof(ValueIndicator), + new FrameworkPropertyMetadata( + defaultValue: (long)-1, + flags: + FrameworkPropertyMetadataOptions.AffectsArrange + | FrameworkPropertyMetadataOptions.AffectsMeasure + | FrameworkPropertyMetadataOptions.AffectsRender, + propertyChangedCallback: new PropertyChangedCallback(OnValueChange))); + + static ValueIndicator() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ValueIndicator), new FrameworkPropertyMetadata(typeof(ValueIndicator))); + } + + public ValueIndicator() + { + Icon = VectorResources.TryGet(ResourcesUri, $"{GetType().Name}Icon"); + } + + public long Value + { + get => (long)GetValue(ValueProperty); + set => SetValue(ValueProperty, value); + } + + public string Header + { + get => (string)GetValue(HeaderProperty); + set => SetValue(HeaderProperty, value); + } + + public ControlTemplate Icon + { + get => (ControlTemplate)GetValue(IconProperty); + set => SetValue(IconProperty, value); + } + + static void OnValueChange(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + d.SetValue(ValueProperty, (long)e.NewValue); + } + } +} diff --git a/src/BuildVision.UI/Controls/Indicators/WarningProjectsIndicator.cs b/src/BuildVision.UI/Controls/Indicators/WarningProjectsIndicator.cs new file mode 100644 index 00000000..a85c6772 --- /dev/null +++ b/src/BuildVision.UI/Controls/Indicators/WarningProjectsIndicator.cs @@ -0,0 +1,22 @@ +using System.Windows; + +namespace BuildVision.UI.Controls.Indicators +{ + public class WarningProjectsIndicator : ValueIndicator + { + static WarningProjectsIndicator() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(WarningProjectsIndicator), new FrameworkPropertyMetadata(typeof(WarningProjectsIndicator))); + } + + public WarningProjectsIndicator() + { + Header = UI.Resources.WarningProjectsIndicator_Header; + } + + static void OnValueChange(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + d.SetValue(ValueProperty, (long)e.NewValue); + } + } +} diff --git a/src/BuildVision.UI/Controls/Indicators/WarningsIndicator.cs b/src/BuildVision.UI/Controls/Indicators/WarningsIndicator.cs new file mode 100644 index 00000000..f92db81a --- /dev/null +++ b/src/BuildVision.UI/Controls/Indicators/WarningsIndicator.cs @@ -0,0 +1,22 @@ +using System.Windows; + +namespace BuildVision.UI.Controls.Indicators +{ + public class WarningsIndicator : ValueIndicator + { + static WarningsIndicator() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(WarningsIndicator), new FrameworkPropertyMetadata(typeof(WarningsIndicator))); + } + + public WarningsIndicator() + { + Header = UI.Resources.WarningsIndicator_Header; + } + + static void OnValueChange(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + d.SetValue(ValueProperty, (long)e.NewValue); + } + } +} diff --git a/src/BuildVision.UI/Converters/AlternatingRowBackgroundConverter.cs b/src/BuildVision.UI/Converters/AlternatingRowBackgroundConverter.cs index a19e4596..86fd46ad 100644 --- a/src/BuildVision.UI/Converters/AlternatingRowBackgroundConverter.cs +++ b/src/BuildVision.UI/Converters/AlternatingRowBackgroundConverter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Globalization; using System.Windows.Data; using System.Windows.Media; @@ -13,11 +13,12 @@ public class AlternatingRowBackgroundConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - var backg = value as SolidColorBrush; - if (backg == null) + if (!(value is SolidColorBrush backg)) + { return value; + } - Color color = backg.Color; + var color = backg.Color; int darkerDelta = -15; int r = color.R + darkerDelta; @@ -51,9 +52,20 @@ public object Convert(object value, Type targetType, object parameter, CultureIn g = color.G + lighterDelta; b = color.B + lighterDelta; - if (r > 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; + if (r > 255) + { + r = 255; + } + + if (g > 255) + { + g = 255; + } + + if (b > 255) + { + b = 255; + } } var newColor = Color.FromArgb(255, (byte)r, (byte)g, (byte)b); @@ -65,4 +77,4 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Converters/BooleanToHiddenConverter.cs b/src/BuildVision.UI/Converters/BooleanToHiddenConverter.cs new file mode 100644 index 00000000..8b920a78 --- /dev/null +++ b/src/BuildVision.UI/Converters/BooleanToHiddenConverter.cs @@ -0,0 +1,31 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace BuildVision.UI.Converters +{ + [ValueConversion(typeof(bool), typeof(Visibility))] + public class BooleanToHiddenConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + bool flag = false; + if (value is bool) + { + flag = (bool)value; + } + else if (value is bool?) + { + var nullable = (bool?)value; + flag = nullable.HasValue && nullable.Value; + } + return flag ? Visibility.Hidden : Visibility.Visible; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return value is Visibility ? (Visibility)value == Visibility.Hidden : (object)false; + } + } +} diff --git a/src/BuildVision.UI/Converters/ColumnWidthConverter.cs b/src/BuildVision.UI/Converters/ColumnWidthConverter.cs index 177ef40a..be9d2595 100644 --- a/src/BuildVision.UI/Converters/ColumnWidthConverter.cs +++ b/src/BuildVision.UI/Converters/ColumnWidthConverter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Globalization; using System.Windows.Data; @@ -9,20 +9,13 @@ public class ColumnWidthConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - double val = (double)value; - - if (double.IsNaN(val)) - return "auto"; - - return val; + var val = (double)value; + return double.IsNaN(val) ? "auto" : (object)val; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { - if (value as string == "auto") - return double.NaN; - - return value; + return value as string == "auto" ? double.NaN : value; } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Converters/DataGridLengthStringConverter.cs b/src/BuildVision.UI/Converters/DataGridLengthStringConverter.cs index 05f91ca9..0dfa6aee 100644 --- a/src/BuildVision.UI/Converters/DataGridLengthStringConverter.cs +++ b/src/BuildVision.UI/Converters/DataGridLengthStringConverter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Globalization; using System.Windows.Controls; using System.Windows.Data; @@ -13,12 +13,11 @@ public object Convert(object value, Type targetType, object parameter, CultureIn var val = (DataGridLength)value; if (val.IsAuto) - return "auto"; - - if (val.IsStar) - return val.DisplayValue.ToString("0.0") + "*"; + { + return "auto"; + } - return val.Value.ToString("0.0"); + return val.IsStar ? val.DisplayValue.ToString("0.0") + "*" : val.Value.ToString("0.0"); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) @@ -28,10 +27,14 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu var val = ((string)value).Trim().ToLower(); if (val == "auto") + { return new DataGridLength(1.0, DataGridLengthUnitType.Auto); + } - if (val.EndsWith("*")) + if (val.EndsWith("*", StringComparison.InvariantCulture)) + { return new DataGridLength(double.Parse(val.TrimEnd('*')), DataGridLengthUnitType.Star); + } return new DataGridLength(double.Parse(val)); } @@ -41,4 +44,4 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu } } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Converters/ExpanderIsExpandedConverter.cs b/src/BuildVision.UI/Converters/ExpanderIsExpandedConverter.cs index ab7d6f5d..14e823db 100644 --- a/src/BuildVision.UI/Converters/ExpanderIsExpandedConverter.cs +++ b/src/BuildVision.UI/Converters/ExpanderIsExpandedConverter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Windows.Controls; @@ -11,10 +11,11 @@ public class ExpanderIsExpandedConverter : IMultiValueConverter public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { var collectionViewGroup = (CollectionViewGroup)values[0]; - var collapsedGroups = (IList)values[1]; - if (collapsedGroups == null || collapsedGroups.Count == 0) + if (!(values[1] is IList collapsedGroups) || collapsedGroups.Count == 0) + { return true; + } string groupId = GetGroupIdentifier(collectionViewGroup); bool collapsed = collapsedGroups.Contains(groupId); @@ -28,15 +29,18 @@ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, public static void SaveState(Expander exp, bool collapsed, IList collapsedGroups) { - var collectionViewGroup = exp.DataContext as CollectionViewGroup; - if (collectionViewGroup == null) + if (!(exp.DataContext is CollectionViewGroup collectionViewGroup)) + { return; + } string groupId = GetGroupIdentifier(collectionViewGroup); if (collapsed) { if (!collapsedGroups.Contains(groupId)) + { collapsedGroups.Add(groupId); + } } else { @@ -48,12 +52,11 @@ private static string GetGroupIdentifier(CollectionViewGroup collectionViewGroup { object groupId = collectionViewGroup.Name; if (groupId == null) + { return null; + } - if (groupId is string) - return (string)groupId; - - return groupId.ToString(); + return groupId is string ? (string)groupId : groupId.ToString(); } } } diff --git a/src/BuildVision.UI/Converters/GridColumnSettingsToColumnExampleValueConverter.cs b/src/BuildVision.UI/Converters/GridColumnSettingsToColumnExampleValueConverter.cs index b3439b07..ffbd26da 100644 --- a/src/BuildVision.UI/Converters/GridColumnSettingsToColumnExampleValueConverter.cs +++ b/src/BuildVision.UI/Converters/GridColumnSettingsToColumnExampleValueConverter.cs @@ -1,8 +1,6 @@ -using System; +using System; using System.Globalization; using System.Windows.Data; - -using BuildVision.UI; using BuildVision.UI.DataGrid; using BuildVision.UI.Settings.Models.Columns; @@ -23,18 +21,26 @@ public object Convert(object[] values, Type targetType, object parameter, Cultur private static string FormatExample(object example, string stringFormat) { if (example == null) + { return Resources.GridCellNoneTextInBrackets; + } try { if (string.IsNullOrWhiteSpace(stringFormat)) + { return example.ToString(); + } if (example is DateTime) + { return ((DateTime)example).ToString(stringFormat); + } if (example is TimeSpan) + { return ((TimeSpan)example).ToString(stringFormat); + } return string.Format(stringFormat, example); } @@ -49,4 +55,4 @@ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, throw new InvalidOperationException(); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Converters/IsErrorToBorderThicknessConverter.cs b/src/BuildVision.UI/Converters/InProgressToBoolConverter.cs similarity index 59% rename from src/BuildVision.UI/Converters/IsErrorToBorderThicknessConverter.cs rename to src/BuildVision.UI/Converters/InProgressToBoolConverter.cs index 8d5bba32..71f80f74 100644 --- a/src/BuildVision.UI/Converters/IsErrorToBorderThicknessConverter.cs +++ b/src/BuildVision.UI/Converters/InProgressToBoolConverter.cs @@ -1,17 +1,17 @@ -using System; +using System; using System.Globalization; -using System.Windows; using System.Windows.Data; +using BuildVision.Contracts; namespace BuildVision.UI.Converters { - [ValueConversion(typeof(bool), typeof(Thickness))] - public class IsErrorToBorderThicknessConverter : IValueConverter + [ValueConversion(typeof(BuildState), typeof(bool))] + public class InProgressToBoolConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - var isError = (bool)value; - return isError ? new Thickness(1) : new Thickness(0); + var buildState = (BuildState)value; + return buildState == BuildState.InProgress; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) @@ -19,4 +19,4 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Converters/InProgressToCollapsedConverter.cs b/src/BuildVision.UI/Converters/InProgressToCollapsedConverter.cs new file mode 100644 index 00000000..2fe585a9 --- /dev/null +++ b/src/BuildVision.UI/Converters/InProgressToCollapsedConverter.cs @@ -0,0 +1,23 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; +using BuildVision.Contracts; + +namespace BuildVision.UI.Converters +{ + [ValueConversion(typeof(BuildState), typeof(Visibility))] + public class InProgressToCollapsedConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var buildState = (BuildState)value; + return buildState == BuildState.InProgress ? Visibility.Collapsed : Visibility.Visible; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/BuildVision.UI/Converters/InProgressToVisibleConverter.cs b/src/BuildVision.UI/Converters/InProgressToVisibleConverter.cs new file mode 100644 index 00000000..0f6a911b --- /dev/null +++ b/src/BuildVision.UI/Converters/InProgressToVisibleConverter.cs @@ -0,0 +1,23 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; +using BuildVision.Contracts; + +namespace BuildVision.UI.Converters +{ + [ValueConversion(typeof(BuildState), typeof(Visibility))] + public class InProgressToVisibleConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var buildState = (BuildState)value; + return buildState == BuildState.InProgress ? Visibility.Visible : Visibility.Collapsed; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/BuildVision.UI/Converters/IndicatorVectorIconConverter.cs b/src/BuildVision.UI/Converters/IndicatorVectorIconConverter.cs deleted file mode 100644 index bd5f289b..00000000 --- a/src/BuildVision.UI/Converters/IndicatorVectorIconConverter.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Diagnostics; -using System.Globalization; -using System.Windows.Controls; -using System.Windows.Data; - -using BuildVision.UI.Models.Indicators.Core; -using BuildVision.UI.Extensions; - -namespace BuildVision.UI.Converters -{ - [ValueConversion(typeof(ValueIndicator), typeof(ControlTemplate))] - public class IndicatorVectorIconConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - Debug.Assert(value is ValueIndicator); - return VectorResources.TryGet(ValueIndicator.ResourcesUri, value.GetType().Name); - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotSupportedException(); - } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Converters/IsSeparatorIndicatorConverter.cs b/src/BuildVision.UI/Converters/IsSeparatorIndicatorConverter.cs deleted file mode 100644 index 82829877..00000000 --- a/src/BuildVision.UI/Converters/IsSeparatorIndicatorConverter.cs +++ /dev/null @@ -1,22 +0,0 @@ -using BuildVision.UI.Models.Indicators; -using BuildVision.UI.Models.Indicators.Core; -using System; -using System.Globalization; -using System.Windows.Data; - -namespace BuildVision.UI.Converters -{ - [ValueConversion(typeof(ValueIndicator), typeof(bool))] - public class IsSeparatorIndicatorConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - return (value is SeparatorIndicator); - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new InvalidOperationException(); - } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Converters/MultiBindingStringFormatConverter.cs b/src/BuildVision.UI/Converters/MultiBindingStringFormatConverter.cs index 217e7733..1280542b 100644 --- a/src/BuildVision.UI/Converters/MultiBindingStringFormatConverter.cs +++ b/src/BuildVision.UI/Converters/MultiBindingStringFormatConverter.cs @@ -1,9 +1,9 @@ -using System; +using System; using System.Globalization; using System.Linq; using System.Windows.Data; using BuildVision.Common; -using BuildVision.UI.Common.Logging; +using BuildVision.Common.Logging; namespace BuildVision.UI.Converters { @@ -16,7 +16,9 @@ public class MultiBindingStringFormatConverter : IMultiValueConverter public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values == null || values.Length < 2) + { return string.Empty; + } try { @@ -25,7 +27,7 @@ public object Convert(object[] values, Type targetType, object parameter, Cultur } catch (Exception ex) { - ex.Trace("Format error: " + ex.Message); + LogManager.ForContext().Error(ex, "Error during MultiBindingStringFormatConverter."); return string.Format("", ex.Message); } } @@ -35,4 +37,4 @@ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, throw new InvalidOperationException(); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Converters/NumberToIsPositiveConverter.cs b/src/BuildVision.UI/Converters/NumberToIsPositiveConverter.cs index b6470a5f..46f83c87 100644 --- a/src/BuildVision.UI/Converters/NumberToIsPositiveConverter.cs +++ b/src/BuildVision.UI/Converters/NumberToIsPositiveConverter.cs @@ -9,9 +9,10 @@ public class NumberToIsPositiveConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - double val; - if (value != null && double.TryParse(value.ToString(), out val)) + if (value != null && double.TryParse(value.ToString(), out var val)) + { return val > 0; + } return false; } @@ -21,4 +22,4 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu throw new InvalidOperationException(); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Converters/ObjectsReferencesEqualsConverter.cs b/src/BuildVision.UI/Converters/ObjectsReferencesEqualsConverter.cs index e34707c3..d12cf1b2 100644 --- a/src/BuildVision.UI/Converters/ObjectsReferencesEqualsConverter.cs +++ b/src/BuildVision.UI/Converters/ObjectsReferencesEqualsConverter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Globalization; using System.Windows.Data; @@ -12,7 +12,9 @@ public object Convert(object[] values, Type targetType, object parameter, Cultur for (int i = 0; i < values.Length - 1; i++) { if (!ReferenceEquals(values[i], values[i + 1])) + { return false; + } } return true; @@ -23,4 +25,4 @@ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, throw new InvalidOperationException(); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Converters/StateIconKeyToIconConverter.cs b/src/BuildVision.UI/Converters/StateIconKeyToIconConverter.cs new file mode 100644 index 00000000..daba00e5 --- /dev/null +++ b/src/BuildVision.UI/Converters/StateIconKeyToIconConverter.cs @@ -0,0 +1,27 @@ +using System; +using System.Globalization; +using System.Windows.Controls; +using System.Windows.Data; +using BuildVision.UI.Extensions; + +namespace BuildVision.UI.Converters +{ + [ValueConversion(typeof(string), typeof(ControlTemplate))] + public class StateIconKeyToIconConverter : IValueConverter + { + public const string ResourcesUri = @"Resources/BuildState.Resources.xaml"; + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var stateIconKey = (string)value; + var vector = VectorResources.TryGet(ResourcesUri, stateIconKey) ?? VectorResources.TryGet(ResourcesUri, "StandBy"); + return vector; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + // hope this works.. we don´t need back conversion I guess + return value; + } + } +} diff --git a/src/BuildVision.UI/Converters/SubtractConstantConverter.cs b/src/BuildVision.UI/Converters/SubtractConstantConverter.cs index 94f1e477..6873b0b4 100644 --- a/src/BuildVision.UI/Converters/SubtractConstantConverter.cs +++ b/src/BuildVision.UI/Converters/SubtractConstantConverter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Globalization; using System.Windows.Data; @@ -19,4 +19,4 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu return null; } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Converters/VisibilityToBooleanConverter.cs b/src/BuildVision.UI/Converters/VisibilityToBooleanConverter.cs index 728c96c1..ebee53b9 100644 --- a/src/BuildVision.UI/Converters/VisibilityToBooleanConverter.cs +++ b/src/BuildVision.UI/Converters/VisibilityToBooleanConverter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Globalization; using System.Windows; using System.Windows.Controls; @@ -19,4 +19,4 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu return (new BooleanToVisibilityConverter()).Convert(value, targetType, parameter, culture); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/DataGrid/ColumnsManager.cs b/src/BuildVision.UI/DataGrid/ColumnsManager.cs index fbf17a78..ffde95f2 100644 --- a/src/BuildVision.UI/DataGrid/ColumnsManager.cs +++ b/src/BuildVision.UI/DataGrid/ColumnsManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; @@ -8,26 +8,27 @@ using System.Windows.Data; using System.Windows.Media; using System.Windows.Media.Imaging; -using BuildVision.Contracts; -using BuildVision.UI.Modelss; -using BuildVision.UI.Helpers; +using BuildVision.Common.Logging; +using BuildVision.Contracts.Exceptions; using BuildVision.UI.Extensions; -using BuildVision.UI.Common.Logging; +using BuildVision.UI.Helpers; using BuildVision.UI.Models; +using BuildVision.UI.Modelss; +using BuildVision.UI.Settings.Models; using BuildVision.UI.Settings.Models.Columns; using BuildVision.UI.Settings.Models.Sorting; -using BuildVision.UI.Settings.Models; +using Serilog; namespace BuildVision.UI.DataGrid { public static class ColumnsManager { - private static List _nonSortableColumns = new List + private static readonly List _nonSortableColumns = new List { nameof(ProjectItem.StateBitmap) }; - private static List _nonGroupableColumns = new List + private static readonly List _nonGroupableColumns = new List { nameof(ProjectItem.StateBitmap), nameof(ProjectItem.BuildStartTime), @@ -67,14 +68,20 @@ public static object GetColumnExampleValue(GridColumnSettings gridColumnSettings public static bool ColumnIsSortable(string propertyName) { if (_nonSortableColumns.Contains(propertyName)) + { return false; + } + return true; } public static bool ColumnIsGroupable(GridColumnSettings gridColumnSettings) { if (_nonGroupableColumns.Contains(gridColumnSettings.PropertyNameId)) + { return false; + } + return true; } @@ -100,7 +107,9 @@ public static void GenerateColumns(ObservableCollection columns, { GridColumnAttribute columnConfiguration = property.GetCustomAttribute(); if (columnConfiguration == null) + { continue; + } string propertyName = property.Name; GridColumnSettings columnSettings; @@ -112,11 +121,11 @@ public static void GenerateColumns(ObservableCollection columns, else { columnSettings = new GridColumnSettings( - propertyName, - columnConfiguration.Header, - columnConfiguration.Visible, - columnConfiguration.DisplayIndex, - columnConfiguration.Width, + propertyName, + columnConfiguration.Header, + columnConfiguration.Visible, + columnConfiguration.DisplayIndex, + columnConfiguration.Width, columnConfiguration.ValueStringFormat); gridSettings.Columns.Add(columnSettings); } @@ -138,7 +147,7 @@ public static void GenerateColumns(ObservableCollection columns, } catch (Exception ex) { - ex.TraceUnknownException(); + LogManager.ForContext(typeof(ColumnsManager)).Error(ex, "Failed to sync generatecolumns."); } } @@ -149,9 +158,11 @@ public static void SyncColumnSettings(ObservableCollection colum foreach (DataGridBoundColumn column in columns.OfType()) { string propertyName = column.GetBindedProperty(); - GridColumnSettings columnSettings = gridSettings.Columns[propertyName]; + var columnSettings = gridSettings.Columns[propertyName]; if (columnSettings == null) + { continue; + } columnSettings.Visible = (column.Visibility == Visibility.Visible); columnSettings.DisplayIndex = column.DisplayIndex; @@ -160,7 +171,7 @@ public static void SyncColumnSettings(ObservableCollection colum } catch (Exception ex) { - ex.TraceUnknownException(); + LogManager.ForContext(typeof(ColumnsManager)).Error(ex, "Failed to sync columnsettings."); } } @@ -168,11 +179,15 @@ public static string GetBindedProperty(this DataGridColumn column) { var boundColumn = column as DataGridBoundColumn; if (boundColumn == null) + { return string.Empty; + } var binding = boundColumn.Binding as Binding; if (binding == null) + { return string.Empty; + } return binding.Path.Path; } @@ -189,7 +204,7 @@ private static T GetPropertyAttribute(string propertyName) if (propertyInfo == null) { var ex = new PropertyNotFoundException(propertyName, _itemRowType); - ex.Trace("Unable to find attribute by property."); + LogManager.ForContext(typeof(ColumnsManager)).Error(ex, "Failed to load data for property {PropertyName}.", propertyName); throw ex; } @@ -210,13 +225,22 @@ private static DataGridBoundColumn CreateColumnForProperty(PropertyInfo property { DataGridBoundColumn column; if (property.PropertyType == typeof(BitmapSource) || property.PropertyType == typeof(ImageSource)) + { column = new DataGridImageColumn(); + } else if (property.PropertyType == typeof(ControlTemplate)) + { column = new DataGridContentControlColumn(); + } else if (property.PropertyType == typeof(bool)) + { column = new DataGridCheckBoxColumn(); + } else + { column = new DataGridTextColumn(); + } + return column; } @@ -265,22 +289,32 @@ private static void InitColumn(DataGridBoundColumn column, GridColumnAttribute c column.Visibility = columnSettings.Visible ? Visibility.Visible : Visibility.Collapsed; if (columnSettings.DisplayIndex != -1) + { column.DisplayIndex = columnSettings.DisplayIndex; + } if (!double.IsNaN(columnSettings.Width)) + { column.Width = new DataGridLength(columnSettings.Width); + } if (columnSettings.ValueStringFormat != null) + { column.Binding.StringFormat = columnSettings.ValueStringFormat; + } if (column.GetBindedProperty() == sortDescription.Property) + { column.SortDirection = sortDescription.Order.ToSystem(); + } string columnName = columnSettings.Header; if (string.IsNullOrEmpty(columnName)) + { columnName = columnConfiguration.Header; + } column.SetValue(DataGridColumnExtensions.NameProperty, columnName); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/DataGrid/DataGridContentControlColumn.cs b/src/BuildVision.UI/DataGrid/DataGridContentControlColumn.cs index 5ead63b3..235c8497 100644 --- a/src/BuildVision.UI/DataGrid/DataGridContentControlColumn.cs +++ b/src/BuildVision.UI/DataGrid/DataGridContentControlColumn.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Windows; using System.Windows.Controls; using System.Windows.Data; @@ -9,9 +9,11 @@ public class DataGridContentControlColumn : DataGridBoundColumn { protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) { - ContentControl contentControl = (cell != null) ? (cell.Content as ContentControl) : null; + var contentControl = (cell != null) ? (cell.Content as ContentControl) : null; if (contentControl == null) + { contentControl = new ContentControl(); + } contentControl.ClipToBounds = true; contentControl.SnapsToDevicePixels = true; @@ -26,4 +28,4 @@ protected override FrameworkElement GenerateEditingElement(DataGridCell cell, ob throw new InvalidOperationException(); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/DataGrid/DataGridImageColumn.cs b/src/BuildVision.UI/DataGrid/DataGridImageColumn.cs index 79d8005b..a0c254e4 100644 --- a/src/BuildVision.UI/DataGrid/DataGridImageColumn.cs +++ b/src/BuildVision.UI/DataGrid/DataGridImageColumn.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Windows; using System.Windows.Controls; using System.Windows.Data; @@ -10,9 +10,11 @@ public class DataGridImageColumn : DataGridBoundColumn { protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) { - Image image = (cell != null) ? (cell.Content as Image) : null; + var image = (cell != null) ? (cell.Content as Image) : null; if (image == null) + { image = new Image(); + } image.Stretch = Stretch.None; image.SnapsToDevicePixels = true; @@ -25,4 +27,4 @@ protected override FrameworkElement GenerateEditingElement(DataGridCell cell, ob throw new InvalidOperationException(); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Models/BuildExtraMessageFormat.cs b/src/BuildVision.UI/Enums/BuildExtraMessageFormat.cs similarity index 94% rename from src/BuildVision.UI/Models/BuildExtraMessageFormat.cs rename to src/BuildVision.UI/Enums/BuildExtraMessageFormat.cs index 731d461f..ca0bfd90 100644 --- a/src/BuildVision.UI/Models/BuildExtraMessageFormat.cs +++ b/src/BuildVision.UI/Enums/BuildExtraMessageFormat.cs @@ -1,4 +1,4 @@ -using BuildVision.UI.Helpers; +using BuildVision.UI.Helpers; namespace BuildVision.UI.Models { @@ -16,4 +16,4 @@ public enum BuildExtraMessageFormat [DisplayString(ResourceName = nameof(Resources.EnumBuildStateExtraLabelTemplate_TotalMinutesWithSeconds))] TotalMinutesWithSeconds } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Models/BuildMajorMessageFormat.cs b/src/BuildVision.UI/Enums/BuildMajorMessageFormat.cs similarity index 89% rename from src/BuildVision.UI/Models/BuildMajorMessageFormat.cs rename to src/BuildVision.UI/Enums/BuildMajorMessageFormat.cs index b9e8caa9..4352d695 100644 --- a/src/BuildVision.UI/Models/BuildMajorMessageFormat.cs +++ b/src/BuildVision.UI/Enums/BuildMajorMessageFormat.cs @@ -1,4 +1,4 @@ -using BuildVision.UI.Helpers; +using BuildVision.UI.Helpers; namespace BuildVision.UI.Models { @@ -10,4 +10,4 @@ public enum BuildMajorMessageFormat [DisplayString(ResourceName = nameof(Resources.EnumBuildStateLabelTemplate_ShortForm))] Unnamed } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Models/NavigateToBuildFailureReasonCondition.cs b/src/BuildVision.UI/Enums/NavigateToBuildFailureReasonCondition.cs similarity index 99% rename from src/BuildVision.UI/Models/NavigateToBuildFailureReasonCondition.cs rename to src/BuildVision.UI/Enums/NavigateToBuildFailureReasonCondition.cs index ca707e7e..ad85b36b 100644 --- a/src/BuildVision.UI/Models/NavigateToBuildFailureReasonCondition.cs +++ b/src/BuildVision.UI/Enums/NavigateToBuildFailureReasonCondition.cs @@ -13,4 +13,4 @@ public enum NavigateToBuildFailureReasonCondition [DisplayString(ResourceName = nameof(Resources.NavigateToBuildFailureReasonCondition_OnBuildDone))] OnBuildDone } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Models/ResetTaskBarItemInfoCondition.cs b/src/BuildVision.UI/Enums/ResetTaskBarItemInfoCondition.cs similarity index 99% rename from src/BuildVision.UI/Models/ResetTaskBarItemInfoCondition.cs rename to src/BuildVision.UI/Enums/ResetTaskBarItemInfoCondition.cs index 4cc63b53..2af5da3f 100644 --- a/src/BuildVision.UI/Models/ResetTaskBarItemInfoCondition.cs +++ b/src/BuildVision.UI/Enums/ResetTaskBarItemInfoCondition.cs @@ -16,4 +16,4 @@ public enum ResetTaskBarItemInfoCondition [DisplayString(ResourceName = nameof(Resources.ResetTaskBarItemInfoCondition_ByMouseClick))] ByMouseClick } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Models/SortOrder.cs b/src/BuildVision.UI/Enums/SortOrder.cs similarity index 86% rename from src/BuildVision.UI/Models/SortOrder.cs rename to src/BuildVision.UI/Enums/SortOrder.cs index 85c16854..5b8f3b28 100644 --- a/src/BuildVision.UI/Models/SortOrder.cs +++ b/src/BuildVision.UI/Enums/SortOrder.cs @@ -1,5 +1,4 @@ -using BuildVision.UI; -using BuildVision.UI.Helpers; +using BuildVision.UI.Helpers; namespace BuildVision.UI.Models { @@ -14,4 +13,4 @@ public enum SortOrder [DisplayString(ResourceName = nameof(Resources.EnumSortOrder_Desc))] Descending } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Models/WindowState.cs b/src/BuildVision.UI/Enums/WindowState.cs similarity index 91% rename from src/BuildVision.UI/Models/WindowState.cs rename to src/BuildVision.UI/Enums/WindowState.cs index 14f57e61..24cb1ed9 100644 --- a/src/BuildVision.UI/Models/WindowState.cs +++ b/src/BuildVision.UI/Enums/WindowState.cs @@ -1,5 +1,4 @@ -using BuildVision.UI; -using BuildVision.UI.Helpers; +using BuildVision.UI.Helpers; namespace BuildVision.UI.Models { @@ -20,4 +19,4 @@ public enum WindowState [DisplayString(ResourceName = nameof(Resources.EnumWindowState_Close))] Close } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Extensions/BindingExtensions.cs b/src/BuildVision.UI/Extensions/BindingExtensions.cs index a001d3c8..b7b8945a 100644 --- a/src/BuildVision.UI/Extensions/BindingExtensions.cs +++ b/src/BuildVision.UI/Extensions/BindingExtensions.cs @@ -1,5 +1,4 @@ -using System.Windows; -using System.Windows.Data; +using System.Windows; namespace BuildVision.UI.Extensions { @@ -7,16 +6,14 @@ public static class BindingExtensions { public static void UpdateTarget(this FrameworkElement element, DependencyProperty property) { - BindingExpression expression = element.GetBindingExpression(property); - if (expression != null) - expression.UpdateTarget(); + var expression = element.GetBindingExpression(property); + expression?.UpdateTarget(); } public static void UpdateSource(this FrameworkElement element, DependencyProperty property) { - BindingExpression expression = element.GetBindingExpression(property); - if (expression != null) - expression.UpdateSource(); + var expression = element.GetBindingExpression(property); + expression?.UpdateSource(); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Extensions/DataGridColumnExtensions.cs b/src/BuildVision.UI/Extensions/DataGridColumnExtensions.cs index 354f710e..33a9d049 100644 --- a/src/BuildVision.UI/Extensions/DataGridColumnExtensions.cs +++ b/src/BuildVision.UI/Extensions/DataGridColumnExtensions.cs @@ -9,20 +9,14 @@ public static class DataGridColumnExtensions typeof(string), typeof(DataGridColumnExtensions)); - /// - /// Gets the value of the dependency property. - /// public static string GetName(DependencyObject obj) { return (string)obj.GetValue(NameProperty); } - /// - /// Sets the value of the dependency property. - /// public static void SetName(DependencyObject obj, string value) { obj.SetValue(NameProperty, value); - } + } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Extensions/EnumerationExtension.cs b/src/BuildVision.UI/Extensions/EnumerationExtension.cs index f795cebe..bf5ff149 100644 --- a/src/BuildVision.UI/Extensions/EnumerationExtension.cs +++ b/src/BuildVision.UI/Extensions/EnumerationExtension.cs @@ -1,7 +1,7 @@ -using BuildVision.UI.Helpers; -using System; +using System; using System.Linq; using System.Windows.Markup; +using BuildVision.UI.Helpers; namespace BuildVision.UI.Extensions { @@ -12,7 +12,9 @@ public class EnumerationExtension : MarkupExtension public EnumerationExtension(Type enumType) { if (enumType == null) + { throw new ArgumentNullException("enumType"); + } SetEnumType(enumType); } @@ -20,12 +22,16 @@ public EnumerationExtension(Type enumType) private void SetEnumType(Type value) { if (_enumType == value) + { return; + } var enumType = Nullable.GetUnderlyingType(value) ?? value; if (enumType.IsEnum == false) + { throw new ArgumentException("Type must be an Enum."); + } _enumType = value; } @@ -51,4 +57,4 @@ private string GetDescription(object enumValue) : enumValue.ToString(); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Extensions/ProjectStateExtensions.cs b/src/BuildVision.UI/Extensions/ProjectStateExtensions.cs index 100eba83..2f08a65f 100644 --- a/src/BuildVision.UI/Extensions/ProjectStateExtensions.cs +++ b/src/BuildVision.UI/Extensions/ProjectStateExtensions.cs @@ -1,5 +1,5 @@ +using System.Windows.Controls; using BuildVision.Contracts; -using System.Windows.Controls; namespace BuildVision.UI.Extensions { @@ -8,7 +8,6 @@ public static class ProjectStateExtensions public static bool IsErrorState(this ProjectState state) { return state == ProjectState.BuildError || state == ProjectState.CleanError; - } public static ControlTemplate GetAssociatedContent(this ProjectState state) diff --git a/src/BuildVision.UI/Extensions/TextBlockUtils.cs b/src/BuildVision.UI/Extensions/TextBlockUtils.cs index 29901f63..62713946 100644 --- a/src/BuildVision.UI/Extensions/TextBlockUtils.cs +++ b/src/BuildVision.UI/Extensions/TextBlockUtils.cs @@ -5,29 +5,17 @@ namespace BuildVision.UI.Extensions { public class TextBlockUtils { - /// - /// Identified the attached AutoTooltip property. - /// When true, this will set the - /// property to , and display a tooltip - /// with the full text whenever the text is trimmed. - /// public static readonly DependencyProperty AutoTooltipProperty = DependencyProperty.RegisterAttached( "AutoTooltip", typeof(bool), typeof(TextBlockUtils), new PropertyMetadata(false, OnAutoTooltipPropertyChanged)); - /// - /// Gets the value of the dependency property. - /// public static bool GetAutoTooltip(DependencyObject obj) { return (bool)obj.GetValue(AutoTooltipProperty); } - /// - /// Sets the value of the dependency property. - /// public static void SetAutoTooltip(DependencyObject obj, bool value) { obj.SetValue(AutoTooltipProperty, value); @@ -37,7 +25,9 @@ private static void OnAutoTooltipPropertyChanged(DependencyObject obj, Dependenc { var textBlock = obj as TextBlock; if (textBlock == null) + { return; + } if (e.NewValue.Equals(true)) { @@ -57,9 +47,6 @@ private static void TextBlock_SizeChanged(object sender, SizeChangedEventArgs e) ComputeAutoTooltip(textBlock); } - /// - /// Assigns the ToolTip for the given TextBlock based on whether the text is trimmed. - /// private static void ComputeAutoTooltip(TextBlock textBlock) { textBlock.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); diff --git a/src/BuildVision.UI/Extensions/VectorResources.cs b/src/BuildVision.UI/Extensions/VectorResources.cs index afcbbe4d..4d1c067d 100644 --- a/src/BuildVision.UI/Extensions/VectorResources.cs +++ b/src/BuildVision.UI/Extensions/VectorResources.cs @@ -1,5 +1,4 @@ -using BuildVision.UI; -using System; +using System; using System.Collections.Generic; using System.Management.Instrumentation; using System.Windows; @@ -15,8 +14,7 @@ public static class VectorResources private static object GetResource(string resourceDictionaryRelativeUri, string resourceKey) { - ResourceDictionary dict; - if (_cachedResources.TryGetValue(resourceDictionaryRelativeUri, out dict)) + if (_cachedResources.TryGetValue(resourceDictionaryRelativeUri, out var dict)) { return dict[resourceKey]; } @@ -43,4 +41,4 @@ public static ControlTemplate TryGet(string resourceDictionaryRelativeUri, strin } } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Extensions/VisualHelper.cs b/src/BuildVision.UI/Extensions/VisualHelper.cs index bb5485ef..53a97057 100644 --- a/src/BuildVision.UI/Extensions/VisualHelper.cs +++ b/src/BuildVision.UI/Extensions/VisualHelper.cs @@ -19,11 +19,15 @@ public static T FindVisualChild(DependencyObject obj) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child is T) + { return (T)child; + } var childOfChild = FindVisualChild(child); if (childOfChild != null) + { return childOfChild; + } } return null; @@ -41,11 +45,15 @@ public static IEnumerable FindVisualChildren(DependencyObject obj) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child is T) + { yield return (T)child; + } foreach (T childOfChild in FindVisualChildren(child)) + { yield return childOfChild; + } } } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Helpers/BindingProxy.cs b/src/BuildVision.UI/Helpers/BindingProxy.cs index 53e57663..476b6952 100644 --- a/src/BuildVision.UI/Helpers/BindingProxy.cs +++ b/src/BuildVision.UI/Helpers/BindingProxy.cs @@ -15,8 +15,8 @@ protected override Freezable CreateInstanceCore() public object Data { - get { return (object)GetValue(DataProperty); } - set { SetValue(DataProperty, value); } + get => GetValue(DataProperty); + set => SetValue(DataProperty, value); } // Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc... diff --git a/src/BuildVision.UI/Helpers/BuildImages.cs b/src/BuildVision.UI/Helpers/BuildImages.cs deleted file mode 100644 index 618910d0..00000000 --- a/src/BuildVision.UI/Helpers/BuildImages.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows.Controls; - -using ProjectItem = BuildVision.UI.Models.ProjectItem; -using BuildVision.Contracts; -using BuildVision.UI.Contracts; -using BuildVision.UI.Extensions; - -namespace BuildVision.UI.Helpers -{ - public static class BuildImages - { - public const string BuildActionResourcesUri = @"Resources/BuildAction.Resources.xaml"; - public const string BuildStateResourcesUri = @"Resources/BuildState.Resources.xaml"; - - public static ControlTemplate GetBuildBeginImage(IBuildInfo buildInfo) - { - var buildAction = buildInfo.BuildAction; - var buildScope = buildInfo.BuildScope; - - if (buildAction == null || buildScope == null) - return null; - - string actionKey = GetBuildActionResourceKey(buildAction.Value); - return VectorResources.TryGet(BuildActionResourcesUri, actionKey); - } - - public static ControlTemplate GetBuildDoneImage(IBuildInfo buildInfo, IEnumerable allProjects, out ControlTemplate stateImage) - { - if (buildInfo?.BuildAction == null || buildInfo?.BuildScope == null) - throw new ArgumentNullException(nameof(buildInfo)); - - if (allProjects == null) - throw new InvalidOperationException(); - - int errorProjectsCount = allProjects.Count(item => item.State.IsErrorState()); - bool buildedProjectsSuccess = buildInfo.BuildedProjects.BuildWithoutErrors; - - string stateKey; - - if (buildedProjectsSuccess) - { - if (errorProjectsCount == 0) - stateKey = "BuildDone"; - else - stateKey = "BuildErrorDone"; - } - else if (buildInfo.BuildIsCancelled) - stateKey = "BuildCancelled"; - else - stateKey = "BuildError"; - - stateImage = VectorResources.TryGet(BuildStateResourcesUri, stateKey); - - string actionKey = GetBuildActionResourceKey(buildInfo.BuildAction.Value); - return VectorResources.TryGet(BuildActionResourcesUri, actionKey); - } - - private static string GetBuildActionResourceKey(BuildActions buildAction) - { - switch (buildAction) - { - case BuildActions.BuildActionBuild: - return "Build"; - - case BuildActions.BuildActionRebuildAll: - return "Rebuild"; - - case BuildActions.BuildActionClean: - return "Clean"; - - case BuildActions.BuildActionDeploy: - throw new InvalidOperationException(); - - default: - throw new ArgumentOutOfRangeException(nameof(buildAction)); - } - } - } -} diff --git a/src/BuildVision.UI/Helpers/BuildMessages.cs b/src/BuildVision.UI/Helpers/BuildMessages.cs deleted file mode 100644 index 6aa3c0bf..00000000 --- a/src/BuildVision.UI/Helpers/BuildMessages.cs +++ /dev/null @@ -1,319 +0,0 @@ -using System; -using System.Diagnostics; -using System.Linq; -using BuildVision.Contracts; -using BuildVision.UI.Contracts; -using BuildVision.UI.Models; -using BuildVision.UI.Extensions; -using BuildVision.UI.Settings.Models; - -namespace BuildVision.UI.Helpers -{ - public static class BuildMessages - { - public static string GetBuildBeginMajorMessage(SolutionItem solutionItem, IBuildInfo buildInfo, BuildMessagesSettings labelsSettings) - { - if (buildInfo.BuildAction == null || buildInfo.BuildScope == null || buildInfo.BuildAction.Value == BuildActions.BuildActionDeploy) - return Resources.UnknownBuildActionOrScope_BuildBeginText; - - if (buildInfo.BuildStartTime == null) - throw new InvalidOperationException(); - - var mainString = GetMainString(solutionItem, buildInfo, labelsSettings); - return string.Format(labelsSettings.BuildBeginMajorMessageStringFormat, mainString); - } - - private static string GetMainString(SolutionItem solutionItem, IBuildInfo buildInfo, BuildMessagesSettings labelsSettings) - { - var unitName = GetUnitName(solutionItem, buildInfo, labelsSettings); - var actionName = GetActionName(buildInfo.BuildAction.Value); - var beginAtString = GetBeginAtString(buildInfo.BuildAction.Value); - var timeString = GetTimeString(buildInfo, labelsSettings); - string mainString; - switch (labelsSettings.MajorMessageFormat) - { - case BuildMajorMessageFormat.Entire: - mainString = string.Format(Resources.BuildBeginStateLabelTemplate_Default, actionName, unitName, beginAtString, timeString); - break; - - case BuildMajorMessageFormat.Unnamed: - mainString = string.Format(Resources.BuildBeginStateLabelTemplate_ShortForm, actionName, beginAtString, timeString); - break; - - default: - throw new ArgumentOutOfRangeException(nameof(labelsSettings.MajorMessageFormat)); - } - - return mainString; - } - - private static string GetTimeString(IBuildInfo buildInfo, BuildMessagesSettings labelsSettings) - { - string timeString; - try - { - timeString = buildInfo.BuildStartTime.Value.ToString(labelsSettings.DateTimeFormat); - } - catch (FormatException) - { - timeString = Resources.InvalidTimeStringFormat; - } - - return timeString; - } - - private static string GetBeginAtString(BuildActions? buildAction) - { - switch (buildAction.Value) - { - case BuildActions.BuildActionRebuildAll: - return Resources.BuildActionRebuildAll_BeginAtString; - - case BuildActions.BuildActionBuild: - return Resources.BuildActionBuild_BeginAtString; - - case BuildActions.BuildActionClean: - return Resources.BuildActionClean_BeginAtString; - default: - throw new ArgumentOutOfRangeException(nameof(buildAction)); - } - } - - private static string GetActionName(BuildActions buildAction) - { - switch (buildAction) - { - case BuildActions.BuildActionRebuildAll: - return Resources.BuildActionRebuildAll; - - case BuildActions.BuildActionBuild: - return Resources.BuildActionBuild; - - case BuildActions.BuildActionClean: - return Resources.BuildActionClean; - default: - throw new ArgumentOutOfRangeException(nameof(buildAction)); - } - } - - private static string GetUnitName(SolutionItem solutionItem, IBuildInfo buildInfo, BuildMessagesSettings labelsSettings) - { - string unitName; - switch (buildInfo.BuildScope.Value) - { - case BuildScopes.BuildScopeSolution: - unitName = Resources.BuildScopeSolution_UnitName; - if (labelsSettings.ShowSolutionName) - unitName += string.Format(Resources.BuildScopeSolution_SolutionNameTemplate, solutionItem.Name); - break; - - case BuildScopes.BuildScopeBatch: - unitName = Resources.BuildScopeBatch_UnitName; - break; - - case BuildScopes.BuildScopeProject: - unitName = Resources.BuildScopeProject_UnitName; - if (labelsSettings.ShowProjectName) - { - var proj = buildInfo.BuildScopeProject; - if (proj != null) - { - unitName += string.Format(Resources.BuildScopeProject_ProjectNameTemplate, proj.Name); - } - else - { - unitName = Resources.BuildScopeBatch_UnitName; - buildInfo.OverrideBuildProperties(buildScope: BuildScopes.BuildScopeBatch); - } - } - break; - - default: - throw new ArgumentOutOfRangeException(nameof(buildInfo.BuildScope)); - } - - return unitName; - } - - public static string GetBuildBeginExtraMessage(IBuildInfo buildInfo, BuildMessagesSettings labelsSettings) - { - if (buildInfo == null || buildInfo.BuildStartTime == null || !labelsSettings.ShowExtraMessage || labelsSettings.ExtraMessageDelay < 0) - { - return string.Empty; - } - - TimeSpan timeSpan = DateTime.Now.Subtract(buildInfo.BuildStartTime.Value); - if (timeSpan.TotalSeconds > labelsSettings.ExtraMessageDelay) - { - return GetExtraTimePartString(labelsSettings, timeSpan); - } - - return string.Empty; - } - - public static string GetBuildDoneMessage(SolutionItem solutionItem, IBuildInfo buildInfo, BuildMessagesSettings labelsSettings) - { - return GetBuildDoneMajorMessage(solutionItem, buildInfo, labelsSettings) + GetBuildDoneExtraMessage(buildInfo, labelsSettings); - } - - private static string GetBuildDoneMajorMessage(SolutionItem solutionItem, IBuildInfo buildInfo, BuildMessagesSettings labelsSettings) - { - if (buildInfo == null) - return Resources.BuildDoneText_BuildNotStarted; - - var buildAction = buildInfo.BuildAction; - var buildScope = buildInfo.BuildScope; - - if (buildInfo.BuildFinishTime == null) - throw new InvalidOperationException(); - - string timeString; - try - { - timeString = buildInfo.BuildFinishTime.Value.ToString(labelsSettings.DateTimeFormat); - } - catch (FormatException) - { - timeString = Resources.InvalidTimeStringFormat; - } - - if (buildAction == null || buildScope == null) - return string.Format(Resources.BuildDoneText_NotSupported_BuildActionOrScopeIsNull_CompletedAtTemplate, timeString); //? WTF??? - - string unitName; - switch (buildScope.Value) - { - case BuildScopes.BuildScopeSolution: - unitName = Resources.BuildScopeSolution_UnitName; - if (labelsSettings.ShowSolutionName) - unitName += string.Format(Resources.BuildScopeSolution_SolutionNameTemplate, solutionItem.Name); - break; - - case BuildScopes.BuildScopeBatch: - unitName = Resources.BuildScopeBatch_UnitName; - break; - - case BuildScopes.BuildScopeProject: - unitName = Resources.BuildScopeProject_UnitName; - if (labelsSettings.ShowProjectName) - { - // Skip dependent projects. The last project in the list is the target project. - string uniqProjName = buildInfo.BuildedProjects[buildInfo.BuildedProjects.Count - 1].UniqueName; - ProjectItem projItem = solutionItem.AllProjects.FirstOrDefault(item => item.UniqueName == uniqProjName); - Debug.Assert(projItem != null); - - unitName += string.Format(Resources.BuildScopeProject_ProjectNameTemplate, projItem.Name); - } - break; - - default: - throw new ArgumentOutOfRangeException(nameof(buildScope)); - } - - var actionName = GetActionName(buildInfo); - var resultName = GetResultName(solutionItem, buildInfo); - - string mainString; - switch (labelsSettings.MajorMessageFormat) - { - case BuildMajorMessageFormat.Entire: - mainString = string.Format(Resources.BuildDoneStateLabelTemplate_Default, actionName, unitName, resultName, timeString); - break; - - case BuildMajorMessageFormat.Unnamed: - mainString = string.Format(Resources.BuildDoneStateLabelTemplate_ShortForm, actionName, resultName, timeString); - break; - - default: - throw new ArgumentOutOfRangeException(nameof(labelsSettings.MajorMessageFormat)); - } - - string resultMainString = string.Format(labelsSettings.BuildDoneMajorMessageStringFormat, mainString); - return resultMainString; - } - - private static string GetActionName(IBuildInfo buildInfo) - { - if (buildInfo.BuildAction == null) - throw new InvalidOperationException(); - - switch (buildInfo.BuildAction.Value) - { - case BuildActions.BuildActionBuild: - return Resources.BuildActionBuild; - - case BuildActions.BuildActionRebuildAll: - return Resources.BuildActionRebuildAll; - - case BuildActions.BuildActionClean: - return Resources.BuildActionClean; - - case BuildActions.BuildActionDeploy: - throw new InvalidOperationException(); - - default: - throw new ArgumentOutOfRangeException(nameof(buildInfo.BuildAction)); - } - } - - private static string GetResultName(SolutionItem solutionItem, IBuildInfo buildInfo) - { - var buildAction = buildInfo.BuildAction; - int errorStateProjectsCount = solutionItem.AllProjects.Count(item => item.State.IsErrorState()); - - if (buildInfo.BuildIsCancelled) - return buildAction.Value == BuildActions.BuildActionClean ? Resources.BuildActionCancelled_Clean : Resources.BuildActionCancelled; - else if (!buildInfo.BuildedProjects.BuildWithoutErrors) - return buildAction.Value == BuildActions.BuildActionClean ? Resources.BuildActionFailed_Clean : Resources.BuildActionFailed; - else if (errorStateProjectsCount == 0) - return buildAction.Value == BuildActions.BuildActionClean ? Resources.BuildActionFinishedSuccessfully_Clean : Resources.BuildActionFinishedSuccessfully; - else - return buildAction.Value == BuildActions.BuildActionClean ? Resources.BuildActionFinished_Clean : Resources.BuildActionFinished; - } - - private static string GetBuildDoneExtraMessage(IBuildInfo buildInfo, BuildMessagesSettings labelsSettings) - { - if (buildInfo?.BuildStartTime == null || buildInfo?.BuildFinishTime == null || !labelsSettings.ShowExtraMessage) - return string.Empty; - - TimeSpan timeSpan = buildInfo.BuildFinishTime.Value.Subtract(buildInfo.BuildStartTime.Value); - string extraTimePartString = GetExtraTimePartString(labelsSettings, timeSpan); - return string.Format(labelsSettings.ExtraMessageStringFormat, extraTimePartString); - } - - private static string GetExtraTimePartString(BuildMessagesSettings labelsSettings, TimeSpan timeSpan) - { - string extraTimePartString; - switch (labelsSettings.ExtraMessageFormat) - { - case BuildExtraMessageFormat.Custom: - try - { - extraTimePartString = timeSpan.ToString(labelsSettings.TimeSpanFormat); - } - catch (FormatException) - { - extraTimePartString = Resources.InvalidTimeStringFormat; - } - break; - - case BuildExtraMessageFormat.TotalSeconds: - extraTimePartString = string.Format("{0}", Math.Truncate(timeSpan.TotalSeconds)); - break; - - case BuildExtraMessageFormat.TotalMinutes: - extraTimePartString = string.Format("{0}", Math.Truncate(timeSpan.TotalMinutes)); - break; - - case BuildExtraMessageFormat.TotalMinutesWithSeconds: - extraTimePartString = string.Format("{0:00}:{1:00}", Math.Truncate(timeSpan.TotalMinutes), timeSpan.Seconds); - break; - - default: - throw new ArgumentOutOfRangeException(nameof(labelsSettings.ExtraMessageFormat)); - } - - return string.Format(labelsSettings.ExtraMessageStringFormat, extraTimePartString); - } - } -} diff --git a/src/BuildVision.UI/Helpers/BuildMessagesFactory.cs b/src/BuildVision.UI/Helpers/BuildMessagesFactory.cs new file mode 100644 index 00000000..f7b3da21 --- /dev/null +++ b/src/BuildVision.UI/Helpers/BuildMessagesFactory.cs @@ -0,0 +1,285 @@ +using System; +using BuildVision.Contracts; +using BuildVision.Contracts.Models; +using BuildVision.Exports.Factories; +using BuildVision.UI.Models; +using BuildVision.Views.Settings; + +namespace BuildVision.UI.Helpers +{ + public class BuildMessagesFactory : IBuildMessagesFactory + { + private readonly IPackageSettingsProvider _packageSettingsProvider; + + public BuildMessagesFactory(IPackageSettingsProvider packageSettingsProvider) + { + _packageSettingsProvider = packageSettingsProvider; + } + + public string GetBuildBeginMajorMessage(IBuildInformationModel buildInformationModel) + { + var mainString = GetMainString(buildInformationModel); + return string.Format(_packageSettingsProvider.Settings.BuildMessagesSettings.BuildBeginMajorMessageStringFormat, mainString); + } + + private string GetMainString(IBuildInformationModel buildInformationModel) + { + var unitName = GetUnitName(buildInformationModel.BuildScope); + var actionName = GetActionName(buildInformationModel.BuildAction); + var beginAtString = GetBeginAtString(buildInformationModel.BuildAction); + var timeString = GetTimeString(buildInformationModel.BuildStartTime); + string mainString; + switch (_packageSettingsProvider.Settings.BuildMessagesSettings.MajorMessageFormat) + { + case BuildMajorMessageFormat.Entire: + mainString = string.Format(Resources.BuildBeginStateLabelTemplate_Default, actionName, unitName, beginAtString, timeString); + break; + + case BuildMajorMessageFormat.Unnamed: + mainString = string.Format(Resources.BuildBeginStateLabelTemplate_ShortForm, actionName, beginAtString, timeString); + break; + + default: + throw new ArgumentOutOfRangeException(nameof(_packageSettingsProvider.Settings.BuildMessagesSettings.MajorMessageFormat)); + } + + return mainString; + } + + private string GetTimeString(DateTime? startTime) + { + try + { + return startTime.Value.ToString(_packageSettingsProvider.Settings.BuildMessagesSettings.DateTimeFormat); + } + catch (FormatException) + { + return Resources.InvalidTimeStringFormat; + } + } + + private static string GetBeginAtString(BuildAction? buildAction) + { + switch (buildAction.Value) + { + case BuildAction.RebuildAll: + return Resources.BuildActionRebuildAll_BeginAtString; + + case BuildAction.Build: + return Resources.BuildActionBuild_BeginAtString; + + case BuildAction.Clean: + return Resources.BuildActionClean_BeginAtString; + default: + throw new ArgumentOutOfRangeException(nameof(buildAction)); + } + } + + private static string GetActionName(BuildAction buildAction) + { + switch (buildAction) + { + case BuildAction.RebuildAll: + return Resources.BuildActionRebuildAll; + + case BuildAction.Build: + return Resources.BuildActionBuild; + + case BuildAction.Clean: + return Resources.BuildActionClean; + default: + throw new ArgumentOutOfRangeException(nameof(buildAction), $"Actual: {buildAction}"); + } + } + + private static string GetUnitName(BuildScope buildScope) + { + string unitName = ""; + switch (buildScope) + { + case BuildScope.Solution: + unitName = Resources.BuildScopeSolution_UnitName; + //if (_labelSettings.ShowSolutionName) + //unitName += string.Format(Resources.BuildScopeSolution_SolutionNameTemplate, solutionItem.Name); + break; + + case BuildScope.Batch: + unitName = Resources.BuildScopeBatch_UnitName; + break; + + case BuildScope.Project: + unitName = Resources.BuildScopeProject_UnitName; + // TODO specify name for project? + break; + + default: + throw new ArgumentOutOfRangeException(nameof(buildScope)); + } + + return unitName; + } + + public string GetBuildBeginExtraMessage(IBuildInformationModel buildInformationModel) + { + if (buildInformationModel.BuildStartTime == null || !_packageSettingsProvider.Settings.BuildMessagesSettings.ShowExtraMessage || _packageSettingsProvider.Settings.BuildMessagesSettings.ExtraMessageDelay < 0) + { + return string.Empty; + } + + var timeSpan = DateTime.Now.Subtract(buildInformationModel.BuildStartTime.Value); + if (timeSpan.TotalSeconds > _packageSettingsProvider.Settings.BuildMessagesSettings.ExtraMessageDelay) + { + return GetExtraTimePartString(timeSpan); + } + + return string.Empty; + } + + public string GetBuildDoneMessage(IBuildInformationModel buildInformationModel) + { + return GetBuildDoneMajorMessage(buildInformationModel) + GetBuildDoneExtraMessage(buildInformationModel); + } + + private string GetBuildDoneMajorMessage(IBuildInformationModel buildInformationModel) + { + var buildAction = buildInformationModel.BuildAction; + var buildScope = buildInformationModel.BuildScope; + + if (buildInformationModel.BuildFinishTime == null) + { + throw new InvalidOperationException(); + } + + string timeString; + try + { + timeString = buildInformationModel.BuildFinishTime.Value.ToString(_packageSettingsProvider.Settings.BuildMessagesSettings.DateTimeFormat); + } + catch (FormatException) + { + timeString = Resources.InvalidTimeStringFormat; + } + + string unitName; + switch (buildScope) + { + case BuildScope.Solution: + unitName = Resources.BuildScopeSolution_UnitName; + //if (_labelSettings.ShowSolutionName) + //unitName += string.Format(Resources.BuildScopeSolution_SolutionNameTemplate, solutionItem.Name); + break; + + case BuildScope.Batch: + unitName = Resources.BuildScopeBatch_UnitName; + break; + + case BuildScope.Project: + unitName = Resources.BuildScopeProject_UnitName; + if (_packageSettingsProvider.Settings.BuildMessagesSettings.ShowProjectName) + { + // Todo this is probably wrong. maybe we should go the extra mile and check which projects are selected? + //var uniqProjName = solutionItem.Projects.LastOrDefault(x => x.State == ProjectState.BuildDone)?.UniqueName; + //var projItem = solutionItem.Projects.FirstOrDefault(item => item.UniqueName == uniqProjName); + //unitName += string.Format(Resources.BuildScopeProject_ProjectNameTemplate, projItem.Name); + } + break; + + default: + throw new ArgumentOutOfRangeException(nameof(buildScope)); + } + + var actionName = GetActionName(buildInformationModel.BuildAction); + var resultName = GetResultName(buildInformationModel.ResultState); + + string mainString; + switch (_packageSettingsProvider.Settings.BuildMessagesSettings.MajorMessageFormat) + { + case BuildMajorMessageFormat.Entire: + mainString = string.Format(Resources.BuildDoneStateLabelTemplate_Default, actionName, unitName, resultName, timeString); + break; + + case BuildMajorMessageFormat.Unnamed: + mainString = string.Format(Resources.BuildDoneStateLabelTemplate_ShortForm, actionName, resultName, timeString); + break; + + default: + throw new ArgumentOutOfRangeException(nameof(_packageSettingsProvider.Settings.BuildMessagesSettings.MajorMessageFormat)); + } + + string resultMainString = string.Format(_packageSettingsProvider.Settings.BuildMessagesSettings.BuildDoneMajorMessageStringFormat, mainString); + return resultMainString; + } + + private static string GetResultName(BuildResultState resultState) + { + switch (resultState) + { + case BuildResultState.BuildCancelled: + case BuildResultState.RebuildCancelled: + return Resources.BuildActionCancelled; + case BuildResultState.BuildFailed: + case BuildResultState.RebuildFailed: + return Resources.BuildActionFailed; + case BuildResultState.BuildDone: + case BuildResultState.RebuildDone: + return Resources.BuildActionFinishedSuccessfully; + case BuildResultState.CleanCancelled: + return Resources.BuildActionCancelled_Clean; + case BuildResultState.CleanFailed: + return Resources.BuildActionFailed_Clean; + case BuildResultState.CleanDone: + return Resources.BuildActionFinishedSuccessfully_Clean; + case BuildResultState.Unknown: // Check if this is right + return Resources.BuildActionFinished_Clean; + default: + return Resources.BuildActionFinished; + } + } + + private string GetBuildDoneExtraMessage(IBuildInformationModel buildInformationModel) + { + if (buildInformationModel.BuildStartTime == null || buildInformationModel.BuildFinishTime == null || !_packageSettingsProvider.Settings.BuildMessagesSettings.ShowExtraMessage) + { + return string.Empty; + } + + var timeSpan = buildInformationModel.BuildFinishTime.Value.Subtract(buildInformationModel.BuildStartTime.Value); + return GetExtraTimePartString(timeSpan); + } + + private string GetExtraTimePartString(TimeSpan timeSpan) + { + string extraTimePartString; + switch (_packageSettingsProvider.Settings.BuildMessagesSettings.ExtraMessageFormat) + { + case BuildExtraMessageFormat.Custom: + try + { + extraTimePartString = timeSpan.ToString(_packageSettingsProvider.Settings.BuildMessagesSettings.TimeSpanFormat); + } + catch (FormatException) + { + extraTimePartString = Resources.InvalidTimeStringFormat; + } + break; + + case BuildExtraMessageFormat.TotalSeconds: + extraTimePartString = string.Format("{0}", Math.Truncate(timeSpan.TotalSeconds)); + break; + + case BuildExtraMessageFormat.TotalMinutes: + extraTimePartString = string.Format("{0}", Math.Truncate(timeSpan.TotalMinutes)); + break; + + case BuildExtraMessageFormat.TotalMinutesWithSeconds: + extraTimePartString = string.Format("{0:00}:{1:00}", Math.Truncate(timeSpan.TotalMinutes), timeSpan.Seconds); + break; + + default: + throw new ArgumentOutOfRangeException(nameof(_packageSettingsProvider.Settings.BuildMessagesSettings.ExtraMessageFormat)); + } + + return string.Format(_packageSettingsProvider.Settings.BuildMessagesSettings.ExtraMessageStringFormat, extraTimePartString); + } + } +} diff --git a/src/BuildVision.UI/Helpers/EnumExtensions.cs b/src/BuildVision.UI/Helpers/EnumExtensions.cs index f41066a7..874c4d9c 100644 --- a/src/BuildVision.UI/Helpers/EnumExtensions.cs +++ b/src/BuildVision.UI/Helpers/EnumExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -53,4 +53,4 @@ public static string DisplayString(this Enum value) return (attributes.Length >= 1) ? attributes[0].DisplayString : value.ToString(); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Helpers/ProjectItemColumnSorter.cs b/src/BuildVision.UI/Helpers/ProjectItemColumnSorter.cs index 01a80d16..6849d9b9 100644 --- a/src/BuildVision.UI/Helpers/ProjectItemColumnSorter.cs +++ b/src/BuildVision.UI/Helpers/ProjectItemColumnSorter.cs @@ -1,14 +1,43 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Reflection; using BuildVision.Common; +using BuildVision.Contracts.Exceptions; using BuildVision.UI.Models; -using System.ComponentModel; namespace BuildVision.UI.Helpers { - public class ProjectItemColumnSorter : PropertyColumnSorter + public class ProjectItemColumnSorter : IComparer { - public ProjectItemColumnSorter(ListSortDirection direction, string propertyName) - : base(direction, propertyName) + private readonly int _direction; + private readonly Func _getProperrty; + + public ProjectItemColumnSorter(ListSortDirection direction, Func getProperrty) + { + _direction = (direction == ListSortDirection.Ascending) ? 1 : -1; + _getProperrty = getProperrty; + } + + int IComparer.Compare(object x, object y) => Compare((ProjectItem)x, (ProjectItem)y); + + protected int Compare(ProjectItem x, ProjectItem y) { + var x1 = _getProperrty(x) as IComparable; + var y1 = _getProperrty(y) as IComparable; + + if (x1 != null && y1 != null) + { + return x1.CompareTo(y1) * _direction; + } + + if (x1 == null && y1 == null) + { + return 0; + } + + // Null values always in the bottom. + return (x1 == null) ? 1 : -1; } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Helpers/StyleConverting.cs b/src/BuildVision.UI/Helpers/StyleConverting.cs index ddc42fdb..7c302501 100644 --- a/src/BuildVision.UI/Helpers/StyleConverting.cs +++ b/src/BuildVision.UI/Helpers/StyleConverting.cs @@ -1,9 +1,9 @@ -using BuildVision.UI.Models; -using System; +using System; using System.ComponentModel; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Media.Imaging; +using BuildVision.UI.Models; namespace BuildVision.UI.Helpers { @@ -91,4 +91,4 @@ public static SortOrder ToMedia(this ListSortDirection? listSortDirection) } } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/IPackageSettingsProvider.cs b/src/BuildVision.UI/IPackageSettingsProvider.cs new file mode 100644 index 00000000..1ab1d206 --- /dev/null +++ b/src/BuildVision.UI/IPackageSettingsProvider.cs @@ -0,0 +1,15 @@ +using System; +using System.ComponentModel; +using BuildVision.UI.Settings.Models; + +namespace BuildVision.Views.Settings +{ + public interface IPackageSettingsProvider : INotifyPropertyChanged + { + void Save(); + + ControlSettings Settings { get; } + + event Action SettingsChanged; + } +} diff --git a/src/BuildVision.UI/MainWindow.xaml.cs b/src/BuildVision.UI/MainWindow.xaml.cs index 33a10faf..fe583e43 100644 --- a/src/BuildVision.UI/MainWindow.xaml.cs +++ b/src/BuildVision.UI/MainWindow.xaml.cs @@ -1,5 +1,7 @@ using BuildVision.UI.Settings; using BuildVision.UI.ViewModels; +using Microsoft.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.Shell; using System; using System.Linq; using System.Windows; @@ -16,7 +18,7 @@ public MainWindow() { InitializeComponent(); - var controlViewModel = new ControlViewModel(); + var controlViewModel = new BuildVisionPaneViewModel(); ControlView.DataContext = controlViewModel; } diff --git a/src/BuildVision.UI/Models/BuildInformationModel.cs b/src/BuildVision.UI/Models/BuildInformationModel.cs new file mode 100644 index 00000000..a6620f2b --- /dev/null +++ b/src/BuildVision.UI/Models/BuildInformationModel.cs @@ -0,0 +1,280 @@ +using System; +using System.Windows.Controls; +using BuildVision.Common; +using BuildVision.Contracts; +using BuildVision.Contracts.Models; + +namespace BuildVision.UI.Models +{ + public class BuildInformationModel : BindableBase, IBuildInformationModel + { + private int _errorCount = 0; + public int ErrorCount + { + get => _errorCount; + set => SetProperty(ref _errorCount, value); + } + + private int _warningsCount = 0; + public int WarningsCount + { + get => _warningsCount; + set => SetProperty(ref _warningsCount, value); + } + + private int _messagesCount = 0; + public int MessagesCount + { + get => _messagesCount; + set => SetProperty(ref _messagesCount, value); + } + + private int _succeededProjectsCount = 0; + public int SucceededProjectsCount + { + get => _succeededProjectsCount; + set => SetProperty(ref _succeededProjectsCount, value); + } + + private int _upToDateProjectsCount; + public int UpToDateProjectsCount + { + get => _upToDateProjectsCount; + set => SetProperty(ref _upToDateProjectsCount, value); + } + + private int _failedProjectsCount = 0; + public int FailedProjectsCount + { + get => _failedProjectsCount; + set => SetProperty(ref _failedProjectsCount, value); + } + + private int _warnedProjectsCount = 0; + public int WarnedProjectsCount + { + get => _warnedProjectsCount; + set => SetProperty(ref _warnedProjectsCount, value); + } + + private string _stateMessage = Resources.BuildDoneText_BuildNotStarted; + public string StateMessage + { + get => _stateMessage; + set => SetProperty(ref _stateMessage, value); + } + + private BuildState _currentBuildState = BuildState.NotStarted; + public BuildState CurrentBuildState + { + get => _currentBuildState; + set + { + SetProperty(ref _currentBuildState, value); + OnPropertyChanged(nameof(StateIconKey)); + OnPropertyChanged(nameof(IsFinished)); + } + } + + public BuildResultState ResultState => GetBuildResultState(); + + private BuildAction _buildAction = BuildAction.Unknown; + public BuildAction BuildAction + { + get => _buildAction; + set + { + SetProperty(ref _buildAction, value); + OnPropertyChanged(nameof(StateIconKey)); + } + } + + private BuildScope _buildScope = BuildScope.Unknown; + public BuildScope BuildScope + { + get => _buildScope; + set => SetProperty(ref _buildScope, value); + } + + private DateTime? _buildStartTime = null; + public DateTime? BuildStartTime + { + get => _buildStartTime; + set => SetProperty(ref _buildStartTime, value); + } + + private DateTime? _buildFinishTime = null; + public DateTime? BuildFinishTime + { + get => _buildFinishTime; + set => SetProperty(ref _buildFinishTime, value); + } + + public string StateIconKey + { + get => GetStateIconKey(); + } + + public bool IsFinished + { + get => CurrentBuildState > BuildState.InProgress; + } + + private IProjectItem _currentProject = null; + public IProjectItem CurrentProject + { + get => _currentProject; + set => SetProperty(ref _currentProject, value); + } + + private Guid _buildId = Guid.Empty; + public Guid BuildId + { + get => _buildId; + set => SetProperty(ref _buildId, value); + } + + private string GetStateIconKey() + { + var resultState = GetBuildResultState(); + if (CurrentBuildState == BuildState.InProgress && resultState == BuildResultState.Unknown) + { + if (BuildAction == BuildAction.RebuildAll) + { + return "Rebuild"; + } + + if (BuildAction == BuildAction.Clean) + { + return "Clean"; + } + + if (BuildAction == BuildAction.Build) + { + return "Build"; + } + } + + if (resultState == BuildResultState.Unknown) + { + return "StandBy"; + } + return resultState.ToString(); + } + + private BuildResultState GetBuildResultState() + { + if (CurrentBuildState == BuildState.InProgress) + { + return BuildResultState.Unknown; + } + else if (CurrentBuildState == BuildState.Cancelled) + { + if (BuildAction == BuildAction.RebuildAll) + { + return BuildResultState.RebuildCancelled; + } + + if (BuildAction == BuildAction.Clean) + { + return BuildResultState.CleanCancelled; + } + + if (BuildAction == BuildAction.Build) + { + return BuildResultState.BuildCancelled; + } + else + { + return BuildResultState.Unknown; + } + } + else if (CurrentBuildState == BuildState.Failed) + { + if (BuildAction == BuildAction.RebuildAll) + { + return BuildResultState.RebuildFailed; + } + + if (BuildAction == BuildAction.Clean) + { + return BuildResultState.CleanFailed; + } + + if (BuildAction == BuildAction.Build) + { + return BuildResultState.BuildFailed; + } + else + { + return BuildResultState.Unknown; + } + } + else if (CurrentBuildState == BuildState.ErrorDone) + { + if (BuildAction == BuildAction.RebuildAll) + { + return BuildResultState.RebuildErrorDone; + } + + if (BuildAction == BuildAction.Clean) + { + return BuildResultState.CleanErrorDone; + } + + if (BuildAction == BuildAction.Build) + { + return BuildResultState.BuildErrorDone; + } + else + { + return BuildResultState.Unknown; + } + } + else if (CurrentBuildState == BuildState.Done) + { + if (BuildAction == BuildAction.RebuildAll) + { + return BuildResultState.RebuildDone; + } + + if (BuildAction == BuildAction.Clean) + { + return BuildResultState.CleanDone; + } + + if (BuildAction == BuildAction.Build) + { + return BuildResultState.BuildDone; + } + else + { + return BuildResultState.Unknown; + } + } + else + { + return BuildResultState.Unknown; + } + } + + public int GetFinishedProjectsCount() => SucceededProjectsCount + UpToDateProjectsCount + WarnedProjectsCount + FailedProjectsCount; + + public void ResetState() + { + ErrorCount = 0; + WarningsCount = 0; + MessagesCount = 0; + SucceededProjectsCount = 0; + UpToDateProjectsCount = 0; + FailedProjectsCount = 0; + WarnedProjectsCount = 0; + StateMessage = Resources.BuildDoneText_BuildNotStarted; + CurrentBuildState = BuildState.NotStarted; + BuildAction = BuildAction.Unknown; + BuildScope = BuildScope.Unknown; + BuildStartTime = null; + BuildFinishTime = null; + } + } +} diff --git a/src/BuildVision.UI/Models/ControlModel.cs b/src/BuildVision.UI/Models/ControlModel.cs deleted file mode 100644 index 6e28a4ae..00000000 --- a/src/BuildVision.UI/Models/ControlModel.cs +++ /dev/null @@ -1,32 +0,0 @@ -using BuildVision.UI.Extensions; -using BuildVision.UI.Helpers; -using BuildVision.UI.Models.Indicators.Core; -using System.Collections.ObjectModel; -using System.Windows.Controls; - -namespace BuildVision.UI.Models -{ - public class ControlModel - { - public ProjectItem CurrentProject { get; set; } - - public ControlTemplate ImageCurrentState { get; set; } - - public ControlTemplate ImageCurrentStateResult { get; set; } - - public string TextCurrentState { get; set; } - - public SolutionItem SolutionItem { get; set; } - - public ObservableCollection ValueIndicators { get; set; } - - public ControlModel() - { - ValueIndicators = ValueIndicatorsFactory.CreateCollection(); - SolutionItem = new SolutionItem(); - TextCurrentState = Resources.BuildDoneText_BuildNotStarted; - ImageCurrentState = VectorResources.TryGet(BuildImages.BuildActionResourcesUri, "StandBy"); - ImageCurrentStateResult = null; - } - } -} diff --git a/src/BuildVision.UI/Models/GridColumnSettingsCollection.cs b/src/BuildVision.UI/Models/GridColumnSettingsCollection.cs new file mode 100644 index 00000000..530f7dd1 --- /dev/null +++ b/src/BuildVision.UI/Models/GridColumnSettingsCollection.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace BuildVision.UI.Settings.Models.Columns +{ + public class GridColumnSettingsCollection : List + { + public GridColumnSettings this[string propertyName] => Find(s => s.PropertyNameId == propertyName); + } +} diff --git a/src/BuildVision.UI/Models/Indicators/Core/ResetIndicatorMode.cs b/src/BuildVision.UI/Models/Indicators/Core/ResetIndicatorMode.cs deleted file mode 100644 index 0bba806a..00000000 --- a/src/BuildVision.UI/Models/Indicators/Core/ResetIndicatorMode.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace BuildVision.UI.Models.Indicators.Core -{ - public enum ResetIndicatorMode - { - ResetValue, - Disable - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Models/Indicators/Core/ValueIndicator.cs b/src/BuildVision.UI/Models/Indicators/Core/ValueIndicator.cs deleted file mode 100644 index 6536e2de..00000000 --- a/src/BuildVision.UI/Models/Indicators/Core/ValueIndicator.cs +++ /dev/null @@ -1,130 +0,0 @@ -using System; -using BuildVision.Common; -using BuildVision.UI; -using BuildVision.UI.Contracts; -using BuildVision.UI.Common.Logging; - -namespace BuildVision.UI.Models.Indicators.Core -{ - public abstract class ValueIndicator : BindableBase - { - private int? _value; - private bool _isEnabled; - private bool _isUpdateError; - private string _lastErrorMessage; - - public const string ResourcesUri = @"Resources/ValueIndicator.Resources.xaml"; - - public abstract string Header { get; } - - public abstract string Description { get; } - - protected abstract int? GetValue(IBuildInfo buildContext); - - public int? Value => _value; - public bool IsEnabled => _isEnabled; - - public virtual string StringValue - { - get - { - if (_isUpdateError) - return Resources.GridCellNAText; - - return Value != null ? Value.ToString() : "0"; - } - } - - public bool IsUpdateError - { - get { return _isUpdateError; } - set => SetProperty(ref _isUpdateError, value); - } - - public string LastErrorMessage - { - get { return _lastErrorMessage; } - set - { - SetProperty(ref _lastErrorMessage, value); - OnPropertyChanged(nameof(ToolTip)); - } - } - - public string ToolTip - { - get - { - if (!IsUpdateError) - return Header; - - return string.Format("{0}{1}{2}", - Header, - Environment.NewLine, - string.IsNullOrEmpty(LastErrorMessage) ? "Unknown error" : LastErrorMessage); - } - } - - public virtual double Width - { - get { return double.NaN; } - } - - public void UpdateValue(IBuildInfo buildContext) - { - UpdateValueAction(buildContext); - } - - public void ResetValue(ResetIndicatorMode resetMode) - { - switch (resetMode) - { - case ResetIndicatorMode.ResetValue: - IsUpdateError = false; - _value = null; - _isEnabled = true; - break; - - case ResetIndicatorMode.Disable: - IsUpdateError = false; - _value = null; - _isEnabled = false; - break; - - default: - throw new ArgumentOutOfRangeException(nameof(resetMode)); - } - - RaiseValueChanged(); - } - - private void UpdateValueAction(IBuildInfo buildContext) - { - IsUpdateError = false; - _isEnabled = true; - - try - { - var currentValue = GetValue(buildContext); - _value = currentValue; - LastErrorMessage = null; - } - catch (Exception ex) - { - _value = null; - IsUpdateError = true; - LastErrorMessage = ex.Message; - ex.TraceUnknownException(); - } - - RaiseValueChanged(); - } - - private void RaiseValueChanged() - { - OnPropertyChanged(nameof(Value)); - OnPropertyChanged(nameof(StringValue)); - OnPropertyChanged(nameof(IsEnabled)); - } - } -} diff --git a/src/BuildVision.UI/Models/Indicators/Core/ValueIndicatorsFactory.cs b/src/BuildVision.UI/Models/Indicators/Core/ValueIndicatorsFactory.cs deleted file mode 100644 index 2e961f6f..00000000 --- a/src/BuildVision.UI/Models/Indicators/Core/ValueIndicatorsFactory.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Collections.ObjectModel; - -namespace BuildVision.UI.Models.Indicators.Core -{ - public static class ValueIndicatorsFactory - { - public static ObservableCollection CreateCollection() - { - return new ObservableCollection - { - new ErrorsIndicator(), - new WarningsIndicator(), - new MessagesIndicator(), - - new SeparatorIndicator(), - - new SuccessProjectsIndicator(), - new UpToDateProjectsIndicator(), - new WarningProjectsIndicator(), - new ErrorProjectsIndicator() - }; - } - } -} diff --git a/src/BuildVision.UI/Models/Indicators/ErrorProjectsIndicator.cs b/src/BuildVision.UI/Models/Indicators/ErrorProjectsIndicator.cs deleted file mode 100644 index 720bcaab..00000000 --- a/src/BuildVision.UI/Models/Indicators/ErrorProjectsIndicator.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; - -using BuildVision.UI; -using BuildVision.UI.Models.Indicators.Core; -using BuildVision.UI.Contracts; - -namespace BuildVision.UI.Models.Indicators -{ - public class ErrorProjectsIndicator : ValueIndicator - { - public override string Header => Resources.ErrorProjectsIndicator_Header; - public override string Description => Resources.ErrorProjectsIndicator_Description; - - protected override int? GetValue(IBuildInfo buildContext) - { - try - { - return buildContext.BuildedProjects.BuildErrorCount; - } - catch (NullReferenceException) - { - return null; - } - } - } -} diff --git a/src/BuildVision.UI/Models/Indicators/ErrorsIndicator.cs b/src/BuildVision.UI/Models/Indicators/ErrorsIndicator.cs deleted file mode 100644 index 08446ea3..00000000 --- a/src/BuildVision.UI/Models/Indicators/ErrorsIndicator.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Linq; - -using BuildVision.UI; -using BuildVision.UI.Models.Indicators.Core; -using BuildVision.UI.Contracts; - -namespace BuildVision.UI.Models.Indicators -{ - public class ErrorsIndicator : ValueIndicator - { - public override string Header => Resources.ErrorsIndicator_Header; - public override string Description => Resources.ErrorsIndicator_Description; - - protected override int? GetValue( IBuildInfo buildContext) - { - return buildContext.BuildedProjects.Sum(proj => proj.ErrorsBox.ErrorsCount); - } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Models/Indicators/MessagesIndicator.cs b/src/BuildVision.UI/Models/Indicators/MessagesIndicator.cs deleted file mode 100644 index 450576bd..00000000 --- a/src/BuildVision.UI/Models/Indicators/MessagesIndicator.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Linq; - -using BuildVision.UI; -using BuildVision.UI.Models.Indicators.Core; -using BuildVision.UI.Contracts; - -namespace BuildVision.UI.Models.Indicators -{ - public class MessagesIndicator : ValueIndicator - { - public override string Header => Resources.MessagesIndicator_Header; - public override string Description => Resources.MessagesIndicator_Description; - - protected override int? GetValue(IBuildInfo buildContext) - { - return buildContext.BuildedProjects.Sum(proj => proj.ErrorsBox.MessagesCount); - } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Models/Indicators/SeparatorIndicator.cs b/src/BuildVision.UI/Models/Indicators/SeparatorIndicator.cs deleted file mode 100644 index 8691c5b6..00000000 --- a/src/BuildVision.UI/Models/Indicators/SeparatorIndicator.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Linq; - -using BuildVision.UI; -using BuildVision.UI.Models.Indicators.Core; -using BuildVision.UI.Contracts; - -namespace BuildVision.UI.Models.Indicators -{ - public class SeparatorIndicator : ValueIndicator - { - public override string Header => Resources.SeparatorIndicator_Header; - public override string Description => null; - public override string StringValue => string.Empty; - public override double Width => 20; - - protected override int? GetValue(IBuildInfo buildContext) - { - return null; - } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Models/Indicators/SuccessProjectsIndicator.cs b/src/BuildVision.UI/Models/Indicators/SuccessProjectsIndicator.cs deleted file mode 100644 index 87bbe666..00000000 --- a/src/BuildVision.UI/Models/Indicators/SuccessProjectsIndicator.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Linq; - -using BuildVision.UI; -using BuildVision.UI.Models.Indicators.Core; -using BuildVision.UI.Contracts; -using System; - -namespace BuildVision.UI.Models.Indicators -{ - public class SuccessProjectsIndicator : ValueIndicator - { - public override string Header => Resources.SuccessProjectsIndicator_Header; - public override string Description => Resources.SuccessProjectsIndicator_Description; - - protected override int? GetValue(IBuildInfo buildContext) - { - try - { - return buildContext.BuildedProjects.BuildSuccessCount; - } - catch (NullReferenceException) - { - return null; - } - } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Models/Indicators/UpToDateProjectsIndicator.cs b/src/BuildVision.UI/Models/Indicators/UpToDateProjectsIndicator.cs deleted file mode 100644 index 01a4b84f..00000000 --- a/src/BuildVision.UI/Models/Indicators/UpToDateProjectsIndicator.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using BuildVision.UI.Models.Indicators.Core; -using BuildVision.UI.Contracts; - -namespace BuildVision.UI.Models.Indicators -{ - public class UpToDateProjectsIndicator : ValueIndicator - { - public override string Header => Resources.UpToDateProjectsIndicator_Header; - public override string Description => Resources.UpToDateProjectsIndicator_Description; - - protected override int? GetValue(IBuildInfo buildContext) - { - try - { - return buildContext.BuildedProjects.BuildUpToDateCount; - } - catch (NullReferenceException) - { - return null; - } - } - } -} diff --git a/src/BuildVision.UI/Models/Indicators/WarningProjectsIndicator.cs b/src/BuildVision.UI/Models/Indicators/WarningProjectsIndicator.cs deleted file mode 100644 index aa609d28..00000000 --- a/src/BuildVision.UI/Models/Indicators/WarningProjectsIndicator.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using BuildVision.UI.Models.Indicators.Core; -using BuildVision.UI.Contracts; - -namespace BuildVision.UI.Models.Indicators -{ - public class WarningProjectsIndicator : ValueIndicator - { - public override string Header => Resources.WarningProjectsIndicator_Header; - public override string Description => Resources.WarningProjectsIndicator_Description; - - protected override int? GetValue(IBuildInfo buildContext) - { - try - { - return buildContext.BuildedProjects.BuildWarningsCount; - } - catch (NullReferenceException) - { - return null; - } - } - } -} diff --git a/src/BuildVision.UI/Models/Indicators/WarningsIndicator.cs b/src/BuildVision.UI/Models/Indicators/WarningsIndicator.cs deleted file mode 100644 index 83e55861..00000000 --- a/src/BuildVision.UI/Models/Indicators/WarningsIndicator.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Linq; - -using BuildVision.UI.Models.Indicators.Core; -using BuildVision.UI.Contracts; - -namespace BuildVision.UI.Models.Indicators -{ - public class WarningsIndicator : ValueIndicator - { - public override string Header => Resources.WarningsIndicator_Header; - public override string Description => Resources.WarningsIndicator_Description; - - protected override int? GetValue(IBuildInfo buildContext) - { - return buildContext.BuildedProjects.Sum(proj => proj.ErrorsBox.WarningsCount); - } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Models/ProjectItem.cs b/src/BuildVision.UI/Models/ProjectItem.cs index 959949fc..5516e796 100644 --- a/src/BuildVision.UI/Models/ProjectItem.cs +++ b/src/BuildVision.UI/Models/ProjectItem.cs @@ -1,282 +1,189 @@ using System; +using System.Collections.ObjectModel; using System.Windows.Controls; using BuildVision.Common; using BuildVision.Common.Extensions; using BuildVision.Contracts; -using BuildVision.UI.Modelss; using BuildVision.UI.Extensions; -using BuildVision.UI.Models.Indicators.Core; +using BuildVision.UI.Modelss; namespace BuildVision.UI.Models { - public class ProjectItem : BindableBase - { - private const string ResourcesUri = @"Resources/ProjectItem.Resources.xaml"; - - public ProjectItem() - { - State = ProjectState.Pending; - } - - public bool IsBatchBuildProject { get; set; } - - private string _uniqueName; - - [GridColumn("ProjectItemHeader_UniqueName", ColumnsOrder.UniqueName, false, ExampleValue = @"ConsoleApplication1\ConsoleApplication1.csproj")] - public string UniqueName - { - get => _uniqueName; - set => SetProperty(ref _uniqueName, value); - } - - private string _name; - - [GridColumn("ProjectItemHeader_Name", ColumnsOrder.Name, true, ExampleValue = @"ConsoleApplication1")] - public string Name - { - get => _name; - set => SetProperty(ref _name, value); - } - - private string _fullName; - - [GridColumn("ProjectItemHeader_FullName", ColumnsOrder.FullName, false, ExampleValue = @"D:\Projects\ConsoleApplication1\ConsoleApplication1.csproj")] - public string FullName - { - get => _fullName; - set => SetProperty(ref _fullName, value); - } - - private string _fullPath; - - [GridColumn("ProjectItemHeader_FullPath", ColumnsOrder.FullPath, false, ExampleValue = @"D:\Projects\ConsoleApplication1")] - public string FullPath - { - get => _fullPath; - set => SetProperty(ref _fullPath, value); - } - - private string _language; - - [GridColumn("ProjectItemHeader_Language", ColumnsOrder.Language, true, ExampleValue = @"C#")] - public string Language - { - get => _language; - set => SetProperty(ref _language, value); - } - - private string _commonType; - - /// - /// See registered types in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\[Version "11.0"]\Projects. - /// - [GridColumn("ProjectItemHeader_CommonType", ColumnsOrder.CommonType, false, ExampleValue = @"Windows")] - public string CommonType - { - get => _commonType; - set => SetProperty(ref _commonType, value); - } - - private string _configuration; - - [GridColumn("ProjectItemHeader_Configuration", ColumnsOrder.Configuration, true, ExampleValue = @"Debug")] - public string Configuration - { - get => _configuration; - set => SetProperty(ref _configuration, value); - } - - private string _platform; - - [GridColumn("ProjectItemHeader_Platform", ColumnsOrder.Platform, true, ExampleValue = @"x86")] - public string Platform - { - get => _platform; - set => SetProperty(ref _platform, value); - } - - private ProjectState _state; - - [GridColumn("ProjectItemHeader_State", ColumnsOrder.State, true, ExampleValue = @"BuildDone")] - public ProjectState State - { - get => _state; - set - { - SetProperty(ref _state, value); - OnPropertyChanged(nameof(StateBitmap)); - } - } - - [GridColumn("ProjectItemHeader_StateBitmap", ColumnsOrder.StateBitmap, true, ImageKey = GridColumnAttribute.EmptyHeaderImageKey)] - public ControlTemplate StateBitmap => _state.GetAssociatedContent(); - - private DateTime? _buildStartTime; - - [GridColumn("ProjectItemHeader_BuildStartTime", ColumnsOrder.BuildStartTime, true, ValueStringFormat = @"HH:mm:ss", DateTimeExampleValue = @"2012-07-27T20:06:12.3691406+06:00")] - public DateTime? BuildStartTime - { - get => _buildStartTime; - set - { - SetProperty(ref _buildStartTime, value); - OnPropertyChanged(nameof(BuildStartTime)); - OnPropertyChanged(nameof(BuildElapsedTime)); - } - } - - private DateTime? _buildFinishTime; - - [GridColumn("ProjectItemHeader_BuildFinishTime", ColumnsOrder.BuildFinishTime, true, ValueStringFormat = @"HH:mm:ss", DateTimeExampleValue = @"2012-07-27T20:06:12.3691406+06:00")] - public DateTime? BuildFinishTime - { - get => _buildFinishTime; - set - { - SetProperty(ref _buildFinishTime, value); - OnPropertyChanged(nameof(BuildFinishTime)); - OnPropertyChanged(nameof(BuildElapsedTime)); - } - } - - [GridColumn("ProjectItemHeader_BuildElapsedTime", ColumnsOrder.BuildElapsedTime, true, ValueStringFormat = @"mm\:ss", TimeSpanExampleValue = @"00:09:21.60")] - public TimeSpan? BuildElapsedTime - { - get - { - if (_buildStartTime == null) - return null; - - if (_buildFinishTime == null) - return DateTime.Now.Subtract(_buildStartTime.Value); - - return _buildFinishTime.Value.Truncate(TimeSpan.FromSeconds(1)) - .Subtract(_buildStartTime.Value.Truncate(TimeSpan.FromSeconds(1))); - } - } - - private ErrorsBox _errorsBox; - - public ErrorsBox ErrorsBox - { - get { return _errorsBox ?? (_errorsBox = new ErrorsBox()); } - set - { - if (_errorsBox != value) + public class ProjectItem : BindableBase, IProjectItem + { + private const string ResourcesUri = @"Resources/ProjectItem.Resources.xaml"; + + public bool IsBatchBuildProject { get; set; } + public bool Success { get; set; } + + [GridColumn("ProjectItemHeader_UniqueName", ColumnsOrder.UniqueName, false, ExampleValue = @"ConsoleApplication1\ConsoleApplication1.csproj")] + public string UniqueName { get; set; } + [GridColumn("ProjectItemHeader_Name", ColumnsOrder.Name, true, ExampleValue = @"ConsoleApplication1")] + public string Name { get; set; } + [GridColumn("ProjectItemHeader_FullName", ColumnsOrder.FullName, false, ExampleValue = @"D:\Projects\ConsoleApplication1\ConsoleApplication1.csproj")] + public string FullName { get; set; } + [GridColumn("ProjectItemHeader_FullPath", ColumnsOrder.FullPath, false, ExampleValue = @"D:\Projects\ConsoleApplication1")] + public string FullPath { get; set; } + [GridColumn("ProjectItemHeader_Language", ColumnsOrder.Language, true, ExampleValue = @"C#")] + public string Language { get; set; } + [GridColumn("ProjectItemHeader_CommonType", ColumnsOrder.CommonType, false, ExampleValue = @"Windows")] + public string CommonType { get; set; } + [GridColumn("ProjectItemHeader_Configuration", ColumnsOrder.Configuration, true, ExampleValue = @"Debug")] + public string Configuration { get; set; } + [GridColumn("ProjectItemHeader_Platform", ColumnsOrder.Platform, true, ExampleValue = @"x86")] + public string Platform { get; set; } + [GridColumn("ProjectItemHeader_Framework", ColumnsOrder.Framework, false, ExampleValue = @"3.5")] + public string Framework { get; set; } + [GridColumn("ProjectItemHeader_FlavourType", ColumnsOrder.FlavourType, true, ExampleValue = @"Windows; VSTA")] + public string FlavourType { get; set; } + [GridColumn("ProjectItemHeader_MainFlavourType", ColumnsOrder.MainFlavourType, false, ExampleValue = @"VSTA")] + public string MainFlavourType { get; set; } + [GridColumn("ProjectItemHeader_OutputType", ColumnsOrder.OutputType, false, ExampleValue = @"Library")] + public string OutputType { get; set; } + [GridColumn("ProjectItemHeader_ExtenderNames", ColumnsOrder.ExtenderNames, false, ExampleValue = @"VST")] + public string ExtenderNames { get; set; } + [GridColumn("ProjectItemHeader_RootNamespace", ColumnsOrder.RootNamespace, false, ExampleValue = @"MyApplication")] + public string RootNamespace { get; set; } + [GridColumn("ProjectItemHeader_SolutionFolder", ColumnsOrder.SolutionFolder, false, ExampleValue = @"SolutionFolder1\SolutionFolder2")] + public string SolutionFolder { get; set; } + + [GridColumn("ProjectItemHeader_StateBitmap", ColumnsOrder.StateBitmap, true, ImageKey = GridColumnAttribute.EmptyHeaderImageKey)] + public ControlTemplate StateBitmap => _state.GetAssociatedContent(); + [GridColumn("ProjectItemHeader_BuildElapsedTime", ColumnsOrder.BuildElapsedTime, true, ValueStringFormat = @"mm\:ss", TimeSpanExampleValue = @"00:09:21.60")] + public TimeSpan? BuildElapsedTime { - _errorsBox = value; - OnPropertyChanged("ErrorsBox"); - OnPropertyChanged("ErrorsCount"); - OnPropertyChanged("WarningsCount"); - OnPropertyChanged("MessagesCount"); + get + { + if (_buildStartTime == null) + { + return null; + } + if (_buildFinishTime == null) + { + return DateTime.Now.Subtract(_buildStartTime.Value); + } + return _buildFinishTime.Value.Truncate(TimeSpan.FromSeconds(1)).Subtract(_buildStartTime.Value.Truncate(TimeSpan.FromSeconds(1))); + } } - } - } - - [GridColumn("ProjectItemHeader_ErrorsCount", ColumnsOrder.ErrorsCount, true, ImageDictionaryUri = ValueIndicator.ResourcesUri, ImageKey = "ErrorsIndicator", ExampleValue = 4)] - public int ErrorsCount => ErrorsBox.ErrorsCount; - [GridColumn("ProjectItemHeader_WarningsCount", ColumnsOrder.WarningsCount, true, ImageDictionaryUri = ValueIndicator.ResourcesUri, ImageKey = "WarningsIndicator", ExampleValue = 1253)] - public int WarningsCount => ErrorsBox.WarningsCount; - [GridColumn("ProjectItemHeader_MessagesCount", ColumnsOrder.MessagesCount, false, ImageDictionaryUri = ValueIndicator.ResourcesUri, ImageKey = "MessagesIndicator", ExampleValue = 2)] - public int MessagesCount => ErrorsBox.MessagesCount; - - private string _framework; - - [GridColumn("ProjectItemHeader_Framework", ColumnsOrder.Framework, false, ExampleValue = @"3.5")] - public string Framework - { - get => _framework; - set => SetProperty(ref _framework, value); - } - - private string _flavourType; - - [GridColumn("ProjectItemHeader_FlavourType", ColumnsOrder.FlavourType, true, ExampleValue = @"Windows; VSTA")] - public string FlavourType - { - get => _flavourType; - set => SetProperty(ref _flavourType, value); - } - private string _mainFlavourType; - - [GridColumn("ProjectItemHeader_MainFlavourType", ColumnsOrder.MainFlavourType, false, ExampleValue = @"VSTA")] - public string MainFlavourType - { - get => _mainFlavourType; - set => SetProperty(ref _mainFlavourType, value); - } - - private string _outputType; - - [GridColumn("ProjectItemHeader_OutputType", ColumnsOrder.OutputType, false, ExampleValue = @"Library")] - public string OutputType - { - get => _outputType; - set => SetProperty(ref _outputType, value); - } - - private string _extenderNames; - - [GridColumn("ProjectItemHeader_ExtenderNames", ColumnsOrder.ExtenderNames, false, ExampleValue = @"VST")] - public string ExtenderNames - { - get => _extenderNames; - set => SetProperty(ref _extenderNames, value); - } + private ProjectState _state; + [GridColumn("ProjectItemHeader_State", ColumnsOrder.State, true, ExampleValue = @"BuildDone")] + public ProjectState State + { + get => _state; + set + { + SetProperty(ref _state, value); + OnPropertyChanged(nameof(StateBitmap)); + } + } + private DateTime? _buildStartTime; + [GridColumn("ProjectItemHeader_BuildStartTime", ColumnsOrder.BuildStartTime, true, ValueStringFormat = @"HH:mm:ss", DateTimeExampleValue = @"2012-07-27T20:06:12.3691406+06:00")] + public DateTime? BuildStartTime + { + get => _buildStartTime; + set + { + SetProperty(ref _buildStartTime, value); + OnPropertyChanged(nameof(BuildStartTime)); + OnPropertyChanged(nameof(BuildElapsedTime)); + } + } + private DateTime? _buildFinishTime; + [GridColumn("ProjectItemHeader_BuildFinishTime", ColumnsOrder.BuildFinishTime, true, ValueStringFormat = @"HH:mm:ss", DateTimeExampleValue = @"2012-07-27T20:06:12.3691406+06:00")] + public DateTime? BuildFinishTime + { + get => _buildFinishTime; + set + { + SetProperty(ref _buildFinishTime, value); + OnPropertyChanged(nameof(BuildFinishTime)); + OnPropertyChanged(nameof(BuildElapsedTime)); + } + } - private int? _buildOrder; + public ObservableCollection Errors { get; set; } = new ObservableCollection(); - [GridColumn("ProjectItemHeader_BuildOrder", ColumnsOrder.BuildOrder, false, ImageDictionaryUri = ResourcesUri, ImageKey = "BuildOrder", Width = 23, ExampleValue = 4)] - public int? BuildOrder - { - get => _buildOrder; - set => SetProperty(ref _buildOrder, value); - } + public ObservableCollection Warnings { get; set; } = new ObservableCollection(); - private string _rootNamespace; + public ObservableCollection Messages { get; set; } = new ObservableCollection(); - [GridColumn("ProjectItemHeader_RootNamespace", ColumnsOrder.RootNamespace, false, ExampleValue = @"MyApplication")] - public string RootNamespace - { - get => _rootNamespace; - set => SetProperty(ref _rootNamespace, value); - } + private int _errorsCount; + [GridColumn("ProjectItemHeader_ErrorsCount", ColumnsOrder.ErrorsCount, true, ImageDictionaryUri = "Resources/ValueIndicator.Resources.xaml", ImageKey = "ErrorsIndicatorIcon", ExampleValue = 4)] + public int ErrorsCount + { + get => _errorsCount; + set => SetProperty(ref _errorsCount, value); + } - private string _solutionFolder; + private int _warningsCount; + [GridColumn("ProjectItemHeader_WarningsCount", ColumnsOrder.WarningsCount, true, ImageDictionaryUri = "Resources/ValueIndicator.Resources.xaml", ImageKey = "WarningsIndicatorIcon", ExampleValue = 1253)] + public int WarningsCount + { + get => _warningsCount; + set => SetProperty(ref _warningsCount, value); + } - [GridColumn("ProjectItemHeader_SolutionFolder", ColumnsOrder.SolutionFolder, false, ExampleValue = @"SolutionFolder1\SolutionFolder2")] - public string SolutionFolder - { - get => _solutionFolder; - set => SetProperty(ref _solutionFolder, value); - } + private int _messagesCount; + [GridColumn("ProjectItemHeader_MessagesCount", ColumnsOrder.MessagesCount, false, ImageDictionaryUri = "Resources/ValueIndicator.Resources.xaml", ImageKey = "MessagesIndicatorIcon", ExampleValue = 2)] + public int MessagesCount + { + get => _messagesCount; + set => SetProperty(ref _messagesCount, value); + } - public ProjectItem GetBatchBuildCopy(string configuration, string platform) - { - var pi = Clone(); - pi.Configuration = configuration; - pi.Platform = platform; - pi.ErrorsBox = new ErrorsBox(); - pi.IsBatchBuildProject = true; - return pi; - } + private int? _buildOrder; + [GridColumn("ProjectItemHeader_BuildOrder", ColumnsOrder.BuildOrder, false, ImageDictionaryUri = ResourcesUri, ImageKey = "BuildOrder", Width = 23, ExampleValue = 4)] + public int? BuildOrder + { + get => _buildOrder; + set => SetProperty(ref _buildOrder, value); + } - private ProjectItem Clone() - { - var xmlSerializer = new GenericXmlSerializer(); - return xmlSerializer.Deserialize(xmlSerializer.Serialize(this)); - } + public ProjectItem() => State = ProjectState.Pending; - public void UpdatePostBuildProperties(BuildedProject buildedProjectInfo) - { - if (buildedProjectInfo != null) - ErrorsBox = buildedProjectInfo.ErrorsBox; - } + public void RaiseBuildElapsedTimeChanged() => OnPropertyChanged(nameof(BuildElapsedTime)); - public void RaiseBuildElapsedTimeChanged() - { - OnPropertyChanged(nameof(BuildElapsedTime)); + public void AddErrorItem(ErrorItem errorItem) + { + switch (errorItem.Level) + { + case ErrorLevel.Message: + MessagesCount++; + break; + case ErrorLevel.Warning: + WarningsCount++; + break; + case ErrorLevel.Error: + ErrorsCount++; + break; + default: + throw new ArgumentOutOfRangeException(nameof(errorItem)); + } + if (errorItem.Level != ErrorLevel.Error) + { + return; + } + + int errorNumber = Errors.Count + Warnings.Count + Messages.Count + 1; + errorItem.Number = errorNumber; + switch (errorItem.Level) + { + case ErrorLevel.Message: + Messages.Add(errorItem); + break; + + case ErrorLevel.Warning: + Warnings.Add(errorItem); + break; + + case ErrorLevel.Error: + Errors.Add(errorItem); + break; + + default: + throw new ArgumentOutOfRangeException(nameof(errorItem)); + } + } } - } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Models/SolutionItem.cs b/src/BuildVision.UI/Models/SolutionModel.cs similarity index 56% rename from src/BuildVision.UI/Models/SolutionItem.cs rename to src/BuildVision.UI/Models/SolutionModel.cs index b1d65eaa..a03e5203 100644 --- a/src/BuildVision.UI/Models/SolutionItem.cs +++ b/src/BuildVision.UI/Models/SolutionModel.cs @@ -1,12 +1,17 @@ using BuildVision.Common; -using System.Collections.Generic; -using System.Collections.ObjectModel; +using BuildVision.Contracts.Models; - -namespace BuildVision.UI.Models +namespace BuildVision.Core { - public class SolutionItem : BindableBase + public class SolutionModel : BindableBase, ISolutionModel { + private string _fileName; + public string FileName + { + get => _fileName; + set => SetProperty(ref _fileName, value); + } + private string _name; public string Name { @@ -27,15 +32,5 @@ public bool IsEmpty get => _isEmpty; set => SetProperty(ref _isEmpty, value); } - - public ObservableCollection Projects { get; } - - public List AllProjects { get; } - - public SolutionItem() - { - Projects = new ObservableRangeCollection(); - AllProjects = new List(); - } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Models/SortDescription.cs b/src/BuildVision.UI/Models/SortDescription.cs new file mode 100644 index 00000000..1a9aa29b --- /dev/null +++ b/src/BuildVision.UI/Models/SortDescription.cs @@ -0,0 +1,19 @@ +using BuildVision.UI.Models; + +namespace BuildVision.UI.Settings.Models.Sorting +{ + public class SortDescription + { + public SortOrder Order { get; set; } + + public string Property { get; set; } + + public SortDescription() { } + + public SortDescription(SortOrder order, string property) + { + Order = order; + Property = property; + } + } +} diff --git a/src/BuildVision.UI/Models/WindowStateAction.cs b/src/BuildVision.UI/Models/WindowStateAction.cs new file mode 100644 index 00000000..2c2f04c6 --- /dev/null +++ b/src/BuildVision.UI/Models/WindowStateAction.cs @@ -0,0 +1,16 @@ +using BuildVision.UI.Models; + +namespace BuildVision.UI.Settings.Models.ToolWindow +{ + public class WindowStateAction + { + public WindowState State { get; set; } + + public WindowStateAction() { } + + public WindowStateAction(WindowState state) + { + State = state; + } + } +} diff --git a/src/BuildVision.UI/Properties/GlobalSuppressions.cs b/src/BuildVision.UI/Properties/GlobalSuppressions.cs new file mode 100644 index 00000000..41b8c33d --- /dev/null +++ b/src/BuildVision.UI/Properties/GlobalSuppressions.cs @@ -0,0 +1,34 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~F:BuildVision.UI.Components.SpinnerControl.FormattedValuePropertyKey")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~F:BuildVision.UI.Extensions.VectorResources._baseUri")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Converters.DataGridLengthStringConverter.Convert(System.Object,System.Type,System.Object,System.Globalization.CultureInfo)~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Converters.DataGridLengthStringConverter.ConvertBack(System.Object,System.Type,System.Object,System.Globalization.CultureInfo)~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Converters.GridColumnSettingsToColumnExampleValueConverter.FormatExample(System.Object,System.String)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Converters.MultiBindingStringFormatConverter.Convert(System.Object[],System.Type,System.Object,System.Globalization.CultureInfo)~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Converters.SubtractConstantConverter.Convert(System.Object,System.Type,System.Object,System.Globalization.CultureInfo)~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Helpers.BuildMessagesFactory.GetBuildBeginMajorMessage(BuildVision.Contracts.Models.IBuildInformationModel)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Helpers.BuildMessagesFactory.GetBuildDoneExtraMessage(BuildVision.Contracts.Models.IBuildInformationModel)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Helpers.BuildMessagesFactory.GetBuildDoneMajorMessage(BuildVision.Contracts.Models.IBuildInformationModel)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Helpers.BuildMessagesFactory.GetExtraTimePartString(System.TimeSpan)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Helpers.BuildMessagesFactory.GetMainString(BuildVision.Contracts.Models.IBuildInformationModel)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Helpers.BuildMessagesFactory.GetTimeString(System.Nullable{System.DateTime})~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.ViewModels.BuildVisionPaneViewModel.CopyErrorMessageToClipboard(BuildVision.UI.Models.ProjectItem)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~P:BuildVision.UI.Modelss.GridColumnAttribute.DateTimeExampleValue")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~P:BuildVision.UI.Modelss.GridColumnAttribute.TimeSpanExampleValue")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~P:BuildVision.UI.Settings.Models.BuildMessagesSettings.BuildBeginMajorMessageStringFormat")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~P:BuildVision.UI.Settings.Models.BuildMessagesSettings.BuildDoneMajorMessageStringFormat")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~P:BuildVision.UI.Settings.Models.BuildMessagesSettings.DateTimeFormat")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~P:BuildVision.UI.Settings.Models.BuildMessagesSettings.ExtraMessageStringFormat")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "member", Target = "~P:BuildVision.UI.Settings.Models.BuildMessagesSettings.TimeSpanFormat")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Converters.DataGridLengthStringConverter.ConvertBack(System.Object,System.Type,System.Object,System.Globalization.CultureInfo)~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Converters.GridColumnSettingsToColumnExampleValueConverter.FormatExample(System.Object,System.String)~System.String")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Converters.MultiBindingStringFormatConverter.Convert(System.Object[],System.Type,System.Object,System.Globalization.CultureInfo)~System.Object")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.DataGrid.ColumnsManager.GenerateColumns(System.Collections.ObjectModel.ObservableCollection{System.Windows.Controls.DataGridColumn},BuildVision.UI.Settings.Models.GridSettings)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.DataGrid.ColumnsManager.SyncColumnSettings(System.Collections.ObjectModel.ObservableCollection{System.Windows.Controls.DataGridColumn},BuildVision.UI.Settings.Models.GridSettings)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.ErrorsGrid.ErrorsGridRowOnMouseLeftButtonUp(System.Object,System.Windows.Input.MouseButtonEventArgs)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.Extensions.VectorResources.TryGet(System.String,System.String)~System.Windows.Controls.ControlTemplate")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.ViewModels.BuildVisionPaneViewModel.CopyErrorMessageToClipboard(BuildVision.UI.Models.ProjectItem)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "", Scope = "member", Target = "~M:BuildVision.UI.ViewModels.BuildVisionPaneViewModel.OpenContainingFolder")] diff --git a/src/BuildVision.UI/Resources.Designer.cs b/src/BuildVision.UI/Resources.Designer.cs index 7ddc39b9..504fb22b 100644 --- a/src/BuildVision.UI/Resources.Designer.cs +++ b/src/BuildVision.UI/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace BuildVision.UI { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Resources { @@ -692,6 +692,15 @@ public static string GeneralSettings_NavigateToBuildFailureReasonLabelToolTip { } } + /// + /// Looks up a localized string similar to Help improve BuildVision by providing anynonymous usage data and crash reports. + /// + public static string GeneralSettings_ParticipateInTelemetry { + get { + return ResourceManager.GetString("GeneralSettings_ParticipateInTelemetry", resourceCulture); + } + } + /// /// Looks up a localized string similar to Reset progress after build done. /// diff --git a/src/BuildVision.UI/Resources.resx b/src/BuildVision.UI/Resources.resx index 5e12b259..27ee9cc9 100644 --- a/src/BuildVision.UI/Resources.resx +++ b/src/BuildVision.UI/Resources.resx @@ -607,4 +607,7 @@ on build done Up-to-date Projects + + Help improve BuildVision by providing anynonymous usage data and crash reports + \ No newline at end of file diff --git a/src/BuildVision.UI/Resources/BuildAction.Resources.Test.xaml b/src/BuildVision.UI/Resources/BuildAction.Resources.Test.xaml index 221e5321..39d886f2 100644 --- a/src/BuildVision.UI/Resources/BuildAction.Resources.Test.xaml +++ b/src/BuildVision.UI/Resources/BuildAction.Resources.Test.xaml @@ -6,7 +6,7 @@ - + @@ -23,8 +23,8 @@ SnapsToDevicePixels="True" ClipToBounds="True" UseLayoutRounding="False" - Template="{StaticResource BuildError}" /> - + Template="{StaticResource RebuildSolutionIcon}" /> + - + Template="{StaticResource BuildSolutionIcon}" /> + + Template="{StaticResource CancelBuildSolutionIcon}" /> - + - + Template="{StaticResource CleanSolutionIcon}" /> diff --git a/src/BuildVision.UI/Resources/BuildAction.Resources.xaml b/src/BuildVision.UI/Resources/BuildAction.Resources.xaml index 5ce9a519..8e9b2c0f 100644 --- a/src/BuildVision.UI/Resources/BuildAction.Resources.xaml +++ b/src/BuildVision.UI/Resources/BuildAction.Resources.xaml @@ -1,7 +1,7 @@  - + @@ -12,14 +12,14 @@ - - - + + + + + + + - + - + - + - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/BuildVision.UI/Resources/CommonResources.xaml b/src/BuildVision.UI/Resources/CommonResources.xaml index 1a63dec2..e9c29ba0 100644 --- a/src/BuildVision.UI/Resources/CommonResources.xaml +++ b/src/BuildVision.UI/Resources/CommonResources.xaml @@ -1,6 +1,6 @@  + xmlns:vsfx="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.14.0"> - \ No newline at end of file + diff --git a/src/BuildVision.UI/Resources/ValueIndicator.Resources.Test.xaml b/src/BuildVision.UI/Resources/ValueIndicator.Resources.Test.xaml index 3437d35e..b4351613 100644 --- a/src/BuildVision.UI/Resources/ValueIndicator.Resources.Test.xaml +++ b/src/BuildVision.UI/Resources/ValueIndicator.Resources.Test.xaml @@ -25,21 +25,21 @@ SnapsToDevicePixels="True" ClipToBounds="True" UseLayoutRounding="False" - Template="{StaticResource ErrorsIndicator}" /> + Template="{StaticResource ErrorsIndicatorIcon}" /> + Template="{StaticResource WarningsIndicatorIcon}" /> + Template="{StaticResource MessagesIndicatorIcon}" /> @@ -48,7 +48,7 @@ SnapsToDevicePixels="True" ClipToBounds="True" UseLayoutRounding="False" - Template="{StaticResource SuccessProjectsIndicator}" /> + Template="{StaticResource SuccessProjectsIndicatorIcon}" /> @@ -57,7 +57,7 @@ SnapsToDevicePixels="True" ClipToBounds="True" UseLayoutRounding="False" - Template="{StaticResource UpToDateProjectsIndicator}" /> + Template="{StaticResource UpToDateProjectsIndicatorIcon}" /> @@ -67,7 +67,7 @@ SnapsToDevicePixels="True" ClipToBounds="True" UseLayoutRounding="False" - Template="{StaticResource WarningProjectsIndicator}" /> + Template="{StaticResource WarningProjectsIndicatorIcon}" /> @@ -76,7 +76,7 @@ SnapsToDevicePixels="True" ClipToBounds="True" UseLayoutRounding="False" - Template="{StaticResource ErrorProjectsIndicator}" /> + Template="{StaticResource ErrorProjectsIndicatorIcon}" /> diff --git a/src/BuildVision.UI/Resources/ValueIndicator.Resources.xaml b/src/BuildVision.UI/Resources/ValueIndicator.Resources.xaml index 5ac0f110..33df6466 100644 --- a/src/BuildVision.UI/Resources/ValueIndicator.Resources.xaml +++ b/src/BuildVision.UI/Resources/ValueIndicator.Resources.xaml @@ -1,8 +1,8 @@  + xmlns:vsfx="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.14.0"> - + - + - + - + @@ -110,7 +110,7 @@ - + @@ -135,7 +135,7 @@ - + @@ -160,7 +160,7 @@ - + diff --git a/src/BuildVision.UI/Settings/GeneralSettingsControl.xaml b/src/BuildVision.UI/Settings/GeneralSettingsControl.xaml index 23c39680..5c66c702 100644 --- a/src/BuildVision.UI/Settings/GeneralSettingsControl.xaml +++ b/src/BuildVision.UI/Settings/GeneralSettingsControl.xaml @@ -126,14 +126,14 @@ Content="{x:Static res:Resources.BuildMessagesSettings_StatusBarOutputCheckBox}" IsChecked="{Binding EnableStatusBarOutput}" /> - - + + @@ -173,10 +173,8 @@ - - - + diff --git a/src/BuildVision.UI/Settings/GeneralSettingsControl.xaml.cs b/src/BuildVision.UI/Settings/GeneralSettingsControl.xaml.cs index 36fbfc51..b0143873 100644 --- a/src/BuildVision.UI/Settings/GeneralSettingsControl.xaml.cs +++ b/src/BuildVision.UI/Settings/GeneralSettingsControl.xaml.cs @@ -1,10 +1,6 @@ -using BuildVision.Common; -using BuildVision.Helpers; -using Microsoft.VisualStudio.Shell; -using System; -using System.Diagnostics; -using System.Windows.Controls; +using System.Windows.Controls; using System.Windows.Navigation; +using BuildVision.Helpers; namespace BuildVision.UI.Settings { @@ -21,4 +17,4 @@ private void HyperlinkOnRequestNavigate(object sender, RequestNavigateEventArgs e.Handled = true; } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Settings/GridSettingsControl.xaml.cs b/src/BuildVision.UI/Settings/GridSettingsControl.xaml.cs index d4fb7f3f..0b3d31d7 100644 --- a/src/BuildVision.UI/Settings/GridSettingsControl.xaml.cs +++ b/src/BuildVision.UI/Settings/GridSettingsControl.xaml.cs @@ -4,10 +4,9 @@ using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; - -using Microsoft.VisualStudio.Shell; -using BuildVision.UI.Settings.Models.Columns; using BuildVision.UI.Extensions; +using BuildVision.UI.Settings.Models.Columns; +using Microsoft.VisualStudio.Shell; namespace BuildVision.UI.Settings { @@ -32,7 +31,9 @@ private void OnDataContextChanged(object sender, DependencyPropertyChangedEventA { // http://stackoverflow.com/questions/15025865/wpf-datagrid-not-exiting-edit-mode if (e.NewValue == null) + { Grid.CommitEdit(); + } } private void OnDialogKeyPendingEvent(object sender, RoutedEventArgs e) @@ -57,20 +58,28 @@ private void GridOnCurrentCellChanged(object sender, EventArgs e) private void GridOnCellEditEnding(object sender, DataGridCellEditEndingEventArgs e) { if (_displayIndexCommiting) + { return; + } if (!ReferenceEquals(e.Column, ColumnDisplayIndex)) + { return; + } if (e.EditAction != DataGridEditAction.Commit) + { return; + } _displayIndexCommiting = true; bool commited = Grid.CommitEdit(DataGridEditingUnit.Row, true); _displayIndexCommiting = false; if (!commited) + { return; + } var editedItem = (GridColumnSettings)e.Row.Item; _newDisplayIndex = editedItem.DisplayIndex; @@ -91,10 +100,14 @@ private void GridOnCellEditEnding(object sender, DataGridCellEditEndingEventArgs foreach (GridColumnSettings item in Grid.Items) { if (ReferenceEquals(item, editedItem)) + { continue; + } if (item.DisplayIndex >= _oldDisplayIndex + 1 && item.DisplayIndex <= _newDisplayIndex) + { item.DisplayIndex -= 1; + } } } else @@ -102,10 +115,14 @@ private void GridOnCellEditEnding(object sender, DataGridCellEditEndingEventArgs foreach (GridColumnSettings item in Grid.Items) { if (ReferenceEquals(item, editedItem)) + { continue; + } if (item.DisplayIndex >= _newDisplayIndex && item.DisplayIndex <= _oldDisplayIndex - 1) + { item.DisplayIndex += 1; + } } } @@ -118,7 +135,9 @@ private void GridOnTargetUpdated(object sender, DataTransferEventArgs e) { var grid = (System.Windows.Controls.DataGrid)sender; if (grid.ItemsSource == null) + { return; + } grid.Items.SortDescriptions.Add(new SortDescription("DisplayIndex", ListSortDirection.Ascending)); @@ -127,4 +146,4 @@ private void GridOnTargetUpdated(object sender, DataTransferEventArgs e) } } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Settings/Models/BaseGridColumnSettings.cs b/src/BuildVision.UI/Settings/Models/BaseGridColumnSettings.cs new file mode 100644 index 00000000..26e8fc3a --- /dev/null +++ b/src/BuildVision.UI/Settings/Models/BaseGridColumnSettings.cs @@ -0,0 +1,30 @@ +using System; + +namespace BuildVision.Contracts +{ + public abstract class BaseGridColumnSettingsAttribute : Attribute + { + public string Header { get; set; } + + public bool Visible { get; set; } + + /// + /// -1 for auto. + /// + public int DisplayIndex { get; set; } + + /// + /// double.NaN for auto. + /// + public double Width { get; set; } + + public string ValueStringFormat { get; set; } + + protected BaseGridColumnSettingsAttribute() + { + Width = double.NaN; + DisplayIndex = -1; + Visible = true; + } + } +} diff --git a/src/BuildVision.UI/Settings/Models/BuildMessagesSettings.cs b/src/BuildVision.UI/Settings/Models/BuildMessagesSettings.cs index ec5468ad..fb1cbea9 100644 --- a/src/BuildVision.UI/Settings/Models/BuildMessagesSettings.cs +++ b/src/BuildVision.UI/Settings/Models/BuildMessagesSettings.cs @@ -1,4 +1,4 @@ -using System; +using System; using BuildVision.Common; using BuildVision.UI.Models; @@ -65,7 +65,9 @@ public string BuildBeginMajorMessageStringFormat OnPropertyChanged(nameof(BuildBeginMajorMessageStringFormat)); if (!value.Contains("{0}")) + { throw new FormatException("Format must contain '{0}' argument."); + } string tmp = string.Format(value, "test"); } @@ -83,7 +85,9 @@ public string BuildDoneMajorMessageStringFormat OnPropertyChanged(nameof(BuildDoneMajorMessageStringFormat)); if (!value.Contains("{0}")) + { throw new FormatException("Format must contain '{0}' argument."); + } string tmp = string.Format(value, "test"); } @@ -131,7 +135,9 @@ public string ExtraMessageStringFormat OnPropertyChanged(nameof(ExtraMessageStringFormat)); if (!value.Contains("{0}")) + { throw new FormatException("Format must contain '{0}' argument."); + } var tmp = string.Format(value, "test"); } diff --git a/src/BuildVision.UI/Settings/Models/BuildProgress/BuildProgressSettings.cs b/src/BuildVision.UI/Settings/Models/BuildProgress/BuildProgressSettings.cs deleted file mode 100644 index f0b5c17c..00000000 --- a/src/BuildVision.UI/Settings/Models/BuildProgress/BuildProgressSettings.cs +++ /dev/null @@ -1,14 +0,0 @@ -using BuildVision.UI.Models; -using System.Runtime.Serialization; - -namespace BuildVision.UI.Settings.Models.BuildProgress -{ - public class BuildProgressSettings - { - public bool TaskBarProgressEnabled { get; set; } - - public ResetTaskBarItemInfoCondition ResetTaskBarProgressAfterBuildDone { get; set; } = ResetTaskBarItemInfoCondition.ByMouseClick; - - public int ResetTaskBarProgressDelay { get; set; } = 5000; - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Settings/Models/BuildProgressSettings.cs b/src/BuildVision.UI/Settings/Models/BuildProgressSettings.cs new file mode 100644 index 00000000..60f510f8 --- /dev/null +++ b/src/BuildVision.UI/Settings/Models/BuildProgressSettings.cs @@ -0,0 +1,13 @@ +using BuildVision.UI.Models; + +namespace BuildVision.UI.Settings.Models.BuildProgress +{ + public class BuildProgressSettings + { + public bool TaskBarProgressEnabled { get; set; } + + public ResetTaskBarItemInfoCondition ResetTaskBarProgressAfterBuildDone { get; set; } = ResetTaskBarItemInfoCondition.ByMouseClick; + + public int ResetTaskBarProgressDelay { get; set; } = 5000; + } +} diff --git a/src/BuildVision.UI/Settings/Models/Columns/GridColumnSettingsCollection.cs b/src/BuildVision.UI/Settings/Models/Columns/GridColumnSettingsCollection.cs deleted file mode 100644 index 4b3a9afb..00000000 --- a/src/BuildVision.UI/Settings/Models/Columns/GridColumnSettingsCollection.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; - -namespace BuildVision.UI.Settings.Models.Columns -{ - public class GridColumnSettingsCollection : List - { - public GridColumnSettings this[string propertyName] - { - get { return Find(s => s.PropertyNameId == propertyName); } - } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Settings/Models/ControlSettings.cs b/src/BuildVision.UI/Settings/Models/ControlSettings.cs index 3c47195a..f73528cf 100644 --- a/src/BuildVision.UI/Settings/Models/ControlSettings.cs +++ b/src/BuildVision.UI/Settings/Models/ControlSettings.cs @@ -1,47 +1,56 @@ -using System.Runtime.Serialization; - +using System.Runtime.Serialization; using BuildVision.Common; namespace BuildVision.UI.Settings.Models { - public class ControlSettings : SettingsBase - { - public BuildMessagesSettings BuildMessagesSettings { get; set; } - - public GeneralSettings GeneralSettings { get; set; } - - public GridSettings GridSettings { get; set; } - - public ProjectItemSettings ProjectItemSettings { get; set; } - - public WindowSettings WindowSettings { get; set; } - - public ControlSettings() - { - Init(); - } - - private void OnDeserialized(StreamingContext context) + public class ControlSettings : SettingsBase { - Init(); - } + public BuildMessagesSettings BuildMessagesSettings { get; set; } - private void Init() - { - if (GeneralSettings == null) - GeneralSettings = new GeneralSettings(); + public GeneralSettings GeneralSettings { get; set; } + + public GridSettings GridSettings { get; set; } + + public ProjectItemSettings ProjectItemSettings { get; set; } + + public WindowSettings WindowSettings { get; set; } + + public ControlSettings() + { + Init(); + } + + private void OnDeserialized(StreamingContext context) + { + Init(); + } + + private void Init() + { + if (GeneralSettings == null) + { + GeneralSettings = new GeneralSettings(); + } - if (WindowSettings == null) - WindowSettings = new WindowSettings(); + if (WindowSettings == null) + { + WindowSettings = new WindowSettings(); + } - if (GridSettings == null) - GridSettings = new GridSettings(); + if (GridSettings == null) + { + GridSettings = new GridSettings(); + } - if (BuildMessagesSettings == null) - BuildMessagesSettings = new BuildMessagesSettings(); + if (BuildMessagesSettings == null) + { + BuildMessagesSettings = new BuildMessagesSettings(); + } - if (ProjectItemSettings == null) - ProjectItemSettings = new ProjectItemSettings(); + if (ProjectItemSettings == null) + { + ProjectItemSettings = new ProjectItemSettings(); + } + } } - } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Settings/Models/GeneralSettings.cs b/src/BuildVision.UI/Settings/Models/GeneralSettings.cs index a038f01d..55c38961 100644 --- a/src/BuildVision.UI/Settings/Models/GeneralSettings.cs +++ b/src/BuildVision.UI/Settings/Models/GeneralSettings.cs @@ -1,4 +1,4 @@ -using BuildVision.Common; +using BuildVision.Common; using BuildVision.UI.Models; using BuildVision.UI.Settings.Models.BuildProgress; @@ -14,20 +14,20 @@ public class GeneralSettings : SettingsBase public bool StopBuildAfterFirstError { get; set; } - public bool ShowWarningSignForBuilds { get; set; } - public bool HideUpToDateTargets { get; set; } public NavigateToBuildFailureReasonCondition NavigateToBuildFailureReason { get; set; } public bool FillProjectListOnBuildBegin { get; set; } + public bool ParticipateInTelemetry { get; set; } + public GeneralSettings() { BuildProgressSettings = new BuildProgressSettings(); EnableStatusBarOutput = true; IndicatorsPanelVisible = true; - ShowWarningSignForBuilds = true; + ParticipateInTelemetry = true; } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Settings/Models/Columns/GridColumnSettings.cs b/src/BuildVision.UI/Settings/Models/GridColumnSettings.cs similarity index 80% rename from src/BuildVision.UI/Settings/Models/Columns/GridColumnSettings.cs rename to src/BuildVision.UI/Settings/Models/GridColumnSettings.cs index d6780355..4925a40a 100644 --- a/src/BuildVision.UI/Settings/Models/Columns/GridColumnSettings.cs +++ b/src/BuildVision.UI/Settings/Models/GridColumnSettings.cs @@ -1,4 +1,4 @@ -using BuildVision.Contracts; +using BuildVision.Contracts; namespace BuildVision.UI.Settings.Models.Columns { @@ -9,7 +9,7 @@ public class GridColumnSettings : BaseGridColumnSettingsAttribute PropertyNameId = string.Empty, Header = Resources.NoneMenuItem }; - + public string PropertyNameId { get; set; } private GridColumnSettings() @@ -17,11 +17,11 @@ private GridColumnSettings() } public GridColumnSettings( - string propertyNameId, - string header, - bool visible, - int displayIndex, - double width, + string propertyNameId, + string header, + bool visible, + int displayIndex, + double width, string valueStringFormat) { PropertyNameId = propertyNameId; @@ -32,4 +32,4 @@ public GridColumnSettings( ValueStringFormat = valueStringFormat; } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Settings/Models/GridSettings.cs b/src/BuildVision.UI/Settings/Models/GridSettings.cs index 8ad52998..a762410c 100644 --- a/src/BuildVision.UI/Settings/Models/GridSettings.cs +++ b/src/BuildVision.UI/Settings/Models/GridSettings.cs @@ -2,93 +2,92 @@ using System.Linq; using BuildVision.Common; using BuildVision.UI.DataGrid; -using BuildVision.UI.Settings.Models.Columns; using BuildVision.UI.Models; +using BuildVision.UI.Settings.Models.Columns; using BuildVision.UI.Settings.Models.Sorting; namespace BuildVision.UI.Settings.Models { - public class GridSettings : SettingsBase - { - private GridColumnSettingsCollection _columns; - - private string _groupName; - - private string _groupHeaderFormat; - - private SortDescription _sort; - - private List _collapsedGroups; - - private static string[] _groupHeaderFormatArgs; - - public GridColumnSettingsCollection Columns => _columns ?? (_columns = new GridColumnSettingsCollection()); - - public IEnumerable SortableColumnsUIList - { - get - { - yield return GridColumnSettings.Empty; - foreach (GridColumnSettings column in Columns.Where(x => ColumnsManager.ColumnIsSortable(x.PropertyNameId))) - yield return column; - } - } - - public IEnumerable GroupableColumnsUIList - { - get - { - yield return GridColumnSettings.Empty; - foreach (GridColumnSettings column in Columns.Where(ColumnsManager.ColumnIsGroupable)) - yield return column; - } - } - - public string GroupName - { - get => _groupName ?? (_groupName = string.Empty); - set => _groupName = value; - } - - /// - /// User-friendly header format for groups. - /// For example, "{title}: {value} - {count} items". - /// Available arguments see in . - /// - public string GroupHeaderFormat - { - get => _groupHeaderFormat ?? (_groupHeaderFormat = "{title}: {value}"); - set => _groupHeaderFormat = value; - } - - public string GroupHeaderRawFormat => ConvertGroupHeaderToRawFormat(GroupHeaderFormat); - - public static string[] GroupHeaderFormatArgs => _groupHeaderFormatArgs ?? (_groupHeaderFormatArgs = new[] { "title", "value", "count" }); - - public bool ShowColumnsHeader { get; set; } = true; - - public SortDescription Sort + public class GridSettings : SettingsBase { - get => _sort ?? (_sort = new SortDescription(SortOrder.Ascending, "BuildOrder")); - set => _sort = value; - } - - public List CollapsedGroups => _collapsedGroups ?? (_collapsedGroups = new List()); - - /// - /// Converts user-friendly string format with arguments - /// into system format string (with {0},{1},... arguments). - /// - private static string ConvertGroupHeaderToRawFormat(string userFriendlyFormatString) - { - if (string.IsNullOrEmpty(userFriendlyFormatString)) - return string.Empty; - - string rawFormat = userFriendlyFormatString; - for (int i = 0; i < GroupHeaderFormatArgs.Length; i++) - rawFormat = rawFormat.Replace("{" + GroupHeaderFormatArgs[i], "{" + i); - - return rawFormat; + private GridColumnSettingsCollection _columns; + + private string _groupName; + + private string _groupHeaderFormat; + + private SortDescription _sort; + + private List _collapsedGroups; + + private static string[] _groupHeaderFormatArgs; + + public GridColumnSettingsCollection Columns => _columns ?? (_columns = new GridColumnSettingsCollection()); + + public IEnumerable SortableColumnsUIList + { + get + { + yield return GridColumnSettings.Empty; + foreach (GridColumnSettings column in Columns.Where(x => ColumnsManager.ColumnIsSortable(x.PropertyNameId))) + { + yield return column; + } + } + } + + public IEnumerable GroupableColumnsUIList + { + get + { + yield return GridColumnSettings.Empty; + foreach (GridColumnSettings column in Columns.Where(ColumnsManager.ColumnIsGroupable)) + { + yield return column; + } + } + } + + public string GroupName + { + get => _groupName ?? (_groupName = string.Empty); + set => _groupName = value; + } + + public string GroupHeaderFormat + { + get => _groupHeaderFormat ?? (_groupHeaderFormat = "{title}: {value}"); + set => _groupHeaderFormat = value; + } + + public string GroupHeaderRawFormat => ConvertGroupHeaderToRawFormat(GroupHeaderFormat); + + public static string[] GroupHeaderFormatArgs => _groupHeaderFormatArgs ?? (_groupHeaderFormatArgs = new[] { "title", "value", "count" }); + + public bool ShowColumnsHeader { get; set; } = true; + + public SortDescription Sort + { + get => _sort ?? (_sort = new SortDescription(SortOrder.Ascending, "BuildOrder")); + set => _sort = value; + } + + public List CollapsedGroups => _collapsedGroups ?? (_collapsedGroups = new List()); + + private static string ConvertGroupHeaderToRawFormat(string userFriendlyFormatString) + { + if (string.IsNullOrEmpty(userFriendlyFormatString)) + { + return string.Empty; + } + + string rawFormat = userFriendlyFormatString; + for (int i = 0; i < GroupHeaderFormatArgs.Length; i++) + { + rawFormat = rawFormat.Replace("{" + GroupHeaderFormatArgs[i], "{" + i); + } + + return rawFormat; + } } - } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Settings/Models/ProjectItemSettings.cs b/src/BuildVision.UI/Settings/Models/ProjectItemSettings.cs index 2d171cd6..f1a451ed 100644 --- a/src/BuildVision.UI/Settings/Models/ProjectItemSettings.cs +++ b/src/BuildVision.UI/Settings/Models/ProjectItemSettings.cs @@ -1,10 +1,9 @@ -using BuildVision.Contracts; -using BuildVision.Common; - +using BuildVision.Common; +using BuildVision.Contracts; namespace BuildVision.UI.Settings.Models { public class ProjectItemSettings : SettingsBase - { + { public BuildOutputFileTypes CopyBuildOutputFileTypesToClipboard { get; set; } public ProjectItemSettings() @@ -12,4 +11,4 @@ public ProjectItemSettings() CopyBuildOutputFileTypesToClipboard = new BuildOutputFileTypes(); } } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Settings/Models/Sorting/SortDescription.cs b/src/BuildVision.UI/Settings/Models/Sorting/SortDescription.cs deleted file mode 100644 index b2589b75..00000000 --- a/src/BuildVision.UI/Settings/Models/Sorting/SortDescription.cs +++ /dev/null @@ -1,20 +0,0 @@ - -using BuildVision.UI.Models; - -namespace BuildVision.UI.Settings.Models.Sorting -{ - public class SortDescription - { - public SortOrder Order { get; set; } - - public string Property { get; set; } - - public SortDescription(SortOrder order, string property) - { - Order = order; - Property = property; - } - - public SortDescription() { } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Settings/Models/ToolWindow/WindowStateAction.cs b/src/BuildVision.UI/Settings/Models/ToolWindow/WindowStateAction.cs deleted file mode 100644 index bcef0a2a..00000000 --- a/src/BuildVision.UI/Settings/Models/ToolWindow/WindowStateAction.cs +++ /dev/null @@ -1,17 +0,0 @@ -using BuildVision.UI.Models; -using System.Runtime.Serialization; - -namespace BuildVision.UI.Settings.Models.ToolWindow -{ - public class WindowStateAction - { - public WindowState State { get; set; } - - public WindowStateAction(WindowState state) - { - State = state; - } - - public WindowStateAction() { } - } -} \ No newline at end of file diff --git a/src/BuildVision.UI/Settings/Models/WindowSettings.cs b/src/BuildVision.UI/Settings/Models/WindowSettings.cs index bef48610..190bcc46 100644 --- a/src/BuildVision.UI/Settings/Models/WindowSettings.cs +++ b/src/BuildVision.UI/Settings/Models/WindowSettings.cs @@ -1,22 +1,22 @@ -using BuildVision.Common; +using BuildVision.Common; using BuildVision.UI.Models; using BuildVision.UI.Settings.Models.ToolWindow; namespace BuildVision.UI.Settings.Models { - public class WindowSettings : SettingsBase - { - public WindowStateAction WindowActionOnBuildBegin { get; set; } + public class WindowSettings : SettingsBase + { + public WindowStateAction WindowActionOnBuildBegin { get; set; } - public WindowStateAction WindowActionOnBuildSuccess { get; set; } + public WindowStateAction WindowActionOnBuildSuccess { get; set; } - public WindowStateAction WindowActionOnBuildError { get; set; } + public WindowStateAction WindowActionOnBuildError { get; set; } - public WindowSettings() - { - WindowActionOnBuildBegin = new WindowStateAction(WindowState.Show); - WindowActionOnBuildSuccess = new WindowStateAction(WindowState.Nothing); - WindowActionOnBuildError = new WindowStateAction(WindowState.Show); + public WindowSettings() + { + WindowActionOnBuildBegin = new WindowStateAction(WindowState.Show); + WindowActionOnBuildSuccess = new WindowStateAction(WindowState.Nothing); + WindowActionOnBuildError = new WindowStateAction(WindowState.Show); + } } - } -} \ No newline at end of file +} diff --git a/src/BuildVision.UI/Styles/ControlViewStyle.xaml b/src/BuildVision.UI/Styles/ControlViewStyle.xaml index c3e3d3d1..1b92888b 100644 --- a/src/BuildVision.UI/Styles/ControlViewStyle.xaml +++ b/src/BuildVision.UI/Styles/ControlViewStyle.xaml @@ -31,27 +31,11 @@ - - - - @@ -71,20 +55,9 @@ - - - - - - - - - - - - \ No newline at end of file + diff --git a/src/BuildVision.UI/Styles/ExtensionStyle.xaml b/src/BuildVision.UI/Styles/ExtensionStyle.xaml index b5ec6f2d..dcbec3ba 100644 --- a/src/BuildVision.UI/Styles/ExtensionStyle.xaml +++ b/src/BuildVision.UI/Styles/ExtensionStyle.xaml @@ -1,6 +1,6 @@  + xmlns:environment="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.14.0"> @@ -23,4 +23,4 @@ - \ No newline at end of file + diff --git a/src/BuildVision.UI/Styles/ScrollViewerStyle.xaml b/src/BuildVision.UI/Styles/ScrollViewerStyle.xaml index d989460d..de31d19b 100644 --- a/src/BuildVision.UI/Styles/ScrollViewerStyle.xaml +++ b/src/BuildVision.UI/Styles/ScrollViewerStyle.xaml @@ -1,6 +1,6 @@  @@ -236,4 +236,4 @@ - \ No newline at end of file + diff --git a/src/BuildVision.UI/Themes/Generic.xaml b/src/BuildVision.UI/Themes/Generic.xaml new file mode 100644 index 00000000..edaa2fe1 --- /dev/null +++ b/src/BuildVision.UI/Themes/Generic.xaml @@ -0,0 +1,77 @@ + + + + + + + + + + + +