diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..51c5e5f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,209 @@ +root = true # Do NOT inherit any higher level settings. + +[*.cs] +# IDE0005: Remove unnecessary using directives (https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0005) +dotnet_diagnostic.IDE0005.severity = suggestion +# IDE0017: Object initialization can be simplified (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0017) +dotnet_diagnostic.IDE0017.severity = suggestion +# IDE0022: Use expression body for methods (https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0022) +dotnet_diagnostic.IDE0022.severity = silent +# IDE0028: Simplify collection initialization +dotnet_diagnostic.IDE0028.severity = silent +# IDE0037: Use inferred member name +dotnet_diagnostic.IDE0037.severity = none +# IDE0045: 'if' statement can be simplified (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0045) +dotnet_diagnostic.IDE0045.severity = silent +# IDE0046: Use conditional expression for return (https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0046) +dotnet_diagnostic.IDE0046.severity = none +# IDE0055: Formatting rule (https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0055) +dotnet_diagnostic.IDE0055.severity = none +# IDE0057: Substring can be simplified (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0057) +dotnet_diagnostic.IDE0057.severity = suggestion +# IDE0058: Expression value is never used (https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0058) +dotnet_diagnostic.IDE0058.severity = none +# IDE0063: Use simple 'using' statement (https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0063) +csharp_prefer_simple_using_statement = false +dotnet_diagnostic.IDE0063.severity = none +# IDE0078: Use pattern matching (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0078) +dotnet_diagnostic.IDE0078.severity = warning +# IDE0090: Use 'new(...)' +dotnet_diagnostic.IDE0090.severity = silent +# IDE0220: Add explicit cast (https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0220) +dotnet_diagnostic.IDE0220.severity = warning +# IDE0220: Add explicit cast (https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0220#dotnet_style_prefer_foreach_explicit_cast_in_source) +dotnet_style_prefer_foreach_explicit_cast_in_source = always +# IDE0270: Null check can be simplified (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0270) +dotnet_diagnostic.IDE0270.severity = suggestion +# IDE0280: Use 'nameof' +dotnet_diagnostic.IDE0280.severity = warning +# IDE0290: Use primary constructor - It's a case by case choice. +dotnet_diagnostic.IDE0290.severity = silent +# IDE0305: Collection initialization can be simplified (https://github.com/dotnet/roslyn/issues/70656) +dotnet_diagnostic.IDE0305.severity = silent # Some suggestions are bad. +# IDE1006: Naming rule violation - Sadly, the 'Naming styles' are not sufficient enough, use ReSharper! +dotnet_diagnostic.IDE1006.severity = none + +# CA1024: Use properties where appropriate +dotnet_diagnostic.CA1024.severity = none +# CA1062: Validate arguments of public methods +dotnet_diagnostic.CA1062.severity = silent +# CA1304: Specify CultureInfo +dotnet_diagnostic.CA1304.severity = none +# CA1305: Specify IFormatProvider +dotnet_diagnostic.CA1305.severity = none +# CA1309: Use ordinal string comparison +dotnet_diagnostic.CA1309.severity = none +# CA1507: Use nameof to express symbol names +dotnet_diagnostic.CA1507.severity = suggestion +# CA1716: Identifiers should not match keywords +dotnet_diagnostic.CA1716.severity = none +# CA1720: Identifier contains type name +dotnet_diagnostic.CA1720.severity = none +# CA1725: Parameter names should match base declaration +dotnet_diagnostic.CA1725.severity = silent +# CA1806: Do not ignore method results +dotnet_diagnostic.CA1806.severity = silent +# CA1815: Override equals and operator equals on value types +dotnet_diagnostic.CA1815.severity = silent +# CA1819: Properties should not return arrays +dotnet_diagnostic.CA1819.severity = none +# CA1822: Mark members as static +dotnet_diagnostic.CA1822.severity = silent +# CA1847: Use char literal for a single character lookup +dotnet_diagnostic.CA1847.severity = warning +# CA1848: Use the LoggerMessage delegates +dotnet_diagnostic.CA1848.severity = silent +# CA1863: Use 'CompositeFormat' - The default is warning and in some cases it's not true +dotnet_diagnostic.CA1863.severity = suggestion +# CA2007: Consider calling ConfigureAwait on the awaited task +dotnet_diagnostic.CA2007.severity = none +# CA2016: Forward the 'CancellationToken' parameter to methods +dotnet_diagnostic.CA2016.severity = suggestion # R# is better at this, pointing to the corect method, instead of the whole call. +# CA2201: Do not raise reserved exception types +dotnet_diagnostic.CA2201.severity = error +# CA2234: Pass system uri objects instead of strings +dotnet_diagnostic.CA2234.severity = none + +# CS1591: Missing XML comment for publicly visible type or member (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs1591) +dotnet_diagnostic.CS1591.severity = none +# CS8602: Dereference of a possibly null reference (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/nullable-warnings#possible-dereference-of-null) +dotnet_diagnostic.CS8602.severity = error + +# MSTEST0016: Test class should have test method (https://learn.microsoft.com/en-us/dotnet/core/testing/mstest-analyzers/mstest0016) +dotnet_diagnostic.MSTEST0016.severity = warning +# MSTEST0039: Use newer methods to assert exceptions (https://learn.microsoft.com/en-us/dotnet/core/testing/mstest-analyzers/mstest0039) +dotnet_diagnostic.MSTEST0039.severity = warning +# MSTEST0042: Avoid duplicated 'DataRow' entries (https://learn.microsoft.com/en-us/dotnet/core/testing/mstest-analyzers/mstest0042) +dotnet_diagnostic.MSTEST0042.severity = warning +# MSTEST0049: Flow TestContext.CancellationToken to async operations (https://learn.microsoft.com/en-us/dotnet/core/testing/mstest-analyzers/mstest0049) +dotnet_diagnostic.MSTEST0049.severity = warning + +[*.{cs,vb}] +csharp_style_expression_bodied_methods = when_on_single_line +csharp_style_expression_bodied_accessors = when_on_single_line # https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0027 +csharp_style_expression_bodied_operators = when_on_single_line # https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0023 +csharp_style_namespace_declarations = file_scoped + +dotnet_sort_system_directives_first = false + +dotnet_style_qualification_for_field = true:silent +dotnet_style_qualification_for_property = true:silent +dotnet_style_qualification_for_method = true:silent +dotnet_style_qualification_for_event = true:silent + +# ■■■ Naming styles ■■■ + +# ■■ Non-functional Rules (matching only happens on the 'symbols' (Specification), not the 'style' (Suffix)). + +# ■ Dependency Property backend field - public static readonly DependencyProperty MyProperty = DependencyProperty.Register(...) +dotnet_naming_rule.PublicStaticReadonlyField.severity = warning +dotnet_naming_rule.PublicStaticReadonlyField.symbols = public_static_readonly_fields +dotnet_naming_rule.PublicStaticReadonlyField.style = PascalCaseProperty +# ■ Public static readonly field (Default) - public static readonly TypeOfField MyFieldName = ... +dotnet_naming_rule.PublicStaticReadonlyField.severity = warning +dotnet_naming_rule.PublicStaticReadonlyField.symbols = public_static_readonly_fields +dotnet_naming_rule.PublicStaticReadonlyField.style = PascalCase + +# ■ Dependency Property backend field - private static readonly DependencyPropertyKey MyPropertyKey = DependencyProperty.RegisterReadOnly(...) +dotnet_naming_rule.PrivateStaticReadonlyField.severity = warning # Should be warning +dotnet_naming_rule.PrivateStaticReadonlyField.symbols = private_static_readonly_fields +dotnet_naming_rule.PrivateStaticReadonlyField.style = PascalCasePropertyKey +# ■ Private static readonly field (Default) - private static readonly TypeOfField myFieldName = ... +dotnet_naming_rule.PrivateStaticReadonlyField.severity = information # Should be warning +dotnet_naming_rule.PrivateStaticReadonlyField.symbols = private_static_readonly_fields +dotnet_naming_rule.PrivateStaticReadonlyField.style = CamelCase + +# ■■ End of Non-functional Rules + +dotnet_naming_rule.InstanceField.severity = suggestion +dotnet_naming_rule.InstanceField.symbols = all_fields +dotnet_naming_rule.InstanceField.style = CamelCase + +dotnet_naming_rule.ConstantField.severity = suggestion +dotnet_naming_rule.ConstantField.symbols = const_fields +dotnet_naming_rule.ConstantField.style = PascalCase + +dotnet_naming_rule.NonPrivateField.severity = suggestion +dotnet_naming_rule.NonPrivateField.symbols = non_private_fields +dotnet_naming_rule.NonPrivateField.style = PascalCase + +# ■■■ Symbol specifications ■■■ + +dotnet_naming_symbols.all_fields.applicable_kinds = field + +dotnet_naming_symbols.const_fields.applicable_kinds = field +dotnet_naming_symbols.const_fields.required_modifiers = const + +dotnet_naming_symbols.public_fields.applicable_kinds = field +dotnet_naming_symbols.public_fields.applicable_accessibilities = public + +dotnet_naming_symbols.non_private_fields.applicable_kinds = field +dotnet_naming_symbols.non_private_fields.applicable_accessibilities = public, internal, protected, protected_internal + +dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private +dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readonly, static + +dotnet_naming_symbols.public_static_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.public_static_readonly_fields.applicable_accessibilities = public +dotnet_naming_symbols.public_static_readonly_fields.required_modifiers = readonly, static + +# ■■■ Naming styles ■■■ + +dotnet_naming_style.PascalCase.required_prefix = +dotnet_naming_style.PascalCase.required_suffix = +dotnet_naming_style.PascalCase.word_separator = +dotnet_naming_style.PascalCase.capitalization = pascal_case + +dotnet_naming_style.CamelCase.required_prefix = +dotnet_naming_style.CamelCase.required_suffix = +dotnet_naming_style.CamelCase.word_separator = +dotnet_naming_style.CamelCase.capitalization = camel_case + +dotnet_naming_style.IPascalCase.required_prefix = I +dotnet_naming_style.IPascalCase.required_suffix = +dotnet_naming_style.IPascalCase.word_separator = +dotnet_naming_style.IPascalCase.capitalization = pascal_case + +dotnet_naming_style.PascalCaseProperty.required_suffix = Property +dotnet_naming_style.PascalCaseProperty.capitalization = pascal_case + +dotnet_naming_style.PascalCasePropertyKey.required_suffix = PropertyKey +dotnet_naming_style.PascalCasePropertyKey.capitalization = pascal_case + +# ■■■ RESX Formatter ■■■ + +[*.resx] +resx_formatter_sort_entries = true +resx_formatter_remove_xsd_schema = false +resx_formatter_remove_documentation_comment = true +resx_formatter_sort_comparer = OrdinalIgnoreCase + +# ■■■ MAUI Rules ■■■ + +[*.cs] +# CsWinRT1028: Class should be marked partial +dotnet_diagnostic.CsWinRT1028.severity = warning + +# MVVMTK0034: Direct field reference to [ObservableProperty] backing field +dotnet_diagnostic.MVVMTK0034.severity = error \ No newline at end of file diff --git a/.github/workflows/Launchbar-CI.yaml b/.github/workflows/Launchbar-CI.yaml new file mode 100644 index 0000000..1d95c77 --- /dev/null +++ b/.github/workflows/Launchbar-CI.yaml @@ -0,0 +1,39 @@ +name: Build Launchbar + +on: + push: + branches: + - '*' + tags: + - '*' + pull_request: + branches: + - '*' + +jobs: + build: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v6 # https://github.com/marketplace/actions/checkout + + - name: Setup .NET + uses: actions/setup-dotnet@v5 # https://github.com/marketplace/actions/setup-net-core-sdk + with: + global-json-file: Source/global.json + + - name: Build + run: dotnet build Source/Launchbar.slnx --configuration Release + + - name: Test + run: dotnet test Source/Launchbar.slnx --configuration Release + + - name: Publish + run: dotnet publish Source/Launchbar.slnx --configuration Release + + - name: Upload + uses: actions/upload-artifact@v4 # https://github.com/marketplace/actions/upload-a-build-artifact + with: + name: Launchbar + path: Source/artifacts/publish/Launchbar/release/** + if-no-files-found: error diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml deleted file mode 100644 index 945d349..0000000 --- a/.github/workflows/dotnet.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Build Launchbar - -on: - push: - branches: - - '*' - pull_request: - branches: - - '*' - -jobs: - build: - runs-on: windows-latest - - steps: - - uses: actions/checkout@v3 - - name: Setup .NET - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 7.x - - name: Restore dependencies - run: dotnet restore Source/Launchbar.sln - - name: Build - run: dotnet build Source/Launchbar.sln --no-restore --configuration Release - - name: Test - run: dotnet test Source/Launchbar.sln --no-build --verbosity normal - - name: Publish - run: dotnet publish Source/Launchbar.sln --no-build --configuration Release - - name: Upload - uses: actions/upload-artifact@v3 - with: - name: Launchbar - path: Source/Launchbar/bin/Release/publish/** - if-no-files-found: error diff --git a/.gitignore b/.gitignore index 940794e..27fc493 100644 --- a/.gitignore +++ b/.gitignore @@ -1,288 +1,51 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ -**/Properties/launchSettings.json - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Typescript v1 declaration files -typings/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush -.cr/ - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs +# Example file here https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# fm stuff +*.Generated.runsettings +*.user.json + +# OS specific files +desktop.ini + +# User-specific files +*.suo +*.user + +# Build results +artifacts/ +[Bb]in/ +[Oo]bj/ + +# Visual Studio cache/options directory +.vs/ + +# MSTest test Results +[Tt]est[Rr]esult*/ + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# ReSharper is a .NET coding add-in +*.DotSettings.user + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# Nuget personal access tokens and Credentials +nuget.config + +# Node.js Tools for Visual Studio +node_modules/ + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# JetBrains Rider +.idea/ +*.sln.iml diff --git a/CHANGELOG.md b/CHANGELOG.md index 04b8cb3..95e8b0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,28 @@ # Changelog All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [5.3.0] - 2025-11-21 +### Changed +- Re-enabled DPI awareness. Launchbar now looks sharp and natural on high-DPI displays. +- Increased the maximum menu scale from **2** to **4**. +- Upgrade to .NET 10.0, requires the [.NET Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/10.0/runtime) to run. + +## [5.2.0] - 2025-06-18 +### Changed +- Upgrade to .NET 9.0, requires the [.NET Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/9.0/runtime) to run. +- A lot of internal refactoring to use modern .NET 8.0 and .NET 9.0 features. + ## [5.1.0] - 2023-01-01 ### Changed -- Upgrade to .NET 7.0, requires the [.NET Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/7.0/runtime) to run +- Upgrade to .NET 7.0, requires the [.NET Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/7.0/runtime) to run. ## [5.0.0] - 2021-12-15 ### Changed -- Upgrade to .NET 6.0, requires the [.NET Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/6.0/runtime) to run -- Changelog is now rendered with Markdown +- Upgrade to .NET 6.0, requires the [.NET Desktop Runtime](https://dotnet.microsoft.com/download/dotnet/6.0/runtime) to run. +- Changelog is now rendered with Markdown. + ### Removed - Assembly Strong Name diff --git a/README.md b/README.md index 59de23c..941aae9 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,17 @@ -# Launchbar -Access all your favorite applications and files with only 2 clicks. -No precise mouse movement required, no bloat, no extensions, just a simple launcher. - -**[Download Launchbar here](https://github.com/Mertsch/Launchbar/releases)** - -![Launchbar in action](https://raw.githubusercontent.com/Mertsch/Launchbar/master/Screenshot%2001.png) - -### What do others say? -Check out these sites for a pretty accurate description of Launchbar. - -http://www.freewaregenius.com/looking-for-a-simple-practical-launcher-try-launchbar-4-for-windows -http://www.addictivetips.com/windows-tips/launchbar-a-powerful-application-launcher-with-multi-monitor-support - -http://www.softpedia.com/get/System/Launchers-Shutdown-Tools/Launchbar.shtml -https://www.windows7download.com/win7-launchbar/fqgtfajl.html +Launchbar +=== +Access all your favorite applications and files with only 2 clicks. +No precise mouse movement required, no bloat, no extensions, just a simple launcher. + +**[Download Launchbar here](https://github.com/Mertsch/Launchbar/releases)** + +![Launchbar in action]() + +### What do others say? +Check out these sites for a pretty accurate description of Launchbar. + +- [Looking for a simple, practical launcher? Try Launchbar 4 for Windows](https://www.freewaregenius.com/looking-for-a-simple-practical-launcher-try-launchbar-4-for-windows) +- [Launchbar: A Powerful Application Launcher With Multi-Monitor Support](https://www.addictivetips.com/windows-tips/launchbar-a-powerful-application-launcher-with-multi-monitor-support) +- [Launchbar: Streamline Your Windows 10 Experience!](https://www.windows10download.com/launchbar/) +- [An efficient and intuitive Windows 7 software for lightning-fast app launching.](https://www.windows7download.com/win7-launchbar/fqgtfajl.html) +- [Launchbar is a handy utility that you can use to deploy any program with a simple click.](https://www.top4download.com/launchbar/xppdsttt.html) diff --git a/ReSharper.Global.DotSettings b/ReSharper.Global.DotSettings new file mode 100644 index 0000000..dc857ba --- /dev/null +++ b/ReSharper.Global.DotSettings @@ -0,0 +1,1635 @@ + + None + True + True + False + Advanced + All + True + 1000 + True + $Value$ + True + True + True + True + Directory.Packages.props + *.Generated.html + *.Generated.json + *ModelSnapshot.cs + SOLUTION + True + True + True + ERROR + ERROR + HINT + HINT + DO_NOT_SHOW + DO_NOT_SHOW + HINT + HINT + HINT + HINT + HINT + HINT + HINT + HINT + SUGGESTION + WARNING + WARNING + HINT + HINT + WARNING + WARNING + ERROR + WARNING + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + HINT + SUGGESTION + WARNING + ERROR + ERROR + ERROR + ERROR + ERROR + HINT + HINT + HINT + SUGGESTION + HINT + WARNING + DO_NOT_SHOW + DO_NOT_SHOW + HINT + DO_NOT_SHOW + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + HINT + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + WARNING + ERROR + ERROR + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + HINT + SUGGESTION + ERROR + ERROR + ERROR + ERROR + HINT + ERROR + ERROR + ERROR + ERROR + ERROR + DO_NOT_SHOW + ERROR + ERROR + ERROR + ERROR + DO_NOT_SHOW + HINT + ERROR + HINT + WARNING + DO_NOT_SHOW + HINT + HINT + HINT + ERROR + HINT + WARNING + HINT + SUGGESTION + WARNING + WARNING + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + SUGGESTION + HINT + ERROR + ERROR + ERROR + ERROR + HINT + ERROR + DO_NOT_SHOW + HINT + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + ERROR + ERROR + ERROR + ERROR + ERROR + HINT + SUGGESTION + ERROR + HINT + HINT + HINT + HINT + HINT + ERROR + HINT + ERROR + ERROR + HINT + ERROR + ERROR + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + ERROR + WARNING + SUGGESTION + WARNING + HINT + HINT + ERROR + HINT + DO_NOT_SHOW + HINT + ERROR + ERROR + ERROR + HINT + ERROR + DO_NOT_SHOW + HINT + HINT + SUGGESTION + HINT + ERROR + SUGGESTION + HINT + ERROR + WARNING + WARNING + ERROR + ERROR + HINT + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + ERROR + ERROR + ERROR + SUGGESTION + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + ERROR + DO_NOT_SHOW + WARNING + SUGGESTION + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + SUGGESTION + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + WARNING + ERROR + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW + WARNING + ERROR + ERROR + WARNING + ERROR + WARNING + ERROR + ERROR + ERROR + ERROR + HINT + ERROR + WARNING + ERROR + ERROR + WARNING + ERROR + HINT + WARNING + ERROR + ERROR + ERROR + WARNING + WARNING + WARNING + WARNING + WARNING + WARNING + HINT + HINT + HINT + WARNING + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + WARNING + ERROR + WARNING + WARNING + ERROR + ERROR + WARNING + ERROR + WARNING + ERROR + DO_NOT_SHOW + ERROR + ERROR + ERROR + ERROR + ERROR + WARNING + ERROR + ERROR + True + ShowAndRun + OPTIMISTIC + MergeVsActionsIntoResharperMenu + Experimental + <?xml version="1.0" encoding="utf-16"?><Profile name="fm"><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSUseVar><BehavourStyle>CAN_CHANGE_TO_EXPLICIT</BehavourStyle><LocalVariableStyle>ALWAYS_EXPLICIT</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSRemoveCodeRedundancies>True</CSRemoveCodeRedundancies><XMLReformatCode>True</XMLReformatCode><CSArrangeQualifiers>True</CSArrangeQualifiers><CSEnforceVarKeywordUsageSettings>True</CSEnforceVarKeywordUsageSettings><JsReformatCode>True</JsReformatCode><HtmlReformatCode>True</HtmlReformatCode><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="False" AddMissingParentheses="False" ArrangeBraces="True" ArrangeAttributes="False" ArrangeArgumentsStyle="False" ArrangeCodeBodyStyle="False" ArrangeVarStyle="True" /><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor></Profile> + <?xml version="1.0" encoding="utf-16"?><Profile name="fm Full Reformat"><CSUseVar><BehavourStyle>CAN_CHANGE_TO_EXPLICIT</BehavourStyle><LocalVariableStyle>ALWAYS_EXPLICIT</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSRemoveCodeRedundancies>True</CSRemoveCodeRedundancies><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers><XMLReformatCode>True</XMLReformatCode><CSEnforceVarKeywordUsageSettings>True</CSEnforceVarKeywordUsageSettings><CSArrangeQualifiers>True</CSArrangeQualifiers><HtmlReformatCode>True</HtmlReformatCode><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><JsReformatCode>True</JsReformatCode><CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="False" AddMissingParentheses="False" ArrangeBraces="True" ArrangeAttributes="False" ArrangeArgumentsStyle="False" ArrangeCodeBodyStyle="False" ArrangeVarStyle="True" ArrangeTrailingCommas="False" /><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences></Profile> + <?xml version="1.0" encoding="utf-16"?><Profile name="fm Solution Wide Cleanup"><CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="False" AddMissingParentheses="False" ArrangeBraces="True" ArrangeAttributes="True" ArrangeArgumentsStyle="False" ArrangeCodeBodyStyle="False" ArrangeVarStyle="True" ArrangeTrailingCommas="False" /><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags><CSEnforceVarKeywordUsageSettings>True</CSEnforceVarKeywordUsageSettings><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences></Profile> + fm + True + Required + Required + Required + Required + Join + public private protected internal file static extern new virtual abstract sealed override readonly unsafe required volatile async + EmptyRecursivePattern + ExplicitlyTyped + ExplicitlyTyped + All + True + False + 0 + 0 + 0 + 0 + TOGETHER_SAME_LINE + ALWAYS_ADD + ALWAYS_ADD + ALWAYS_ADD + ALWAYS_ADD + ALWAYS_ADD + ALWAYS_ADD + INDENT + NEXT_LINE_SHIFTED_2 + 1 + 1 + NEVER + False + NEVER + False + ALWAYS_USE + False + False + True + False + False + True + 230 + True + True + ALIGN_ALL + NEXT_LINE + TOGETHER_SAME_LINE + ALWAYS_ADD + NEXT_LINE + NEXT_LINE + True + 1 + 1 + 1 + True + True + True + LINE_BREAK + False + False + WRAP_IF_LONG + WRAP_IF_LONG + 260 + WRAP_IF_LONG + False + 1 + ByFirstAttr + False + 230 + 230 + False + DoNotTouch + False + False + 1 + False + False + 250 + 250 + <Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"> + <TypePattern DisplayName="Non-reorderable types"> + <TypePattern.Match> + <Or> + <And> + <Kind Is="Interface" /> + <Or> + <HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" /> + <HasAttribute Name="System.Runtime.InteropServices.ComImport" /> + </Or> + </And> + <Kind Is="Struct" /> + <HasAttribute Name="JetBrains.Annotations.NoReorderAttribute" /> + <HasAttribute Name="JetBrains.Annotations.NoReorder" /> + </Or> + </TypePattern.Match> + </TypePattern> + + <TypePattern DisplayName="xUnit.net Test Classes" RemoveRegions="All"> + <TypePattern.Match> + <And> + <Kind Is="Class" /> + <HasMember> + <And> + <Kind Is="Method"></Kind> + <HasAttribute Name="Xunit.FactAttribute" Inherited="True" /> + </And> + </HasMember> + </And> + </TypePattern.Match> + + <Region Name="Setup/Teardown"> + <Entry DisplayName="Setup/Teardown Methods"> + <Entry.Match> + <Or> + <Kind Is="Constructor" /> + <And> + <Kind Is="Method"></Kind> + <ImplementsInterface Name="System.IDisposable"></ImplementsInterface> + </And> + </Or> + </Entry.Match> + + <Entry.SortBy> + <Kind> + <Kind.Order> + <DeclarationKind>Constructor</DeclarationKind> + </Kind.Order> + </Kind> + </Entry.SortBy> + </Entry> + </Region> + + <Entry DisplayName="All other members" /> + + <Entry DisplayName="Test Methods" Priority="100"> + <Entry.Match> + <And> + <Kind Is="Method" /> + <HasAttribute Name="Xunit.FactAttribute" Inherited="false" /> + </And> + </Entry.Match> + + <Entry.SortBy> + <Name /> + </Entry.SortBy> + </Entry> + </TypePattern> + + <TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All"> + <TypePattern.Match> + <And> + <Kind Is="Class" /> + <HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="true" /> + </And> + </TypePattern.Match> + + <Region Name="Setup/Teardown"> + <Entry DisplayName="Setup/Teardown Methods"> + <Entry.Match> + <And> + <Kind Is="Method" /> + <Or> + <HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="true" /> + <HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="true" /> + <HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="true" /> + <HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="true" /> + </Or> + </And> + </Entry.Match> + </Entry> + </Region> + + <Entry DisplayName="All other members" /> + + <Entry DisplayName="Test Methods" Priority="100"> + <Entry.Match> + <And> + <Kind Is="Method" /> + <HasAttribute Name="NUnit.Framework.TestAttribute" Inherited="false" /> + </And> + </Entry.Match> + + <Entry.SortBy> + <Name /> + </Entry.SortBy> + </Entry> + </TypePattern> + + <TypePattern DisplayName="Default Pattern"> + <Region Name="Delegates"> + <Entry DisplayName="Public Delegates" Priority="100"> + <Entry.Match> + <And> + <Access Is="Public" /> + <Kind Is="Delegate" /> + </And> + </Entry.Match> + + <Entry.SortBy> + <Name /> + </Entry.SortBy> + </Entry> + </Region> + + <Region Name="${0} enum" Priority="100"> + <Region.GroupBy> + <Name /> + </Region.GroupBy> + + <Entry DisplayName="Public Enums"> + <Entry.Match> + <And> + <Access Is="Public" /> + <Kind Is="Enum" /> + </And> + </Entry.Match> + + <Entry.SortBy> + <Name /> + </Entry.SortBy> + </Entry> + </Region> + + <Entry DisplayName="Static Fields and Constants"> + <Entry.Match> + <Or> + <Kind Is="Constant" /> + <And> + <Kind Is="Field" /> + <Static /> + </And> + </Or> + </Entry.Match> + + <Entry.SortBy> + <Kind> + <Kind.Order> + <DeclarationKind>Constant</DeclarationKind> + <DeclarationKind>Field</DeclarationKind> + </Kind.Order> + </Kind> + </Entry.SortBy> + </Entry> + + <Entry DisplayName="Fields"> + <Entry.Match> + <And> + <Kind Is="Field" /> + <Not> + <Static /> + </Not> + </And> + </Entry.Match> + + <Entry.SortBy> + <Readonly /> + <Name /> + </Entry.SortBy> + </Entry> + + <Entry DisplayName="Constructors"> + <Entry.Match> + <Kind Is="Constructor" /> + </Entry.Match> + + <Entry.SortBy> + <Static/> + </Entry.SortBy> + </Entry> + + <Entry DisplayName="Properties, Indexers"> + <Entry.Match> + <Or> + <Kind Is="Property" /> + <Kind Is="Indexer" /> + </Or> + </Entry.Match> + </Entry> + + <Region Name="${0} Members" Priority="100"> + <Region.GroupBy> + <ImplementsInterface Immediate="true" /> + </Region.GroupBy> + + <Entry DisplayName="Interface Members"> + <Entry.Match> + <And> + <Kind Is="Member" /> + <ImplementsInterface /> + </And> + </Entry.Match> + + <Entry.SortBy> + <ImplementsInterface Immediate="true" /> + </Entry.SortBy> + </Entry> + </Region> + + <Entry DisplayName="All Other Members" /> + + <Region Name="Nested type: ${0}"> + <Region.GroupBy> + <Name /> + </Region.GroupBy> + + <Entry DisplayName="Nested Types"> + <Entry.Match> + <Kind Is="Type" /> + </Entry.Match> + </Entry> + </Region> + </TypePattern> +</Patterns> + + + UsingRegions + False + UseExplicitType + UseExplicitType + UseExplicitType + AD + DB + FS + UI + False + $object$$event$ + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"><ElementKinds><Kind Name="CONSTANT_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Type parameters"><ElementKinds><Kind Name="TYPE_PARAMETER" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Field (private, static, read-only)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb"><ExtraRule Prefix="" Suffix="PropertyKey" Style="AaBb" /></Policy></Policy> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Instance fields (not private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Local variables"><ElementKinds><Kind Name="LOCAL_VARIABLE" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Constant fields (not private)"><ElementKinds><Kind Name="CONSTANT_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static fields (not private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Parameters"><ElementKinds><Kind Name="PARAMETER" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Enum members"><ElementKinds><Kind Name="ENUM_MEMBER" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"><ElementKinds><Kind Name="NAMESPACE" /><Kind Name="CLASS" /><Kind Name="STRUCT" /><Kind Name="ENUM" /><Kind Name="DELEGATE" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Local constants"><ElementKinds><Kind Name="LOCAL_CONSTANT" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Interfaces"><ElementKinds><Kind Name="INTERFACE" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static readonly fields (not private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Private" Description="Methods, properties, events (private)"><ElementKinds><Kind Name="METHOD" /><Kind Name="PROPERTY" /><Kind Name="EVENT" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public" Description="Methods, properties, events"><ElementKinds><Kind Name="METHOD" /><Kind Name="PROPERTY" /><Kind Name="EVENT" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Main method (private)"><ElementKinds><Kind Name="METHOD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb"><ExtraRule Prefix="" Suffix="Main" Style="AaBb" /></Policy></Policy> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + True + True + DisabledOnSelection + BOTH_SIDES + OUTLINE + Narrow + False + True + False + True + PushToShowHints + PushToShowHints + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + False + True + True + MergeVsActionsIntoResharperMenu + True + True + MSTest + TestMethod + True + testMethod + True + [$TestMethodAttribute$] +public void Test() +{ + $END$ +} + True + fixedTypeName("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute") + -1 + 0 + True + 2.0 + InCSharpTypeMember + True + True + XAML + True + propdpBool + True + #region $PropertyName$ + +public $Type$ $PropertyName$ +{ + get { return this.GetValue<$Type$>($PropertyName$Property); } + set { this.SetValueBox($PropertyName$Property, value); } +} + +public static readonly $DependencyProperty$ $PropertyName$Property = $DependencyProperty$.Register( + nameof($PropertyName$), typeof($Type$), typeof($containingType$), new $PropertyMetadata$($Boxes$.$False$)); + +#endregion + True + fixedTypeName("fm.Boxes") + -1 + 5 + True + typeName() + -1 + 2 + True + fixedTypeName("System.Windows.DependencyProperty") + -1 + 3 + True + constant("False") + 6 + True + fixedTypeName("System.Windows.PropertyMetadata") + -1 + 4 + True + 1 + 1 + True + parameterOfType("System.Boolean") + -1 + 0 + True + 3.0 + InCSharpTypeMember + True + True + True + nn + True + [NotNull] + True + 2.0 + InCSharpFile + True + True + XAML + Overrides the default style key with with current class. + True + defaultStyleKeyOverride + True + DefaultStyleKeyProperty.OverrideMetadata(typeof($containingType$), new FrameworkPropertyMetadata(typeof($containingType$))); + True + typeName() + -1 + 0 + True + 3.0 + InCSharpFile + XAML + True + True + Dependency property + True + typeName() + -1 + 0 + True + 3 + True + 4 + True + 1 + True + 2 + True + True + 3.0 + InCSharpTypeMember + propdp + True + #region $PropertyName$ + +public $Type$ $PropertyName$ +{ + get { return ($Type$)this.GetValue($PropertyName$Property); } + set { this.SetValue($PropertyName$Property, value); } +} + +public static readonly $DependencyProperty$ $PropertyName$Property = $DependencyProperty$.Register( + nameof($PropertyName$), typeof($Type$), typeof($containingType$), new $PropertyMetadata$(default($Type$))); + +#endregion + True + True + inserts typeof(<ContainingType>) + True + typeofThis + True + typeof($ContainingType$) + True + typeName() + -1 + 0 + True + 2.0 + InCSharpFile + True + True + MSTest + Inset a ClassInitialize method + True + testClassInitialize + True + [$ClassInitializeAttribute$] +public static void ClassInitialize($TestContext$ testContext) +{ + $END$ +} + True + fixedTypeName("Microsoft.VisualStudio.TestTools.UnitTesting.ClassInitializeAttribute") + -1 + 0 + True + fixedTypeName("Microsoft.VisualStudio.TestTools.UnitTesting.TestContext") + -1 + 1 + True + 2.0 + InCSharpFile + True + True + XAML + True + propdpChangedCallback + True + private static void on$PropertyName$Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) +{ + (($ContainingType$)d).on$PropertyName$Changed(); +} + +private void on$PropertyName$Changed() +{ + $END$ +} + True + typeName() + -1 + 1 + True + 0 + True + 3.0 + InCSharpTypeMember + True + True + cs + Tests + True + &UnitTest + True + True + $HEADER$namespace $NAMESPACE$ +{ + [Microsoft.VisualStudio.TestTools.UnitTesting.TestClass] + public sealed class $CLASS$ + { + [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethod] + public void Test() + { + $END$ + } + } +} + True + getFileNameWithoutExtension() + -1 + 2 + True + fileheader() + -1 + 0 + True + fileDefaultNamespace() + -1 + 1 + True + InCSharpProjectFile + True + True + MSTest + Inset a TestInitialize method + True + testInitialize + True + [$TestInitializeAttribute$] +public void TestInitialize() +{ + $END$ +} + True + fixedTypeName("Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute") + -1 + 0 + True + 2.0 + InCSharpFile + True + True + XAML + True + propdpReadOnly + True + #region $PropertyName$ + +public $Type$ $PropertyName$ +{ + get { return ($Type$)this.GetValue($PropertyName$Property); } + private set { this.SetValue($PropertyName$PropertyKey, value); } +} + +private static readonly $DependencyPropertyKey$ $PropertyName$PropertyKey = $DependencyProperty$.RegisterReadOnly( + nameof($PropertyName$), typeof($Type$), typeof($containingType$), new $PropertyMetadata$(default($Type$))); + +public static readonly $DependencyProperty$ $PropertyName$Property = $PropertyName$PropertyKey.DependencyProperty; + +#endregion + True + typeName() + -1 + 2 + True + fixedTypeName("System.Windows.DependencyProperty") + -1 + 4 + True + fixedTypeName("System.Windows.DependencyPropertyKey") + -1 + 3 + True + fixedTypeName("System.Windows.PropertyMetadata") + -1 + 5 + True + 1 + 1 + True + parameterOfType("System.Boolean") + 0 + True + 3.0 + InCSharpTypeMember + True + True + MSTest + True + testCleanup + True + [$TestCleanupAttribute$] +public void TestCleanup() +{ + $END$ +} + True + fixedTypeName("Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute") + -1 + 0 + True + 2.0 + InCSharpFile + True + True + Adds the basic implementation of IComparable methods + True + compareMethods + True + #region IComparable Member + +[Pure] +public int CompareTo([CanBeNull] object obj) +{ + return this.CompareTo(obj as $ContainingType$); +} + +[Pure] +public int CompareTo([CanBeNull] $ContainingType$ other) +{ + if (other == null) + { + return 1; + } + return $END$; +} + +#endregion + True + typeName() + -1 + 0 + True + 2.0 + InCSharpFile + True + True + MSTest + True + testClassCleanup + True + [$ClassCleanupAttribute$] +public static void ClassInitialize() +{ + $END$ +} + True + fixedTypeName("Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute") + -1 + 0 + True + 2.0 + InCSharpFile + True + True + XAML + True + routedEvent + True + #region $Name$ + +public event $RoutedEventHandler$ $Name$ +{ + add { this.AddHandler($Name$Event, value); } + remove { this.RemoveHandler($Name$Event, value); } +} + +public static readonly $RoutedEvent$ $Name$Event = $EventManager$.RegisterRoutedEvent( + nameof($Name$), $RoutingStrategy$.Bubble, typeof($RoutedEventHandler$), typeof($containingType$)); + +#endregion + True + typeName() + -1 + 1 + True + fixedTypeName("System.Windows.EventManager") + -1 + 5 + True + 1 + 0 + True + fixedTypeName("System.Windows.RoutedEvent") + -1 + 4 + True + fixedTypeName("System.Windows.RoutedEventHandler") + -1 + 3 + True + fixedTypeName("System.Windows.RoutingStrategy") + -1 + 2 + True + 3.0 + InCSharpTypeMember + True + True + True + cbn + True + [CanBeNull] + True + 2.0 + InCSharpFile + True + Convert .ShouldBeFalse() to Assert.IsFalse() + True + CSHARP + Convert to Assert.IsFalse($exp$) + Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse($exp$) + $exp$.ShouldBeFalse() + True + True + System.Boolean + ExpressionPlaceholder + True + Redundant 'ICollection.Count()' call + True + CSHARP + Use 'Count' instead + $collection$.Count + $collection$.Count() + ERROR + True + False + System.Collections.ICollection + ExpressionPlaceholder + True + Convert Assert.IsTrue() + True + CSHARP + Convert to $exp$.ShouldBeTrue() + $exp$.ShouldBeTrue() + $Assert$.IsTrue($exp$) + HINT + True + False + Microsoft.VisualStudio.TestTools.UnitTesting.Assert + TypePlaceholder + True + False + System.Object + ExpressionPlaceholder + True + Comparing 'null' with variable + False + False + False + True + CSHARP + False + False + Compare variable with 'null' + if($expr$ == null) $stmt$ + if(null == $expr$) $stmt$ + SUGGESTION + False + False + Never + False + True + False + + ExpressionPlaceholder + True + -1 + -1 + StatementPlaceholder + True + Negation of ICollection.HasItems() + True + CSHARP + False + Replace !$collection$.HasItems() with $collection$.IsNullOrEmpty() + $collection$.IsNullOrEmpty() + !$collection$.HasItems() + SUGGESTION + True + False + System.Collections.ICollection + ExpressionPlaceholder + True + Negation of ICollection.IsNullOrEmpty() + True + CSHARP + False + Replace !$collection$.IsNullOrEmpty() with $collection$.HasItems() + $collection$.HasItems() + !$collection$.IsNullOrEmpty() + SUGGESTION + True + False + System.Collections.ICollection + ExpressionPlaceholder + True + Convert .ShouldBeTrue() to Assert.IsTrue() + True + CSHARP + Convert to Assert.IsTrue($exp$) + Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue($exp$) + $exp$.ShouldBeTrue() + True + True + System.Boolean + ExpressionPlaceholder + True + Possible misuse of overloaded constructor + True + CSHARP + Use new $PropertyMetadata$((object)null) + new $PropertyMetadata$((object)null) + new $PropertyMetadata$(null) + WARNING + True + True + System.Object + TypePlaceholder + True + False + System.Windows.PropertyMetadata + TypePlaceholder + True + Possible unintended use of local time + True + CSHARP + Use $dateTime$.UtcNow.Date instead (and convert to local time if needed) + $dateTime$.UtcNow.Date + $dateTime$.Today + ERROR + True + True + System.DateTime + ExpressionPlaceholder + True + Convert Assert.AreEqual() to .ShouldBe() with Comment + True + CSHARP + Convert to $expActual$.ShouldBe($expExpected$, $comment$) + $expActual$.ShouldBe($expExpected$, $comment$) + $Assert$.AreEqual($expExpected$, $expActual$, $comment$) + HINT + True + False + Microsoft.VisualStudio.TestTools.UnitTesting.Assert + Microsoft.VisualStudio.TestTools.UnitTesting.Assert + ExpressionPlaceholder + True + False + System.String + 1 + 1 + ArgumentPlaceholder + True + False + System.Object + ExpressionPlaceholder + True + 1 + 1 + ArgumentPlaceholder + True + 1 + 1 + ArgumentPlaceholder + True + Convert '(T)GetValue(DP)' to 'GetValue<T>(DP)' + True + False + System.Windows.DependencyProperty + ExpressionPlaceholder + True + False + + TypePlaceholder + True + CSHARP + False + Replace with 'GetValue<$type$>($DependencyProperty$)' + this.GetValue<$type$>($DependencyProperty$) + ($type$)this.GetValue($DependencyProperty$) + SUGGESTION + True + Redundant 'Array.Any()' call + True + CSHARP + Use 'Array.Length > 0' instead + $array$.Length > 0 + $array$.Any() + ERROR + True + False + System.Array + ExpressionPlaceholder + True + Redundant 'Array.Count()' call + True + CSHARP + Use 'Length' instead + $array$.Length + $array$.Count() + ERROR + True + False + System.Array + ExpressionPlaceholder + True + Return type should be Task for async TestMethod + True + CSHARP + Replace return type with Task + [$TestMethod$] +public async System.Threading.Tasks.Task $TestMethodName$() +{ + $TestMethodBody$ +} + [$TestMethod$] +public async void $TestMethodName$() +{ + $TestMethodBody$ +} + ERROR + True + False + + TypePlaceholder + True + -1 + -1 + StatementPlaceholder + True + True + False + + IdentifierPlaceholder + True + False + + TypePlaceholder + True + This may throw TaskCanceledException, $action$ should return a $task$ instead of void + CSHARP + $task$.Run($action$, $ct$) + ERROR + True + False + System.Action + ExpressionPlaceholder + True + False + System.Threading.CancellationToken + ExpressionPlaceholder + True + False + System.Threading.Tasks.Task + TypePlaceholder + True + Convert Assert.AreEqual() to .ShouldBe() + True + CSHARP + Convert to $expActual$.ShouldBe($expExpected$) + $expActual$.ShouldBe($expExpected$) + $Assert$.AreEqual($expExpected$, $expActual$) + HINT + True + False + Microsoft.VisualStudio.TestTools.UnitTesting.Assert + ExpressionPlaceholder + True + 1 + 1 + ArgumentPlaceholder + True + 1 + 1 + ArgumentPlaceholder + True + Convert 'SetValue(DP, bool)' to 'SetValueBox(DP, bool)' + True + True + System.Windows.DependencyProperty + ExpressionPlaceholder + True + True + System.Boolean + ExpressionPlaceholder + True + CSHARP + False + Replace with 'SetValueBox($DependencyProperty$, $value$)' + this.SetValueBox($DependencyProperty$, $value$) + this.SetValue($DependencyProperty$, $value$) + SUGGESTION + True + Convert 'SetValue(DPK, bool)' to 'SetValueBox(DPK, bool)' + True + True + System.Windows.DependencyPropertyKey + ExpressionPlaceholder + True + True + System.Boolean + ExpressionPlaceholder + True + CSHARP + False + Replace with 'SetValueBox($DependencyProperty$, $value$)' + this.SetValueBox($DependencyProperty$, $value$) + this.SetValue($DependencyProperty$, $value$) + SUGGESTION + True + Convert Assert.IsFalse() to .ShouldBeFalse() + True + CSHARP + Convert to $exp$.ShouldBeFalse() + $exp$.ShouldBeFalse() + $Assert$.IsFalse($exp$) + HINT + True + False + Microsoft.VisualStudio.TestTools.UnitTesting.Assert + TypePlaceholder + True + False + System.Object + ExpressionPlaceholder + True + ExpectedException is deprecated + False + True + CSHARP + Use Exception.Expect + $ExpectedException$ + ERROR + False + True + False + System.Exception + TypePlaceholder + True + False + Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionBaseAttribute + TypePlaceholder + True + Redundant Boolean conversion + True + CSHARP + $input$ + $Convert$.ToBoolean($input$) + ERROR + True + True + System.Convert + TypePlaceholder + True + True + System.Boolean + ExpressionPlaceholder + True + Possible unintended use of local time + True + CSHARP + Use DateTime.UtcNow instead (and convert to local time if needed) + $dateTime$.UtcNow + $dateTime$.Now + ERROR + True + True + System.DateTime + ExpressionPlaceholder + True + Redundant KeyCollection iteration + True + CSHARP + Replace with ContainsKey + $dic$.ContainsKey($exp$) + $dic$.Keys.Contains($exp$) + ERROR + True + False + System.Collections.IDictionary + ExpressionPlaceholder + True + True + + ExpressionPlaceholder + SUGGESTION + True + Negation of string.HasContent() + True + CSHARP + False + Replace !$string$.HasContent() with $string$.IsNullOrEmpty() + $string$.IsNullOrEmpty() + !$string$.HasContent() + SUGGESTION + True + False + System.String + ExpressionPlaceholder + True + Redundant 'Array.ToArray()' call + True + CSHARP + Remove redundant 'ToArray' + $array$ + $array$.ToArray() + ERROR + True + False + System.Array + ExpressionPlaceholder + True + Negation of string.IsNullOrEmpty() + True + CSHARP + False + Replace !$string$.IsNullOrEmpty() with $string$.HasContent() + $string$.HasContent() + !$string$.IsNullOrEmpty() + SUGGESTION + True + False + System.String + ExpressionPlaceholder + False + diff --git a/Screenshot 01.png b/Screenshot.png similarity index 100% rename from Screenshot 01.png rename to Screenshot.png diff --git a/Source/Directory.Build.props b/Source/Directory.Build.props new file mode 100644 index 0000000..2544469 --- /dev/null +++ b/Source/Directory.Build.props @@ -0,0 +1,108 @@ + + + + preview + + latest-recommended + + true + + enable + + enable + + en + + true + true + $(DefaultItemExcludes);**\*.DotSettings + + false + true + false + true + true + false + + + + + + + + + true + + $(NoWarn);CS1591 + + + + + true + + + + + + + net9.0 + + false + false + + + embedded + + + + + + + + + + + + + + + + + + net9.0 + + false + false + + $(MSBuildThisFileDirectory)\Default.runsettings + + + + + + + + + + + true + + + true + + + + + + + + + net9.0 + + false + false + + + + + \ No newline at end of file diff --git a/Source/Directory.Packages.props b/Source/Directory.Packages.props new file mode 100644 index 0000000..62f7726 --- /dev/null +++ b/Source/Directory.Packages.props @@ -0,0 +1,12 @@ + + + true + true + + + + + + + + \ No newline at end of file diff --git a/Source/Launchbar.sln b/Source/Launchbar.sln deleted file mode 100644 index 6321d5a..0000000 --- a/Source/Launchbar.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Launchbar", "Launchbar\Launchbar.csproj", "{55B26A32-A0F3-4E58-8B0F-D992D199069F}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2EDD5948-9BFA-47F7-AC71-5E19EF7522D0}" - ProjectSection(SolutionItems) = preProject - ..\CHANGELOG.md = ..\CHANGELOG.md - ..\.github\workflows\dotnet.yml = ..\.github\workflows\dotnet.yml - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {55B26A32-A0F3-4E58-8B0F-D992D199069F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {55B26A32-A0F3-4E58-8B0F-D992D199069F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {55B26A32-A0F3-4E58-8B0F-D992D199069F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {55B26A32-A0F3-4E58-8B0F-D992D199069F}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {C53CD7C1-6ECD-4648-BEC9-B2106234D6B9} - EndGlobalSection -EndGlobal diff --git a/Source/Launchbar.slnx b/Source/Launchbar.slnx new file mode 100644 index 0000000..a925400 --- /dev/null +++ b/Source/Launchbar.slnx @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Source/Launchbar.slnx.DotSettings b/Source/Launchbar.slnx.DotSettings new file mode 100644 index 0000000..391bf9d --- /dev/null +++ b/Source/Launchbar.slnx.DotSettings @@ -0,0 +1,6 @@ + + ..\..\ReSharper.Global.DotSettings + True + True + 1 + \ No newline at end of file diff --git a/Source/Launchbar/App.xaml b/Source/Launchbar/App.xaml index 1b29a87..7648ebe 100644 --- a/Source/Launchbar/App.xaml +++ b/Source/Launchbar/App.xaml @@ -2,6 +2,7 @@ x:Class="Launchbar.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 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" mc:Ignorable="d" xmlns:lb="clr-namespace:Launchbar" xmlns:shapes="clr-namespace:Launchbar.Shapes" xmlns:p="clr-namespace:Launchbar.Properties"> @@ -23,31 +24,30 @@ - + + IsOpen="{Binding Path=(MenuItem.IsSubmenuOpen), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MenuItem}}}"/> - + - + - + - - + + - + @@ -55,75 +55,74 @@ - + - - - - - - - + ProgramStyle="{StaticResource StyleProgram}" + SubmenuStyle="{StaticResource StyleSubmenu}" + SeparatorStyle="{StaticResource StyleSeparator}" + SettingsStyle="{StaticResource StyleSettings}" + ExitStyle="{StaticResource StyleExit}"/> - diff --git a/Source/Launchbar/App.xaml.cs b/Source/Launchbar/App.xaml.cs index 0a86f27..78eaec5 100644 --- a/Source/Launchbar/App.xaml.cs +++ b/Source/Launchbar/App.xaml.cs @@ -1,21 +1,15 @@ -using System; -using System.Collections.Immutable; +using Launchbar.Properties; +using Microsoft.Win32; using System.ComponentModel; using System.Security; -using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Input; -using Launchbar.Properties; -using Microsoft.Win32; using WpfScreenHelper; namespace Launchbar; -/// -/// Interaction logic for App.xaml -/// -public partial class App : Application +public sealed partial class App : Application, IDisposable { #if DEBUG private const string MutexName = @"Global\LaunchbarSingleInstanceMutex(Debug)"; @@ -25,29 +19,25 @@ public partial class App : Application #region Fields - private static SplashScreen splashScreen; + private static SplashScreen? splashScreen; - // ReSharper disable NotAccessedField.Local -#pragma warning disable IDE0052 // Remove unread private members - We need to keep the mutex alive during the lifetime of the app. - private static Mutex instanceMutex; -#pragma warning restore IDE0052 // Remove unread private members - // ReSharper restore NotAccessedField.Local + private readonly Mutex instanceMutex; - private WindowBar barLeft; + private WindowBar? barLeft; - private WindowBar barTop; + private WindowBar? barTop; - private WindowBar barRight; + private WindowBar? barRight; - private WindowBar barBottom; + private WindowBar? barBottom; - private WindowBar barLeftSecondary; + private WindowBar? barLeftSecondary; - private WindowBar barTopSecondary; + private WindowBar? barTopSecondary; - private WindowBar barRightSecondary; + private WindowBar? barRightSecondary; - private WindowBar barBottomSecondary; + private WindowBar? barBottomSecondary; private readonly Area primaryArea = new Area(); @@ -74,7 +64,7 @@ public App() #region Make sure that only one instance of the application is running at any given time. - instanceMutex = new Mutex(false, MutexName, out bool instantiated); + this.instanceMutex = new Mutex(false, MutexName, out bool instantiated); if (!instantiated) { MessageBox.Show(Launchbar.Properties.Resources.SingleInstanceWarning, @@ -82,10 +72,11 @@ public App() MessageBoxImage.Information); try { - splashScreen.Close(TimeSpan.Zero); + splashScreen?.Close(TimeSpan.Zero); } catch (Win32Exception) { } this.Shutdown(); + this.contextMenu = default!; return; } @@ -106,22 +97,20 @@ public App() SystemEvents.DisplaySettingsChanged += this.displaySettingsChanged; } catch (SecurityException) { } - this.displaySettingsChanged(null, null); // Do primary initialization. + this.displaySettingsChanged(null, EventArgs.Empty); // Do primary initialization. setting.PropertyChanged += this.settingsPropertyChanged; - // ReSharper disable PossibleNullReferenceException - this.contextMenu = (ContextMenu)this.FindResource("contextMenuTemplate"); - // ReSharper restore PossibleNullReferenceException + this.contextMenu = this.FindResource("ContextMenuTemplate") as ContextMenu ?? throw new InvalidOperationException("Missing 'contextMenuTemplate'."); this.forceContextMenuLayout(); try { - splashScreen.Close(new TimeSpan(TimeSpan.TicksPerSecond)); + splashScreen?.Close(new TimeSpan(TimeSpan.TicksPerSecond)); } catch (Win32Exception) { - splashScreen.Close(TimeSpan.Zero); + splashScreen?.Close(TimeSpan.Zero); } finally { @@ -153,7 +142,7 @@ private void contextMenuClosed(object sender, RoutedEventArgs e) #endregion - private void settingsPropertyChanged(object sender, PropertyChangedEventArgs e) + private void settingsPropertyChanged(object? sender, PropertyChangedEventArgs e) { switch (e.PropertyName) { @@ -188,14 +177,14 @@ private void settingsPropertyChanged(object sender, PropertyChangedEventArgs e) } } - private void displaySettingsChanged(object sender, EventArgs e) + private void displaySettingsChanged(object? sender, EventArgs e) { - ImmutableArray screens = Screen.AllScreens.ToImmutableArray(); + Screen[] screens = Screen.AllScreens.ToArray(); int count = screens.Length; if (count > 0) { - Rect area = screens[0].WorkingArea; + Rect area = screens[0].WpfWorkingArea; this.primaryArea.Update(area.X, area.Y, area.Width, area.Height); if (this.currentDisplayCount < 1) @@ -217,19 +206,15 @@ private void displaySettingsChanged(object sender, EventArgs e) if (count > 1) { - Rect area = screens[1].WorkingArea; + Rect area = screens[1].WpfWorkingArea; this.secondaryArea.Update(area.X, area.Y, area.Width, area.Height); if (this.currentDisplayCount < 2) { - openOrCloseBar(Dock.Left, Settings.Default.BarLeftSecondary, this.secondaryArea, - ref this.barLeftSecondary); - openOrCloseBar(Dock.Top, Settings.Default.BarTopSecondary, this.secondaryArea, - ref this.barTopSecondary); - openOrCloseBar(Dock.Right, Settings.Default.BarRightSecondary, this.secondaryArea, - ref this.barRightSecondary); - openOrCloseBar(Dock.Bottom, Settings.Default.BarBottomSecondary, this.secondaryArea, - ref this.barBottomSecondary); + openOrCloseBar(Dock.Left, Settings.Default.BarLeftSecondary, this.secondaryArea, ref this.barLeftSecondary); + openOrCloseBar(Dock.Top, Settings.Default.BarTopSecondary, this.secondaryArea, ref this.barTopSecondary); + openOrCloseBar(Dock.Right, Settings.Default.BarRightSecondary, this.secondaryArea, ref this.barRightSecondary); + openOrCloseBar(Dock.Bottom, Settings.Default.BarBottomSecondary, this.secondaryArea, ref this.barBottomSecondary); this.currentDisplayCount = 2; } } @@ -242,14 +227,14 @@ private void displaySettingsChanged(object sender, EventArgs e) } } - private static void openOrCloseBar(Dock dock, bool open, Area area, ref WindowBar windowBar) + private static void openOrCloseBar(Dock dock, bool open, Area? area, ref WindowBar? windowBar) { - if (windowBar == null && open && area != null && area.IsActive) + if (windowBar is null && open && area is { IsActive: true }) { windowBar = new WindowBar(dock, area); windowBar.Show(); } - else if (windowBar != null && !open) + else if (windowBar is { } && !open) { windowBar.Close(); windowBar = null; @@ -261,13 +246,10 @@ public static void OpenOrActivateSettings() WindowCollection wc = Current.Windows; lock (wc.SyncRoot!) { - foreach (Window w in wc) + foreach (WindowSettings w in wc.OfType()) { - if (w is WindowSettings) - { - w.Activate(); - return; - } + w.Activate(); + return; } } new WindowSettings().Show(); @@ -289,4 +271,16 @@ public static ContextMenu RequestContextMenu() // Attach to this object. return app.contextMenu; } + + protected override void OnExit(ExitEventArgs e) + { + base.OnExit(e); + + this.instanceMutex.Dispose(); + } + + public void Dispose() + { + this.instanceMutex.Dispose(); + } } \ No newline at end of file diff --git a/Source/Launchbar/Area.cs b/Source/Launchbar/Area.cs index 4ae1fc3..b8b881d 100644 --- a/Source/Launchbar/Area.cs +++ b/Source/Launchbar/Area.cs @@ -1,5 +1,3 @@ -using System; - namespace Launchbar; public sealed class Area diff --git a/Source/Launchbar/Design.cs b/Source/Launchbar/Design.cs new file mode 100644 index 0000000..bc42c8a --- /dev/null +++ b/Source/Launchbar/Design.cs @@ -0,0 +1,11 @@ +namespace Launchbar; + +public static class Design +{ + public static Program Program => new Program { Text = "DesignProgram" }; + public static Separator Separator => new Separator(); + public static MenuEntry MenuEntry => new Submenu(); + public static Submenu Submenu => new Submenu(); + public static MenuEntrySettings Settings => new MenuEntrySettings(); + public static MenuEntryExit Exit => new MenuEntryExit(); +} \ No newline at end of file diff --git a/Source/Launchbar/ElementCreator.cs b/Source/Launchbar/ElementCreator.cs index a9d79f6..cacc305 100644 --- a/Source/Launchbar/ElementCreator.cs +++ b/Source/Launchbar/ElementCreator.cs @@ -1,8 +1,6 @@ -using System; -using System.Globalization; +using System.Globalization; using System.Windows.Controls; using System.Windows.Data; -using JetBrains.Annotations; namespace Launchbar; @@ -19,12 +17,12 @@ public sealed class ElementCreator : IValueConverter /// A . /// /// Objects described by the template. - public object Convert([CanBeNull] object value, Type targetType, object parameter, CultureInfo culture) + public object Convert(object? value, Type targetType, object? parameter, CultureInfo? culture) { return parameter switch { ControlTemplate ct => new Control { Template = ct }, - _ => throw new ArgumentException("You must specify a ControlTemplate.", nameof(parameter)) + _ => throw new ArgumentException(@"You must specify a ControlTemplate.", nameof(parameter)), }; } @@ -36,7 +34,7 @@ public object Convert([CanBeNull] object value, Type targetType, object paramete /// /// /// - public object ConvertBack([CanBeNull] object value, Type targetType, object parameter, CultureInfo culture) + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { throw new NotSupportedException(); } diff --git a/Source/Launchbar/Launchbar.csproj b/Source/Launchbar/Launchbar.csproj index 63c84f5..ab0ec1c 100644 --- a/Source/Launchbar/Launchbar.csproj +++ b/Source/Launchbar/Launchbar.csproj @@ -1,28 +1,27 @@  - - net7.0-windows + net10.0-windows true WinExe - false + true + + false + + true Resources\Next.ico - 5.1.0 - Launchbar RunIT to the next level. - Copyright © Mertsch $([System.DateTime]::UtcNow.Year) - - - - + + + + - @@ -47,5 +46,4 @@ Settings.settings - \ No newline at end of file diff --git a/Source/Launchbar/Menu.cs b/Source/Launchbar/Menu.cs index 8888685..209e806 100644 --- a/Source/Launchbar/Menu.cs +++ b/Source/Launchbar/Menu.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.ObjectModel; -using System.Linq; -using System.Threading.Tasks; +using System.Collections.ObjectModel; using System.Windows.Threading; -using JetBrains.Annotations; namespace Launchbar; @@ -11,20 +7,20 @@ namespace Launchbar; /// Dummy class. /// This class contains the menu entries and will be saved with the application settings. /// -public class Menu : NotifyBase +public sealed class Menu : NotifyBase { #region Fields - private MenuEntryCollection entries; + private MenuEntryCollection? entries; #endregion /// /// Gets or sets a list of menu entries. /// - public MenuEntryCollection Entries + public MenuEntryCollection? Entries { - get { return this.entries; } + get => this.entries; set { if (this.entries == value) @@ -36,31 +32,29 @@ public MenuEntryCollection Entries } } + [MustUseReturnValue] public static Menu CreateDefault() { return new Menu { - entries = new MenuEntryCollection - { + entries = + [ new MenuEntrySettings(), new MenuEntryExit(), - } + ], }; } - public void FillIconCacheAsync([NotNull] Dispatcher dispatcher) + public void FillIconCacheAsync(Dispatcher dispatcher) { - if (dispatcher == null) - { - throw new ArgumentNullException(nameof(dispatcher)); - } + ArgumentNullException.ThrowIfNull(dispatcher); Task.Run(() => getIcons(this.Entries, dispatcher)); } - private static async Task getIcons([CanBeNull, ItemNotNull] ObservableCollection entries, [NotNull] Dispatcher dispatcher) + private static async Task getIcons(ObservableCollection? entries, Dispatcher dispatcher) { - if (entries == null) + if (entries is null) { return; // Nothing to do } diff --git a/Source/Launchbar/MenuEntry.cs b/Source/Launchbar/MenuEntry.cs index 8a05744..50063a0 100644 --- a/Source/Launchbar/MenuEntry.cs +++ b/Source/Launchbar/MenuEntry.cs @@ -1,4 +1,4 @@ -using System.Xml.Serialization; +using System.Xml.Serialization; namespace Launchbar; @@ -13,22 +13,20 @@ public class MenuEntry : NotifyBase { public const string IsSelectedProperty = "IsSelected"; - private bool isSelected; - /// /// Gets or sets whether this object is selected. /// [XmlIgnore] public bool IsSelected { - get { return this.isSelected; } + get; set { - if (this.isSelected == value) + if (field == value) { return; } - this.isSelected = value; + field = value; this.OnPropertyChanged(IsSelectedProperty); } } @@ -37,7 +35,7 @@ public bool IsSelected /// Gets or sets the parent of this object. /// [XmlIgnore] - public MenuEntryCollection Parent { get; set; } + public MenuEntryCollection? Parent { get; set; } /// /// Move this item upwards in the parent collection. @@ -57,7 +55,7 @@ public void MoveDown() private void move(bool up) { - MenuEntryCollection parent = this.Parent; + MenuEntryCollection? parent = this.Parent; if (parent == null) { return; // Unable to do anything @@ -71,7 +69,7 @@ private void move(bool up) { return; // We can't move the element any further. } - MenuEntryCollection parentParent = parent.Parent.Parent; + MenuEntryCollection? parentParent = parent.Parent.Parent; if (parentParent == null) { return; // There is nothing we can do. @@ -97,7 +95,7 @@ private void move(bool up) delta = -1; // Decrease the index by one. } - Submenu moveInto = parent[index + delta] as Submenu; + Submenu? moveInto = parent[index + delta] as Submenu; if (moveInto == null) { parent.Move(index, index + delta); diff --git a/Source/Launchbar/MenuEntryAdvanced.cs b/Source/Launchbar/MenuEntryAdvanced.cs index 0f1416a..2d2f609 100644 --- a/Source/Launchbar/MenuEntryAdvanced.cs +++ b/Source/Launchbar/MenuEntryAdvanced.cs @@ -1,7 +1,6 @@ -using System.Text; +using Launchbar.Win32; using System.Windows.Media; using System.Xml.Serialization; -using Launchbar.Win32; namespace Launchbar; @@ -14,16 +13,10 @@ public class MenuEntryAdvanced : MenuEntry { #region Fields - private string text; - - private string iconPath; + private string? iconPath; private int iconIndex; - private ImageSource icon; - - private IconType iconType = IconType.Default; - #endregion #region Properties @@ -31,16 +24,16 @@ public class MenuEntryAdvanced : MenuEntry /// /// Get or set the text to be shown for this entry. /// - public string Text + public string? Text { - get { return this.text; } + get; set { - if (this.text == value) + if (field == value) { return; } - this.text = value; + field = value; this.OnPropertyChanged(nameof(this.Text)); } } @@ -48,9 +41,9 @@ public string Text /// /// Path to a file that contains an icon at the specified icon index /// - public string IconPath + public string? IconPath { - get { return this.iconPath; } + get => this.iconPath; set { if (value == string.Empty) @@ -72,7 +65,7 @@ public string IconPath /// public int IconIndex { - get { return this.iconIndex; } + get => this.iconIndex; set { if (this.iconIndex == value) @@ -91,32 +84,32 @@ public int IconIndex [XmlIgnore] public IconType IconType { - get { return this.iconType; } + get; private set { - if (this.iconType == value) + if (field == value) { return; } - this.iconType = value; + field = value; this.OnPropertyChanged(nameof(this.IconType)); } - } + } = IconType.Default; /// /// Gets the icon to display when is set to . /// [XmlIgnore] - public ImageSource Icon + public ImageSource? Icon { - get { return this.icon; } + get; private set { - if (this.icon == value) + if (field == value) { return; } - this.icon = value; + field = value; this.OnPropertyChanged(nameof(this.Icon)); } } @@ -128,7 +121,7 @@ private set /// public void UpdateIcon() { - ImageSource newIcon = null; + ImageSource? newIcon = null; IconType newType = IconType.Warning; if (!string.IsNullOrEmpty(this.iconPath)) @@ -141,7 +134,7 @@ public void UpdateIcon() } else { - Program p = this as Program; + Program? p = this as Program; if (p == null) // Not a program - use the default icon. { newType = IconType.Default; @@ -150,7 +143,7 @@ public void UpdateIcon() { if (p.IsValidFile) // Valid file? { - newIcon = WinHelper.ExtractAssociatedIcon(p.PathAbsolute); + newIcon = WinHelper.ExtractAssociatedIcon(p.PathAbsolute!); // IsValidFile tests the path newType = IconType.Custom; } else if (p.IsValidPath) // Valid dictionary? @@ -179,20 +172,15 @@ public void ChooseIcon() } else { - if (this is Program p && p.IsValidFile) // When the program path is valid, use that path as default. + if (this is Program { IsValidFile: true } p) // When the program path is valid, use that path as default. { - path = p.Path; + path = p.Path!; // IsValidFile tests the path } } - // We need to have a string that is long enough to handle a more complex path than - // the default one (more characters in length). - StringBuilder sb = new StringBuilder(path, 4096); // 4095 + null-char should be enough - - // Methods returns one when pressing OK in the dialog. - if (SafeNativeMethods.PickIconDlg(nint.Zero, sb, (uint)sb.Capacity, ref index) == 1) + if (WinHelper.PickIconDialog(ref path, ref index)) { - this.IconPath = sb.ToString(); //save the information + this.IconPath = path; this.IconIndex = index; } this.UpdateIcon(); diff --git a/Source/Launchbar/MenuEntryCollection.cs b/Source/Launchbar/MenuEntryCollection.cs index f27f2e0..90c4634 100644 --- a/Source/Launchbar/MenuEntryCollection.cs +++ b/Source/Launchbar/MenuEntryCollection.cs @@ -1,20 +1,16 @@ -using System; using System.Collections.ObjectModel; -using JetBrains.Annotations; namespace Launchbar; -public class MenuEntryCollection : ObservableCollection +public sealed class MenuEntryCollection : ObservableCollection { - public Submenu Parent { get; set; } + public Submenu? Parent { get; set; } // ReSharper disable once AnnotationConflictInHierarchy - protected override void InsertItem(int index, [NotNull] MenuEntry item) + protected override void InsertItem(int index, MenuEntry item) { - if (item is null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); + item.Parent = this; base.InsertItem(index, item); item.IsSelected = true; @@ -25,7 +21,7 @@ protected override void RemoveItem(int index) this[index].IsSelected = false; this[index].Parent = null; base.RemoveItem(index); - if (index == 0) + if (index <= 0) { if (this.Parent == null) { @@ -44,12 +40,10 @@ protected override void RemoveItem(int index) } // ReSharper disable once AnnotationConflictInHierarchy - protected override void SetItem(int index, [NotNull] MenuEntry item) + protected override void SetItem(int index, MenuEntry item) { - if (item is null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); + this[index].Parent = null; item.Parent = this; base.SetItem(index, item); diff --git a/Source/Launchbar/MenuEntryExit.cs b/Source/Launchbar/MenuEntryExit.cs index a7681f7..e4344a4 100644 --- a/Source/Launchbar/MenuEntryExit.cs +++ b/Source/Launchbar/MenuEntryExit.cs @@ -1,4 +1,3 @@ -using System; using System.Windows; using System.Windows.Input; @@ -9,18 +8,18 @@ namespace Launchbar; /// public sealed class MenuEntryExit : MenuEntry, ICommand { - public event EventHandler CanExecuteChanged + public event EventHandler? CanExecuteChanged { add { } remove { } } - public bool CanExecute(object parameter) + public bool CanExecute(object? parameter) { return true; } - public void Execute(object parameter) + public void Execute(object? parameter) { Application.Current.Shutdown(); // Quit } diff --git a/Source/Launchbar/MenuEntrySettings.cs b/Source/Launchbar/MenuEntrySettings.cs index 66377e3..9fed092 100644 --- a/Source/Launchbar/MenuEntrySettings.cs +++ b/Source/Launchbar/MenuEntrySettings.cs @@ -1,4 +1,3 @@ -using System; using System.Windows.Input; namespace Launchbar; @@ -6,20 +5,20 @@ namespace Launchbar; /// /// This class represents a settings entry. /// -public class MenuEntrySettings : MenuEntry, ICommand +public sealed class MenuEntrySettings : MenuEntry, ICommand { - public event EventHandler CanExecuteChanged + public event EventHandler? CanExecuteChanged { add { } remove { } } - public bool CanExecute(object parameter) + public bool CanExecute(object? parameter) { return true; } - public void Execute(object parameter) + public void Execute(object? parameter) { App.OpenOrActivateSettings(); // Quit } diff --git a/Source/Launchbar/MenuItemExtensions.cs b/Source/Launchbar/MenuItemExtensions.cs index 88945b7..ef35a80 100644 --- a/Source/Launchbar/MenuItemExtensions.cs +++ b/Source/Launchbar/MenuItemExtensions.cs @@ -4,12 +4,13 @@ namespace Launchbar; public static class MenuItemExtensions { - public static void SetIconTemplate(DependencyObject d, DataTemplate value) + public static void SetIconTemplate(DependencyObject d, DataTemplate? value) { d.SetValue(IconTemplateProperty, value); } - public static DataTemplate GetIconTemplate(DependencyObject d) + [MustUseReturnValue] + public static DataTemplate? GetIconTemplate(DependencyObject d) { return (DataTemplate)d.GetValue(IconTemplateProperty); } diff --git a/Source/Launchbar/MenuItemStyleSelector.cs b/Source/Launchbar/MenuItemStyleSelector.cs index 0f4d926..145f160 100644 --- a/Source/Launchbar/MenuItemStyleSelector.cs +++ b/Source/Launchbar/MenuItemStyleSelector.cs @@ -1,28 +1,22 @@ using System.Windows; using System.Windows.Controls; -using JetBrains.Annotations; namespace Launchbar; public sealed class MenuItemStyleSelector : StyleSelector { - [CanBeNull] - public Style ProgramStyle { get; set; } + public Style? ProgramStyle { get; set; } - [CanBeNull] - public Style SubmenuStyle { get; set; } + public Style? SubmenuStyle { get; set; } - [CanBeNull] - public Style SeparatorStyle { get; set; } + public Style? SeparatorStyle { get; set; } - [CanBeNull] - public Style SettingsStyle { get; set; } + public Style? SettingsStyle { get; set; } - [CanBeNull] - public Style ExitStyle { get; set; } + public Style? ExitStyle { get; set; } - [CanBeNull, MustUseReturnValue] - public override Style SelectStyle([CanBeNull] object item, [CanBeNull] DependencyObject container) + [MustUseReturnValue] + public override Style? SelectStyle(object? item, DependencyObject? container) { return item switch { @@ -31,7 +25,7 @@ public override Style SelectStyle([CanBeNull] object item, [CanBeNull] Dependenc Separator => this.SeparatorStyle, MenuEntrySettings => this.SettingsStyle, MenuEntryExit => this.ExitStyle, - _ => null + _ => null, }; } } \ No newline at end of file diff --git a/Source/Launchbar/MetaData.cs b/Source/Launchbar/MetaData.cs index 88bbeb1..bbfd385 100644 --- a/Source/Launchbar/MetaData.cs +++ b/Source/Launchbar/MetaData.cs @@ -1,15 +1,11 @@ -using System; -using System.Reflection; -using JetBrains.Annotations; +using System.Reflection; namespace Launchbar; public static class MetaData { - [NotNull] private static readonly Lazy version = new Lazy(() => Assembly.GetExecutingAssembly().GetCustomAttribute()?.InformationalVersion ?? "Unknown"); - [NotNull] public static string Version => version.Value; } \ No newline at end of file diff --git a/Source/Launchbar/NotifyBase.cs b/Source/Launchbar/NotifyBase.cs index 532a707..48a3596 100644 --- a/Source/Launchbar/NotifyBase.cs +++ b/Source/Launchbar/NotifyBase.cs @@ -1,5 +1,4 @@ using System.ComponentModel; -using JetBrains.Annotations; namespace Launchbar; @@ -8,15 +7,15 @@ public class NotifyBase : INotifyPropertyChanged /// /// Indicates the change of a property. /// - public event PropertyChangedEventHandler PropertyChanged = delegate { }; + public event PropertyChangedEventHandler? PropertyChanged = delegate { }; /// /// Raises the event. /// /// Name of the property which changed. [NotifyPropertyChangedInvocator] - protected void OnPropertyChanged([NotNull] string propertyName) + protected void OnPropertyChanged(string propertyName) { - this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + this.PropertyChanged!.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } \ No newline at end of file diff --git a/Source/Launchbar/Program.cs b/Source/Launchbar/Program.cs index 5b0b3a8..5e8377c 100644 --- a/Source/Launchbar/Program.cs +++ b/Source/Launchbar/Program.cs @@ -1,9 +1,7 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using System.IO; using System.Windows; using System.Windows.Input; -using JetBrains.Annotations; namespace Launchbar; @@ -14,13 +12,9 @@ public sealed class Program : MenuEntryAdvanced, ICommand { #region Fields - private string path; + private string? pathAbsolute; - private string pathAbsolute; - - private string arguments; - - private ProcessPriorityClass priority = ProcessPriorityClass.Normal; + private string? arguments; #endregion @@ -29,28 +23,21 @@ public sealed class Program : MenuEntryAdvanced, ICommand /// /// Path to the file to start. /// - public string Path + public string? Path { - get { return this.path; } + get; set { if (value == string.Empty) { value = null; } - if (this.path == value) + if (field == value) { return; } - this.path = value; - if (value == null) - { - this.pathAbsolute = null; - } - else - { - this.pathAbsolute = Environment.ExpandEnvironmentVariables(value); - } + field = value; + this.pathAbsolute = value == null ? null : Environment.ExpandEnvironmentVariables(value); this.OnPropertyChanged(nameof(this.Path)); this.OnPropertyChanged(nameof(this.IsValidFile)); @@ -62,12 +49,12 @@ public string Path /// /// Absolute path to the file to start (resolves environment variables). /// - public string PathAbsolute => this.pathAbsolute; + public string? PathAbsolute => this.pathAbsolute; /// /// Arguments to pass when starting the file. /// - public string Arguments + public string? Arguments { get { return this.arguments; } set @@ -90,17 +77,17 @@ public string Arguments /// public ProcessPriorityClass Priority { - get { return this.priority; } + get; set { - if (this.priority == value) + if (field == value) { return; } - this.priority = value; + field = value; this.OnPropertyChanged(nameof(this.Priority)); } - } + } = ProcessPriorityClass.Normal; /// /// Does the specified path point to an existing file? @@ -134,15 +121,15 @@ public void Run() Arguments = this.arguments }; - string workingDir = System.IO.Path.GetDirectoryName(this.pathAbsolute); - if (workingDir != null) + string? workingDir = System.IO.Path.GetDirectoryName(this.pathAbsolute); + if (workingDir is { }) { startInfo.WorkingDirectory = workingDir; } - if (Process.Start(startInfo) is Process process) // Start the process and set the priority (if a new process has been created). + if (Process.Start(startInfo) is { } process) // Start the process and set the priority (if a new process has been created). { - if (this.Priority != ProcessPriorityClass.Normal) // Only set priority if not default (as setting priority may cause an exception). + if (this.Priority is not ProcessPriorityClass.Normal) // Only set priority if not default (as setting priority may cause an exception). { process.PriorityClass = this.Priority; } @@ -164,18 +151,18 @@ public void TryRun() } } - public event EventHandler CanExecuteChanged + public event EventHandler? CanExecuteChanged { add { } remove { } } - public bool CanExecute([CanBeNull] object parameter) + public bool CanExecute(object? parameter) { return true; } - public void Execute([CanBeNull] object parameter) + public void Execute(object? parameter) { this.TryRun(); } diff --git a/Source/Launchbar/Properties/AssemblyInfo.cs b/Source/Launchbar/Properties/AssemblyInfo.cs index c7fe67b..f89173c 100644 --- a/Source/Launchbar/Properties/AssemblyInfo.cs +++ b/Source/Launchbar/Properties/AssemblyInfo.cs @@ -1,6 +1,3 @@ using System.Windows; -using System.Windows.Media; -[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] - -[assembly: DisableDpiAwareness] \ No newline at end of file +[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] \ No newline at end of file diff --git a/Source/Launchbar/Resources/Aero.Extended.xaml b/Source/Launchbar/Resources/Aero.Extended.xaml index 40241cd..867b5b3 100644 --- a/Source/Launchbar/Resources/Aero.Extended.xaml +++ b/Source/Launchbar/Resources/Aero.Extended.xaml @@ -30,7 +30,7 @@ Offset="1"/> - + @@ -283,14 +283,14 @@ VerticalAlignment="Center" ContentSource="Icon" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> - - - + - \ No newline at end of file diff --git a/Source/Launchbar/Resources/Images.xaml b/Source/Launchbar/Resources/Images.xaml index e26b230..e0fb9fc 100644 --- a/Source/Launchbar/Resources/Images.xaml +++ b/Source/Launchbar/Resources/Images.xaml @@ -2,7 +2,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> - + @@ -12,8 +12,8 @@ - - + + @@ -22,91 +22,95 @@ - - + + - + - - + + - + - + - + - - + + - + - - + + - + - + - + - - + + - + - - + + @@ -115,23 +119,24 @@ - - + + - + - - + + @@ -140,15 +145,16 @@ - - + + - + @@ -158,9 +164,9 @@ - + - + @@ -170,54 +176,54 @@ - - + + - + - - + + - + - - + + - + - + - + - + @@ -225,9 +231,9 @@ - + - + @@ -237,59 +243,59 @@ - - + + - + - - + + - + - - + + - + - + - + - + - + \ No newline at end of file diff --git a/Source/Launchbar/Resources/Styles.MarkDown.xaml b/Source/Launchbar/Resources/Styles.MarkDown.xaml index 73fee23..02904c9 100644 --- a/Source/Launchbar/Resources/Styles.MarkDown.xaml +++ b/Source/Launchbar/Resources/Styles.MarkDown.xaml @@ -1,112 +1,112 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/Launchbar/Shapes/ShapeApplication.xaml b/Source/Launchbar/Shapes/ShapeApplication.xaml index 89b9214..be8bdbf 100644 --- a/Source/Launchbar/Shapes/ShapeApplication.xaml +++ b/Source/Launchbar/Shapes/ShapeApplication.xaml @@ -1,20 +1,22 @@ - + + - + - - + + @@ -23,26 +25,26 @@ - - + + - + - + - + @@ -50,7 +52,7 @@ - + @@ -59,11 +61,11 @@ - - + + - + \ No newline at end of file diff --git a/Source/Launchbar/Shapes/ShapeApplication.xaml.cs b/Source/Launchbar/Shapes/ShapeApplication.xaml.cs index c479eef..3ed605f 100644 --- a/Source/Launchbar/Shapes/ShapeApplication.xaml.cs +++ b/Source/Launchbar/Shapes/ShapeApplication.xaml.cs @@ -3,9 +3,6 @@ namespace Launchbar.Shapes; -/// -/// Interaction logic for ShapeApplications.xaml -/// public sealed partial class ShapeApplication : UserControl { public ShapeApplication() @@ -13,8 +10,10 @@ public ShapeApplication() this.InitializeComponent(); } - private void sizeChanged(object sender, SizeChangedEventArgs e) + protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) { + base.OnRenderSizeChanged(sizeInfo); + this.scaler.ScaleX = this.ActualWidth / this.shape.Width; this.scaler.ScaleY = this.ActualHeight / this.shape.Height; } diff --git a/Source/Launchbar/Shapes/ShapeClose.xaml b/Source/Launchbar/Shapes/ShapeClose.xaml index bcdb8c2..a187de5 100644 --- a/Source/Launchbar/Shapes/ShapeClose.xaml +++ b/Source/Launchbar/Shapes/ShapeClose.xaml @@ -1,10 +1,10 @@  - + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> + + @@ -24,21 +24,22 @@ - - + + - + - - + + @@ -47,8 +48,8 @@ - - + + @@ -70,21 +71,22 @@ - - + + - + - - + + @@ -93,8 +95,8 @@ - - + + @@ -104,7 +106,7 @@ - + diff --git a/Source/Launchbar/Shapes/ShapeClose.xaml.cs b/Source/Launchbar/Shapes/ShapeClose.xaml.cs index 71288a9..03665b5 100644 --- a/Source/Launchbar/Shapes/ShapeClose.xaml.cs +++ b/Source/Launchbar/Shapes/ShapeClose.xaml.cs @@ -1,11 +1,10 @@ -using System.Windows; +using fm; +using fm.Extensions; +using System.Windows; using System.Windows.Controls; namespace Launchbar.Shapes; -/// -/// Interaction logic for ShapeClose.xaml -/// public sealed partial class ShapeClose : UserControl { /// @@ -13,23 +12,22 @@ public sealed partial class ShapeClose : UserControl /// public bool IsHover { - get { return (bool)this.GetValue(IsHoverProperty); } - set { this.SetValue(IsHoverProperty, value); } + get { return this.GetValue(IsHoverProperty); } + set { this.SetValueBox(IsHoverProperty, value); } } - /// - /// Identifies the property. - /// - public static readonly DependencyProperty IsHoverProperty = - DependencyProperty.Register("IsHover", typeof(bool), typeof(ShapeClose)); + public static readonly DependencyProperty IsHoverProperty = DependencyProperty.Register( + nameof(IsHover), typeof(bool), typeof(ShapeClose), new PropertyMetadata(Boxes.False)); public ShapeClose() { this.InitializeComponent(); } - private void sizeChanged(object sender, SizeChangedEventArgs e) + protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) { + base.OnRenderSizeChanged(sizeInfo); + this.scaler.ScaleX = this.ActualWidth / this.shape.Width; this.scaler.ScaleY = this.ActualHeight / this.shape.Height; } diff --git a/Source/Launchbar/Shapes/ShapeDelete.xaml b/Source/Launchbar/Shapes/ShapeDelete.xaml index 8a00519..5b89062 100644 --- a/Source/Launchbar/Shapes/ShapeDelete.xaml +++ b/Source/Launchbar/Shapes/ShapeDelete.xaml @@ -1,38 +1,38 @@  + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> + - + - - - + + + - + - - - + + + - + \ No newline at end of file diff --git a/Source/Launchbar/Shapes/ShapeDelete.xaml.cs b/Source/Launchbar/Shapes/ShapeDelete.xaml.cs index 3c3fe03..2375004 100644 --- a/Source/Launchbar/Shapes/ShapeDelete.xaml.cs +++ b/Source/Launchbar/Shapes/ShapeDelete.xaml.cs @@ -3,21 +3,17 @@ namespace Launchbar.Shapes; -/// -/// Interaction logic for ShapeDelete.xaml -/// public sealed partial class ShapeDelete : UserControl { - /// - /// Create a new instance of this class. - /// public ShapeDelete() { this.InitializeComponent(); } - private void sizeChanged(object sender, SizeChangedEventArgs e) + protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) { + base.OnRenderSizeChanged(sizeInfo); + this.scaler.ScaleX = this.ActualWidth / this.shape.Width; this.scaler.ScaleY = this.ActualHeight / this.shape.Height; } diff --git a/Source/Launchbar/Shapes/ShapeFolder.xaml b/Source/Launchbar/Shapes/ShapeFolder.xaml index 8fbeee8..0edaecd 100644 --- a/Source/Launchbar/Shapes/ShapeFolder.xaml +++ b/Source/Launchbar/Shapes/ShapeFolder.xaml @@ -1,8 +1,10 @@ - - + + + @@ -10,21 +12,21 @@ - + - - + + - - + + @@ -35,7 +37,7 @@ - - - - - - + - - - diff --git a/Source/Launchbar/WindowSettings.xaml.cs b/Source/Launchbar/WindowSettings.xaml.cs index 5ba1bcd..107cf61 100644 --- a/Source/Launchbar/WindowSettings.xaml.cs +++ b/Source/Launchbar/WindowSettings.xaml.cs @@ -1,14 +1,12 @@ -using System; +using fm.Extensions; +using Launchbar.Properties; +using Microsoft.Win32; using System.Diagnostics; using System.IO; using System.Windows; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Navigation; -using fm.Extensions; -using JetBrains.Annotations; -using Launchbar.Properties; -using Microsoft.Win32; namespace Launchbar; @@ -19,9 +17,9 @@ internal sealed partial class WindowSettings : Window /// /// Gets the currently selected . /// - public MenuEntry SelectedMenuEntry + public MenuEntry? SelectedMenuEntry { - get { return this.GetValue(SelectedMenuEntryProperty); } + get { return this.GetValue(SelectedMenuEntryProperty); } set { this.SetValue(SelectedMenuEntryProperty, value); } } @@ -49,9 +47,9 @@ public bool IsProgram /// /// Gets the currently selected object. /// - public Program SelectedProgram + public Program? SelectedProgram { - get { return this.GetValue(SelectedProgramProperty); } + get { return this.GetValue(SelectedProgramProperty); } private set { this.SetValue(SelectedProgramProperty, value); } } @@ -79,9 +77,9 @@ public bool IsMenuEntryAdvanced /// /// Gets the currently selected object. /// - public MenuEntryAdvanced SelectedMenuEntryAdvanced + public MenuEntryAdvanced? SelectedMenuEntryAdvanced { - get { return this.GetValue(SelectedMenuEntryAdvancedProperty); } + get { return this.GetValue(SelectedMenuEntryAdvancedProperty); } private set { this.SetValue(SelectedMenuEntryAdvancedProperty, value); } } @@ -104,47 +102,43 @@ private void treeViewEntriesSelectedItemChanged(object sender, RoutedPropertyCha this.SelectedMenuEntry = newValue as MenuEntry; - MenuEntryAdvanced mea = newValue as MenuEntryAdvanced; - Program program = newValue as Program; + MenuEntryAdvanced? mea = newValue as MenuEntryAdvanced; + Program? program = newValue as Program; this.SelectedMenuEntryAdvanced = mea; - this.IsMenuEntryAdvanced = mea != null; + this.IsMenuEntryAdvanced = mea is { }; this.SelectedProgram = program; - this.IsProgram = program != null; + this.IsProgram = program is { }; } - private void requestNavigateHyperlink([CanBeNull] object sender, [NotNull] RequestNavigateEventArgs e) + private void requestNavigateHyperlink(object? sender, RequestNavigateEventArgs e) { requestNavigate(e); } - private void requestNavigateCommand([CanBeNull] object sender, [NotNull] ExecutedRoutedEventArgs e) + private void requestNavigateCommand(object? sender, ExecutedRoutedEventArgs e) { requestNavigate(e); } - private static void requestNavigate([NotNull] RoutedEventArgs e) + private static void requestNavigate(RoutedEventArgs e) { - string uri = null; + string? uri = null; switch (e) { case RequestNavigateEventArgs en: uri = en.Uri.ToString(); break; case ExecutedRoutedEventArgs er: - switch (er.Parameter) - { - case Uri u: - uri = u.ToString(); - break; - case string s: - uri = s; - break; - } + uri = er.Parameter switch + { + Uri u => u.ToString(), + string s => s, + _ => uri, + }; break; default: - if (e.OriginalSource is Hyperlink hyperlink && - hyperlink.NavigateUri is Uri navUri) + if (e.OriginalSource is Hyperlink { NavigateUri: { } navUri }) { uri = navUri.ToString(); } @@ -167,19 +161,19 @@ private static void requestNavigate([NotNull] RoutedEventArgs e) #region Buttons - private void buttonOkClick(object sender, RoutedEventArgs e) + private void buttonOkClick(object? sender, RoutedEventArgs? e) { this.buttonApplyClick(null, null); this.Close(); } - private void buttonCancelClick(object sender, RoutedEventArgs e) + private void buttonCancelClick(object? sender, RoutedEventArgs? e) { Settings.Default.Reload(); this.Close(); } - private void buttonApplyClick(object sender, RoutedEventArgs e) + private void buttonApplyClick(object? sender, RoutedEventArgs? e) { // Read the Menu property to force a settings file update on save. if (Settings.Default.Menu == null) { } @@ -187,7 +181,7 @@ private void buttonApplyClick(object sender, RoutedEventArgs e) Settings.Default.Save(); } - private void buttonShutdownClick(object sender, RoutedEventArgs e) + private void buttonShutdownClick(object? sender, RoutedEventArgs? e) { Application.Current.Shutdown(); } @@ -198,12 +192,12 @@ private void buttonShutdownClick(object sender, RoutedEventArgs e) private void buttonMoveUpClick(object sender, RoutedEventArgs e) { - this.SelectedMenuEntry.MoveUp(); + this.SelectedMenuEntry?.MoveUp(); } private void buttonMoveDownClick(object sender, RoutedEventArgs e) { - this.SelectedMenuEntry.MoveDown(); + this.SelectedMenuEntry?.MoveDown(); } private void buttonAddProgramClick(object sender, RoutedEventArgs e) @@ -235,34 +229,27 @@ private void buttonAddExitClick(object sender, RoutedEventArgs e) private void addMenuEntry(MenuEntry newEntry) { - MenuEntry selected = this.SelectedMenuEntry; - if (selected != null) + MenuEntry? selected = this.SelectedMenuEntry; + if (selected is { }) { if (selected is Submenu submenu) { - if (submenu.MenuEntries == null) - { - submenu.MenuEntries = new MenuEntryCollection(); - } submenu.MenuEntries.Add(newEntry); } else { - selected.Parent.Insert(selected.Parent.IndexOf(selected) + 1, newEntry); + selected.Parent?.Insert(selected.Parent.IndexOf(selected) + 1, newEntry); } } else { - Settings.Default.Menu.Entries.Add(newEntry); + Settings.Default.Menu.Entries?.Add(newEntry); } } private void buttonDeleteClick(object sender, RoutedEventArgs e) { - if (this.SelectedMenuEntry != null) - { - this.SelectedMenuEntry.Parent.Remove(this.SelectedMenuEntry); - } + this.SelectedMenuEntry?.Parent?.Remove(this.SelectedMenuEntry); } private void selectTextTextBox() @@ -277,12 +264,12 @@ private void selectTextTextBox() private void buttonChooseIconClick(object sender, RoutedEventArgs e) { - this.SelectedMenuEntryAdvanced.ChooseIcon(); + this.SelectedMenuEntryAdvanced?.ChooseIcon(); } private void buttonClearIconClick(object sender, RoutedEventArgs e) { - this.SelectedMenuEntryAdvanced.ClearIcon(); + this.SelectedMenuEntryAdvanced?.ClearIcon(); } #endregion @@ -301,7 +288,7 @@ private void buttonBrowseClick(object sender, RoutedEventArgs e) // Text to be displayed in the file textbox. FileName = "Use this directory.", // Do not check for valid filename because we also want to accept directories. - CheckFileExists = false + CheckFileExists = false, }; if (ofd.ShowDialog() != true) @@ -314,37 +301,25 @@ private void buttonBrowseClick(object sender, RoutedEventArgs e) private void treeViewDrop(object sender, DragEventArgs e) { - string[] files = e.Data.GetData(DataFormats.FileDrop) as string[]; + string[]? files = e.Data.GetData(DataFormats.FileDrop) as string[]; - if (files == null || files.Length == 0) + if (files.IsNullOrEmpty()) { return; // Nothing to add; } - MenuEntry selected = this.SelectedMenuEntry; - MenuEntryCollection parent; - if (selected == null) - { - parent = Settings.Default.Menu.Entries; - } - else - { - Submenu submenu = selected as Submenu; - if (submenu == null) - { - parent = selected.Parent; - } - else + MenuEntryCollection? parent = this.SelectedMenuEntry switch { - parent = submenu.MenuEntries; - } - } + null => Settings.Default.Menu.Entries, + Submenu submenu => submenu.MenuEntries, + { } selectedMenu => selectedMenu.Parent, + }; foreach (string file in files) { - parent.Add(new Program + parent?.Add(new Program { Text = Path.GetFileNameWithoutExtension(file), - Path = file + Path = file, }); } } diff --git a/Source/NuGet.config b/Source/NuGet.config deleted file mode 100644 index a7a4c2f..0000000 --- a/Source/NuGet.config +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/Source/Product.props b/Source/Product.props new file mode 100644 index 0000000..44b898a --- /dev/null +++ b/Source/Product.props @@ -0,0 +1,11 @@ + + + + Launchbar + 5.3.0 + 5.3.0.3 + + Copyright © Mertsch $([System.DateTime]::UtcNow.Year) + + + \ No newline at end of file diff --git a/Source/global.json b/Source/global.json new file mode 100644 index 0000000..09090d5 --- /dev/null +++ b/Source/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "version": "10.0.100", // https://dotnet.microsoft.com/en-us/download/dotnet/10.0 + "rollForward": "latestMajor" + } +}