mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-01-26 22:17:15 +01:00
Compare commits
26 Commits
dev/migrie
...
dev/vanzue
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2f0008473 | ||
|
|
8586dc88bb | ||
|
|
3322b8ca2f | ||
|
|
50038cbf3e | ||
|
|
041ddf0754 | ||
|
|
474756036e | ||
|
|
25fc5a26ff | ||
|
|
23372413fe | ||
|
|
28c41d0838 | ||
|
|
155275918f | ||
|
|
e08cc398fa | ||
|
|
3b3df5b74f | ||
|
|
b5584eee76 | ||
|
|
5380b477a5 | ||
|
|
37c80b40bf | ||
|
|
a0fd2d1517 | ||
|
|
6623d0a2ee | ||
|
|
6ff59488eb | ||
|
|
2a53fd137a | ||
|
|
ef159bcd4d | ||
|
|
8479d0f084 | ||
|
|
3f52b2cfc9 | ||
|
|
32fdf79085 | ||
|
|
2398b5e6f0 | ||
|
|
ca473b488b | ||
|
|
d37105bf84 |
6
.github/actions/spell-check/allow/code.txt
vendored
6
.github/actions/spell-check/allow/code.txt
vendored
@@ -282,3 +282,9 @@ xef
|
||||
xes
|
||||
PACKAGEVERSIONNUMBER
|
||||
APPXMANIFESTVERSION
|
||||
|
||||
# MRU lists
|
||||
CACHEWRITE
|
||||
MRUCMPPROC
|
||||
MRUINFO
|
||||
REGSTR
|
||||
|
||||
19
.github/actions/spell-check/expect.txt
vendored
19
.github/actions/spell-check/expect.txt
vendored
@@ -38,6 +38,7 @@ ALLAPPS
|
||||
ALLCHILDREN
|
||||
ALLINPUT
|
||||
Allman
|
||||
Allmodule
|
||||
ALLOWUNDO
|
||||
ALLVIEW
|
||||
ALPHATYPE
|
||||
@@ -218,6 +219,7 @@ coclass
|
||||
CODENAME
|
||||
codereview
|
||||
Codespaces
|
||||
Coen
|
||||
COINIT
|
||||
colid
|
||||
colorconv
|
||||
@@ -245,6 +247,7 @@ CONTEXTMENUHANDLER
|
||||
contractversion
|
||||
CONTROLPARENT
|
||||
copiedcolorrepresentation
|
||||
coppied
|
||||
copyable
|
||||
COPYPEN
|
||||
COREWINDOW
|
||||
@@ -443,6 +446,7 @@ ERRORIMAGE
|
||||
ERRORTITLE
|
||||
ESettings
|
||||
esrp
|
||||
etd
|
||||
ETDT
|
||||
etl
|
||||
etw
|
||||
@@ -527,8 +531,8 @@ frm
|
||||
FROMTOUCH
|
||||
fsanitize
|
||||
fsmgmt
|
||||
fxf
|
||||
fuzzingtesting
|
||||
fxf
|
||||
FZE
|
||||
gacutil
|
||||
Gaeilge
|
||||
@@ -733,6 +737,7 @@ INSTALLSTARTMENUSHORTCUT
|
||||
INSTALLSTATE
|
||||
Inste
|
||||
Interlop
|
||||
intput
|
||||
INTRESOURCE
|
||||
INVALIDARG
|
||||
invalidoperatioexception
|
||||
@@ -815,6 +820,7 @@ LMEM
|
||||
LMENU
|
||||
LOADFROMFILE
|
||||
LOBYTE
|
||||
localappdata
|
||||
localpackage
|
||||
LOCALSYSTEM
|
||||
LOCATIONCHANGE
|
||||
@@ -1117,6 +1123,7 @@ oldtheme
|
||||
oleaut
|
||||
OLECHAR
|
||||
onebranch
|
||||
OOBEUI
|
||||
openas
|
||||
opencode
|
||||
OPENFILENAME
|
||||
@@ -1382,8 +1389,8 @@ RIDEV
|
||||
RIGHTSCROLLBAR
|
||||
riid
|
||||
RKey
|
||||
RNumber
|
||||
Rns
|
||||
RNumber
|
||||
rop
|
||||
ROUNDSMALL
|
||||
ROWSETEXT
|
||||
@@ -1394,6 +1401,7 @@ Rsp
|
||||
rstringalnum
|
||||
rstringalpha
|
||||
rstringdigit
|
||||
rtb
|
||||
RTB
|
||||
RTLREADING
|
||||
rtm
|
||||
@@ -1432,6 +1440,7 @@ secpol
|
||||
securestring
|
||||
SEEMASKINVOKEIDLIST
|
||||
SELCHANGE
|
||||
selfhost
|
||||
SENDCHANGE
|
||||
sendvirtualinput
|
||||
serverside
|
||||
@@ -1528,6 +1537,7 @@ SLGP
|
||||
sln
|
||||
SMALLICON
|
||||
smartphone
|
||||
smileys
|
||||
SMTO
|
||||
SNAPPROCESS
|
||||
snk
|
||||
@@ -1614,6 +1624,8 @@ svgz
|
||||
SVSI
|
||||
SWFO
|
||||
SWP
|
||||
SWPNOSIZE
|
||||
SWPNOZORDER
|
||||
SWRESTORE
|
||||
symbolrequestprod
|
||||
SYMCACHE
|
||||
@@ -1753,8 +1765,8 @@ Uptool
|
||||
urld
|
||||
Usb
|
||||
USEDEFAULT
|
||||
USEINSTALLERFORTEST
|
||||
USEFILEATTRIBUTES
|
||||
USEINSTALLERFORTEST
|
||||
USESHOWWINDOW
|
||||
USESTDHANDLES
|
||||
USRDLL
|
||||
@@ -1868,6 +1880,7 @@ winexe
|
||||
winforms
|
||||
winget
|
||||
wingetcreate
|
||||
wingetpkgs
|
||||
Winhook
|
||||
WINL
|
||||
winlogon
|
||||
|
||||
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@@ -4,7 +4,7 @@
|
||||
<!-- Please review the items on the PR checklist before submitting-->
|
||||
## PR Checklist
|
||||
|
||||
- [ ] **Closes:** #xxx
|
||||
- [ ] Closes: #xxx
|
||||
- [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected
|
||||
- [ ] **Tests:** Added/updated and all pass
|
||||
- [ ] **Localization:** All end-user-facing strings can be localized
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<PackageVersion Include="Microsoft.Bot.AdaptiveExpressions.Core" Version="4.23.0" />
|
||||
<PackageVersion Include="Appium.WebDriver" Version="4.4.5" />
|
||||
<PackageVersion Include="Azure.AI.OpenAI" Version="1.0.0-beta.17" />
|
||||
<PackageVersion Include="CoenM.ImageSharp.ImageHash" Version="1.3.6" />
|
||||
<PackageVersion Include="CommunityToolkit.Common" Version="8.4.0" />
|
||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageVersion Include="CommunityToolkit.WinUI.Animations" Version="8.2.250402" />
|
||||
@@ -69,6 +70,7 @@
|
||||
<PackageVersion Include="NLog.Schema" Version="5.2.8" />
|
||||
<PackageVersion Include="OpenAI" Version="2.0.0" />
|
||||
<PackageVersion Include="ReverseMarkdown" Version="4.1.0" />
|
||||
<PackageVersion Include="RtfPipe" Version="2.0.7677.4303" />
|
||||
<PackageVersion Include="ScipBe.Common.Office.OneNote" Version="3.0.1" />
|
||||
<PackageVersion Include="SharpCompress" Version="0.37.2" />
|
||||
<!-- Don't update SkiaSharp.Views.WinUI to version 3.* branch as this brakes the HexBox control in Registry Preview. -->
|
||||
|
||||
@@ -1496,6 +1496,7 @@ SOFTWARE.
|
||||
- AdaptiveCards.Templating 2.0.5
|
||||
- Appium.WebDriver 4.4.5
|
||||
- Azure.AI.OpenAI 1.0.0-beta.17
|
||||
- CoenM.ImageSharp.ImageHash 1.3.6
|
||||
- CommunityToolkit.Common 8.4.0
|
||||
- CommunityToolkit.Labs.WinUI.Controls.MarkdownTextBlock 0.1.250703-build.2173
|
||||
- CommunityToolkit.Mvvm 8.4.0
|
||||
|
||||
419
PowerToys.sln
419
PowerToys.sln
@@ -39,14 +39,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fancyzones", "fancyzones",
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FancyZonesLib", "src\modules\fancyzones\FancyZonesLib\FancyZonesLib.vcxproj", "{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests-FancyZones", "src\modules\fancyzones\FancyZonesTests\UnitTests\UnitTests.vcxproj", "{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FancyZones.UnitTests", "src\modules\fancyzones\FancyZonesTests\UnitTests\UnitTests.vcxproj", "{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99} = {F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{1AFB6476-670D-4E80-A464-657E01DFF482}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests-CommonLib", "src\common\UnitTests-CommonLib\UnitTests-CommonLib.vcxproj", "{1A066C63-64B3-45F8-92FE-664E1CCE8077}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common.Lib.UnitTests", "src\common\UnitTests-CommonLib\UnitTests-CommonLib.vcxproj", "{1A066C63-64B3-45F8-92FE-664E1CCE8077}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FancyZonesEditor", "src\modules\fancyzones\editor\FancyZonesEditor\FancyZonesEditor.csproj", "{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}"
|
||||
EndProject
|
||||
@@ -60,11 +60,8 @@ EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameLib", "src\modules\powerrename\lib\PowerRenameLib.vcxproj", "{51920F1F-C28C-4ADF-8660-4238766796C2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameTest", "src\modules\powerrename\testapp\PowerRenameTest.vcxproj", "{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2} = {51920F1F-C28C-4ADF-8660-4238766796C2}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameUnitTests", "src\modules\powerrename\unittests\PowerRenameLibUnitTests.vcxproj", "{2151F984-E006-4A9F-92EF-C6DDE3DC8413}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRename.UnitTests", "src\modules\powerrename\unittests\PowerRenameLibUnitTests.vcxproj", "{2151F984-E006-4A9F-92EF-C6DDE3DC8413}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2} = {51920F1F-C28C-4ADF-8660-4238766796C2}
|
||||
{B25AC7A5-FB9F-4789-B392-D5C85E948670} = {B25AC7A5-FB9F-4789-B392-D5C85E948670}
|
||||
@@ -80,7 +77,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageResizerUI", "src\modul
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageResizerExt", "src\modules\imageresizer\dll\ImageResizerExt.vcxproj", "{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageResizerUITest", "src\modules\imageresizer\tests\ImageResizerUITest.csproj", "{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageResizer.UnitTests", "src\modules\imageresizer\tests\ImageResizer.UnitTests.csproj", "{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerToys.ActionRunner", "src\ActionRunner\ActionRunner.vcxproj", "{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
@@ -152,13 +149,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PreviewHandlerCommon", "src
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarkdownPreviewHandler", "src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewHandler.csproj", "{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-MarkdownPreviewHandler", "src\modules\previewpane\UnitTests-MarkdownPreviewHandler\UnitTests-MarkdownPreviewHandler.csproj", "{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.MarkdownPreviewHandler.UnitTests", "src\modules\previewpane\UnitTests-MarkdownPreviewHandler\Preview.MarkdownPreviewHandler.UnitTests.csproj", "{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SvgPreviewHandler", "src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj", "{DA425894-6E13-404F-8DCB-78584EC0557A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-SvgPreviewHandler", "src\modules\previewpane\UnitTests-SvgPreviewHandler\UnitTests-SvgPreviewHandler.csproj", "{060D75DA-2D1C-48E6-A4A1-6F0718B64661}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.SvgPreviewHandler.UnitTests", "src\modules\previewpane\UnitTests-SvgPreviewHandler\Preview.SvgPreviewHandler.UnitTests.csproj", "{060D75DA-2D1C-48E6-A4A1-6F0718B64661}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-PreviewHandlerCommon", "src\modules\previewpane\UnitTests-PreviewHandlerCommon\UnitTests-PreviewHandlerCommon.csproj", "{748417CA-F17E-487F-9411-CAFB6D3F4877}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.PreviewHandlerCommon.UnitTests", "src\modules\previewpane\UnitTests-PreviewHandlerCommon\Preview.PreviewHandlerCommon.UnitTests.csproj", "{748417CA-F17E-487F-9411-CAFB6D3F4877}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "powerpreview", "src\modules\previewpane\powerpreview\powerpreview.vcxproj", "{217DF501-135C-4E38-BFC8-99D4821032EA}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
@@ -195,7 +192,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManagedCommon", "src\common
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Program.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.Program.UnitTests\Microsoft.Plugin.Program.UnitTests.csproj", "{42851751-CBC8-45A6-97F5-7A0753F7B4D1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-SvgThumbnailProvider", "src\modules\previewpane\UnitTests-SvgThumbnailProvider\UnitTests-SvgThumbnailProvider.csproj", "{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.SvgThumbnailProvider.UnitTests", "src\modules\previewpane\UnitTests-SvgThumbnailProvider\Preview.SvgThumbnailProvider.UnitTests.csproj", "{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SvgThumbnailProvider", "src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj", "{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}"
|
||||
EndProject
|
||||
@@ -216,10 +213,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Settings.UI.UnitTests", "sr
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest\Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.csproj", "{632BBE62-5421-49EA-835A-7FFA4F499BD6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Folder.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.Folder.UnitTests\Microsoft.Plugin.Folder.UnitTests.csproj", "{4FA206A5-F69F-4193-BF8F-F6EEB496734C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest-ColorPickerUI", "src\modules\colorPicker\UnitTest-ColorPickerUI\UnitTest-ColorPickerUI.csproj", "{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spdlog", "src\logging\logging.vcxproj", "{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.System", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.System\Microsoft.PowerToys.Run.Plugin.System.csproj", "{FD8EB419-FF9C-4D88-BB6F-BF6CED37747B}"
|
||||
@@ -235,7 +228,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logger", "src\common\logger
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SettingsAPI", "src\common\SettingsAPI\SettingsAPI.vcxproj", "{6955446D-23F7-4023-9BB3-8657F904AF99}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Interop.Tests", "src\common\interop\interop-tests\Microsoft.Interop.Tests.csproj", "{58736667-1027-4AD7-BFDF-7A3A6474103A}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Interop.UnitTests", "src\common\interop\interop-tests\Common.Interop.UnitTests.csproj", "{58736667-1027-4AD7-BFDF-7A3A6474103A}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "notifications", "notifications", "{D92131D6-7610-4D60-A7DB-1C169783F83B}"
|
||||
EndProject
|
||||
@@ -307,7 +300,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.UI", "src\common\Com
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfPreviewHandler", "src\modules\previewpane\PdfPreviewHandler\PdfPreviewHandler.csproj", "{69E1EE8D-143A-4060-9129-4658ACF14AAF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-PdfPreviewHandler", "src\modules\previewpane\UnitTests-PdfPreviewHandler\UnitTests-PdfPreviewHandler.csproj", "{ECC20689-002A-4354-95A6-B58DF089C6FF}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.PdfPreviewHandler.UnitTests", "src\modules\previewpane\UnitTests-PdfPreviewHandler\Preview.PdfPreviewHandler.UnitTests.csproj", "{ECC20689-002A-4354-95A6-B58DF089C6FF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.Registry", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Registry\Microsoft.PowerToys.Run.Plugin.Registry.csproj", "{4BABF3FE-3451-42FD-873F-3C332E18DCEF}"
|
||||
EndProject
|
||||
@@ -317,13 +310,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEngine", "sr
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEngineLibrary", "src\modules\keyboardmanager\KeyboardManagerEngineLibrary\KeyboardManagerEngineLibrary.vcxproj", "{E496B7FC-1E99-4BAB-849B-0E8367040B02}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEngineTest", "src\modules\keyboardmanager\KeyboardManagerEngineTest\KeyboardManagerEngineTest.vcxproj", "{7F4B3A60-BC27-45A7-8000-68B0B6EA7466}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManager.Engine.UnitTests", "src\modules\keyboardmanager\KeyboardManagerEngineTest\KeyboardManagerEngineTest.vcxproj", "{7F4B3A60-BC27-45A7-8000-68B0B6EA7466}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditor", "src\modules\keyboardmanager\KeyboardManagerEditor\KeyboardManagerEditor.vcxproj", "{8DF78B53-200E-451F-9328-01EB907193AE}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditorLibrary", "src\modules\keyboardmanager\KeyboardManagerEditorLibrary\KeyboardManagerEditorLibrary.vcxproj", "{23D2070D-E4AD-4ADD-85A7-083D9C76AD49}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditorTest", "src\modules\keyboardmanager\KeyboardManagerEditorTest\KeyboardManagerEditorTest.vcxproj", "{62173D9A-6724-4C00-A1C8-FB646480A9EC}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManager.Editor.UnitTests", "src\modules\keyboardmanager\KeyboardManagerEditorTest\KeyboardManagerEditorTest.vcxproj", "{62173D9A-6724-4C00-A1C8-FB646480A9EC}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "awake", "awake", "{127F38E0-40AA-4594-B955-5616BF206882}"
|
||||
EndProject
|
||||
@@ -351,7 +344,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plu
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfThumbnailProvider", "src\modules\previewpane\PdfThumbnailProvider\PdfThumbnailProvider.csproj", "{11491FD8-F921-48BF-880C-7FEA185B80A1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-PdfThumbnailProvider", "src\modules\previewpane\UnitTests-PdfThumbnailProvider\UnitTests-PdfThumbnailProvider.csproj", "{F40C3397-1834-4530-B2D9-8F8B8456BCDF}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.PdfThumbnailProvider.UnitTests", "src\modules\previewpane\UnitTests-PdfThumbnailProvider\Preview.PdfThumbnailProvider.UnitTests.csproj", "{F40C3397-1834-4530-B2D9-8F8B8456BCDF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.WindowsTerminal", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsTerminal\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.csproj", "{A2D583F0-B70C-4462-B1F0-8E81AFB7BA85}"
|
||||
EndProject
|
||||
@@ -365,11 +358,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MouseHighlighter", "src\mod
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GcodeThumbnailProvider", "src\modules\previewpane\GcodeThumbnailProvider\GcodeThumbnailProvider.csproj", "{809AA252-E17A-4FA2-B0A1-0450976B763F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-GcodeThumbnailProvider", "src\modules\previewpane\UnitTests-GcodeThumbnailProvider\UnitTests-GcodeThumbnailProvider.csproj", "{133281D8-1BCE-4D07-B31E-796612A9609E}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.GcodeThumbnailProvider.UnitTests", "src\modules\previewpane\UnitTests-GcodeThumbnailProvider\Preview.GcodeThumbnailProvider.UnitTests.csproj", "{133281D8-1BCE-4D07-B31E-796612A9609E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GcodePreviewHandler", "src\modules\previewpane\GcodePreviewHandler\GcodePreviewHandler.csproj", "{805306FF-A562-4415-8DEF-E493BDC45918}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-GcodePreviewHandler", "src\modules\previewpane\UnitTests-GcodePreviewHandler\UnitTests-GcodePreviewHandler.csproj", "{FCF3E52D-B80A-4FC3-98FD-6391354F0EE3}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.GcodePreviewHandler.UnitTests", "src\modules\previewpane\UnitTests-GcodePreviewHandler\Preview.GcodePreviewHandler.UnitTests.csproj", "{FCF3E52D-B80A-4FC3-98FD-6391354F0EE3}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AlwaysOnTop", "AlwaysOnTop", "{60CD2D4F-C3B9-4897-9821-FCA5098B41CE}"
|
||||
EndProject
|
||||
@@ -383,7 +376,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MousePointerCrosshairs", "s
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StlThumbnailProvider", "src\modules\previewpane\StlThumbnailProvider\StlThumbnailProvider.csproj", "{F7C8C0F1-5431-4347-89D0-8E5354F93CF2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-StlThumbnailProvider", "src\modules\previewpane\UnitTests-StlThumbnailProvider\UnitTests-StlThumbnailProvider.csproj", "{F1F6B6B6-9F18-4A17-8B5C-97DF552C53DC}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.StlThumbnailProvider.UnitTests", "src\modules\previewpane\UnitTests-StlThumbnailProvider\Preview.StlThumbnailProvider.UnitTests.csproj", "{F1F6B6B6-9F18-4A17-8B5C-97DF552C53DC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonacoPreviewHandler", "src\modules\previewpane\MonacoPreviewHandler\MonacoPreviewHandler.csproj", "{04B193D7-3E21-46B8-A958-89B63A8A69DE}"
|
||||
EndProject
|
||||
@@ -419,6 +412,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerOCR", "src\modules\Pow
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerOCRModuleInterface", "src\modules\PowerOCR\PowerOCRModuleInterface\PowerOCRModuleInterface.vcxproj", "{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B1234567-1234-1234-1234-123456789ABC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.History", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.History\Microsoft.PowerToys.Run.Plugin.History.csproj", "{212AD910-8488-4036-BE20-326931B75FB2}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MeasureTool", "MeasureTool", "{7AC943C9-52E8-44CF-9083-744D8049667B}"
|
||||
@@ -440,7 +435,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostsUILib", "src\modules\H
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Hosts", "Hosts", "{F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hosts.Tests", "src\modules\Hosts\Hosts.Tests\Hosts.Tests.csproj", "{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostsEditor.UnitTests", "src\modules\Hosts\Hosts.Tests\HostsEditor.UnitTests.csproj", "{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HostsModuleInterface", "src\modules\Hosts\HostsModuleInterface\HostsModuleInterface.vcxproj", "{B41B888C-7DB8-4747-B262-4062E05A230D}"
|
||||
EndProject
|
||||
@@ -530,8 +525,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CropAndLockModuleInterface"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cmdNotFound", "cmdNotFound", "{4C0D0746-BE5B-49EE-BD5D-A7811628AE8B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-FancyZonesEditor", "src\modules\fancyzones\UnitTests-FancyZonesEditor\UnitTests-FancyZonesEditor.csproj", "{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EnvironmentVariables", "EnvironmentVariables", "{538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnvironmentVariablesUILib", "src\modules\EnvironmentVariables\EnvironmentVariablesUILib\EnvironmentVariablesUILib.csproj", "{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA}"
|
||||
@@ -546,9 +539,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QoiPreviewHandlerCpp", "src
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QoiPreviewHandler", "src\modules\previewpane\QoiPreviewHandler\QoiPreviewHandler.csproj", "{6B04803D-B418-4833-A67E-B0FC966636A5}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-QoiPreviewHandler", "src\modules\previewpane\UnitTests-QoiPreviewHandler\UnitTests-QoiPreviewHandler.csproj", "{3940AD4D-F748-4BE4-9083-85769CD553EF}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.QoiPreviewHandler.UnitTests", "src\modules\previewpane\UnitTests-QoiPreviewHandler\Preview.QoiPreviewHandler.UnitTests.csproj", "{3940AD4D-F748-4BE4-9083-85769CD553EF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-QoiThumbnailProvider", "src\modules\previewpane\UnitTests-QoiThumbnailProvider\UnitTests-QoiThumbnailProvider.csproj", "{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.QoiThumbnailProvider.UnitTests", "src\modules\previewpane\UnitTests-QoiThumbnailProvider\Preview.QoiThumbnailProvider.UnitTests.csproj", "{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CmdNotFoundModuleInterface", "src\modules\cmdNotFound\CmdNotFoundModuleInterface\CmdNotFoundModuleInterface.vcxproj", "{0014D652-901F-4456-8D65-06FC5F997FB0}"
|
||||
EndProject
|
||||
@@ -564,10 +557,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RegistryPreview", "src\modu
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnvironmentVariables", "src\modules\EnvironmentVariables\EnvironmentVariables\EnvironmentVariables.csproj", "{DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UITests-FancyZones", "src\modules\fancyzones\UITests-FancyZones\UITests-FancyZones.csproj", "{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UITests-FancyZonesEditor", "src\modules\fancyzones\UITests-FancyZonesEditor\UITests-FancyZonesEditor.csproj", "{3A9A791E-94A9-49F8-8401-C11CE288D5FB}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FancyZonesEditorCommon", "src\modules\fancyzones\FancyZonesEditorCommon\FancyZonesEditorCommon.csproj", "{C0974915-8A1D-4BF0-977B-9587D3807AB7}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DSC", "DSC", "{557C4636-D7E1-4838-A504-7D19B725EE95}"
|
||||
@@ -604,7 +593,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WindowProperties", "WindowP
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WorkspacesLib", "src\modules\Workspaces\WorkspacesLib\WorkspacesLib.vcxproj", "{B31FCC55-B5A4-4EA7-B414-2DCEAE6AF332}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WorkspacesLibUnitTests", "src\modules\Workspaces\WorkspacesLib.UnitTests\WorkspacesLibUnitTests.vcxproj", "{A85D4D9F-9A39-4B5D-8B5A-9F2D5C9A8B4C}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Workspaces.Lib.UnitTests", "src\modules\Workspaces\WorkspacesLib.UnitTests\WorkspacesLibUnitTests.vcxproj", "{A85D4D9F-9A39-4B5D-8B5A-9F2D5C9A8B4C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkspacesLauncherUI", "src\modules\Workspaces\WorkspacesLauncherUI\WorkspacesLauncherUI.csproj", "{9C53CC25-0623-4569-95BC-B05410675EE3}"
|
||||
EndProject
|
||||
@@ -680,10 +669,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WebSea
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WinGet", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WinGet\Microsoft.CmdPal.Ext.WinGet.csproj", "{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvancedPaste.UnitTests", "src\modules\AdvancedPaste\AdvancedPaste.UnitTests\AdvancedPaste.UnitTests.csproj", "{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvancedPaste.FuzzTests", "src\modules\AdvancedPaste\AdvancedPaste.FuzzTests\AdvancedPaste.FuzzTests.csproj", "{7F5B9557-5878-4438-A721-3E28296BA193}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ZoomIt", "ZoomIt", "{DD6E12FE-5509-4ABC-ACC2-3D6DC98A238C}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZoomIt", "src\modules\ZoomIt\ZoomIt\ZoomIt.vcxproj", "{0A84F764-3A88-44CD-AA96-41BDBD48627B}"
|
||||
@@ -700,19 +685,17 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeyboardManagerEditorUI", "
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditorLibraryWrapper", "src\modules\keyboardmanager\KeyboardManagerEditorLibraryWrapper\KeyboardManagerEditorLibraryWrapper.vcxproj", "{4382A954-179A-4078-92AF-715187DFFF50}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hosts.FuzzTests", "src\modules\Hosts\Hosts.FuzzTests\Hosts.FuzzTests.csproj", "{EBED240C-8702-452D-B764-6DB9DA9179AF}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HostsEditor.FuzzTests", "src\modules\Hosts\Hosts.FuzzTests\HostsEditor.FuzzTests.csproj", "{EBED240C-8702-452D-B764-6DB9DA9179AF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hosts.UITests", "src\modules\Hosts\Hosts.UITests\Hosts.UITests.csproj", "{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HostsEditor.UITests", "src\modules\Hosts\Hosts.UITests\HostsEditor.UITests.csproj", "{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegistryPreview.FuzzTests", "src\modules\registrypreview\RegistryPreview.FuzzTests\RegistryPreview.FuzzTests.csproj", "{5702B3CC-8575-48D5-83D8-15BB42269CD3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.System", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.System\Microsoft.CmdPal.Ext.System.csproj", "{64B88F02-CD88-4ED8-9624-989A800230F9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FancyZones.FuzzTests", "src\modules\fancyzones\FancyZones.FuzzTests\FancyZones.FuzzTests.csproj", "{0217E86E-3476-9946-DE8E-9D200CEBD47A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CmdPalKeyboardService", "src\modules\cmdpal\CmdPalKeyboardService\CmdPalKeyboardService.vcxproj", "{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRename.FuzzingTest", "src\modules\powerrename\PowerRename.FuzzingTest\PowerRename.FuzzingTest.vcxproj", "{2694E2FB-DCD5-4BFF-A418-B6C3C7CE3B8E}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRename.FuzzTests", "src\modules\powerrename\PowerRename.FuzzingTest\PowerRename.FuzzingTest.vcxproj", "{2694E2FB-DCD5-4BFF-A418-B6C3C7CE3B8E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BgcodePreviewHandler", "src\modules\previewpane\BgcodePreviewHandler\BgcodePreviewHandler.csproj", "{9E0CBC06-F29A-4810-B93C-97D53863B95E}"
|
||||
EndProject
|
||||
@@ -722,27 +705,76 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BgcodeThumbnailProviderCpp"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BgcodeThumbnailProvider", "src\modules\previewpane\BgcodeThumbnailProvider\BgcodeThumbnailProvider.csproj", "{9BC1C986-1E97-4D07-A7B1-CE226C239EFA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-BgcodePreviewHandler", "src\modules\previewpane\UnitTests-BgcodePreviewHandler\UnitTests-BgcodePreviewHandler.csproj", "{99CA1509-FB73-456E-AFAF-AB89C017BD72}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Preview.BgcodePreviewHandler.UnitTests", "src\modules\previewpane\UnitTests-BgcodePreviewHandler\Preview.BgcodePreviewHandler.UnitTests.csproj", "{99CA1509-FB73-456E-AFAF-AB89C017BD72}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-BgcodeThumbnailProvider", "src\modules\previewpane\UnitTests-BgcodeThumbnailProvider\UnitTests-BgcodeThumbnailProvider.csproj", "{61CBF221-9452-4934-B685-146285E080D7}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Preview.BgcodeThumbnailProvider.UnitTests", "src\modules\previewpane\UnitTests-BgcodeThumbnailProvider\Preview.BgcodeThumbnailProvider.UnitTests.csproj", "{61CBF221-9452-4934-B685-146285E080D7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MouseUtils.UITests", "src\modules\MouseUtils\MouseUtils.UITests\MouseUtils.UITests.csproj", "{4E0AE3A4-2EE0-44D7-A2D0-8769977254A1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkspacesEditorUITest", "src\modules\Workspaces\WorkspacesEditorUITest\WorkspacesEditorUITest.csproj", "{43E779F3-D83C-48B1-BA8D-1912DBD76FC9}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Workspaces.Editor.UITests", "src\modules\Workspaces\WorkspacesEditorUITest\Workspaces.Editor.UITests.csproj", "{43E779F3-D83C-48B1-BA8D-1912DBD76FC9}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalculatorEngineCommon", "src\common\CalculatorEngineCommon\CalculatorEngineCommon.vcxproj", "{2CF78CF7-8FEB-4BE1-9591-55FA25B48FC6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedCsWin32", "src\common\ManagedCsWin32\ManagedCsWin32.csproj", "{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerRenameUITest", "src\modules\powerrename\PowerRenameUITest\PowerRenameUITest.csproj", "{9D3F3793-EFE3-4525-8782-238015DABA62}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerRename.UITests", "src\modules\powerrename\PowerRenameUITest\PowerRename.UITests.csproj", "{9D3F3793-EFE3-4525-8782-238015DABA62}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Core.ViewModels", "src\modules\cmdpal\Microsoft.CmdPal.Core.ViewModels\Microsoft.CmdPal.Core.ViewModels.csproj", "{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Core.Control", "src\modules\cmdpal\Microsoft.CmdPal.Core.Control\Microsoft.CmdPal.Core.Control.csproj", "{7E043FD6-F17A-04CE-F8D0-E24CB036BFB5}"
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{0E556541-6A45-42CB-AE49-EE5A9BE05E7C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Core.UI", "src\modules\cmdpal\Microsoft.CmdPal.Core.UI\Microsoft.CmdPal.Core.UI.csproj", "{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}"
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{27D9CB3A-46D1-402C-9273-F88CB8AC42F7}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B9617A31-0F0A-4397-851D-BF2FBEE32D7F}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
src\modules\launcher\Plugins\Microsoft.Plugin.Folder.UnitTests\Microsoft.Plugin.Folder.UnitTests.csproj = src\modules\launcher\Plugins\Microsoft.Plugin.Folder.UnitTests\Microsoft.Plugin.Folder.UnitTests.csproj
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{1C48CD47-D610-463A-A53C-AF82DD6C47E7}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D9BD324E-1D80-44AA-8E7B-73EB00944434}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8EF25507-2575-4ADE-BF7E-D23376903AB8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerOCR.UITests", "src\modules\PowerOCR\PowerOCR-UITests\PowerOCR.UITests.csproj", "{070AC093-C9F2-20AD-0BCD-F318FC2761EA}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{2C318EC3-BA86-4372-B1BC-DB0F33C208B2}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BFFB607F-7C78-434B-86B9-DA4C8196A1B5}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{66E1534A-1587-42B2-912F-45C994D32904}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{E885E71F-0B34-4A03-B13B-20F4E05E90BB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{264B412F-DB8B-4CF8-A74B-96998B183045}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{3527BF37-DFC5-4309-A032-29278CA21328}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{68328142-5B31-4715-BCBB-7B6345EE0971}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvancedPaste.FuzzTests", "src\modules\AdvancedPaste\AdvancedPaste.FuzzTests\AdvancedPaste.FuzzTests.csproj", "{4122388B-59E4-CDB0-0338-EA6881DF86F0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvancedPaste.UnitTests", "src\modules\AdvancedPaste\AdvancedPaste.UnitTests\AdvancedPaste.UnitTests.csproj", "{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.UITests", "src\modules\cmdpal\Microsoft.CmdPal.UITests\Microsoft.CmdPal.UITests.csproj", "{6748A29D-DA6A-033A-825B-752295FF6AA0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FancyZones.FuzzTests", "src\modules\fancyzones\FancyZones.FuzzTests\FancyZones.FuzzTests.csproj", "{6EABCF9A-6526-441F-932F-658B1DC3E403}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FancyZones.UITests", "src\modules\fancyzones\FancyZones.UITests\FancyZones.UITests.csproj", "{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FancyZonesEditor.UITests", "src\modules\fancyzones\FancyZonesEditor.UITests\FancyZonesEditor.UITests.csproj", "{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FancyZonesEditor.UnitTests", "src\modules\fancyzones\FancyZonesEditor.UnitTests\FancyZonesEditor.UnitTests.csproj", "{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColorPickerUI.UnitTests", "src\modules\colorPicker\ColorPickerUI.UnitTests\ColorPickerUI.UnitTests.csproj", "{F93C2817-C846-4259-84D8-B39A6B57C8DE}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{8131151D-B0E9-4E18-84A5-E5F946C4480A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Calc.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.Calc.UnitTests\Microsoft.CmdPal.Ext.Calc.UnitTests.csproj", "{E816D7AC-4688-4ECB-97CC-3D8E798F3825}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -1144,22 +1176,6 @@ Global
|
||||
{632BBE62-5421-49EA-835A-7FFA4F499BD6}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{632BBE62-5421-49EA-835A-7FFA4F499BD6}.Release|x64.ActiveCfg = Release|x64
|
||||
{632BBE62-5421-49EA-835A-7FFA4F499BD6}.Release|x64.Build.0 = Release|x64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Debug|x64.Build.0 = Debug|x64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|x64.ActiveCfg = Release|x64
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|x64.Build.0 = Release|x64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Debug|x64.Build.0 = Debug|x64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Release|x64.ActiveCfg = Release|x64
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Release|x64.Build.0 = Release|x64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
@@ -2044,14 +2060,6 @@ Global
|
||||
{3157FA75-86CF-4EE2-8F62-C43F776493C6}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{3157FA75-86CF-4EE2-8F62-C43F776493C6}.Release|x64.ActiveCfg = Release|x64
|
||||
{3157FA75-86CF-4EE2-8F62-C43F776493C6}.Release|x64.Build.0 = Release|x64
|
||||
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Debug|x64.Build.0 = Debug|x64
|
||||
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Release|x64.ActiveCfg = Release|x64
|
||||
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Release|x64.Build.0 = Release|x64
|
||||
{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||
{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||
{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
@@ -2176,22 +2184,6 @@ Global
|
||||
{DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Release|x64.ActiveCfg = Release|x64
|
||||
{DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Release|x64.Build.0 = Release|x64
|
||||
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|x64.Build.0 = Debug|x64
|
||||
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|x64.ActiveCfg = Release|x64
|
||||
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|x64.Build.0 = Release|x64
|
||||
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|x64.Build.0 = Debug|x64
|
||||
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|x64.ActiveCfg = Release|x64
|
||||
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|x64.Build.0 = Release|x64
|
||||
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Debug|x64.ActiveCfg = Debug|x64
|
||||
@@ -2516,22 +2508,6 @@ Global
|
||||
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Release|x64.ActiveCfg = Release|x64
|
||||
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Release|x64.Build.0 = Release|x64
|
||||
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Release|x64.Deploy.0 = Release|x64
|
||||
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Debug|x64.Build.0 = Debug|x64
|
||||
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Release|x64.ActiveCfg = Release|x64
|
||||
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Release|x64.Build.0 = Release|x64
|
||||
{7F5B9557-5878-4438-A721-3E28296BA193}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{7F5B9557-5878-4438-A721-3E28296BA193}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{7F5B9557-5878-4438-A721-3E28296BA193}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7F5B9557-5878-4438-A721-3E28296BA193}.Debug|x64.Build.0 = Debug|x64
|
||||
{7F5B9557-5878-4438-A721-3E28296BA193}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{7F5B9557-5878-4438-A721-3E28296BA193}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{7F5B9557-5878-4438-A721-3E28296BA193}.Release|x64.ActiveCfg = Release|x64
|
||||
{7F5B9557-5878-4438-A721-3E28296BA193}.Release|x64.Build.0 = Release|x64
|
||||
{0A84F764-3A88-44CD-AA96-41BDBD48627B}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{0A84F764-3A88-44CD-AA96-41BDBD48627B}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{0A84F764-3A88-44CD-AA96-41BDBD48627B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
@@ -2624,14 +2600,6 @@ Global
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|x64.ActiveCfg = Release|x64
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|x64.Build.0 = Release|x64
|
||||
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Debug|x64.Build.0 = Debug|x64
|
||||
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Release|x64.ActiveCfg = Release|x64
|
||||
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Release|x64.Build.0 = Release|x64
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
@@ -2726,14 +2694,6 @@ Global
|
||||
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}.Release|x64.ActiveCfg = Release|x64
|
||||
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}.Release|x64.Build.0 = Release|x64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|x64.Build.0 = Debug|x64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|x64.ActiveCfg = Release|x64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|x64.Build.0 = Release|x64
|
||||
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|x64.ActiveCfg = Debug|x64
|
||||
@@ -2750,26 +2710,86 @@ Global
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|x64.ActiveCfg = Release|x64
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|x64.Build.0 = Release|x64
|
||||
{7E043FD6-F17A-04CE-F8D0-E24CB036BFB5}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{7E043FD6-F17A-04CE-F8D0-E24CB036BFB5}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{7E043FD6-F17A-04CE-F8D0-E24CB036BFB5}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7E043FD6-F17A-04CE-F8D0-E24CB036BFB5}.Debug|x64.Build.0 = Debug|x64
|
||||
{7E043FD6-F17A-04CE-F8D0-E24CB036BFB5}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{7E043FD6-F17A-04CE-F8D0-E24CB036BFB5}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{7E043FD6-F17A-04CE-F8D0-E24CB036BFB5}.Release|x64.ActiveCfg = Release|x64
|
||||
{7E043FD6-F17A-04CE-F8D0-E24CB036BFB5}.Release|x64.Build.0 = Release|x64
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}.Debug|ARM64.Deploy.0 = Debug|ARM64
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}.Debug|x64.Build.0 = Debug|x64
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}.Release|ARM64.Deploy.0 = Release|ARM64
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}.Release|x64.ActiveCfg = Release|x64
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}.Release|x64.Build.0 = Release|x64
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1}.Release|x64.Deploy.0 = Release|x64
|
||||
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Debug|x64.Build.0 = Debug|x64
|
||||
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Release|x64.ActiveCfg = Release|x64
|
||||
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Release|x64.Build.0 = Release|x64
|
||||
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Debug|x64.Build.0 = Debug|x64
|
||||
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Release|x64.ActiveCfg = Release|x64
|
||||
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Release|x64.Build.0 = Release|x64
|
||||
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Debug|x64.Build.0 = Debug|x64
|
||||
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Release|x64.ActiveCfg = Release|x64
|
||||
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Release|x64.Build.0 = Release|x64
|
||||
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Debug|x64.Build.0 = Debug|x64
|
||||
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Release|x64.ActiveCfg = Release|x64
|
||||
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Release|x64.Build.0 = Release|x64
|
||||
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Debug|x64.Build.0 = Debug|x64
|
||||
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Release|x64.ActiveCfg = Release|x64
|
||||
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Release|x64.Build.0 = Release|x64
|
||||
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Debug|x64.Build.0 = Debug|x64
|
||||
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Release|x64.ActiveCfg = Release|x64
|
||||
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Release|x64.Build.0 = Release|x64
|
||||
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Debug|x64.Build.0 = Debug|x64
|
||||
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Release|x64.ActiveCfg = Release|x64
|
||||
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Release|x64.Build.0 = Release|x64
|
||||
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Debug|x64.Build.0 = Debug|x64
|
||||
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Release|x64.ActiveCfg = Release|x64
|
||||
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Release|x64.Build.0 = Release|x64
|
||||
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Debug|x64.Build.0 = Debug|x64
|
||||
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Release|x64.ActiveCfg = Release|x64
|
||||
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Release|x64.Build.0 = Release|x64
|
||||
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Debug|x64.Build.0 = Debug|x64
|
||||
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Release|x64.ActiveCfg = Release|x64
|
||||
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -2778,26 +2798,26 @@ Global
|
||||
{3BB8493E-D18E-4485-A320-CB40F90F55AE} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{D1D6BC88-09AE-4FB4-AD24-5DED46A791DD} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9} = {264B412F-DB8B-4CF8-A74B-96998B183045}
|
||||
{1A066C63-64B3-45F8-92FE-664E1CCE8077} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{B25AC7A5-FB9F-4789-B392-D5C85E948670} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{51920F1F-C28C-4ADF-8660-4238766796C2} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{2151F984-E006-4A9F-92EF-C6DDE3DC8413} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{2151F984-E006-4A9F-92EF-C6DDE3DC8413} = {66E1534A-1587-42B2-912F-45C994D32904}
|
||||
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{6C7F47CC-2151-44A3-A546-41C70025132C} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34} = {6C7F47CC-2151-44A3-A546-41C70025132C}
|
||||
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B} = {6C7F47CC-2151-44A3-A546-41C70025132C}
|
||||
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8} = {6C7F47CC-2151-44A3-A546-41C70025132C}
|
||||
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8} = {0E556541-6A45-42CB-AE49-EE5A9BE05E7C}
|
||||
{17DA04DF-E393-4397-9CF0-84DABE11032E} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{38BDB927-829B-4C65-9CD9-93FB05D66D65} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{FF742965-9A80-41A5-B042-D6C7D3A21708} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{FF742965-9A80-41A5-B042-D6C7D3A21708} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
|
||||
{4AFC9975-2456-4C70-94A4-84073C1CED93} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{59BD9891-3837-438A-958D-ADC7F91F6F7E} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{4D971245-7A70-41D5-BAA0-DDB5684CAF51} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
@@ -2810,31 +2830,29 @@ Global
|
||||
{2F305555-C296-497E-AC20-5FA1B237996A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{AF2349B8-E5B6-4004-9502-687C1C7730B1} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{DA425894-6E13-404F-8DCB-78584EC0557A} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{060D75DA-2D1C-48E6-A4A1-6F0718B64661} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{748417CA-F17E-487F-9411-CAFB6D3F4877} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{060D75DA-2D1C-48E6-A4A1-6F0718B64661} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{748417CA-F17E-487F-9411-CAFB6D3F4877} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{217DF501-135C-4E38-BFC8-99D4821032EA} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{08C8C05F-0362-41BC-818C-724572DF8B06} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{5D00D290-4016-4CFE-9E41-1E7C724509BA} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{4AED67B6-55FD-486F-B917-E543DEE2CB3C} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{42851751-CBC8-45A6-97F5-7A0753F7B4D1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{42851751-CBC8-45A6-97F5-7A0753F7B4D1} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
|
||||
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{655C9AF2-18D3-4DA6-80E4-85504A7722BA} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
|
||||
{BA58206B-1493-4C75-BFEA-A85768A1E156} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
|
||||
{1D78B84B-CA39-406C-98F4-71F7EC266CC0} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{03276A39-D4E9-417C-8FFD-200B0EE5E871} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{B81FB7B6-D30E-428F-908A-41422EFC1172} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{0F85E674-34AE-443D-954C-8321EB8B93B1} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
{632BBE62-5421-49EA-835A-7FFA4F499BD6} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{4FA206A5-F69F-4193-BF8F-F6EEB496734C} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
|
||||
{B81FB7B6-D30E-428F-908A-41422EFC1172} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
|
||||
{0F85E674-34AE-443D-954C-8321EB8B93B1} = {E885E71F-0B34-4A03-B13B-20F4E05E90BB}
|
||||
{632BBE62-5421-49EA-835A-7FFA4F499BD6} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F} = {E4E03FE0-94FD-47C7-88C5-F17D0AA549D3}
|
||||
{FD8EB419-FF9C-4D88-BB6F-BF6CED37747B} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{DA5A6FE9-0040-40CC-83CC-764AE5306590} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{DA5A6FE9-0040-40CC-83CC-764AE5306590} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
|
||||
{0351ADA4-0C32-4652-9BA0-41F7B602372B} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD} = {E4E03FE0-94FD-47C7-88C5-F17D0AA549D3}
|
||||
{6955446D-23F7-4023-9BB3-8657F904AF99} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
@@ -2853,20 +2871,20 @@ Global
|
||||
{8F62026A-294B-41C6-8839-87463613F216} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{C3A17DCA-217B-462C-BB0C-BE086AF80081} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{69E1EE8D-143A-4060-9129-4658ACF14AAF} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{ECC20689-002A-4354-95A6-B58DF089C6FF} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{ECC20689-002A-4354-95A6-B58DF089C6FF} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{4BABF3FE-3451-42FD-873F-3C332E18DCEF} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{0648DF05-5DDA-4BE1-B5F2-584926EBDB65} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{0648DF05-5DDA-4BE1-B5F2-584926EBDB65} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
|
||||
{BA661F5B-1D5A-4FFC-9BF1-FC39DF280BDD} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{E496B7FC-1E99-4BAB-849B-0E8367040B02} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{7F4B3A60-BC27-45A7-8000-68B0B6EA7466} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{7F4B3A60-BC27-45A7-8000-68B0B6EA7466} = {D9BD324E-1D80-44AA-8E7B-73EB00944434}
|
||||
{8DF78B53-200E-451F-9328-01EB907193AE} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{23D2070D-E4AD-4ADD-85A7-083D9C76AD49} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC} = {D9BD324E-1D80-44AA-8E7B-73EB00944434}
|
||||
{127F38E0-40AA-4594-B955-5616BF206882} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A} = {127F38E0-40AA-4594-B955-5616BF206882}
|
||||
{D940E07F-532C-4FF3-883F-790DA014F19A} = {127F38E0-40AA-4594-B955-5616BF206882}
|
||||
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
|
||||
{106CBECA-0701-4FC3-838C-9DF816A19AE2} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81} = {106CBECA-0701-4FC3-838C-9DF816A19AE2}
|
||||
{2EDB3EB4-FA92-4BFF-B2D8-566584837231} = {106CBECA-0701-4FC3-838C-9DF816A19AE2}
|
||||
@@ -2874,27 +2892,27 @@ Global
|
||||
{FF1D7936-842A-4BBB-8BEA-E9FE796DE700} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{5043CECE-E6A7-4867-9CBE-02D27D83747A} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{11491FD8-F921-48BF-880C-7FEA185B80A1} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{F40C3397-1834-4530-B2D9-8F8B8456BCDF} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{F40C3397-1834-4530-B2D9-8F8B8456BCDF} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{A2D583F0-B70C-4462-B1F0-8E81AFB7BA85} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{4ED320BC-BA04-4D42-8D15-CBE62151F08B} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{4ED320BC-BA04-4D42-8D15-CBE62151F08B} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
|
||||
{322566EF-20DC-43A6-B9F8-616AF942579A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{E94FD11C-0591-456F-899F-EFC0CA548336} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
||||
{782A61BE-9D85-4081-B35C-1CCC9DCC1E88} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
||||
{809AA252-E17A-4FA2-B0A1-0450976B763F} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{133281D8-1BCE-4D07-B31E-796612A9609E} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{133281D8-1BCE-4D07-B31E-796612A9609E} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{805306FF-A562-4415-8DEF-E493BDC45918} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{FCF3E52D-B80A-4FC3-98FD-6391354F0EE3} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{FCF3E52D-B80A-4FC3-98FD-6391354F0EE3} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{60CD2D4F-C3B9-4897-9821-FCA5098B41CE} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2} = {60CD2D4F-C3B9-4897-9821-FCA5098B41CE}
|
||||
{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9} = {60CD2D4F-C3B9-4897-9821-FCA5098B41CE}
|
||||
{9F94B303-5E21-4364-9362-64426F8DB932} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{EAE14C0E-7A6B-45DA-9080-A7D8C077BA6E} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
||||
{F7C8C0F1-5431-4347-89D0-8E5354F93CF2} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{F1F6B6B6-9F18-4A17-8B5C-97DF552C53DC} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{F1F6B6B6-9F18-4A17-8B5C-97DF552C53DC} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{04B193D7-3E21-46B8-A958-89B63A8A69DE} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{5BDBD6C9-A31F-4CEB-871A-5E9E709197EF} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{FD464B4C-2F68-4D06-91E7-4208146C41F5} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{FD464B4C-2F68-4D06-91E7-4208146C41F5} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
|
||||
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
|
||||
{020A7474-3601-4160-A159-D7B70B77B15F} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
{27718999-C175-450A-861C-89F911E16A88} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{1DBBB112-4BB1-444B-8EBB-E66555C76BA6} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
@@ -2908,6 +2926,7 @@ Global
|
||||
{A50C70A6-2DA0-4027-B90E-B1A40755A8A5} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{25C91A4E-BA4E-467A-85CD-8B62545BF674} = {A50C70A6-2DA0-4027-B90E-B1A40755A8A5}
|
||||
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1} = {A50C70A6-2DA0-4027-B90E-B1A40755A8A5}
|
||||
{B1234567-1234-1234-1234-123456789ABC} = {A50C70A6-2DA0-4027-B90E-B1A40755A8A5}
|
||||
{212AD910-8488-4036-BE20-326931B75FB2} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{7AC943C9-52E8-44CF-9083-744D8049667B} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A} = {7AC943C9-52E8-44CF-9083-744D8049667B}
|
||||
@@ -2916,7 +2935,7 @@ Global
|
||||
{C97D9A5D-206C-454E-997E-009E227D7F02} = {0F14491C-6369-4C45-AAA8-135814E66E6B}
|
||||
{31D1C81D-765F-4446-AA62-E743F6325049} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
||||
{F05E590D-AD46-42BE-9C25-6A63ADD2E3EA} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
||||
{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A} = {1C48CD47-D610-463A-A53C-AF82DD6C47E7}
|
||||
{B41B888C-7DB8-4747-B262-4062E05A230D} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
||||
{AB82E5DD-C32D-4F28-9746-2C780846188E} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
||||
@@ -2945,7 +2964,7 @@ Global
|
||||
{A663E672-B26D-4EC0-BEAB-FE2E424AC46F} = {B6C42F16-73EB-477E-8B0D-4E6CF6C20AAC}
|
||||
{8A08D663-4995-40E3-B42C-3F910625F284} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
||||
{923DF87C-CA99-4D1C-B1D2-959174E95BFA} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
||||
{D5E42C63-57C5-4EF6-AECE-1E2FCA725B77} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
||||
{D5E42C63-57C5-4EF6-AECE-1E2FCA725B77} = {2C318EC3-BA86-4372-B1BC-DB0F33C208B2}
|
||||
{D962A009-834F-4EEC-AABB-430DF8F98E39} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
||||
{9873BA05-4C41-4819-9283-CF45D795431B} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{FC373B24-3293-453C-AAF5-CF2909DCEE6A} = {9873BA05-4C41-4819-9283-CF45D795431B}
|
||||
@@ -2956,12 +2975,11 @@ Global
|
||||
{9EBAA524-0EDA-470B-95D4-39383285CBB2} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{D095BE44-1F2E-463E-A494-121892A75EA2} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{90F9FA90-2C20-4004-96E6-F3B78151F5A5} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
|
||||
{3B227528-4BA6-4CAF-B44A-A10C78A64849} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{F5E1146E-B7B3-4E11-85FD-270A500BD78C} = {3B227528-4BA6-4CAF-B44A-A10C78A64849}
|
||||
{3157FA75-86CF-4EE2-8F62-C43F776493C6} = {3B227528-4BA6-4CAF-B44A-A10C78A64849}
|
||||
{4C0D0746-BE5B-49EE-BD5D-A7811628AE8B} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{538ED0BB-B863-4B20-98CC-BCDF7FA0B68A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA} = {538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}
|
||||
{B9420661-B0E4-4241-ABD4-4A27A1F64250} = {538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}
|
||||
@@ -2969,8 +2987,8 @@ Global
|
||||
{D949EC7D-48A9-4279-95D5-078E7FD1F048} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{3BAF9C81-A194-4925-A035-5E24A5D1E542} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{6B04803D-B418-4833-A67E-B0FC966636A5} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{3940AD4D-F748-4BE4-9083-85769CD553EF} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{3940AD4D-F748-4BE4-9083-85769CD553EF} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{0014D652-901F-4456-8D65-06FC5F997FB0} = {4C0D0746-BE5B-49EE-BD5D-A7811628AE8B}
|
||||
{799A50D8-DE89-4ED1-8FF8-AD5A9ED8C0CA} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
||||
{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
||||
@@ -2978,8 +2996,6 @@ Global
|
||||
{02DD46D3-F761-47D9-8894-2D6DA0124650} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
||||
{8E23E173-7127-4A5F-9F93-3049F2B68047} = {929C1324-22E8-4412-A9A8-80E85F3985A5}
|
||||
{DFF88D16-D36F-40A4-A955-CDCAA76EF7B8} = {538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}
|
||||
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{3A9A791E-94A9-49F8-8401-C11CE288D5FB} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{C0974915-8A1D-4BF0-977B-9587D3807AB7} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{1D6893CB-BC0C-46A8-A76C-9728706CA51A} = {557C4636-D7E1-4838-A504-7D19B725EE95}
|
||||
{8ACB33D9-C95B-47D4-8363-9731EE0930A0} = {CA716AE6-FE5C-40AC-BB8F-2C87912687AC}
|
||||
@@ -2989,7 +3005,7 @@ Global
|
||||
{BE126CBB-AE12-406A-9837-A05ACFCA57A7} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
|
||||
{14CB58B7-D280-4A7A-95DE-4B2DF14EA000} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
|
||||
{B31FCC55-B5A4-4EA7-B414-2DCEAE6AF332} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
|
||||
{A85D4D9F-9A39-4B5D-8B5A-9F2D5C9A8B4C} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
|
||||
{A85D4D9F-9A39-4B5D-8B5A-9F2D5C9A8B4C} = {68328142-5B31-4715-BCBB-7B6345EE0971}
|
||||
{9C53CC25-0623-4569-95BC-B05410675EE3} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
|
||||
{45285DF2-9742-4ECA-9AC9-58951FC26489} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
|
||||
{3D63307B-9D27-44FD-B033-B26F39245B85} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
|
||||
@@ -2997,7 +3013,7 @@ Global
|
||||
{2CAC093E-5FCF-4102-9C2C-AC7DD5D9EB96} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
|
||||
{37D07516-4185-43A4-924F-3C7A5D95ECF6} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
|
||||
{8F021B46-362B-485C-BFBA-CCF83E820CBD} = {8F62026A-294B-41C6-8839-87463613F216}
|
||||
{66614C26-314C-4B91-9071-76133422CFEF} = {B6C42F16-73EB-477E-8B0D-4E6CF6C20AAC}
|
||||
{66614C26-314C-4B91-9071-76133422CFEF} = {BFFB607F-7C78-434B-86B9-DA4C8196A1B5}
|
||||
{3846508C-77EB-4034-A702-F8BB263C4F79} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2} = {3846508C-77EB-4034-A702-F8BB263C4F79}
|
||||
{6CE438DF-C245-4997-A360-0A0939E4BA34} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
|
||||
@@ -3027,8 +3043,6 @@ Global
|
||||
{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
|
||||
{605E914B-7232-4789-AF46-BF5D3DDFC14E} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
|
||||
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
|
||||
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE} = {9873BA05-4C41-4819-9283-CF45D795431B}
|
||||
{7F5B9557-5878-4438-A721-3E28296BA193} = {9873BA05-4C41-4819-9283-CF45D795431B}
|
||||
{DD6E12FE-5509-4ABC-ACC2-3D6DC98A238C} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||
{0A84F764-3A88-44CD-AA96-41BDBD48627B} = {DD6E12FE-5509-4ABC-ACC2-3D6DC98A238C}
|
||||
{E4585179-2AC1-4D5F-A3FF-CFC5392F694C} = {DD6E12FE-5509-4ABC-ACC2-3D6DC98A238C}
|
||||
@@ -3037,30 +3051,49 @@ Global
|
||||
{A558C25D-2007-498E-8B6F-43405AFAE9E2} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{08F9155D-B6DC-46E5-9C83-AF60B655898B} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{4382A954-179A-4078-92AF-715187DFFF50} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{EBED240C-8702-452D-B764-6DB9DA9179AF} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
||||
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
||||
{5702B3CC-8575-48D5-83D8-15BB42269CD3} = {929C1324-22E8-4412-A9A8-80E85F3985A5}
|
||||
{EBED240C-8702-452D-B764-6DB9DA9179AF} = {1C48CD47-D610-463A-A53C-AF82DD6C47E7}
|
||||
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0} = {1C48CD47-D610-463A-A53C-AF82DD6C47E7}
|
||||
{5702B3CC-8575-48D5-83D8-15BB42269CD3} = {8131151D-B0E9-4E18-84A5-E5F946C4480A}
|
||||
{64B88F02-CD88-4ED8-9624-989A800230F9} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
|
||||
{0217E86E-3476-9946-DE8E-9D200CEBD47A} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2} = {3846508C-77EB-4034-A702-F8BB263C4F79}
|
||||
{2694E2FB-DCD5-4BFF-A418-B6C3C7CE3B8E} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{2694E2FB-DCD5-4BFF-A418-B6C3C7CE3B8E} = {66E1534A-1587-42B2-912F-45C994D32904}
|
||||
{9E0CBC06-F29A-4810-B93C-97D53863B95E} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{F6088A11-1C9E-4420-AA90-CF7E78DD7F1C} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{47B0678C-806B-4FE1-9F50-46BA88989532} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{9BC1C986-1E97-4D07-A7B1-CE226C239EFA} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{99CA1509-FB73-456E-AFAF-AB89C017BD72} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{61CBF221-9452-4934-B685-146285E080D7} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A1} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
||||
{43E779F3-D83C-48B1-BA8D-1912DBD76FC9} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
|
||||
{99CA1509-FB73-456E-AFAF-AB89C017BD72} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{61CBF221-9452-4934-B685-146285E080D7} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A1} = {2C318EC3-BA86-4372-B1BC-DB0F33C208B2}
|
||||
{43E779F3-D83C-48B1-BA8D-1912DBD76FC9} = {68328142-5B31-4715-BCBB-7B6345EE0971}
|
||||
{2CF78CF7-8FEB-4BE1-9591-55FA25B48FC6} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{9D3F3793-EFE3-4525-8782-238015DABA62} = {66E1534A-1587-42B2-912F-45C994D32904}
|
||||
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {3846508C-77EB-4034-A702-F8BB263C4F79}
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||
{9D3F3793-EFE3-4525-8782-238015DABA62} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {3846508C-77EB-4034-A702-F8BB263C4F79}
|
||||
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||
{7E043FD6-F17A-04CE-F8D0-E24CB036BFB5} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||
{289277DE-09D4-A186-75D6-7FCA4A1BBAF1} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||
{0E556541-6A45-42CB-AE49-EE5A9BE05E7C} = {6C7F47CC-2151-44A3-A546-41C70025132C}
|
||||
{27D9CB3A-46D1-402C-9273-F88CB8AC42F7} = {9873BA05-4C41-4819-9283-CF45D795431B}
|
||||
{B9617A31-0F0A-4397-851D-BF2FBEE32D7F} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
|
||||
{1C48CD47-D610-463A-A53C-AF82DD6C47E7} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
||||
{D9BD324E-1D80-44AA-8E7B-73EB00944434} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||
{8EF25507-2575-4ADE-BF7E-D23376903AB8} = {3846508C-77EB-4034-A702-F8BB263C4F79}
|
||||
{070AC093-C9F2-20AD-0BCD-F318FC2761EA} = {B1234567-1234-1234-1234-123456789ABC}
|
||||
{2C318EC3-BA86-4372-B1BC-DB0F33C208B2} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
||||
{BFFB607F-7C78-434B-86B9-DA4C8196A1B5} = {B6C42F16-73EB-477E-8B0D-4E6CF6C20AAC}
|
||||
{66E1534A-1587-42B2-912F-45C994D32904} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
|
||||
{E885E71F-0B34-4A03-B13B-20F4E05E90BB} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
{264B412F-DB8B-4CF8-A74B-96998B183045} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
|
||||
{3527BF37-DFC5-4309-A032-29278CA21328} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
|
||||
{6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{68328142-5B31-4715-BCBB-7B6345EE0971} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
|
||||
{4122388B-59E4-CDB0-0338-EA6881DF86F0} = {27D9CB3A-46D1-402C-9273-F88CB8AC42F7}
|
||||
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55} = {27D9CB3A-46D1-402C-9273-F88CB8AC42F7}
|
||||
{6748A29D-DA6A-033A-825B-752295FF6AA0} = {8EF25507-2575-4ADE-BF7E-D23376903AB8}
|
||||
{6EABCF9A-6526-441F-932F-658B1DC3E403} = {264B412F-DB8B-4CF8-A74B-96998B183045}
|
||||
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15} = {264B412F-DB8B-4CF8-A74B-96998B183045}
|
||||
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83} = {264B412F-DB8B-4CF8-A74B-96998B183045}
|
||||
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9} = {264B412F-DB8B-4CF8-A74B-96998B183045}
|
||||
{F93C2817-C846-4259-84D8-B39A6B57C8DE} = {3527BF37-DFC5-4309-A032-29278CA21328}
|
||||
{8131151D-B0E9-4E18-84A5-E5F946C4480A} = {929C1324-22E8-4412-A9A8-80E85F3985A5}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||
|
||||
@@ -68,7 +68,7 @@ The PowerToys UI test pipeline provides flexible options for building and testin
|
||||
- Pipeline: https://microsoft.visualstudio.com/Dart/_build?definitionId=161438&_a=summary
|
||||
|
||||
## How to add the first UI tests for your modules
|
||||
|
||||
- Follow the naming convention: 
|
||||
- Create a new project and add the following references to the project file. Change the OutputPath to your own module's path.
|
||||
```
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
@@ -87,6 +87,13 @@
|
||||
|
||||
### Building PowerToys Locally
|
||||
|
||||
#### One stop script for building installer
|
||||
1. Open developer powershell for vs 2022
|
||||
2. Run tools\build\build-installer.ps1
|
||||
> For the first-time setup, please run the installer as an administrator. This ensures that the Wix tool can move wix.target to the desired location and trust the certificate used to sign the MSIX packages.
|
||||
|
||||
The following manual steps will not install the MSIX apps (such as Command Palette) on your local installer.
|
||||
|
||||
#### Prerequisites for building the MSI installer
|
||||
|
||||
1. Install the [WiX Toolset Visual Studio 2022 Extension](https://marketplace.visualstudio.com/items?itemName=WixToolset.WixToolsetVisualStudio2022Extension).
|
||||
|
||||
33
doc/devdocs/development/test-winget-install-locally.md
Normal file
33
doc/devdocs/development/test-winget-install-locally.md
Normal file
@@ -0,0 +1,33 @@
|
||||
## If for any reason, you'd like to test winget install scenario, you can follow this doc:
|
||||
|
||||
### Powertoys winget manifest definition:
|
||||
[winget repository](https://github.com/microsoft/winget-pkgs/tree/master/manifests/m/Microsoft/PowerToys)
|
||||
|
||||
### How to test a winget installation locally:
|
||||
1. Get artifacts from release CI pipeline Pipelines - Runs for PowerToys Signed YAML Release Build, or you can build one yourself by execute the
|
||||
'tools\build\build-installer.ps1' script
|
||||
|
||||
2. Get the artifact hash, this is required to define winget manifest
|
||||
```powershell
|
||||
cd /path/to/your/directory/contains/installer
|
||||
Get-FileHash -Path ".\<Installer-name>.exe" -Algorithm SHA256
|
||||
```
|
||||
3. Host your installer.exe - Attention: staged github release artifacts or artifacts in release pipeline is not OK in this step
|
||||
You can self-host it or you can upload to a publicly available endpoint
|
||||
**How to selfhost it** (A extremely simple way):
|
||||
```powershell
|
||||
python -m http.server 8000
|
||||
```
|
||||
|
||||
4. Download a version folder from wingetpkgs like: [version 0.92.1](https://github.com/microsoft/winget-pkgs/tree/master/manifests/m/Microsoft/PowerToys/0.92.1)
|
||||
and you get **a folder contains 3 yml files**
|
||||
>note: Do not put any files other than these three in this folder
|
||||
|
||||
5. Modify the yml files based on your version and the self hosted artifact link, and modify the sha256 hash for the installer you'd like to use
|
||||
|
||||
6. Start winget install:
|
||||
```powershell
|
||||
#execute as admin
|
||||
winget settings --enable LocalManifestFiles
|
||||
winget install --manifest "<folder_path_of_manifest_files>" --architecture x64 --scope user
|
||||
```
|
||||
BIN
doc/devdocs/images/uitests/naming.png
Normal file
BIN
doc/devdocs/images/uitests/naming.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
@@ -67,10 +67,7 @@ Once you've discussed your proposed feature/fix/etc. with a team member, and an
|
||||
- When you'd like the team to take a look (even if the work is not yet fully complete) mark the PR as 'Ready For Review' so that the team can review your work and provide comments, suggestions, and request changes. It may take several cycles, but the end result will be solid, testable, conformant code that is safe for us to merge.
|
||||
- When the PR is approved, let the owner of the PR merge it. For community contributions, the reviewer who approved the PR can also merge it.
|
||||
- Use the `Squash and merge` option to merge a PR. If you don't want to squash it because there are logically different commits, use `Rebase and merge`.
|
||||
- We don't close issues automatically when referenced in a PR, so after the PR is merged:
|
||||
- mark the issue(s) that the PR solved with the `Resolution-Fix-Committed` label, remove the `In progress` label and if the issue is assigned to a project, move the item to the `Done` status.
|
||||
- don't close the issue if it's a bug in the current released version; since users tend to not search for closed issues, we will close the resolved issues when a new version is released.
|
||||
- if it's not a code fix that effects the end user, the issue can be closed (for example a fix in the build or a code refactoring and so on).
|
||||
- Close issues automatically when referenced in a PR. You can use [closing keywords](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) in the body of the PR to have GitHub automatically link your PR to the issue.
|
||||
|
||||
## Compiling PowerToys
|
||||
|
||||
|
||||
@@ -24,5 +24,16 @@ namespace Microsoft.PowerToys.UITest
|
||||
{
|
||||
this.Find<NavigationViewItem>(value).Click();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Select a text item from the ComboBox.
|
||||
/// </summary>
|
||||
/// <param name="value">The text to select from the ComboBox.</param>
|
||||
public void SelectTxt(string value)
|
||||
{
|
||||
this.Click(); // First click to expand the ComboBox
|
||||
Thread.Sleep(100); // Wait for the dropdown to appear
|
||||
this.Find<Element>(value).Click(); // Find and click the text item using basic Element type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,7 +364,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
/// Save UI Element to a PNG file.
|
||||
/// </summary>
|
||||
/// <param name="path">the full path</param>
|
||||
internal void SaveToPngFile(string path)
|
||||
public void SaveToPngFile(string path)
|
||||
{
|
||||
Assert.IsNotNull(this.windowsElement, $"WindowsElement is null in method SaveToPngFile with parameter: path = {path}");
|
||||
this.windowsElement.GetScreenshot().SaveAsFile(path);
|
||||
|
||||
38
src/common/UITestAutomation/Element/RadioButton.cs
Normal file
38
src/common/UITestAutomation/Element/RadioButton.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.PowerToys.UITest
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a radio button UI element in the application.
|
||||
/// </summary>
|
||||
public class RadioButton : Element
|
||||
{
|
||||
private static readonly string ExpectedControlType = "ControlType.RadioButton";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RadioButton"/> class.
|
||||
/// </summary>
|
||||
public RadioButton()
|
||||
{
|
||||
this.TargetControlType = RadioButton.ExpectedControlType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the RadioButton is selected.
|
||||
/// </summary>
|
||||
public bool IsSelected => this.Selected;
|
||||
|
||||
/// <summary>
|
||||
/// Select the RadioButton.
|
||||
/// </summary>
|
||||
public void Select()
|
||||
{
|
||||
if (!this.IsSelected)
|
||||
{
|
||||
this.Click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
Runner,
|
||||
Workspaces,
|
||||
PowerRename,
|
||||
CommandPalette,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -104,6 +105,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
[PowerToysModule.Runner] = new ModuleInfo("PowerToys.exe", "PowerToys"),
|
||||
[PowerToysModule.Workspaces] = new ModuleInfo("PowerToys.WorkspacesEditor.exe", "Workspaces Editor"),
|
||||
[PowerToysModule.PowerRename] = new ModuleInfo("PowerToys.PowerRename.exe", "PowerRename", "WinUI3Apps"),
|
||||
[PowerToysModule.CommandPalette] = new ModuleInfo("Microsoft.CmdPal.UI.exe", "PowerToys Command Palette", "WinUI3Apps\\CmdPal"),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -91,15 +91,12 @@ namespace Microsoft.PowerToys.UITest
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exit a exe.
|
||||
/// Exit a exe by Name.
|
||||
/// </summary>
|
||||
/// <param name="appPath">The path to the application executable.</param>
|
||||
public void ExitExe(string appPath)
|
||||
/// <param name="processName">The path to the application executable.</param>
|
||||
public void ExitExeByName(string processName)
|
||||
{
|
||||
// Exit Exe
|
||||
string exeName = Path.GetFileNameWithoutExtension(appPath);
|
||||
|
||||
Process[] processes = Process.GetProcessesByName(exeName);
|
||||
Process[] processes = Process.GetProcessesByName(processName);
|
||||
foreach (Process process in processes)
|
||||
{
|
||||
try
|
||||
@@ -114,6 +111,18 @@ namespace Microsoft.PowerToys.UITest
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exit a exe.
|
||||
/// </summary>
|
||||
/// <param name="appPath">The path to the application executable.</param>
|
||||
public void ExitExe(string appPath)
|
||||
{
|
||||
// Exit Exe
|
||||
string exeName = Path.GetFileNameWithoutExtension(appPath);
|
||||
|
||||
ExitExeByName(exeName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a new exe and takes control of it.
|
||||
/// </summary>
|
||||
@@ -122,26 +131,34 @@ namespace Microsoft.PowerToys.UITest
|
||||
public void StartExe(string appPath, string[]? args = null)
|
||||
{
|
||||
var opts = new AppiumOptions();
|
||||
opts.AddAdditionalCapability("app", appPath);
|
||||
|
||||
if (args != null && args.Length > 0)
|
||||
if (scope == PowerToysModule.PowerToysSettings)
|
||||
{
|
||||
// Build command line arguments string
|
||||
string argsString = string.Join(" ", args.Select(arg =>
|
||||
TryLaunchPowerToysSettings(opts);
|
||||
}
|
||||
else
|
||||
{
|
||||
opts.AddAdditionalCapability("app", appPath);
|
||||
|
||||
if (args != null && args.Length > 0)
|
||||
{
|
||||
// Quote arguments that contain spaces
|
||||
if (arg.Contains(' '))
|
||||
// Build command line arguments string
|
||||
string argsString = string.Join(" ", args.Select(arg =>
|
||||
{
|
||||
return $"\"{arg}\"";
|
||||
}
|
||||
// Quote arguments that contain spaces
|
||||
if (arg.Contains(' '))
|
||||
{
|
||||
return $"\"{arg}\"";
|
||||
}
|
||||
|
||||
return arg;
|
||||
}));
|
||||
return arg;
|
||||
}));
|
||||
|
||||
opts.AddAdditionalCapability("appArguments", argsString);
|
||||
opts.AddAdditionalCapability("appArguments", argsString);
|
||||
}
|
||||
}
|
||||
|
||||
this.Driver = NewWindowsDriver(opts);
|
||||
Driver = NewWindowsDriver(opts);
|
||||
}
|
||||
|
||||
private void TryLaunchPowerToysSettings(AppiumOptions opts)
|
||||
@@ -150,15 +167,18 @@ namespace Microsoft.PowerToys.UITest
|
||||
|
||||
var runnerProcessInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = locationPath + this.runnerPath,
|
||||
FileName = locationPath + runnerPath,
|
||||
Verb = "runas",
|
||||
Arguments = "--open-settings",
|
||||
};
|
||||
|
||||
this.ExitExe(runnerProcessInfo.FileName);
|
||||
this.runner = Process.Start(runnerProcessInfo);
|
||||
ExitExe(runnerProcessInfo.FileName);
|
||||
runner = Process.Start(runnerProcessInfo);
|
||||
Thread.Sleep(5000);
|
||||
|
||||
// Exit CmdPal UI before launching new process if use installer for test
|
||||
ExitExeByName("Microsoft.CmdPal.UI");
|
||||
|
||||
if (root != null)
|
||||
{
|
||||
const int maxRetries = 5;
|
||||
@@ -168,7 +188,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
for (int attempt = 1; attempt <= maxRetries; attempt++)
|
||||
{
|
||||
var settingsWindow = ApiHelper.FindDesktopWindowHandler(
|
||||
new[] { windowName, AdministratorPrefix + windowName });
|
||||
[windowName, AdministratorPrefix + windowName]);
|
||||
|
||||
if (settingsWindow.Count > 0)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
<PackageReference Include="System.Private.Uri" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" />
|
||||
<PackageReference Include="CoenM.ImageSharp.ImageHash" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Microsoft.PowerToys.UITest
|
||||
|
||||
public bool IsInPipeline { get; }
|
||||
|
||||
public string? ScreenshotDirectory { get; set; }
|
||||
|
||||
public static MonitorInfoData.ParamsWrapper MonitorInfoData { get; set; } = new MonitorInfoData.ParamsWrapper() { Monitors = new List<MonitorInfoData.MonitorInfoDataWrapper>() };
|
||||
|
||||
private readonly PowerToysModule scope;
|
||||
@@ -29,7 +31,6 @@ namespace Microsoft.PowerToys.UITest
|
||||
private readonly string[]? commandLineArgs;
|
||||
private SessionHelper? sessionHelper;
|
||||
private System.Threading.Timer? screenshotTimer;
|
||||
private string? screenshotDirectory;
|
||||
|
||||
public UITestBase(PowerToysModule scope = PowerToysModule.PowerToysSettings, WindowSize size = WindowSize.UnSpecified, string[]? commandLineArgs = null)
|
||||
{
|
||||
@@ -58,11 +59,11 @@ namespace Microsoft.PowerToys.UITest
|
||||
CloseOtherApplications();
|
||||
if (IsInPipeline)
|
||||
{
|
||||
screenshotDirectory = Path.Combine(this.TestContext.TestResultsDirectory ?? string.Empty, "UITestScreenshots_" + Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(screenshotDirectory);
|
||||
ScreenshotDirectory = Path.Combine(this.TestContext.TestResultsDirectory ?? string.Empty, "UITestScreenshots_" + Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(ScreenshotDirectory);
|
||||
|
||||
// Take screenshot every 1 second
|
||||
screenshotTimer = new System.Threading.Timer(ScreenCapture.TimerCallback, screenshotDirectory, TimeSpan.Zero, TimeSpan.FromMilliseconds(1000));
|
||||
screenshotTimer = new System.Threading.Timer(ScreenCapture.TimerCallback, ScreenshotDirectory, TimeSpan.Zero, TimeSpan.FromMilliseconds(1000));
|
||||
|
||||
// Escape Popups before starting
|
||||
System.Windows.Forms.SendKeys.SendWait("{ESC}");
|
||||
@@ -415,9 +416,9 @@ namespace Microsoft.PowerToys.UITest
|
||||
|
||||
protected void AddScreenShotsToTestResultsDirectory()
|
||||
{
|
||||
if (screenshotDirectory != null)
|
||||
if (ScreenshotDirectory != null)
|
||||
{
|
||||
foreach (string file in Directory.GetFiles(screenshotDirectory))
|
||||
foreach (string file in Directory.GetFiles(ScreenshotDirectory))
|
||||
{
|
||||
this.TestContext.AddResultFile(file);
|
||||
}
|
||||
@@ -627,6 +628,23 @@ namespace Microsoft.PowerToys.UITest
|
||||
Console.WriteLine($"Failed to change display resolution. Error code: {result}");
|
||||
}
|
||||
}
|
||||
|
||||
// Windows API for moving windows
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
|
||||
|
||||
private const uint SWPNOSIZE = 0x0001;
|
||||
private const uint SWPNOZORDER = 0x0004;
|
||||
|
||||
public static void MoveWindow(Element window, int x, int y)
|
||||
{
|
||||
var windowHandle = IntPtr.Parse(window.GetAttribute("NativeWindowHandle") ?? "0", System.Globalization.CultureInfo.InvariantCulture);
|
||||
if (windowHandle != IntPtr.Zero)
|
||||
{
|
||||
SetWindowPos(windowHandle, IntPtr.Zero, x, y, 0, 0, SWPNOSIZE | SWPNOZORDER);
|
||||
Task.Delay(500).Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,11 @@ using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using CoenM.ImageHash;
|
||||
using CoenM.ImageHash.HashAlgorithms;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
|
||||
namespace Microsoft.PowerToys.UITest
|
||||
{
|
||||
@@ -127,34 +131,75 @@ namespace Microsoft.PowerToys.UITest
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if two images are equal bit-by-bit
|
||||
/// Test if two images are equal using ImageHash comparison
|
||||
/// </summary>
|
||||
/// <param name="baselineImage">baseline image</param>
|
||||
/// <param name="testImage">test image</param>
|
||||
/// <returns>true if are equal,otherwise false</returns>
|
||||
private static bool AreEqual(Bitmap baselineImage, Bitmap testImage)
|
||||
{
|
||||
if (baselineImage.Width != testImage.Width || baselineImage.Height != testImage.Height)
|
||||
try
|
||||
{
|
||||
return false;
|
||||
// Define a threshold for similarity percentage
|
||||
const int SimilarityThreshold = 95;
|
||||
|
||||
// Use CoenM.ImageHash for perceptual hash comparison
|
||||
var hashAlgorithm = new AverageHash();
|
||||
|
||||
// Convert System.Drawing.Bitmap to SixLabors.ImageSharp.Image
|
||||
using var baselineImageSharp = ConvertBitmapToImageSharp(baselineImage);
|
||||
using var testImageSharp = ConvertBitmapToImageSharp(testImage);
|
||||
|
||||
// Calculate hashes for both images
|
||||
var baselineHash = hashAlgorithm.Hash(baselineImageSharp);
|
||||
var testHash = hashAlgorithm.Hash(testImageSharp);
|
||||
|
||||
// Compare hashes using CompareHash method
|
||||
// Returns similarity percentage (0-100, where 100 is identical)
|
||||
var similarity = CompareHash.Similarity(baselineHash, testHash);
|
||||
|
||||
// Consider images equal if similarity is very high
|
||||
// Allow for minor rendering differences (threshold can be adjusted)
|
||||
return similarity >= SimilarityThreshold; // 95% similarity threshold
|
||||
}
|
||||
|
||||
// WinAppDriver sometimes adds a border to the screenshot (around 2 pix width), and it is not always consistent.
|
||||
// So we exclude the border when comparing the images, and usually it is the edge of the windows, won't affect the comparison.
|
||||
int excludeBorderWidth = 5, excludeBorderHeight = 5;
|
||||
|
||||
for (int x = excludeBorderWidth; x < baselineImage.Width - excludeBorderWidth; x++)
|
||||
catch
|
||||
{
|
||||
for (int y = excludeBorderHeight; y < baselineImage.Height - excludeBorderHeight; y++)
|
||||
// Fallback to pixel-by-pixel comparison if hash comparison fails
|
||||
if (baselineImage.Width != testImage.Width || baselineImage.Height != testImage.Height)
|
||||
{
|
||||
if (!VisualHelper.PixIsSame(baselineImage.GetPixel(x, y), testImage.GetPixel(x, y)))
|
||||
return false;
|
||||
}
|
||||
|
||||
// WinAppDriver sometimes adds a border to the screenshot (around 2 pix width), and it is not always consistent.
|
||||
// So we exclude the border when comparing the images, and usually it is the edge of the windows, won't affect the comparison.
|
||||
int excludeBorderWidth = 5, excludeBorderHeight = 5;
|
||||
|
||||
for (int x = excludeBorderWidth; x < baselineImage.Width - excludeBorderWidth; x++)
|
||||
{
|
||||
for (int y = excludeBorderHeight; y < baselineImage.Height - excludeBorderHeight; y++)
|
||||
{
|
||||
return false;
|
||||
if (!VisualHelper.PixIsSame(baselineImage.GetPixel(x, y), testImage.GetPixel(x, y)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert System.Drawing.Bitmap to SixLabors.ImageSharp.Image
|
||||
/// </summary>
|
||||
/// <param name="bitmap">The bitmap to convert</param>
|
||||
/// <returns>ImageSharp Image</returns>
|
||||
private static Image<Rgba32> ConvertBitmapToImageSharp(Bitmap bitmap)
|
||||
{
|
||||
using var memoryStream = new MemoryStream();
|
||||
bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
|
||||
memoryStream.Position = 0;
|
||||
return SixLabors.ImageSharp.Image.Load<Rgba32>(memoryStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>UnitTestsCommonLib</RootNamespace>
|
||||
<ProjectSubType>NativeUnitTestProject</ProjectSubType>
|
||||
<ProjectName>Common.Lib.UnitTests</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<!-- Look at Directory.Build.props in root for common stuff as well -->
|
||||
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{2B1505FA-132A-460B-B22B-7CC3FFAB0C5D}</ProjectGuid>
|
||||
<RootNamespace>Microsoft.AdvancedPaste.UITests</RootNamespace>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
<!-- This is a UI test, so don't run as part of MSBuild -->
|
||||
<RunVSTest>false</RunVSTest>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\tests\UITests-AdvancedPaste\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Appium.WebDriver" />
|
||||
<PackageReference Include="MSTest" />
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
<PackageReference Include="System.Private.Uri" />
|
||||
<PackageReference Include="System.Text.RegularExpressions" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="TestFiles\**\*.*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,791 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using Microsoft.AdvancedPaste.UITests.Helper;
|
||||
using Microsoft.CodeCoverage.Core.Reports.Coverage;
|
||||
using Microsoft.PowerToys.UITest;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OpenQA.Selenium;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
using static System.Resources.ResXFileRef;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolTip;
|
||||
|
||||
namespace Microsoft.AdvancedPaste.UITests
|
||||
{
|
||||
[TestClass]
|
||||
public class AdvancedPasteUITest : UITestBase
|
||||
{
|
||||
private readonly string testFilesFolderPath;
|
||||
private readonly string tempRTFFileName = "TempFile.rtf";
|
||||
private readonly string pasteAsPlainTextRawFileName = "PasteAsPlainTextFileRaw.rtf";
|
||||
private readonly string pasteAsPlainTextPlainFileName = "PasteAsPlainTextFilePlain.rtf";
|
||||
private readonly string pasteAsPlainTextPlainNoRepeatFileName = "PasteAsPlainTextFilePlainNoRepeat.rtf";
|
||||
private readonly string wordpadPath = @"C:\Program Files\wordpad\wordpad.exe";
|
||||
|
||||
private readonly string tempTxtFileName = "TempFile.txt";
|
||||
private readonly string pasteAsMarkdownSrcFile = "PasteAsMarkdownFile.html";
|
||||
private readonly string pasteAsMarkdownResultFile = "PasteAsMarkdownResultFile.txt";
|
||||
|
||||
private readonly string pasteAsJsonFileName = "PasteAsJsonFile.xml";
|
||||
private readonly string pasteAsJsonResultFile = "PasteAsJsonResultFile.txt";
|
||||
|
||||
private bool _notepadSettingsChanged;
|
||||
|
||||
// Static constructor - runs before any instance is created
|
||||
static AdvancedPasteUITest()
|
||||
{
|
||||
// Using the predefined settings.
|
||||
// paste as plain text: win + ctrl + alt + o
|
||||
// paste as markdown text: win + ctrl + alt + m
|
||||
// paste as json text: win + ctrl + alt + j
|
||||
CopySettingsFileBeforeTests();
|
||||
}
|
||||
|
||||
public AdvancedPasteUITest()
|
||||
: base(PowerToysModule.PowerToysSettings, size: WindowSize.Small)
|
||||
{
|
||||
Type currentTestType = typeof(AdvancedPasteUITest);
|
||||
string? dirName = Path.GetDirectoryName(currentTestType.Assembly.Location);
|
||||
Assert.IsNotNull(dirName, "Failed to get directory name of the current test assembly.");
|
||||
|
||||
string testFilesFolder = Path.Combine(dirName, "TestFiles");
|
||||
Assert.IsTrue(Directory.Exists(testFilesFolder), $"Test files directory not found at: {testFilesFolder}");
|
||||
|
||||
testFilesFolderPath = testFilesFolder;
|
||||
|
||||
// ignore the notepad settings in pipeline
|
||||
_notepadSettingsChanged = true;
|
||||
}
|
||||
|
||||
[TestInitialize]
|
||||
public void TestInitialize()
|
||||
{
|
||||
Session.CloseMainWindow();
|
||||
SendKeys(Key.Win, Key.M);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("AdvancedPasteUITest")]
|
||||
[TestCategory("PasteAsPlainText")]
|
||||
[Ignore("Temporarily disabled due to wordpad.exe is missing in pipeline.")]
|
||||
public void TestCasePasteAsPlainText()
|
||||
{
|
||||
// Copy some rich text(e.g word of the text is different color, another work is bold, underlined, etd.).
|
||||
// Paste the text using standard Windows Ctrl + V shortcut and ensure that rich text is pasted(with all colors, formatting, etc.)
|
||||
DeleteAndCopyFile(pasteAsPlainTextRawFileName, tempRTFFileName);
|
||||
ContentCopyAndPasteDirectly(tempRTFFileName, isRTF: true);
|
||||
|
||||
var resultWithFormatting = FileReader.CompareRtfFiles(
|
||||
Path.Combine(testFilesFolderPath, tempRTFFileName),
|
||||
Path.Combine(testFilesFolderPath, pasteAsPlainTextRawFileName),
|
||||
compareFormatting: true);
|
||||
|
||||
Assert.IsTrue(resultWithFormatting.IsConsistent, "RTF files should be identical including formatting");
|
||||
|
||||
// Paste the text using Paste As Plain Text activation shortcut and ensure that plain text without any formatting is pasted.
|
||||
// Paste again the text using standard Windows Ctrl + V shortcut and ensure the text is now pasted plain without formatting as well.
|
||||
DeleteAndCopyFile(pasteAsPlainTextRawFileName, tempRTFFileName);
|
||||
ContentCopyAndPasteWithShortcutThenPasteAgain(tempRTFFileName, isRTF: true);
|
||||
resultWithFormatting = FileReader.CompareRtfFiles(
|
||||
Path.Combine(testFilesFolderPath, tempRTFFileName),
|
||||
Path.Combine(testFilesFolderPath, pasteAsPlainTextPlainFileName),
|
||||
compareFormatting: true);
|
||||
Assert.IsTrue(resultWithFormatting.IsConsistent, "RTF files should be identical without formatting");
|
||||
|
||||
// Copy some rich text again.
|
||||
// Open Advanced Paste window using hotkey, click Paste as Plain Text button and confirm that plain text without any formatting is pasted.
|
||||
DeleteAndCopyFile(pasteAsPlainTextRawFileName, tempRTFFileName);
|
||||
ContentCopyAndPasteCase3(tempRTFFileName, isRTF: true);
|
||||
resultWithFormatting = FileReader.CompareRtfFiles(
|
||||
Path.Combine(testFilesFolderPath, tempRTFFileName),
|
||||
Path.Combine(testFilesFolderPath, pasteAsPlainTextPlainNoRepeatFileName),
|
||||
compareFormatting: true);
|
||||
Assert.IsTrue(resultWithFormatting.IsConsistent, "RTF files should be identical without formatting");
|
||||
|
||||
// Copy some rich text again.
|
||||
// Open Advanced Paste window using hotkey, press Ctrl + 1 and confirm that plain text without any formatting is pasted.
|
||||
DeleteAndCopyFile(pasteAsPlainTextRawFileName, tempRTFFileName);
|
||||
ContentCopyAndPasteCase4(tempRTFFileName, isRTF: true);
|
||||
resultWithFormatting = FileReader.CompareRtfFiles(
|
||||
Path.Combine(testFilesFolderPath, tempRTFFileName),
|
||||
Path.Combine(testFilesFolderPath, pasteAsPlainTextPlainNoRepeatFileName),
|
||||
compareFormatting: true);
|
||||
Assert.IsTrue(resultWithFormatting.IsConsistent, "RTF files should be identical without formatting");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("AdvancedPasteUITest")]
|
||||
[TestCategory("PasteAsMarkdownCase1")]
|
||||
public void TestCasePasteAsMarkdownCase1()
|
||||
{
|
||||
if (_notepadSettingsChanged == false)
|
||||
{
|
||||
ChangeNotePadSettings();
|
||||
}
|
||||
|
||||
// Copy some text(e.g.some HTML text - convertible to Markdown)
|
||||
// Paste the text using set hotkey and confirm that pasted text is converted to markdown
|
||||
DeleteAndCopyFile(pasteAsMarkdownSrcFile, tempTxtFileName);
|
||||
ContentCopyAndPasteAsMarkdownCase1(tempTxtFileName);
|
||||
var result = FileReader.CompareRtfFiles(
|
||||
Path.Combine(testFilesFolderPath, tempTxtFileName),
|
||||
Path.Combine(testFilesFolderPath, pasteAsMarkdownResultFile),
|
||||
compareFormatting: true);
|
||||
Assert.IsTrue(result.IsConsistent, "Paste as markdown using shortcut failed.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("AdvancedPasteUITest")]
|
||||
[TestCategory("PasteAsMarkdownCase2")]
|
||||
public void TestCasePasteAsMarkdownCase2()
|
||||
{
|
||||
if (_notepadSettingsChanged == false)
|
||||
{
|
||||
ChangeNotePadSettings();
|
||||
}
|
||||
|
||||
// Copy some text(same as in the previous step or different.If nothing is coppied between steps, previously pasted Markdown text will be picked up from clipboard and converted again to nested Markdown).
|
||||
// Open Advanced Paste window using hotkey, click Paste as markdown button and confirm that pasted text is converted to markdown
|
||||
DeleteAndCopyFile(pasteAsMarkdownSrcFile, tempTxtFileName);
|
||||
ContentCopyAndPasteAsMarkdownCase2(tempTxtFileName);
|
||||
var result = FileReader.CompareRtfFiles(
|
||||
Path.Combine(testFilesFolderPath, tempTxtFileName),
|
||||
Path.Combine(testFilesFolderPath, pasteAsMarkdownResultFile),
|
||||
compareFormatting: true);
|
||||
Assert.IsTrue(result.IsConsistent, "Paste as markdown using shortcut failed.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("AdvancedPasteUITest")]
|
||||
[TestCategory("PasteAsMarkdownCase3")]
|
||||
public void TestCasePasteAsMarkdownCase3()
|
||||
{
|
||||
if (_notepadSettingsChanged == false)
|
||||
{
|
||||
ChangeNotePadSettings();
|
||||
}
|
||||
|
||||
// Copy some text(same as in the previous step or different.If nothing is coppied between steps, previously pasted Markdown text will be picked up from clipboard and converted again to nested Markdown).
|
||||
// Open Advanced Paste window using hotkey, press Ctrl + 2 and confirm that pasted text is converted to markdown
|
||||
DeleteAndCopyFile(pasteAsMarkdownSrcFile, tempTxtFileName);
|
||||
ContentCopyAndPasteAsMarkdownCase3(tempTxtFileName);
|
||||
var result = FileReader.CompareRtfFiles(
|
||||
Path.Combine(testFilesFolderPath, tempTxtFileName),
|
||||
Path.Combine(testFilesFolderPath, pasteAsMarkdownResultFile),
|
||||
compareFormatting: true);
|
||||
Assert.IsTrue(result.IsConsistent, "Paste as markdown using shortcut failed.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("AdvancedPasteUITest")]
|
||||
[TestCategory("PasteAsJSONCase1")]
|
||||
public void TestCasePasteAsJSONCase1()
|
||||
{
|
||||
if (_notepadSettingsChanged == false)
|
||||
{
|
||||
ChangeNotePadSettings();
|
||||
}
|
||||
|
||||
// Copy some XML or CSV text(or any other text, it will be converted to simple JSON object)
|
||||
// Paste the text using set hotkey and confirm that pasted text is converted to JSON
|
||||
DeleteAndCopyFile(pasteAsJsonFileName, tempTxtFileName);
|
||||
ContentCopyAndPasteAsJsonCase1(tempTxtFileName);
|
||||
var result = FileReader.CompareRtfFiles(
|
||||
Path.Combine(testFilesFolderPath, tempTxtFileName),
|
||||
Path.Combine(testFilesFolderPath, pasteAsJsonResultFile),
|
||||
compareFormatting: true);
|
||||
Assert.IsTrue(result.IsConsistent, "Paste as Json using shortcut failed.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("AdvancedPasteUITest")]
|
||||
[TestCategory("PasteAsJSONCase2")]
|
||||
public void TestCasePasteAsJSONCase2()
|
||||
{
|
||||
if (_notepadSettingsChanged == false)
|
||||
{
|
||||
ChangeNotePadSettings();
|
||||
}
|
||||
|
||||
// Copy some text(same as in the previous step or different.If nothing is coppied between steps, previously pasted JSON text will be picked up from clipboard and converted again to nested JSON).
|
||||
// Open Advanced Paste window using hotkey, click Paste as markdown button and confirm that pasted text is converted to markdown
|
||||
DeleteAndCopyFile(pasteAsJsonFileName, tempTxtFileName);
|
||||
ContentCopyAndPasteAsJsonCase2(tempTxtFileName);
|
||||
var result = FileReader.CompareRtfFiles(
|
||||
Path.Combine(testFilesFolderPath, tempTxtFileName),
|
||||
Path.Combine(testFilesFolderPath, pasteAsJsonResultFile),
|
||||
compareFormatting: true);
|
||||
Assert.IsTrue(result.IsConsistent, "Paste as Json using shortcut failed.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory("AdvancedPasteUITest")]
|
||||
[TestCategory("PasteAsJSONCase3")]
|
||||
public void TestCasePasteAsJSONCase3()
|
||||
{
|
||||
if (_notepadSettingsChanged == false)
|
||||
{
|
||||
ChangeNotePadSettings();
|
||||
}
|
||||
|
||||
// Copy some text(same as in the previous step or different.If nothing is coppied between steps, previously pasted JSON text will be picked up from clipboard and converted again to nested JSON).
|
||||
// Open Advanced Paste window using hotkey, press Ctrl + 3 and confirm that pasted text is converted to markdown
|
||||
DeleteAndCopyFile(pasteAsJsonFileName, tempTxtFileName);
|
||||
ContentCopyAndPasteAsJsonCase3(tempTxtFileName);
|
||||
var result = FileReader.CompareRtfFiles(
|
||||
Path.Combine(testFilesFolderPath, tempTxtFileName),
|
||||
Path.Combine(testFilesFolderPath, pasteAsJsonResultFile),
|
||||
compareFormatting: true);
|
||||
Assert.IsTrue(result.IsConsistent, "Paste as Json using shortcut failed.");
|
||||
}
|
||||
|
||||
/*
|
||||
* Clipboard History
|
||||
- [] Open Settings and Enable clipboard history (if not enabled already). Open Advanced Paste window with hotkey, click Clipboard history and try deleting some entry. Check OS clipboard history (Win+V), and confirm that the same entry no longer exist.
|
||||
- [] Open Advanced Paste window with hotkey, click Clipboard history, and click any entry (but first). Observe that entry is put on top of clipboard history. Check OS clipboard history (Win+V), and confirm that the same entry is on top of the clipboard.
|
||||
- [] Open Settings and Disable clipboard history. Open Advanced Paste window with hotkey and observe that Clipboard history button is disabled.
|
||||
* Disable Advanced Paste, try different Advanced Paste hotkeys and confirm that it's disabled and nothing happens.
|
||||
*/
|
||||
private void TestCaseClipboardHistory()
|
||||
{
|
||||
}
|
||||
|
||||
private void ContentCopyAndPasteDirectly(string fileName, bool isRTF = false)
|
||||
{
|
||||
string tempFile = Path.Combine(testFilesFolderPath, fileName);
|
||||
|
||||
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
|
||||
if (process == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
|
||||
}
|
||||
|
||||
Thread.Sleep(15000);
|
||||
|
||||
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
|
||||
|
||||
window.Click();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.A);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.C);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.Delete);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.V);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.Backspace);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.S);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
process.Kill(true);
|
||||
}
|
||||
|
||||
private void ContentCopyAndPasteWithShortcutThenPasteAgain(string fileName, bool isRTF = false)
|
||||
{
|
||||
string tempFile = Path.Combine(testFilesFolderPath, fileName);
|
||||
|
||||
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
|
||||
if (process == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
|
||||
}
|
||||
|
||||
Thread.Sleep(15000);
|
||||
|
||||
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
|
||||
|
||||
window.Click();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.A);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.C);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.Delete);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.Win, Key.LCtrl, Key.Alt, Key.O);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.V);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.S);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
process.Kill(true);
|
||||
}
|
||||
|
||||
private void ContentCopyAndPasteCase3(string fileName, bool isRTF = false)
|
||||
{
|
||||
// Copy some rich text again.
|
||||
// Open Advanced Paste window using hotkey, click Paste as Plain Text button and confirm that plain text without any formatting is pasted.
|
||||
string tempFile = Path.Combine(testFilesFolderPath, fileName);
|
||||
|
||||
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
|
||||
if (process == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
|
||||
}
|
||||
|
||||
Thread.Sleep(15000);
|
||||
|
||||
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
|
||||
|
||||
window.Click();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.A);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.C);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.Delete);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// Open Advanced Paste window using hotkey
|
||||
this.SendKeys(Key.Win, Key.Shift, Key.V);
|
||||
Thread.Sleep(15000);
|
||||
|
||||
// Click Paste as Plain Text button and confirm that plain text without any formatting is pasted.
|
||||
var apWind = this.Find<Window>("Advanced Paste", global: true);
|
||||
apWind.Find<TextBlock>("Paste as plain text").Click();
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.S);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
process.Kill(true);
|
||||
}
|
||||
|
||||
private void ContentCopyAndPasteCase4(string fileName, bool isRTF = false)
|
||||
{
|
||||
// Copy some rich text again.
|
||||
// Open Advanced Paste window using hotkey, press Ctrl + 1 and confirm that plain text without any formatting is pasted.
|
||||
string tempFile = Path.Combine(testFilesFolderPath, fileName);
|
||||
|
||||
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
|
||||
if (process == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
|
||||
}
|
||||
|
||||
Thread.Sleep(15000);
|
||||
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
|
||||
|
||||
window.Click();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.A);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.C);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.Delete);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// Open Advanced Paste window using hotkey
|
||||
this.SendKeys(Key.Win, Key.Shift, Key.V);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// press Ctrl + 1 and confirm that plain text without any formatting is pasted.
|
||||
this.SendKeys(Key.LCtrl, Key.Num1);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.S);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
process.Kill(true);
|
||||
}
|
||||
|
||||
private void ContentCopyAndPasteAsMarkdownCase1(string fileName, bool isRTF = false)
|
||||
{
|
||||
// Copy some rich text again.
|
||||
// Open Advanced Paste window using hotkey, press Ctrl + 1 and confirm that plain text without any formatting is pasted.
|
||||
string tempFile = Path.Combine(testFilesFolderPath, fileName);
|
||||
|
||||
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
|
||||
if (process == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
|
||||
}
|
||||
|
||||
Thread.Sleep(15000);
|
||||
|
||||
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
|
||||
|
||||
window.Click();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.A);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.C);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.Delete);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.Win, Key.LCtrl, Key.Alt, Key.M);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.S);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
window.Close();
|
||||
}
|
||||
|
||||
private void ContentCopyAndPasteAsMarkdownCase2(string fileName, bool isRTF = false)
|
||||
{
|
||||
string tempFile = Path.Combine(testFilesFolderPath, fileName);
|
||||
|
||||
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
|
||||
if (process == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
|
||||
}
|
||||
|
||||
Thread.Sleep(15000);
|
||||
|
||||
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
|
||||
|
||||
window.Click();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.A);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.C);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.Delete);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// Open Advanced Paste window using hotkey
|
||||
this.SendKeys(Key.Win, Key.Shift, Key.V);
|
||||
Thread.Sleep(15000);
|
||||
|
||||
// click Paste as markdown button and confirm that pasted text is converted to markdown
|
||||
var apWind = this.Find<Window>("Advanced Paste", global: true);
|
||||
apWind.Find<TextBlock>("Paste as markdown").Click();
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.S);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
window.Close();
|
||||
}
|
||||
|
||||
private void ContentCopyAndPasteAsMarkdownCase3(string fileName, bool isRTF = false)
|
||||
{
|
||||
string tempFile = Path.Combine(testFilesFolderPath, fileName);
|
||||
|
||||
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
|
||||
if (process == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
|
||||
}
|
||||
|
||||
Thread.Sleep(15000);
|
||||
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
|
||||
|
||||
window.Click();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.A);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.C);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.Delete);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// Open Advanced Paste window using hotkey
|
||||
this.SendKeys(Key.Win, Key.Shift, Key.V);
|
||||
Thread.Sleep(15000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.Num2);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.S);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
window.Close();
|
||||
}
|
||||
|
||||
private void ContentCopyAndPasteAsJsonCase1(string fileName, bool isRTF = false)
|
||||
{
|
||||
// Copy some rich text again.
|
||||
// Open Advanced Paste window using hotkey, press Ctrl + 1 and confirm that plain text without any formatting is pasted.
|
||||
string tempFile = Path.Combine(testFilesFolderPath, fileName);
|
||||
|
||||
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
|
||||
if (process == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
|
||||
}
|
||||
|
||||
Thread.Sleep(15000);
|
||||
|
||||
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
|
||||
|
||||
window.Click();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.A);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.C);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.Delete);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.Win, Key.LCtrl, Key.Alt, Key.J);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.S);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
window.Close();
|
||||
}
|
||||
|
||||
private void ContentCopyAndPasteAsJsonCase2(string fileName, bool isRTF = false)
|
||||
{
|
||||
string tempFile = Path.Combine(testFilesFolderPath, fileName);
|
||||
|
||||
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
|
||||
if (process == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
|
||||
}
|
||||
|
||||
Thread.Sleep(15000);
|
||||
|
||||
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
|
||||
|
||||
window.Click();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.A);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.C);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.Delete);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// Open Advanced Paste window using hotkey
|
||||
this.SendKeys(Key.Win, Key.Shift, Key.V);
|
||||
Thread.Sleep(15000);
|
||||
|
||||
// click Paste as markdown button and confirm that pasted text is converted to markdown
|
||||
var apWind = this.Find<Window>("Advanced Paste", global: true);
|
||||
apWind.Find<TextBlock>("Paste as JSON").Click();
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.S);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
window.Close();
|
||||
}
|
||||
|
||||
private void ContentCopyAndPasteAsJsonCase3(string fileName, bool isRTF = false)
|
||||
{
|
||||
string tempFile = Path.Combine(testFilesFolderPath, fileName);
|
||||
|
||||
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
|
||||
if (process == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
|
||||
}
|
||||
|
||||
Thread.Sleep(15000);
|
||||
|
||||
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
|
||||
|
||||
window.Click();
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.A);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.LCtrl, Key.C);
|
||||
Thread.Sleep(1000);
|
||||
this.SendKeys(Key.Delete);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
// Open Advanced Paste window using hotkey
|
||||
this.SendKeys(Key.Win, Key.Shift, Key.V);
|
||||
Thread.Sleep(15000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.Num3);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
this.SendKeys(Key.LCtrl, Key.S);
|
||||
Thread.Sleep(1000);
|
||||
|
||||
window.Close();
|
||||
}
|
||||
|
||||
private string DeleteAndCopyFile(string sourceFileName, string destinationFileName)
|
||||
{
|
||||
string sourcePath = Path.Combine(testFilesFolderPath, sourceFileName);
|
||||
string destinationPath = Path.Combine(testFilesFolderPath, destinationFileName);
|
||||
|
||||
// Check if source file exists
|
||||
if (!File.Exists(sourcePath))
|
||||
{
|
||||
throw new FileNotFoundException($"Source file not found: {sourcePath}");
|
||||
}
|
||||
|
||||
// Delete destination file if it exists
|
||||
if (File.Exists(destinationPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(destinationPath);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new IOException($"Failed to delete file {destinationPath}. The file may be in use: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the source file to the destination
|
||||
try
|
||||
{
|
||||
File.Copy(sourcePath, destinationPath);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new IOException($"Failed to copy file from {sourcePath} to {destinationPath}: {ex.Message}", ex);
|
||||
}
|
||||
|
||||
return destinationPath;
|
||||
}
|
||||
|
||||
private void ChangeNotePadSettings()
|
||||
{
|
||||
Process process = Process.Start("notepad.exe");
|
||||
if (process == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to start Notepad.exe");
|
||||
}
|
||||
|
||||
Thread.Sleep(15000);
|
||||
|
||||
var window = FindWindowWithFlexibleTitle("Untitled", false);
|
||||
|
||||
window.Find<PowerToys.UITest.Button>("Settings").Click();
|
||||
var combobox = window.Find<PowerToys.UITest.ComboBox>("Opening files");
|
||||
combobox.SelectTxt("Open in a new window");
|
||||
|
||||
window.Find<Group>("When Notepad starts").Click();
|
||||
|
||||
window.Find<PowerToys.UITest.RadioButton>("Open a new window").Select();
|
||||
|
||||
_notepadSettingsChanged = true;
|
||||
window.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a window with flexible title matching, trying multiple title variations
|
||||
/// </summary>
|
||||
/// <param name="baseTitle">The base title to search for</param>
|
||||
/// <param name="isRTF">Whether the window is a WordPad window</param>
|
||||
/// <returns>The found Window element or throws an exception if not found</returns>
|
||||
private Window FindWindowWithFlexibleTitle(string baseTitle, bool isRTF)
|
||||
{
|
||||
Window? window = null;
|
||||
string appType = isRTF ? "WordPad" : "Notepad";
|
||||
|
||||
// Try different title variations
|
||||
string[] titleVariations = new string[]
|
||||
{
|
||||
baseTitle + (isRTF ? " - WordPad" : " - Notepad"), // With suffix
|
||||
baseTitle, // Without suffix
|
||||
Path.GetFileNameWithoutExtension(baseTitle) + (isRTF ? " - WordPad" : " - Notepad"), // Without extension, with suffix
|
||||
Path.GetFileNameWithoutExtension(baseTitle), // Without extension, without suffix
|
||||
};
|
||||
|
||||
Exception? lastException = null;
|
||||
|
||||
foreach (string title in titleVariations)
|
||||
{
|
||||
try
|
||||
{
|
||||
window = this.Find<Window>(title, global: true);
|
||||
if (window != null)
|
||||
{
|
||||
return window;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Save the exception, but continue trying other variations
|
||||
lastException = ex;
|
||||
}
|
||||
}
|
||||
|
||||
// If we couldn't find the window with any variation, throw an exception with details
|
||||
throw new InvalidOperationException(
|
||||
$"Failed to find {appType} window with title containing '{baseTitle}'. ");
|
||||
}
|
||||
|
||||
private static void CopySettingsFileBeforeTests()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Determine the assembly location and test files path
|
||||
string? assemblyLocation = Path.GetDirectoryName(typeof(AdvancedPasteUITest).Assembly.Location);
|
||||
if (assemblyLocation == null)
|
||||
{
|
||||
Debug.WriteLine("ERROR: Failed to get assembly location");
|
||||
return;
|
||||
}
|
||||
|
||||
string testFilesFolder = Path.Combine(assemblyLocation, "TestFiles");
|
||||
if (!Directory.Exists(testFilesFolder))
|
||||
{
|
||||
Debug.WriteLine($"ERROR: Test files directory not found at: {testFilesFolder}");
|
||||
return;
|
||||
}
|
||||
|
||||
// Settings file source path
|
||||
string settingsFileName = "settings.json";
|
||||
string sourceSettingsPath = Path.Combine(testFilesFolder, settingsFileName);
|
||||
|
||||
// Make sure the source file exists
|
||||
if (!File.Exists(sourceSettingsPath))
|
||||
{
|
||||
Debug.WriteLine($"ERROR: Settings file not found at: {sourceSettingsPath}");
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine the target directory in %LOCALAPPDATA%
|
||||
string targetDirectory = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||
"Microsoft",
|
||||
"PowerToys",
|
||||
"AdvancedPaste");
|
||||
|
||||
// Create the directory if it doesn't exist
|
||||
if (!Directory.Exists(targetDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(targetDirectory);
|
||||
}
|
||||
|
||||
string targetSettingsPath = Path.Combine(targetDirectory, settingsFileName);
|
||||
|
||||
// Copy the file and overwrite if it exists
|
||||
File.Copy(sourceSettingsPath, targetSettingsPath, true);
|
||||
|
||||
Debug.WriteLine($"Successfully copied settings file from {sourceSettingsPath} to {targetSettingsPath}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"ERROR copying settings file: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Microsoft.AdvancedPaste.UITests.Helper;
|
||||
|
||||
public class FileReader
|
||||
{
|
||||
public static string ReadContent(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
return File.ReadAllText(filePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to read file: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReadRTFPlainText(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var rtb = new System.Windows.Forms.RichTextBox())
|
||||
{
|
||||
rtb.Rtf = File.ReadAllText(filePath);
|
||||
return rtb.Text;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to read plain text from file: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the contents of two RTF files to check if they are consistent.
|
||||
/// </summary>
|
||||
/// <param name="firstFilePath">Path to the first RTF file</param>
|
||||
/// <param name="secondFilePath">Path to the second RTF file</param>
|
||||
/// <param name="compareFormatting">If true, compares the raw RTF content (including formatting).
|
||||
/// If false, compares only the plain text content.</param>
|
||||
/// <returns>
|
||||
/// A tuple containing: (bool isConsistent, string firstContent, string secondContent)
|
||||
/// - isConsistent: true if the files are consistent according to the comparison method
|
||||
/// - firstContent: the content of the first file
|
||||
/// - secondContent: the content of the second file
|
||||
/// </returns>
|
||||
public static (bool IsConsistent, string FirstContent, string SecondContent) CompareRtfFiles(
|
||||
string firstFilePath,
|
||||
string secondFilePath,
|
||||
bool compareFormatting = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
string firstContent, secondContent;
|
||||
|
||||
if (compareFormatting)
|
||||
{
|
||||
// Compare raw RTF content (including formatting)
|
||||
firstContent = ReadContent(firstFilePath);
|
||||
secondContent = ReadContent(secondFilePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Compare only the plain text content
|
||||
firstContent = ReadRTFPlainText(firstFilePath);
|
||||
secondContent = ReadRTFPlainText(secondFilePath);
|
||||
}
|
||||
|
||||
bool isConsistent = string.Equals(firstContent, secondContent, StringComparison.Ordinal);
|
||||
return (isConsistent, firstContent, secondContent);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to compare RTF files: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<note>
|
||||
<to>Tove</to>
|
||||
<from>Jani</from>
|
||||
<heading>Reminder</heading>
|
||||
<body>Don't forget me this weekend!</body>
|
||||
</note>
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"note": {
|
||||
"to": "Tove",
|
||||
"from": "Jani",
|
||||
"heading": "Reminder",
|
||||
"body": "Don't forget me this weekend!"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
|
||||
<h2 title="I'm a header">The title Attribute</h2>
|
||||
|
||||
<p title="I'm a tooltip">Mouse over this paragraph, to display the title attribute as a tooltip.</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
## The title Attribute
|
||||
|
||||
Mouse over this paragraph, to display the title attribute as a tooltip.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
{"properties":{"IsAdvancedAIEnabled":{"value":false},"ShowCustomPreview":{"value":true},"CloseAfterLosingFocus":{"value":false},"advanced-paste-ui-hotkey":{"win":true,"ctrl":false,"alt":false,"shift":true,"code":86,"key":""},"paste-as-plain-hotkey":{"win":true,"ctrl":true,"alt":true,"shift":false,"code":79,"key":""},"paste-as-markdown-hotkey":{"win":true,"ctrl":true,"alt":true,"shift":false,"code":77,"key":""},"paste-as-json-hotkey":{"win":true,"ctrl":true,"alt":true,"shift":false,"code":74,"key":""},"custom-actions":{"value":[]},"additional-actions":{"image-to-text":{"shortcut":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"isShown":true},"paste-as-file":{"isShown":true,"paste-as-txt-file":{"shortcut":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"isShown":true},"paste-as-png-file":{"shortcut":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"isShown":true},"paste-as-html-file":{"shortcut":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"isShown":true}},"transcode":{"isShown":true,"transcode-to-mp3":{"shortcut":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"isShown":true},"transcode-to-mp4":{"shortcut":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"isShown":true}}}},"name":"AdvancedPaste","version":"1"}
|
||||
@@ -0,0 +1,41 @@
|
||||
## [Advanced Paste](tests-checklist-template-advanced-paste-section.md)
|
||||
NOTES:
|
||||
When using Advanced Paste, make sure that window focused while starting/using Advanced paste is text editor or has text input field focused (e.g. Word).
|
||||
* Paste As Plain Text
|
||||
- [x] Copy some rich text (e.g word of the text is different color, another work is bold, underlined, etd.).
|
||||
- [x] Paste the text using standard Windows Ctrl + V shortcut and ensure that rich text is pasted (with all colors, formatting, etc.)
|
||||
- [x] Paste the text using Paste As Plain Text activation shortcut and ensure that plain text without any formatting is pasted.
|
||||
- [x] Paste again the text using standard Windows Ctrl + V shortcut and ensure the text is now pasted plain without formatting as well.
|
||||
- [x] Copy some rich text again.
|
||||
- [x] Open Advanced Paste window using hotkey, click Paste as Plain Text button and confirm that plain text without any formatting is pasted.
|
||||
- [x] Copy some rich text again.
|
||||
- [x] Open Advanced Paste window using hotkey, press Ctrl + 1 and confirm that plain text without any formatting is pasted.
|
||||
* Paste As Markdown
|
||||
- [] Open Settings and set Paste as Markdown directly hotkey
|
||||
- [x] Copy some text (e.g. some HTML text - convertible to Markdown)
|
||||
- [x] Paste the text using set hotkey and confirm that pasted text is converted to markdown
|
||||
- [x] Copy some text (same as in the previous step or different. If nothing is coppied between steps, previously pasted Markdown text will be picked up from clipboard and converted again to nested Markdown).
|
||||
- [x] Open Advanced Paste window using hotkey, click Paste as markdown button and confirm that pasted text is converted to markdown
|
||||
- [x] Copy some text (same as in the previous step or different. If nothing is coppied between steps, previously pasted Markdown text will be picked up from clipboard and converted again to nested Markdown).
|
||||
- [x] Open Advanced Paste window using hotkey, press Ctrl + 2 and confirm that pasted text is converted to markdown
|
||||
* Paste As JSON
|
||||
- [] Open Settings and set Paste as JSON directly hotkey
|
||||
- [x] Copy some XML or CSV text (or any other text, it will be converted to simple JSON object)
|
||||
- [x] Paste the text using set hotkey and confirm that pasted text is converted to JSON
|
||||
- [x] Copy some text (same as in the previous step or different. If nothing is coppied between steps, previously pasted JSON text will be picked up from clipboard and converted again to nested JSON).
|
||||
- [x] Open Advanced Paste window using hotkey, click Paste as markdown button and confirm that pasted text is converted to markdown
|
||||
- [x] Copy some text (same as in the previous step or different. If nothing is coppied between steps, previously pasted JSON text will be picked up from clipboard and converted again to nested JSON).
|
||||
- [x] Open Advanced Paste window using hotkey, press Ctrl + 3 and confirm that pasted text is converted to markdown
|
||||
* Paste as custom format using AI
|
||||
- [] Open Settings, navigate to Enable Paste with AI and set OpenAI key.
|
||||
- [] Copy some text to clipboard. Any text.
|
||||
- [] Open Advanced Paste window using hotkey, and confirm that Custom intput text box is now enabled. Write "Insert smiley after every word" and press Enter. Observe that result preview shows coppied text with smileys between words. Press Enter to paste the result and observe that it is pasted.
|
||||
- [] Open Advanced Paste window using hotkey. Input some query (any, feel free to play around) and press Enter. When result is shown, click regenerate button, to see if new result is generated. Select one of the results and paste. Observe that correct result is pasted.
|
||||
- [] Create few custom actions. Set up hotkey for custom actions and confirm they work. Enable/disable custom actions and confirm that the change is reflected in Advanced Paste UI - custom action is not listed. Try different ctrl + <num> in-app shortcuts for custom actions. Try moving custom actions up/down and confirm that the change is reflected in Advanced Paste UI.
|
||||
- [] Open Settings and disable Custom format preview. Open Advanced Paste window with hotkey, enter some query and press enter. Observe that result is now pasted right away, without showing the preview first.
|
||||
- [] Open Settings and Disable Enable Paste with AI. Open Advanced Paste window with hotkey and observe that Custom Input text box is now disabled.
|
||||
* Clipboard History
|
||||
- [] Open Settings and Enable clipboard history (if not enabled already). Open Advanced Paste window with hotkey, click Clipboard history and try deleting some entry. Check OS clipboard history (Win+V), and confirm that the same entry no longer exist.
|
||||
- [] Open Advanced Paste window with hotkey, click Clipboard history, and click any entry (but first). Observe that entry is put on top of clipboard history. Check OS clipboard history (Win+V), and confirm that the same entry is on top of the clipboard.
|
||||
- [] Open Settings and Disable clipboard history. Open Advanced Paste window with hotkey and observe that Clipboard history button is disabled.
|
||||
* Disable Advanced Paste, try different Advanced Paste hotkeys and confirm that it's disabled and nothing happens.
|
||||
@@ -4,8 +4,8 @@
|
||||
{
|
||||
"fuzzer": {
|
||||
"$type": "libfuzzerDotNet",
|
||||
"dll": "Hosts.FuzzTests.dll",
|
||||
"class": "Hosts.FuzzTests.FuzzTests",
|
||||
"dll": "HostsEditor.FuzzTests.dll",
|
||||
"class": "HostsEditor.FuzzTests.FuzzTests",
|
||||
"method": "FuzzValidIPv4",
|
||||
"FuzzingTargetBinaries": [
|
||||
"PowerToys.Hosts.dll"
|
||||
@@ -35,8 +35,8 @@
|
||||
// the DLL and PDB files
|
||||
// you will need to add any other files required
|
||||
// (globs are supported)
|
||||
"Hosts.FuzzTests.dll",
|
||||
"Hosts.FuzzTests.pdb",
|
||||
"HostsEditor.FuzzTests.dll",
|
||||
"HostsEditor.FuzzTests.pdb",
|
||||
"Microsoft.Windows.SDK.NET.dll",
|
||||
"WinRT.Runtime.dll"
|
||||
],
|
||||
@@ -45,8 +45,8 @@
|
||||
{
|
||||
"fuzzer": {
|
||||
"$type": "libfuzzerDotNet",
|
||||
"dll": "Hosts.FuzzTests.dll",
|
||||
"class": "Hosts.FuzzTests.FuzzTests",
|
||||
"dll": "HostsEditor.FuzzTests.dll",
|
||||
"class": "HostsEditor.FuzzTests.FuzzTests",
|
||||
"method": "FuzzValidIPv6",
|
||||
"FuzzingTargetBinaries": [
|
||||
"PowerToys.Hosts.dll"
|
||||
@@ -76,8 +76,8 @@
|
||||
// the DLL and PDB files
|
||||
// you will need to add any other files required
|
||||
// (globs are supported)
|
||||
"Hosts.FuzzTests.dll",
|
||||
"Hosts.FuzzTests.pdb",
|
||||
"HostsEditor.FuzzTests.dll",
|
||||
"HostsEditor.FuzzTests.pdb",
|
||||
"Microsoft.Windows.SDK.NET.dll",
|
||||
"WinRT.Runtime.dll"
|
||||
],
|
||||
@@ -86,8 +86,8 @@
|
||||
{
|
||||
"fuzzer": {
|
||||
"$type": "libfuzzerDotNet",
|
||||
"dll": "Hosts.FuzzTests.dll",
|
||||
"class": "Hosts.FuzzTests.FuzzTests",
|
||||
"dll": "HostsEditor.FuzzTests.dll",
|
||||
"class": "HostsEditor.FuzzTests.FuzzTests",
|
||||
"method": "FuzzValidHosts",
|
||||
"FuzzingTargetBinaries": [
|
||||
"PowerToys.Hosts.dll"
|
||||
@@ -117,8 +117,8 @@
|
||||
// the DLL and PDB files
|
||||
// you will need to add any other files required
|
||||
// (globs are supported)
|
||||
"Hosts.FuzzTests.dll",
|
||||
"Hosts.FuzzTests.pdb",
|
||||
"HostsEditor.FuzzTests.dll",
|
||||
"HostsEditor.FuzzTests.pdb",
|
||||
"Microsoft.Windows.SDK.NET.dll",
|
||||
"WinRT.Runtime.dll"
|
||||
],
|
||||
@@ -127,8 +127,8 @@
|
||||
{
|
||||
"fuzzer": {
|
||||
"$type": "libfuzzerDotNet",
|
||||
"dll": "Hosts.FuzzTests.dll",
|
||||
"class": "Hosts.FuzzTests.FuzzTests",
|
||||
"dll": "HostsEditor.FuzzTests.dll",
|
||||
"class": "HostsEditor.FuzzTests.FuzzTests",
|
||||
"method": "FuzzWriteAsync",
|
||||
"FuzzingTargetBinaries": [
|
||||
"PowerToys.Hosts.dll"
|
||||
@@ -160,8 +160,8 @@
|
||||
// (globs are supported)
|
||||
"Castle.Core.dll",
|
||||
"CommunityToolkit.Mvvm.dll",
|
||||
"Hosts.FuzzTests.dll",
|
||||
"Hosts.FuzzTests.pdb",
|
||||
"HostsEditor.FuzzTests.dll",
|
||||
"HostsEditor.FuzzTests.pdb",
|
||||
"Microsoft.Windows.SDK.NET.dll",
|
||||
"Moq.dll",
|
||||
"System.IO.Abstractions.dll",
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
|
||||
<PropertyGroup>
|
||||
<RootNamespace>PowerOCR.UITests</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>Library</OutputType>
|
||||
<RunVSTest>false</RunVSTest>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\tests\PowerOCR.UITests\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest" />
|
||||
<ProjectReference Include="..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
59
src/modules/PowerOCR/PowerOCR-UITests/PowerOCRTests.cs
Normal file
59
src/modules/PowerOCR/PowerOCR-UITests/PowerOCRTests.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.PowerToys.UITest;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using static Microsoft.PowerToys.UITest.UITestBase;
|
||||
|
||||
namespace PowerOCR.UITests;
|
||||
|
||||
[TestClass]
|
||||
public class PowerOCRTests : UITestBase
|
||||
{
|
||||
public PowerOCRTests()
|
||||
: base(PowerToysModule.PowerToysSettings, WindowSize.Medium)
|
||||
{
|
||||
}
|
||||
|
||||
[TestInitialize]
|
||||
public void TestInitialize()
|
||||
{
|
||||
if (FindAll<NavigationViewItem>("Text Extractor").Count == 0)
|
||||
{
|
||||
// Expand Advanced list-group if needed
|
||||
Find<NavigationViewItem>("System Tools").Click();
|
||||
}
|
||||
|
||||
Find<NavigationViewItem>("Text Extractor").Click();
|
||||
|
||||
Find<ToggleSwitch>("Enable Text Extractor").Toggle(true);
|
||||
|
||||
SendKeys(Key.Win, Key.D);
|
||||
}
|
||||
|
||||
[TestMethod("PowerOCR.DetectTextExtractor")]
|
||||
[TestCategory("PowerOCR Detection")]
|
||||
public void DetectTextExtractorTest()
|
||||
{
|
||||
try
|
||||
{
|
||||
SendKeys(Key.Win, Key.Shift, Key.T);
|
||||
|
||||
Thread.Sleep(5000);
|
||||
|
||||
var textExtractorWindow = Find("TextExtractor", 10000, true);
|
||||
|
||||
Assert.IsNotNull(textExtractorWindow, "TextExtractor window should be found after hotkey activation");
|
||||
|
||||
Console.WriteLine("✓ TextExtractor window detected successfully after hotkey activation");
|
||||
|
||||
SendKeys(Key.Esc);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Failed to detect TextExtractor window: {ex.Message}");
|
||||
Assert.Fail("TextExtractor window was not found after hotkey activation");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
<ProjectGuid>{A85D4D9F-9A39-4B5D-8B5A-9F2D5C9A8B4C}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>WorkspacesLibUnitTests</RootNamespace>
|
||||
<ProjectName>WorkspacesLibUnitTests</ProjectName>
|
||||
<ProjectName>Workspaces.Lib.UnitTests</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.CmdPal.Common.Services;
|
||||
|
||||
public interface IRunHistoryService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the run history.
|
||||
/// </summary>
|
||||
/// <returns>A list of run history items.</returns>
|
||||
IReadOnlyList<string> GetRunHistory();
|
||||
|
||||
/// <summary>
|
||||
/// Clears the run history.
|
||||
/// </summary>
|
||||
void ClearRunHistory();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a run history item.
|
||||
/// </summary>
|
||||
/// <param name="item">The run history item to add.</param>
|
||||
void AddRunHistoryItem(string item);
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\..\CmdPalVersion.props" />
|
||||
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
|
||||
<Import Project="..\..\..\Common.Dotnet.AotCompatibility.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<RootNamespace>Microsoft.CmdPal.Core.Control</RootNamespace>
|
||||
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\WinUI3Apps\CmdPal</OutputPath>
|
||||
<!-- For MVVM Toolkit Partial Properties/AOT support -->
|
||||
<LangVersion>preview</LangVersion>
|
||||
<!-- Disable SA1313 for Primary Constructor fields conflict https://learn.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/instance-constructors#primary-constructors -->
|
||||
<NoWarn>SA1313;</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<CsWinRTAotOptimizerEnabled>true</CsWinRTAotOptimizerEnabled>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- This lets us actually reference types from Microsoft.Terminal.UI -->
|
||||
<CsWinRTIncludes>Microsoft.Terminal.UI;</CsWinRTIncludes>
|
||||
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Converters" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Animations" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.Markdown" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" />
|
||||
<!-- <PackageReference Include="WinUIEx" /> -->
|
||||
<PackageReference Include="Microsoft.Windows.CsWin32">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" />
|
||||
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging
|
||||
Tools extension to be activated for this project even if the Windows App SDK Nuget
|
||||
package has not yet been restored.
|
||||
-->
|
||||
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<ProjectCapability Include="Msix" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<RdXmlFile Include="rd.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.CmdPal.Common\Microsoft.CmdPal.Common.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.CmdPal.Core.ViewModels\Microsoft.CmdPal.Core.ViewModels.csproj" />
|
||||
|
||||
<ProjectReference Include="..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
|
||||
|
||||
<ProjectReference Include="..\Microsoft.Terminal.UI\Microsoft.Terminal.UI.vcxproj">
|
||||
<ReferenceOutputAssembly>True</ReferenceOutputAssembly>
|
||||
<Private>True</Private>
|
||||
<CopyLocalSatelliteAssemblies>True</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="LoadingPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="ShellPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\SearchBar.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Styles\Button.xaml">
|
||||
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
||||
</Page>
|
||||
<Page Update="Styles\TextBox.xaml">
|
||||
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
||||
</Page>
|
||||
<Page Update="Styles\Colors.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Styles\Settings.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Page
|
||||
x:Class="Microsoft.CmdPal.Core.Control.Pages.LoadingPage"
|
||||
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">
|
||||
|
||||
<Grid>
|
||||
<ProgressRing
|
||||
Width="36"
|
||||
Height="36"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
IsIndeterminate="True" />
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -1,46 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Pages;
|
||||
|
||||
/// <summary>
|
||||
/// We use this page to do initialization of our extensions and cache loading to hydrate our ViewModels.
|
||||
/// </summary>
|
||||
public sealed partial class LoadingPage : Page
|
||||
{
|
||||
private readonly DispatcherQueue _queue = DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
public LoadingPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
if (e.Parameter is ShellViewModel shellVM
|
||||
&& shellVM.LoadCommand != null)
|
||||
{
|
||||
// This will load the built-in commands, then navigate to the main page.
|
||||
// Once the mainpage loads, we'll start loading extensions.
|
||||
shellVM.LoadCommand.Execute(null);
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
await shellVM.LoadCommand.ExecutionTask!;
|
||||
|
||||
if (shellVM.LoadCommand.ExecutionTask.Status != TaskStatus.RanToCompletion)
|
||||
{
|
||||
// TODO: Handle failure case
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
base.OnNavigatedTo(e);
|
||||
}
|
||||
}
|
||||
@@ -1,515 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Page
|
||||
x:Class="Microsoft.CmdPal.Core.Control.Pages.ShellPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:animations="using:CommunityToolkit.WinUI.Animations"
|
||||
xmlns:cmdpalUI="using:Microsoft.CmdPal.Core.Control"
|
||||
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
|
||||
xmlns:cpcontrols="using:Microsoft.CmdPal.Core.Control.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:help="using:Microsoft.CmdPal.Core.Control.Helpers"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:toolkit="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
xmlns:viewModels="using:Microsoft.CmdPal.Core.Control.ViewModels"
|
||||
xmlns:coreViewModels="using:Microsoft.CmdPal.Core.ViewModels"
|
||||
Background="Transparent"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="../Styles/Button.xaml" />
|
||||
<ResourceDictionary Source="../Styles/Colors.xaml" />
|
||||
<ResourceDictionary Source="../Styles/TextBlock.xaml" />
|
||||
<ResourceDictionary Source="../Styles/TextBox.xaml" />
|
||||
<ResourceDictionary Source="../Styles/Settings.xaml" />
|
||||
<ResourceDictionary Source="../Controls/Tag.xaml" />
|
||||
<!-- <ResourceDictionary Source="../Controls/KeyVisual/KeyVisual.xaml" /> -->
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<converters:StringVisibilityConverter
|
||||
x:Key="StringNotEmptyToVisibilityConverter"
|
||||
EmptyValue="Collapsed"
|
||||
NotEmptyValue="Visible" />
|
||||
|
||||
<converters:BoolNegationConverter x:Key="BoolNegationConverter" />
|
||||
|
||||
<cmdpalUI:MessageStateToSeverityConverter x:Key="MessageStateToSeverityConverter" />
|
||||
|
||||
<cmdpalUI:DetailsDataTemplateSelector
|
||||
x:Key="DetailsDataTemplateSelector"
|
||||
CommandTemplate="{StaticResource DetailsCommandsTemplate}"
|
||||
LinkTemplate="{StaticResource DetailsLinkTemplate}"
|
||||
SeparatorTemplate="{StaticResource DetailsSeparatorTemplate}"
|
||||
TagTemplate="{StaticResource DetailsTagsTemplate}" />
|
||||
|
||||
<converters:BoolToVisibilityConverter
|
||||
x:Key="BoolToInvertedVisibilityConverter"
|
||||
FalseValue="Visible"
|
||||
TrueValue="Collapsed" />
|
||||
|
||||
<DataTemplate x:Key="TagTemplate" x:DataType="coreViewModels:TagViewModel">
|
||||
<cpcontrols:Tag
|
||||
HorizontalAlignment="Left"
|
||||
AutomationProperties.Name="{x:Bind Text, Mode=OneWay}"
|
||||
BackgroundColor="{x:Bind Background, Mode=OneWay}"
|
||||
FontSize="12"
|
||||
ForegroundColor="{x:Bind Foreground, Mode=OneWay}"
|
||||
Icon="{x:Bind Icon, Mode=OneWay}"
|
||||
Text="{x:Bind Text, Mode=OneWay}"
|
||||
ToolTipService.ToolTip="{x:Bind ToolTip, Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="CommandTemplate" x:DataType="coreViewModels:CommandViewModel">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<Button
|
||||
Name="Command"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Left"
|
||||
Click="Command_Click"
|
||||
Style="{StaticResource SubtleButtonStyle}">
|
||||
<StackPanel VerticalAlignment="Center" Orientation="Horizontal">
|
||||
<cpcontrols:IconBox
|
||||
Width="16"
|
||||
Height="16"
|
||||
Margin="0,3,8,0"
|
||||
SourceKey="{x:Bind Icon, Mode=OneWay}"
|
||||
SourceRequested="{x:Bind help:IconCacheProvider.SourceRequested}" />
|
||||
<TextBlock Text="{x:Bind Name}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="DetailsLinkTemplate" x:DataType="coreViewModels:DetailsLinkViewModel">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock
|
||||
IsTextSelectionEnabled="True"
|
||||
Text="{x:Bind Key, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<TextBlock
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
IsTextSelectionEnabled="True"
|
||||
Text="{x:Bind Text, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords"
|
||||
Visibility="{x:Bind IsText, Mode=OneWay}" />
|
||||
<HyperlinkButton
|
||||
Padding="0"
|
||||
Content="{x:Bind Text, Mode=OneWay}"
|
||||
FontSize="12"
|
||||
NavigateUri="{x:Bind Link, Mode=OneWay}"
|
||||
Visibility="{x:Bind IsLink, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="DetailsCommandsTemplate" x:DataType="coreViewModels:DetailsCommandsViewModel">
|
||||
<StackPanel Orientation="Vertical" Spacing="4">
|
||||
<TextBlock
|
||||
IsTextSelectionEnabled="True"
|
||||
Text="{x:Bind Key, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ItemsControl
|
||||
ItemTemplate="{StaticResource CommandTemplate}"
|
||||
ItemsSource="{x:Bind Commands, Mode=OneWay}"
|
||||
Visibility="{x:Bind HasCommands, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="DetailsSeparatorTemplate" x:DataType="coreViewModels:DetailsSeparatorViewModel">
|
||||
<StackPanel Margin="0,8,8,0" Orientation="Vertical">
|
||||
<Border
|
||||
Margin="8,0,0,0"
|
||||
BorderBrush="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
BorderThickness="0,0,0,2">
|
||||
<TextBlock
|
||||
Margin="-8,0,0,8"
|
||||
FontWeight="SemiBold"
|
||||
IsTextSelectionEnabled="True"
|
||||
Text="{x:Bind Key, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="DetailsTagsTemplate" x:DataType="coreViewModels:DetailsTagsViewModel">
|
||||
<StackPanel Orientation="Vertical" Spacing="4">
|
||||
<TextBlock
|
||||
IsTextSelectionEnabled="True"
|
||||
Text="{x:Bind Key, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ItemsControl
|
||||
ItemTemplate="{StaticResource TagTemplate}"
|
||||
ItemsSource="{x:Bind Tags, Mode=OneWay}"
|
||||
Visibility="{x:Bind HasTags, Mode=OneWay}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<toolkit:WrapPanel
|
||||
x:Name="TagsWrapPanel"
|
||||
MinWidth="0"
|
||||
Padding="0"
|
||||
HorizontalSpacing="4"
|
||||
Orientation="Horizontal"
|
||||
VerticalSpacing="4" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Background="{ThemeResource LayerOnAcrylicPrimaryBackgroundBrush}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Back button and search box -->
|
||||
<Grid
|
||||
Padding="0,12,0,12"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Back button -->
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image
|
||||
Width="20"
|
||||
Margin="20,0,6,0"
|
||||
HorizontalAlignment="Center"
|
||||
ui:VisualExtensions.NormalizedCenterPoint="0.5,0.5"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Source="ms-appx:///Assets/icon.svg"
|
||||
Visibility="{x:Bind ViewModel.CurrentPage.IsNested, Mode=OneWay, Converter={StaticResource BoolToInvertedVisibilityConverter}}">
|
||||
<animations:Implicit.ShowAnimations>
|
||||
<animations:OpacityAnimation
|
||||
EasingMode="EaseIn"
|
||||
EasingType="Cubic"
|
||||
From="0"
|
||||
To="1.0"
|
||||
Duration="0:0:0.187" />
|
||||
<animations:ScaleAnimation
|
||||
EasingMode="EaseIn"
|
||||
EasingType="Cubic"
|
||||
From="0.5"
|
||||
To="1"
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.ShowAnimations>
|
||||
<animations:Implicit.HideAnimations>
|
||||
<animations:OpacityAnimation
|
||||
EasingMode="EaseOut"
|
||||
EasingType="Cubic"
|
||||
From="1.0"
|
||||
To="0"
|
||||
Duration="0:0:0.187" />
|
||||
<animations:ScaleAnimation
|
||||
EasingMode="EaseOut"
|
||||
EasingType="Cubic"
|
||||
From="1"
|
||||
To="0.5"
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.HideAnimations>
|
||||
</Image>
|
||||
<Button
|
||||
x:Name="BackButton"
|
||||
x:Uid="BackButton"
|
||||
Margin="4,0,4,0"
|
||||
Padding="4"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
ui:VisualExtensions.NormalizedCenterPoint="0.5,0.5"
|
||||
Content="{ui:FontIcon Glyph=,
|
||||
FontSize=14}"
|
||||
FontSize="16"
|
||||
Style="{StaticResource SubtleButtonStyle}"
|
||||
Tapped="BackButton_Tapped"
|
||||
Visibility="{x:Bind ViewModel.CurrentPage.IsNested, Mode=OneWay}">
|
||||
<animations:Implicit.ShowAnimations>
|
||||
<animations:OpacityAnimation
|
||||
EasingMode="EaseIn"
|
||||
EasingType="Cubic"
|
||||
From="0"
|
||||
To="1.0"
|
||||
Duration="0:0:0.333" />
|
||||
<animations:ScaleAnimation
|
||||
From="0.5"
|
||||
To="1"
|
||||
Duration="0:0:0.333" />
|
||||
<animations:TranslationAnimation
|
||||
From="16,0,0"
|
||||
To="0,0,0"
|
||||
Duration="0:0:0.333" />
|
||||
</animations:Implicit.ShowAnimations>
|
||||
<animations:Implicit.HideAnimations>
|
||||
<animations:OpacityAnimation
|
||||
EasingMode="EaseOut"
|
||||
EasingType="Cubic"
|
||||
From="1.0"
|
||||
To="0"
|
||||
Duration="0:0:0.333" />
|
||||
<animations:ScaleAnimation
|
||||
EasingMode="EaseOut"
|
||||
EasingType="Cubic"
|
||||
From="1"
|
||||
To="0.5"
|
||||
Duration="0:0:0.333" />
|
||||
<animations:TranslationAnimation
|
||||
EasingMode="EaseOut"
|
||||
EasingType="Cubic"
|
||||
From="0,0,0"
|
||||
To="16,0,0"
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.HideAnimations>
|
||||
</Button>
|
||||
<cpcontrols:IconBox
|
||||
Grid.Column="1"
|
||||
Width="20"
|
||||
Margin="4,0,4,0"
|
||||
VerticalAlignment="Center"
|
||||
ui:VisualExtensions.NormalizedCenterPoint="0.5,0.5"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
SourceKey="{x:Bind ViewModel.CurrentPage.Icon, Mode=OneWay}"
|
||||
SourceRequested="{x:Bind help:IconCacheProvider.SourceRequested}"
|
||||
Visibility="{x:Bind ViewModel.CurrentPage.IsNested, Mode=OneWay}">
|
||||
<animations:Implicit.ShowAnimations>
|
||||
<animations:OpacityAnimation
|
||||
From="0"
|
||||
To="1.0"
|
||||
Duration="0:0:0.333" />
|
||||
<animations:ScaleAnimation
|
||||
From="0.8"
|
||||
To="1"
|
||||
Duration="0:0:0.333" />
|
||||
<animations:TranslationAnimation
|
||||
From="8,0,0"
|
||||
To="0,0,0"
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.ShowAnimations>
|
||||
<animations:Implicit.HideAnimations>
|
||||
<animations:OpacityAnimation
|
||||
From="1.0"
|
||||
To="0"
|
||||
Duration="0:0:0.333" />
|
||||
<animations:ScaleAnimation
|
||||
From="1"
|
||||
To="0.8"
|
||||
Duration="0:0:0.333" />
|
||||
<animations:TranslationAnimation
|
||||
From="0,0,0"
|
||||
To="8,0,0"
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.HideAnimations>
|
||||
</cpcontrols:IconBox>
|
||||
</StackPanel>
|
||||
<!-- Search box: wrapped in a grid to enable RepositionThemeTransitions -->
|
||||
<Grid Grid.Column="1" HorizontalAlignment="Stretch">
|
||||
<cpcontrols:SearchBar
|
||||
x:Name="SearchBox"
|
||||
HorizontalAlignment="Stretch"
|
||||
CurrentPageViewModel="{x:Bind ViewModel.CurrentPage, Mode=OneWay}" />
|
||||
<Grid.Transitions>
|
||||
<TransitionCollection>
|
||||
<RepositionThemeTransition />
|
||||
</TransitionCollection>
|
||||
</Grid.Transitions>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<ProgressBar
|
||||
Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Bottom"
|
||||
IsIndeterminate="True"
|
||||
Visibility="{x:Bind ViewModel.CurrentPage.IsLoading, Mode=OneWay}">
|
||||
<animations:Implicit.ShowAnimations>
|
||||
<animations:OpacityAnimation
|
||||
From="0"
|
||||
To="1.0"
|
||||
Duration="0:0:0.333" />
|
||||
</animations:Implicit.ShowAnimations>
|
||||
<animations:Implicit.HideAnimations>
|
||||
<animations:OpacityAnimation
|
||||
From="1.0"
|
||||
To="0"
|
||||
Duration="0:0:0.333" />
|
||||
</animations:Implicit.HideAnimations>
|
||||
</ProgressBar>
|
||||
|
||||
<Grid
|
||||
x:Name="ContentGrid"
|
||||
Grid.Row="1"
|
||||
BorderBrush="{ThemeResource DividerStrokeColorDefaultBrush}"
|
||||
BorderThickness="0,1,0,1">
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="3*" />
|
||||
<ColumnDefinition x:Name="DetailsColumn" Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Frame
|
||||
Name="RootFrame"
|
||||
IsNavigationStackEnabled="True"
|
||||
Navigated="RootFrame_Navigated" />
|
||||
|
||||
<ScrollViewer
|
||||
x:Name="DetailsContent"
|
||||
Grid.Column="1"
|
||||
Margin="4"
|
||||
HorizontalAlignment="Stretch"
|
||||
ui:VisualExtensions.NormalizedCenterPoint="0.5,0.5"
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{ThemeResource DividerStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}"
|
||||
Visibility="Collapsed">
|
||||
<animations:Implicit.ShowAnimations>
|
||||
<animations:OpacityAnimation
|
||||
From="0"
|
||||
To="1.0"
|
||||
Duration="0:0:0.187" />
|
||||
<animations:TranslationAnimation
|
||||
From="24,0,0"
|
||||
To="0,0,0"
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.ShowAnimations>
|
||||
<animations:Implicit.HideAnimations>
|
||||
<animations:OpacityAnimation
|
||||
From="1.0"
|
||||
To="0"
|
||||
Duration="0:0:0.187" />
|
||||
<animations:TranslationAnimation
|
||||
From="0,0,0"
|
||||
To="24,0,0"
|
||||
Duration="0:0:0.187" />
|
||||
</animations:Implicit.HideAnimations>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<cpcontrols:IconBox
|
||||
x:Name="HeroImageBorder"
|
||||
Width="64"
|
||||
Margin="0,0,16,16"
|
||||
HorizontalAlignment="Left"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
SourceKey="{x:Bind ViewModel.Details.HeroImage, Mode=OneWay}"
|
||||
SourceRequested="{x:Bind help:IconCacheProvider.SourceRequested}"
|
||||
Visibility="{x:Bind HasHeroImage, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
FontSize="18"
|
||||
FontWeight="SemiBold"
|
||||
Text="{x:Bind ViewModel.Details.Title, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords"
|
||||
Visibility="{x:Bind ViewModel.Details.Title, Converter={StaticResource StringNotEmptyToVisibilityConverter}, Mode=OneWay}" />
|
||||
|
||||
<toolkit:MarkdownTextBlock
|
||||
Grid.Row="2"
|
||||
Margin="0,4,0,24"
|
||||
Background="Transparent"
|
||||
Header3FontSize="12"
|
||||
Header3FontWeight="Normal"
|
||||
Header3Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
IsTextSelectionEnabled="True"
|
||||
Text="{x:Bind ViewModel.Details.Body, Mode=OneWay}" />
|
||||
|
||||
<ItemsRepeater
|
||||
Grid.Row="3"
|
||||
ItemTemplate="{StaticResource DetailsDataTemplateSelector}"
|
||||
ItemsSource="{x:Bind ViewModel.Details.Metadata, Mode=OneWay}">
|
||||
<ItemsRepeater.Layout>
|
||||
<StackLayout Spacing="12" />
|
||||
</ItemsRepeater.Layout>
|
||||
</ItemsRepeater>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
<!-- /DetailsContent -->
|
||||
</Grid>
|
||||
<ScrollView
|
||||
Grid.Row="2"
|
||||
Grid.ColumnSpan="2"
|
||||
MaxHeight="120"
|
||||
Background="{ThemeResource SystemControlErrorBackgroundColor}"
|
||||
BorderBrush="{ThemeResource SystemControlErrorTextForegroundBrush}"
|
||||
BorderThickness="0,1,0,1"
|
||||
CornerRadius="0"
|
||||
Visibility="{x:Bind ViewModel.CurrentPage.ErrorMessage, Converter={StaticResource StringNotEmptyToVisibilityConverter}, Mode=OneWay}">
|
||||
<TextBlock Margin="16,8,16,16" IsTextSelectionEnabled="True">
|
||||
<Run
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{ThemeResource SystemErrorTextColor}"
|
||||
Text="Error(s) on page:" />
|
||||
<LineBreak /><Run Text="{x:Bind ViewModel.CurrentPage.ErrorMessage, Mode=OneWay}" />
|
||||
</TextBlock>
|
||||
</ScrollView>
|
||||
</Grid>
|
||||
|
||||
<!--
|
||||
Horrifying: You may ask yourself - why is there a Background on this InfoBar?
|
||||
|
||||
Well, as it turns out, the Informational InfoBar has a transparent
|
||||
background. It just cannot be bothered. So, we need to manually give
|
||||
it one to actually obscure the text beneath it. And you can't just give
|
||||
the InfoBar itself a Background, because then the other Severity's
|
||||
won't get colorized.
|
||||
|
||||
See https://github.com/microsoft/microsoft-ui-xaml/issues/5741
|
||||
-->
|
||||
<StackPanel
|
||||
Grid.Row="0"
|
||||
Margin="16,8,16,8"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Bottom"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
CornerRadius="{ThemeResource ControlCornerRadius}">
|
||||
<InfoBar
|
||||
CornerRadius="{ThemeResource ControlCornerRadius}"
|
||||
IsOpen="{x:Bind ViewModel.CurrentPage.HasStatusMessage, Mode=OneWay}"
|
||||
Message="{x:Bind ViewModel.CurrentPage.MostRecentStatusMessage.Message, Mode=OneWay}"
|
||||
Severity="{x:Bind ViewModel.CurrentPage.MostRecentStatusMessage.State, Mode=OneWay, Converter={StaticResource MessageStateToSeverityConverter}}">
|
||||
|
||||
<InfoBar.Content>
|
||||
<ProgressBar
|
||||
Margin="0,-20,0,0"
|
||||
IsIndeterminate="{x:Bind ViewModel.CurrentPage.MostRecentStatusMessage.Progress.IsIndeterminate, Mode=OneWay}"
|
||||
Visibility="{x:Bind ViewModel.CurrentPage.MostRecentStatusMessage.HasProgress, Mode=OneWay}"
|
||||
Value="{x:Bind ViewModel.CurrentPage.MostRecentStatusMessage.Progress.ProgressPercent, Mode=OneWay}" />
|
||||
<!-- Margin="0,0,0,6" MaxWidth="200"/> -->
|
||||
</InfoBar.Content>
|
||||
</InfoBar>
|
||||
</StackPanel>
|
||||
|
||||
<Grid Grid.Row="1" Background="{ThemeResource LayerOnAcrylicSecondaryBackgroundBrush}">
|
||||
<cpcontrols:CommandBar CurrentPageViewModel="{x:Bind ViewModel.CurrentPage, Mode=OneWay}" />
|
||||
</Grid>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup>
|
||||
<VisualState x:Name="DetailsCollapsed" />
|
||||
<VisualState x:Name="DetailsVisible">
|
||||
<VisualState.StateTriggers>
|
||||
<StateTrigger IsActive="{x:Bind ViewModel.IsDetailsVisible, Mode=OneWay}" />
|
||||
</VisualState.StateTriggers>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="DetailsContent.Visibility" Value="Visible" />
|
||||
<Setter Target="DetailsColumn.Width" Value="2*" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -1,498 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.WinUI;
|
||||
|
||||
// using ManagedCommon;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
|
||||
// using Microsoft.PowerToys.Telemetry;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Input;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media.Animation;
|
||||
using DispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Pages;
|
||||
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
|
||||
IRecipient<NavigateBackMessage>,
|
||||
IRecipient<ShowDetailsMessage>,
|
||||
IRecipient<HideDetailsMessage>,
|
||||
IRecipient<ClearSearchMessage>,
|
||||
IRecipient<LaunchUriMessage>,
|
||||
IRecipient<GoHomeMessage>,
|
||||
IRecipient<GoBackMessage>,
|
||||
IRecipient<ShowConfirmationMessage>,
|
||||
IRecipient<ShowToastMessage>,
|
||||
IRecipient<NavigateToPageMessage>,
|
||||
INotifyPropertyChanged
|
||||
{
|
||||
private readonly DispatcherQueue _queue = DispatcherQueue.GetForCurrentThread();
|
||||
|
||||
private readonly DispatcherQueueTimer _debounceTimer = DispatcherQueue.GetForCurrentThread().CreateTimer();
|
||||
|
||||
private readonly TaskScheduler _mainTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
|
||||
|
||||
private readonly SlideNavigationTransitionInfo _slideRightTransition = new() { Effect = SlideNavigationTransitionEffect.FromRight };
|
||||
private readonly SuppressNavigationTransitionInfo _noAnimation = new();
|
||||
|
||||
public ShellViewModel? ViewModel
|
||||
{
|
||||
get => (ShellViewModel?)GetValue(ViewModelProperty);
|
||||
set
|
||||
{
|
||||
SetValue(ViewModelProperty, value);
|
||||
RootFrame.Navigate(typeof(LoadingPage), ViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for ViewModel. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty ViewModelProperty =
|
||||
DependencyProperty.Register(nameof(ViewModel), typeof(ShellViewModel), typeof(ShellPage), new PropertyMetadata(null, null));
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
public ShellPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
// how we are doing navigation around
|
||||
WeakReferenceMessenger.Default.Register<NavigateBackMessage>(this);
|
||||
|
||||
// WeakReferenceMessenger.Default.Register<OpenSettingsMessage>(this);
|
||||
// WeakReferenceMessenger.Default.Register<HotkeySummonMessage>(this);
|
||||
// WeakReferenceMessenger.Default.Register<SettingsWindowClosedMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<ShowDetailsMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<HideDetailsMessage>(this);
|
||||
|
||||
WeakReferenceMessenger.Default.Register<ClearSearchMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<LaunchUriMessage>(this);
|
||||
|
||||
WeakReferenceMessenger.Default.Register<GoHomeMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<GoBackMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<ShowConfirmationMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<ShowToastMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<NavigateToPageMessage>(this);
|
||||
|
||||
AddHandler(PointerPressedEvent, new PointerEventHandler(ShellPage_OnPointerPressed), true);
|
||||
}
|
||||
|
||||
// protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
// {
|
||||
// if (e.Parameter is ShellViewModel vm)
|
||||
// {
|
||||
// ViewModel = vm;
|
||||
// }
|
||||
// }
|
||||
public void Receive(NavigateBackMessage message)
|
||||
{
|
||||
// var settings = App.Current.Services.GetService<SettingsModel>()!;
|
||||
|
||||
// if (RootFrame.CanGoBack)
|
||||
// {
|
||||
// if (!message.FromBackspace ||
|
||||
// settings.BackspaceGoesBack)
|
||||
// {
|
||||
// GoBack();
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (!message.FromBackspace)
|
||||
// {
|
||||
// // If we can't go back then we must be at the top and thus escape again should quit.
|
||||
// WeakReferenceMessenger.Default.Send<DismissMessage>();
|
||||
|
||||
// PowerToysTelemetry.Log.WriteEvent(new CmdPalDismissedOnEsc());
|
||||
// }
|
||||
// }
|
||||
GoBack();
|
||||
}
|
||||
|
||||
public void Receive(NavigateToPageMessage message)
|
||||
{
|
||||
// TODO GH #526 This needs more better locking too
|
||||
_ = _queue.TryEnqueue(() =>
|
||||
{
|
||||
// Also hide our details pane about here, if we had one
|
||||
HideDetails();
|
||||
|
||||
// Navigate to the appropriate host page for that VM
|
||||
RootFrame.Navigate(
|
||||
message.Page switch
|
||||
{
|
||||
ListViewModel => typeof(ListPage),
|
||||
|
||||
// ContentPageViewModel => typeof(ContentPage),
|
||||
_ => throw new NotSupportedException(),
|
||||
},
|
||||
message.Page,
|
||||
message.WithAnimation ? _slideRightTransition : _noAnimation);
|
||||
|
||||
// TODO! Telem
|
||||
// PowerToysTelemetry.Log.WriteEvent(new OpenPage(RootFrame.BackStackDepth));
|
||||
|
||||
// Refocus on the Search for continual typing on the next search request
|
||||
SearchBox.Focus(Microsoft.UI.Xaml.FocusState.Programmatic);
|
||||
|
||||
if (!(ViewModel?.IsNested ?? false))
|
||||
{
|
||||
// todo BODGY
|
||||
RootFrame.BackStack.Clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Receive(ShowConfirmationMessage message)
|
||||
{
|
||||
DispatcherQueue.TryEnqueue(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await HandleConfirmArgsOnUiThread(message.Args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CoreLogger.LogError(ex.ToString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Receive(ShowToastMessage message)
|
||||
{
|
||||
// DispatcherQueue.TryEnqueue(() =>
|
||||
// {
|
||||
// _toast.ShowToast(message.Message);
|
||||
// });
|
||||
}
|
||||
|
||||
// This gets called from the UI thread
|
||||
private async Task HandleConfirmArgsOnUiThread(IConfirmationArgs? args)
|
||||
{
|
||||
if (args == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ViewModel == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ConfirmResultViewModel vm = new(args, new(ViewModel.CurrentPage));
|
||||
var initializeDialogTask = Task.Run(() => { InitializeConfirmationDialog(vm); });
|
||||
await initializeDialogTask;
|
||||
|
||||
var resourceLoader = Microsoft.CmdPal.Core.Control.Helpers.ResourceLoaderInstance.ResourceLoader;
|
||||
var confirmText = resourceLoader.GetString("ConfirmationDialog_ConfirmButtonText");
|
||||
var cancelText = resourceLoader.GetString("ConfirmationDialog_CancelButtonText");
|
||||
|
||||
var name = string.IsNullOrEmpty(vm.PrimaryCommand.Name) ? confirmText : vm.PrimaryCommand.Name;
|
||||
ContentDialog dialog = new()
|
||||
{
|
||||
Title = vm.Title,
|
||||
Content = vm.Description,
|
||||
PrimaryButtonText = name,
|
||||
CloseButtonText = cancelText,
|
||||
XamlRoot = this.XamlRoot,
|
||||
};
|
||||
|
||||
if (vm.IsPrimaryCommandCritical)
|
||||
{
|
||||
dialog.DefaultButton = ContentDialogButton.Close;
|
||||
|
||||
// TODO: Maybe we need to style the primary button to be red?
|
||||
// dialog.PrimaryButtonStyle = new Style(typeof(Button))
|
||||
// {
|
||||
// Setters =
|
||||
// {
|
||||
// new Setter(Button.ForegroundProperty, new SolidColorBrush(Colors.Red)),
|
||||
// new Setter(Button.BackgroundProperty, new SolidColorBrush(Colors.Red)),
|
||||
// },
|
||||
// };
|
||||
}
|
||||
|
||||
var result = await dialog.ShowAsync();
|
||||
if (result == ContentDialogResult.Primary)
|
||||
{
|
||||
var performMessage = new PerformCommandMessage(vm);
|
||||
WeakReferenceMessenger.Default.Send(performMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
// cancel
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeConfirmationDialog(ConfirmResultViewModel vm)
|
||||
{
|
||||
vm.SafeInitializePropertiesSynchronous();
|
||||
}
|
||||
|
||||
// public void Receive(OpenSettingsMessage message)
|
||||
// {
|
||||
// _ = DispatcherQueue.TryEnqueue(() =>
|
||||
// {
|
||||
// OpenSettings();
|
||||
// });
|
||||
// }
|
||||
|
||||
// public void OpenSettings()
|
||||
// {
|
||||
// if (_settingsWindow == null)
|
||||
// {
|
||||
// _settingsWindow = new SettingsWindow();
|
||||
// }
|
||||
|
||||
// _settingsWindow.Activate();
|
||||
// }
|
||||
public void Receive(ShowDetailsMessage message)
|
||||
{
|
||||
// TERRIBLE HACK TODO GH #245
|
||||
// There's weird wacky bugs with debounce currently.
|
||||
if (ViewModel != null && !ViewModel.IsDetailsVisible)
|
||||
{
|
||||
ViewModel.Details = message.Details;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasHeroImage)));
|
||||
ViewModel.IsDetailsVisible = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// GH #322:
|
||||
// For inexplicable reasons, if you try to change the details too fast,
|
||||
// we'll explode. This seemingly only happens if you change the details
|
||||
// while we're also scrolling a new list view item into view.
|
||||
_debounceTimer.Debounce(
|
||||
() =>
|
||||
{
|
||||
if (ViewModel != null)
|
||||
{
|
||||
ViewModel.Details = message.Details;
|
||||
}
|
||||
|
||||
// Trigger a re-evaluation of whether we have a hero image based on
|
||||
// the current theme
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasHeroImage)));
|
||||
},
|
||||
interval: TimeSpan.FromMilliseconds(50),
|
||||
immediate: ViewModel?.IsDetailsVisible == false);
|
||||
if (ViewModel != null)
|
||||
{
|
||||
ViewModel.IsDetailsVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(HideDetailsMessage message) => HideDetails();
|
||||
|
||||
public void Receive(LaunchUriMessage message) => _ = global::Windows.System.Launcher.LaunchUriAsync(message.Uri);
|
||||
|
||||
private void HideDetails()
|
||||
{
|
||||
if (ViewModel != null)
|
||||
{
|
||||
ViewModel.Details = null;
|
||||
ViewModel.IsDetailsVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(ClearSearchMessage message) => SearchBox.ClearSearch();
|
||||
|
||||
// public void Receive(HotkeySummonMessage message)
|
||||
// {
|
||||
// _ = DispatcherQueue.TryEnqueue(() => SummonOnUiThread(message));
|
||||
// }
|
||||
|
||||
// public void Receive(SettingsWindowClosedMessage message) => _settingsWindow = null;
|
||||
|
||||
// private void SummonOnUiThread(HotkeySummonMessage message)
|
||||
// {
|
||||
// var settings = App.Current.Services.GetService<SettingsModel>()!;
|
||||
// var commandId = message.CommandId;
|
||||
// var isRoot = string.IsNullOrEmpty(commandId);
|
||||
// if (isRoot)
|
||||
// {
|
||||
// // If this is the hotkey for the root level, then always show us
|
||||
// WeakReferenceMessenger.Default.Send<ShowWindowMessage>(new(message.Hwnd));
|
||||
|
||||
// // Depending on the settings, either
|
||||
// // * Go home, or
|
||||
// // * Select the search text (if we should remain open on this page)
|
||||
// if (settings.HotkeyGoesHome)
|
||||
// {
|
||||
// GoHome(false);
|
||||
// }
|
||||
// else if (settings.HighlightSearchOnActivate)
|
||||
// {
|
||||
// SearchBox.SelectSearch();
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// // For a hotkey bound to a command, first lookup the
|
||||
// // command from our list of toplevel commands.
|
||||
// var tlcManager = App.Current.Services.GetService<TopLevelCommandManager>()!;
|
||||
// var topLevelCommand = tlcManager.LookupCommand(commandId);
|
||||
// if (topLevelCommand != null)
|
||||
// {
|
||||
// var command = topLevelCommand.CommandViewModel.Model.Unsafe;
|
||||
// var isPage = command is not IInvokableCommand;
|
||||
|
||||
// // If the bound command is an invokable command, then
|
||||
// // we don't want to open the window at all - we want to
|
||||
// // just do it.
|
||||
// if (isPage)
|
||||
// {
|
||||
// // If we're here, then the bound command was a page
|
||||
// // of some kind. Let's pop the stack, show the window, and navigate to it.
|
||||
// GoHome(false);
|
||||
|
||||
// WeakReferenceMessenger.Default.Send<ShowWindowMessage>(new(message.Hwnd));
|
||||
// }
|
||||
|
||||
// var msg = topLevelCommand.GetPerformCommandMessage();
|
||||
// msg.WithAnimation = false;
|
||||
// WeakReferenceMessenger.Default.Send<PerformCommandMessage>(msg);
|
||||
|
||||
// // we can't necessarily SelectSearch() here, because when the page is loaded,
|
||||
// // we'll fetch the SearchText from the page itself, and that'll stomp the
|
||||
// // selection we start now.
|
||||
// // That's probably okay though.
|
||||
// }
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// }
|
||||
// }
|
||||
|
||||
// WeakReferenceMessenger.Default.Send<FocusSearchBoxMessage>();
|
||||
// }
|
||||
public void Receive(GoBackMessage message)
|
||||
{
|
||||
_ = DispatcherQueue.TryEnqueue(() => GoBack(message.WithAnimation, message.FocusSearch));
|
||||
}
|
||||
|
||||
private void GoBack(bool withAnimation = true, bool focusSearch = true)
|
||||
{
|
||||
HideDetails();
|
||||
|
||||
// Note: That we restore the VM state below in RootFrame_Navigated call back after this occurs.
|
||||
// In the future, we may want to manage the back stack ourselves vs. relying on Frame
|
||||
// We could replace Frame with a ContentPresenter, but then have to manage transition animations ourselves.
|
||||
// However, then we have more fine-grained control on the back stack, managing the VM cache, and not
|
||||
// having that all be a black box, though then we wouldn't cache the XAML page itself, but sometimes that is a drawback.
|
||||
// However, we do a good job here, see ForwardStack.Clear below, and BackStack.Clear above about managing that.
|
||||
if (withAnimation)
|
||||
{
|
||||
RootFrame.GoBack();
|
||||
}
|
||||
else
|
||||
{
|
||||
RootFrame.GoBack(_noAnimation);
|
||||
}
|
||||
|
||||
// Don't store pages we're navigating away from in the Frame cache
|
||||
// TODO: In the future we probably want a short cache (3-5?) of recent VMs in case the user re-navigates
|
||||
// back to a recent page they visited (like the Pokedex) so we don't have to reload it from scratch.
|
||||
// That'd be retrieved as we re-navigate in the PerformCommandMessage logic above
|
||||
RootFrame.ForwardStack.Clear();
|
||||
|
||||
if (!RootFrame.CanGoBack)
|
||||
{
|
||||
ViewModel?.GoHome();
|
||||
}
|
||||
|
||||
if (focusSearch)
|
||||
{
|
||||
SearchBox.Focus(Microsoft.UI.Xaml.FocusState.Programmatic);
|
||||
SearchBox.SelectSearch();
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(GoHomeMessage message)
|
||||
{
|
||||
_ = DispatcherQueue.TryEnqueue(() => GoHome(withAnimation: message.WithAnimation, focusSearch: message.FocusSearch));
|
||||
}
|
||||
|
||||
private void GoHome(bool withAnimation = true, bool focusSearch = true)
|
||||
{
|
||||
while (RootFrame.CanGoBack)
|
||||
{
|
||||
GoBack(withAnimation, focusSearch);
|
||||
}
|
||||
}
|
||||
|
||||
private void BackButton_Tapped(object sender, Microsoft.UI.Xaml.Input.TappedRoutedEventArgs e) => WeakReferenceMessenger.Default.Send<NavigateBackMessage>(new());
|
||||
|
||||
private void RootFrame_Navigated(object sender, Microsoft.UI.Xaml.Navigation.NavigationEventArgs e)
|
||||
{
|
||||
// This listens to the root frame to ensure that we also track the content's page VM as well that we passed as a parameter.
|
||||
// This is currently used for both forward and backward navigation.
|
||||
// As when we go back that we restore ourselves to the proper state within our VM
|
||||
if (e.Parameter is PageViewModel page)
|
||||
{
|
||||
// Note, this shortcuts and fights a bit with our LoadPageViewModel above, but we want to better fast display and incrementally load anyway
|
||||
// We just need to reconcile our loading systems a bit more in the future.
|
||||
if (ViewModel != null)
|
||||
{
|
||||
ViewModel.CurrentPage = page;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether determines if the current Details have a HeroImage, given the theme
|
||||
/// we're currently in. This needs to be evaluated in the view, because the
|
||||
/// viewModel doesn't actually know what the current theme is.
|
||||
/// </summary>
|
||||
public bool HasHeroImage
|
||||
{
|
||||
get
|
||||
{
|
||||
var requestedTheme = ActualTheme;
|
||||
var iconInfoVM = ViewModel?.Details?.HeroImage;
|
||||
return iconInfoVM?.HasIcon(requestedTheme == Microsoft.UI.Xaml.ElementTheme.Light) ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
// [DynamicWindowsRuntimeCast(typeof(Button))]
|
||||
private void Command_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button button && button.DataContext is CommandViewModel commandViewModel)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<PerformCommandMessage>(new(commandViewModel.Model));
|
||||
}
|
||||
}
|
||||
|
||||
private void ShellPage_OnPointerPressed(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ptr = e.Pointer;
|
||||
if (ptr.PointerDeviceType == PointerDeviceType.Mouse)
|
||||
{
|
||||
var ptrPt = e.GetCurrentPoint(this);
|
||||
if (ptrPt.Properties.IsXButton1Pressed)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send(new NavigateBackMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CoreLogger.LogError("Error handling mouse button press event", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||
<Application>
|
||||
<Assembly Name="Microsoft.WinUI">
|
||||
<Type Name="Microsoft.UI.Xaml.Controls.FontIconSource" Dynamic="Required All" />
|
||||
</Assembly>
|
||||
</Application>
|
||||
</Directives>
|
||||
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Application
|
||||
x:Class="Microsoft.CmdPal.Core.UI.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Microsoft.CmdPal.Core.UI">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
<!-- Other merged dictionaries here -->
|
||||
<ResourceDictionary Source="Styles/Button.xaml" />
|
||||
<ResourceDictionary Source="Styles/Colors.xaml" />
|
||||
<ResourceDictionary Source="Styles/TextBlock.xaml" />
|
||||
<ResourceDictionary Source="Styles/TextBox.xaml" />
|
||||
<ResourceDictionary Source="Styles/Settings.xaml" />
|
||||
<ResourceDictionary Source="Styles/Tag.xaml" />
|
||||
<!-- <ResourceDictionary Source="Controls/KeyVisual/KeyVisual.xaml" /> -->
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<!-- Other app resources here -->
|
||||
|
||||
<!-- <x:Double x:Key="SettingActionControlMinWidth">240</x:Double> -->
|
||||
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -1,160 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.Ext.Shell;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
namespace Microsoft.CmdPal.Core.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Provides application-specific behavior to supplement the default Application class.
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the current <see cref="App"/> instance in use.
|
||||
/// </summary>
|
||||
public static new App Current => (App)Application.Current;
|
||||
|
||||
public Window? AppWindow { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IServiceProvider"/> instance to resolve application services.
|
||||
/// </summary>
|
||||
public IServiceProvider Services { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="App"/> class.
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
Services = ConfigureServices();
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the application is launched.
|
||||
/// </summary>
|
||||
/// <param name="args">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
|
||||
{
|
||||
AppWindow = new MainWindow(Services);
|
||||
|
||||
// var activatedEventArgs = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs();
|
||||
// ((MainWindow)AppWindow).HandleLaunch(activatedEventArgs);
|
||||
AppWindow.Activate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the services for the application
|
||||
/// </summary>
|
||||
private static ServiceProvider ConfigureServices()
|
||||
{
|
||||
// TODO: It's in the Labs feed, but we can use Sergio's AOT-friendly source generator for this: https://github.com/CommunityToolkit/Labs-Windows/discussions/463
|
||||
ServiceCollection services = new();
|
||||
|
||||
// Root services
|
||||
services.AddSingleton(TaskScheduler.FromCurrentSynchronizationContext());
|
||||
|
||||
// Built-in Commands. Order matters - this is the order they'll be presented by default.
|
||||
services.AddSingleton<ICommandProvider, ShellCommandsProvider>(); // TODO! test
|
||||
|
||||
// Models
|
||||
|
||||
// TODO!
|
||||
services.AddSingleton<IRootPageService, CoreRootPageService>();
|
||||
|
||||
services.AddSingleton<IAppHostService, DummyAppHostService>();
|
||||
|
||||
// services.AddSingleton(new TelemetryForwarder());
|
||||
|
||||
// ViewModels
|
||||
services.AddSingleton<ShellViewModel>();
|
||||
|
||||
// TODO!
|
||||
services.AddSingleton<IPageViewModelFactoryService, CoreViewModelFactory>();
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
|
||||
internal sealed class CoreRootPageService : IRootPageService, IDisposable
|
||||
{
|
||||
private readonly ShellCommandsProvider _shellCommandsProvider = new();
|
||||
|
||||
public CoreRootPageService()
|
||||
{
|
||||
}
|
||||
|
||||
public IPage GetRootPage()
|
||||
{
|
||||
var commands = _shellCommandsProvider.TopLevelCommands();
|
||||
var commandItem = commands[0];
|
||||
return (commandItem.Command as IPage)!;
|
||||
}
|
||||
|
||||
public void GoHome()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnPerformCommand(object? context, bool topLevel, AppExtensionHost? currentHost)
|
||||
{
|
||||
}
|
||||
|
||||
public Task PostLoadRootPageAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task PreLoadAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed partial class DummyAppHost : AppExtensionHost
|
||||
{
|
||||
public override string? GetExtensionDisplayName() => "This is test code fool";
|
||||
}
|
||||
|
||||
internal sealed class DummyAppHostService : IAppHostService
|
||||
{
|
||||
private readonly DummyAppHost _host = new();
|
||||
|
||||
public AppExtensionHost GetDefaultHost() => _host;
|
||||
|
||||
public AppExtensionHost GetHostForCommand(object? context, AppExtensionHost? currentHost) => _host;
|
||||
}
|
||||
|
||||
internal sealed class CoreViewModelFactory : IPageViewModelFactoryService
|
||||
{
|
||||
private readonly TaskScheduler _scheduler;
|
||||
|
||||
public CoreViewModelFactory(TaskScheduler scheduler)
|
||||
{
|
||||
_scheduler = scheduler;
|
||||
}
|
||||
|
||||
public PageViewModel? TryCreatePageViewModel(IPage page, bool nested, AppExtensionHost host)
|
||||
{
|
||||
return page switch
|
||||
{
|
||||
IListPage listPage => new ListViewModel(listPage, _scheduler, host) { IsNested = nested },
|
||||
IContentPage contentPage => new ContentPageViewModel(contentPage, _scheduler, host),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<Window
|
||||
x:Class="Microsoft.CmdPal.Core.UI.MainWindow"
|
||||
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"
|
||||
xmlns:pages="using:Microsoft.CmdPal.Core.Control.Pages"
|
||||
xmlns:viewModels="using:Microsoft.CmdPal.Core.ViewModels"
|
||||
mc:Ignorable="d">
|
||||
<pages:ShellPage x:Name="RootShellPage" ViewModel="{x:Bind ShellViewModel, Mode=OneWay}" />
|
||||
</Window>
|
||||
@@ -1,668 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Common.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
// using Microsoft.CmdPal.UI.Events;
|
||||
// using Microsoft.CmdPal.UI.Helpers;
|
||||
// using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.UI.Composition;
|
||||
using Microsoft.UI.Composition.SystemBackdrops;
|
||||
using Microsoft.UI.Input;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Windows.Foundation;
|
||||
using Windows.Graphics;
|
||||
using Windows.UI;
|
||||
using Windows.UI.WindowManagement;
|
||||
using Windows.Win32.Foundation;
|
||||
using WinRT;
|
||||
|
||||
// using RS_ = Microsoft.CmdPal.UI.Helpers.ResourceLoaderInstance;
|
||||
namespace Microsoft.CmdPal.Core.UI;
|
||||
|
||||
public sealed partial class MainWindow : Window,
|
||||
IRecipient<DismissMessage>,
|
||||
IRecipient<ShowWindowMessage>,
|
||||
IRecipient<HideWindowMessage>,
|
||||
IRecipient<QuitMessage>
|
||||
{
|
||||
// [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Stylistically, window messages are WM_")]
|
||||
// [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:Field names should begin with lower-case letter", Justification = "Stylistically, window messages are WM_")]
|
||||
// private readonly uint WM_TASKBAR_RESTART;
|
||||
private readonly HWND _hwnd;
|
||||
|
||||
// private readonly WNDPROC? _hotkeyWndProc;
|
||||
// private readonly WNDPROC? _originalWndProc;
|
||||
// private readonly List<TopLevelHotkey> _hotkeys = [];
|
||||
// private readonly KeyboardListener _keyboardListener;
|
||||
// private bool _ignoreHotKeyWhenFullScreen = true;
|
||||
private DesktopAcrylicController? _acrylicController;
|
||||
private SystemBackdropConfiguration? _configurationSource;
|
||||
|
||||
public ShellViewModel ShellViewModel { get; }
|
||||
|
||||
public MainWindow(IServiceProvider provider)
|
||||
{
|
||||
ShellViewModel = provider.GetRequiredService<ShellViewModel>();
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
_hwnd = new HWND(WinRT.Interop.WindowNative.GetWindowHandle(this).ToInt32());
|
||||
|
||||
// unsafe
|
||||
// {
|
||||
// CommandPaletteHost.SetHostHwnd((ulong)_hwnd.Value);
|
||||
// }
|
||||
|
||||
// _keyboardListener = new KeyboardListener();
|
||||
// _keyboardListener.Start();
|
||||
|
||||
// _keyboardListener.SetProcessCommand(new CmdPalKeyboardService.ProcessCommand(HandleSummon));
|
||||
// this.SetIcon();
|
||||
AppWindow.Title = "Command Palette Core";
|
||||
AppWindow.Resize(new SizeInt32(740, 320));
|
||||
PositionCentered();
|
||||
SetAcrylic();
|
||||
|
||||
WeakReferenceMessenger.Default.Register<DismissMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<QuitMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<ShowWindowMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<HideWindowMessage>(this);
|
||||
|
||||
// Hide our titlebar.
|
||||
// We need to both ExtendsContentIntoTitleBar, then set the height to Collapsed
|
||||
// to hide the old caption buttons. Then, in UpdateRegionsForCustomTitleBar,
|
||||
// we'll make the top drag-able again. (after our content loads)
|
||||
ExtendsContentIntoTitleBar = true;
|
||||
AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Collapsed;
|
||||
SizeChanged += WindowSizeChanged;
|
||||
RootShellPage.Loaded += RootShellPage_Loaded;
|
||||
|
||||
// WM_TASKBAR_RESTART = PInvoke.RegisterWindowMessage("TaskbarCreated");
|
||||
|
||||
// // LOAD BEARING: If you don't stick the pointer to HotKeyPrc into a
|
||||
// // member (and instead like, use a local), then the pointer we marshal
|
||||
// // into the WindowLongPtr will be useless after we leave this function,
|
||||
// // and our **WindProc will explode**.
|
||||
// _hotkeyWndProc = HotKeyPrc;
|
||||
// var hotKeyPrcPointer = Marshal.GetFunctionPointerForDelegate(_hotkeyWndProc);
|
||||
// _originalWndProc = Marshal.GetDelegateForFunctionPointer<WNDPROC>(PInvoke.SetWindowLongPtr(_hwnd, WINDOW_LONG_PTR_INDEX.GWL_WNDPROC, hotKeyPrcPointer));
|
||||
|
||||
// Load our settings, and then also wire up a settings changed handler
|
||||
// HotReloadSettings();
|
||||
// App.Current.Services.GetService<SettingsModel>()!.SettingsChanged += SettingsChangedHandler;
|
||||
|
||||
// Make sure that we update the acrylic theme when the OS theme changes
|
||||
RootShellPage.ActualThemeChanged += (s, e) => UpdateAcrylic();
|
||||
|
||||
// // Hardcoding event name to avoid bringing in the PowerToys.interop dependency. Event name must match CMDPAL_SHOW_EVENT from shared_constants.h
|
||||
// NativeEventWaiter.WaitForEventLoop("Local\\PowerToysCmdPal-ShowEvent-62336fcd-8611-4023-9b30-091a6af4cc5a", () =>
|
||||
// {
|
||||
// Summon(string.Empty);
|
||||
// });
|
||||
}
|
||||
|
||||
// private void SettingsChangedHandler(SettingsModel sender, object? args) => HotReloadSettings();
|
||||
private void RootShellPage_Loaded(object sender, RoutedEventArgs e) =>
|
||||
|
||||
// Now that our content has loaded, we can update our draggable regions
|
||||
UpdateRegionsForCustomTitleBar();
|
||||
|
||||
private void WindowSizeChanged(object sender, WindowSizeChangedEventArgs args) => UpdateRegionsForCustomTitleBar();
|
||||
|
||||
private void PositionCentered()
|
||||
{
|
||||
var displayArea = DisplayArea.GetFromWindowId(AppWindow.Id, DisplayAreaFallback.Nearest);
|
||||
PositionCentered(displayArea);
|
||||
}
|
||||
|
||||
private void PositionCentered(DisplayArea displayArea)
|
||||
{
|
||||
if (displayArea is not null)
|
||||
{
|
||||
var centeredPosition = AppWindow.Position;
|
||||
centeredPosition.X = (displayArea.WorkArea.Width - AppWindow.Size.Width) / 2;
|
||||
centeredPosition.Y = (displayArea.WorkArea.Height - AppWindow.Size.Height) / 2;
|
||||
|
||||
centeredPosition.X += displayArea.WorkArea.X;
|
||||
centeredPosition.Y += displayArea.WorkArea.Y;
|
||||
AppWindow.Move(centeredPosition);
|
||||
}
|
||||
}
|
||||
|
||||
// private void HotReloadSettings()
|
||||
// {
|
||||
// var settings = App.Current.Services.GetService<SettingsModel>()!;
|
||||
|
||||
// SetupHotkey(settings);
|
||||
// App.Current.Services.GetService<TrayIconService>()!.SetupTrayIcon(settings.ShowSystemTrayIcon);
|
||||
|
||||
// _ignoreHotKeyWhenFullScreen = settings.IgnoreShortcutWhenFullscreen;
|
||||
|
||||
// this.SetVisibilityInSwitchers(Debugger.IsAttached);
|
||||
// }
|
||||
|
||||
// We want to use DesktopAcrylicKind.Thin and custom colors as this is the default material
|
||||
// other Shell surfaces are using, this cannot be set in XAML however.
|
||||
private void SetAcrylic()
|
||||
{
|
||||
if (DesktopAcrylicController.IsSupported())
|
||||
{
|
||||
// Hooking up the policy object.
|
||||
_configurationSource = new SystemBackdropConfiguration
|
||||
{
|
||||
// Initial configuration state.
|
||||
IsInputActive = true,
|
||||
};
|
||||
UpdateAcrylic();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAcrylic()
|
||||
{
|
||||
_acrylicController = GetAcrylicConfig(Content);
|
||||
|
||||
// Enable the system backdrop.
|
||||
// Note: Be sure to have "using WinRT;" to support the Window.As<...>() call.
|
||||
_acrylicController.AddSystemBackdropTarget(this.As<ICompositionSupportsSystemBackdrop>());
|
||||
_acrylicController.SetSystemBackdropConfiguration(_configurationSource);
|
||||
}
|
||||
|
||||
private static DesktopAcrylicController GetAcrylicConfig(UIElement content)
|
||||
{
|
||||
var feContent = content as FrameworkElement;
|
||||
|
||||
return feContent?.ActualTheme == ElementTheme.Light
|
||||
? new DesktopAcrylicController()
|
||||
{
|
||||
Kind = DesktopAcrylicKind.Thin,
|
||||
TintColor = Color.FromArgb(255, 243, 243, 243),
|
||||
LuminosityOpacity = 0.90f,
|
||||
TintOpacity = 0.0f,
|
||||
FallbackColor = Color.FromArgb(255, 238, 238, 238),
|
||||
}
|
||||
: new DesktopAcrylicController()
|
||||
{
|
||||
Kind = DesktopAcrylicKind.Thin,
|
||||
TintColor = Color.FromArgb(255, 32, 32, 32),
|
||||
LuminosityOpacity = 0.96f,
|
||||
TintOpacity = 0.5f,
|
||||
FallbackColor = Color.FromArgb(255, 28, 28, 28),
|
||||
};
|
||||
}
|
||||
|
||||
// private void ShowHwnd(IntPtr hwndValue, MonitorBehavior target)
|
||||
// {
|
||||
// var hwnd = new HWND(hwndValue != 0 ? hwndValue : _hwnd);
|
||||
|
||||
// // Make sure our HWND is cloaked before any possible window manipulations
|
||||
// Cloak();
|
||||
|
||||
// // Remember, IsIconic == "minimized", which is entirely different state
|
||||
// // from "show/hide"
|
||||
// // If we're currently minimized, restore us first, before we reveal
|
||||
// // our window. Otherwise, we'd just be showing a minimized window -
|
||||
// // which would remain not visible to the user.
|
||||
// if (PInvoke.IsIconic(hwnd))
|
||||
// {
|
||||
// PInvoke.ShowWindow(hwnd, SHOW_WINDOW_CMD.SW_RESTORE);
|
||||
// }
|
||||
|
||||
// var display = GetScreen(hwnd, target);
|
||||
// PositionCentered(display);
|
||||
|
||||
// // Just to be sure, SHOW our hwnd.
|
||||
// PInvoke.ShowWindow(hwnd, SHOW_WINDOW_CMD.SW_SHOW);
|
||||
|
||||
// // Once we're done, uncloak to avoid all animations
|
||||
// Uncloak();
|
||||
|
||||
// PInvoke.SetForegroundWindow(hwnd);
|
||||
// PInvoke.SetActiveWindow(hwnd);
|
||||
|
||||
// // Push our window to the top of the Z-order and make it the topmost, so that it appears above all other windows.
|
||||
// // We want to remove the topmost status when we hide the window (because we cloak it instead of hiding it).
|
||||
// PInvoke.SetWindowPos(hwnd, HWND.HWND_TOPMOST, 0, 0, 0, 0, SET_WINDOW_POS_FLAGS.SWP_NOMOVE | SET_WINDOW_POS_FLAGS.SWP_NOSIZE);
|
||||
// }
|
||||
// private DisplayArea GetScreen(HWND currentHwnd, MonitorBehavior target)
|
||||
// {
|
||||
// // Leaving a note here, in case we ever need it:
|
||||
// // https://github.com/microsoft/microsoft-ui-xaml/issues/6454
|
||||
// // If we need to ever FindAll, we'll need to iterate manually
|
||||
// var displayAreas = Microsoft.UI.Windowing.DisplayArea.FindAll();
|
||||
// switch (target)
|
||||
// {
|
||||
// case MonitorBehavior.InPlace:
|
||||
// if (PInvoke.GetWindowRect(currentHwnd, out var bounds))
|
||||
// {
|
||||
// RectInt32 converted = new(bounds.X, bounds.Y, bounds.Width, bounds.Height);
|
||||
// return DisplayArea.GetFromRect(converted, DisplayAreaFallback.Nearest);
|
||||
// }
|
||||
|
||||
// break;
|
||||
|
||||
// case MonitorBehavior.ToFocusedWindow:
|
||||
// var foregroundWindowHandle = PInvoke.GetForegroundWindow();
|
||||
// if (foregroundWindowHandle != IntPtr.Zero)
|
||||
// {
|
||||
// if (PInvoke.GetWindowRect(foregroundWindowHandle, out var fgBounds))
|
||||
// {
|
||||
// RectInt32 converted = new(fgBounds.X, fgBounds.Y, fgBounds.Width, fgBounds.Height);
|
||||
// return DisplayArea.GetFromRect(converted, DisplayAreaFallback.Nearest);
|
||||
// }
|
||||
// }
|
||||
|
||||
// break;
|
||||
|
||||
// case MonitorBehavior.ToPrimary:
|
||||
// return DisplayArea.Primary;
|
||||
|
||||
// case MonitorBehavior.ToMouse:
|
||||
// default:
|
||||
// if (PInvoke.GetCursorPos(out var cursorPos))
|
||||
// {
|
||||
// return DisplayArea.GetFromPoint(new PointInt32(cursorPos.X, cursorPos.Y), DisplayAreaFallback.Nearest);
|
||||
// }
|
||||
|
||||
// break;
|
||||
// }
|
||||
|
||||
// return DisplayArea.Primary;
|
||||
// }
|
||||
public void Receive(ShowWindowMessage message)
|
||||
{
|
||||
// var settings = App.Current.Services.GetService<SettingsModel>()!;
|
||||
|
||||
// ShowHwnd(message.Hwnd, settings.SummonOn);
|
||||
}
|
||||
|
||||
public void Receive(HideWindowMessage message)
|
||||
{
|
||||
// This might come in off the UI thread. Make sure to hop back.
|
||||
DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
HideWindow();
|
||||
});
|
||||
}
|
||||
|
||||
public void Receive(QuitMessage message) =>
|
||||
|
||||
// This might come in on a background thread
|
||||
DispatcherQueue.TryEnqueue(() => Close());
|
||||
|
||||
public void Receive(DismissMessage message)
|
||||
{
|
||||
// This might come in off the UI thread. Make sure to hop back.
|
||||
DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
HideWindow();
|
||||
});
|
||||
}
|
||||
|
||||
private void HideWindow()
|
||||
{
|
||||
// // Cloak our HWND to avoid all animations.
|
||||
// Cloak();
|
||||
|
||||
// // Then hide our HWND, to make sure that the OS gives the FG / focus back to another app
|
||||
// // (there's no way for us to guess what the right hwnd might be, only the OS can do it right)
|
||||
// PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
|
||||
|
||||
// // TRICKY: show our HWND again. This will trick XAML into painting our
|
||||
// // HWND again, so that we avoid the "flicker" caused by a WinUI3 app
|
||||
// // window being first shown
|
||||
// // SW_SHOWNA will prevent us for trying to fight the focus back
|
||||
// PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_SHOWNA);
|
||||
|
||||
// // Intentionally leave the window cloaked. So our window is "visible",
|
||||
// // but also cloaked, so you can't see it.
|
||||
}
|
||||
|
||||
private void Cloak()
|
||||
{
|
||||
// unsafe
|
||||
// {
|
||||
// BOOL value = true;
|
||||
// PInvoke.DwmSetWindowAttribute(_hwnd, DWMWINDOWATTRIBUTE.DWMWA_CLOAK, &value, (uint)sizeof(BOOL));
|
||||
// }
|
||||
|
||||
// // Because we're only cloaking the window, bury it at the bottom in case something can
|
||||
// // see it - e.g. some accessibility helper (note: this also removes the top-most status).
|
||||
// PInvoke.SetWindowPos(_hwnd, HWND.HWND_BOTTOM, 0, 0, 0, 0, SET_WINDOW_POS_FLAGS.SWP_NOMOVE | SET_WINDOW_POS_FLAGS.SWP_NOSIZE);
|
||||
}
|
||||
|
||||
private void Uncloak()
|
||||
{
|
||||
// unsafe
|
||||
// {
|
||||
// BOOL value = false;
|
||||
// PInvoke.DwmSetWindowAttribute(_hwnd, DWMWINDOWATTRIBUTE.DWMWA_CLOAK, &value, (uint)sizeof(BOOL));
|
||||
// }
|
||||
}
|
||||
|
||||
internal void MainWindow_Closed(object sender, WindowEventArgs args)
|
||||
{
|
||||
// var serviceProvider = App.Current.Services;
|
||||
// var extensionService = serviceProvider.GetService<IExtensionService>()!;
|
||||
// extensionService.SignalStopExtensionsAsync();
|
||||
|
||||
// App.Current.Services.GetService<TrayIconService>()!.Destroy();
|
||||
|
||||
// WinUI bug is causing a crash on shutdown when FailFastOnErrors is set to true (#51773592).
|
||||
// Workaround by turning it off before shutdown.
|
||||
App.Current.DebugSettings.FailFastOnErrors = false;
|
||||
DisposeAcrylic();
|
||||
|
||||
// _keyboardListener.Stop();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
private void DisposeAcrylic()
|
||||
{
|
||||
if (_acrylicController != null)
|
||||
{
|
||||
_acrylicController.Dispose();
|
||||
_acrylicController = null!;
|
||||
_configurationSource = null!;
|
||||
}
|
||||
}
|
||||
|
||||
// Updates our window s.t. the top of the window is draggable.
|
||||
private void UpdateRegionsForCustomTitleBar()
|
||||
{
|
||||
// Specify the interactive regions of the title bar.
|
||||
var scaleAdjustment = RootShellPage.XamlRoot.RasterizationScale;
|
||||
|
||||
// Get the rectangle around our XAML content. We're going to mark this
|
||||
// rectangle as "Passthrough", so that the normal window operations
|
||||
// (resizing, dragging) don't apply in this space.
|
||||
var transform = RootShellPage.TransformToVisual(null);
|
||||
|
||||
// Reserve 16px of space at the top for dragging.
|
||||
var topHeight = 16;
|
||||
var bounds = transform.TransformBounds(new Rect(
|
||||
0,
|
||||
topHeight,
|
||||
RootShellPage.ActualWidth,
|
||||
RootShellPage.ActualHeight));
|
||||
var contentRect = GetRect(bounds, scaleAdjustment);
|
||||
var rectArray = new RectInt32[] { contentRect };
|
||||
var nonClientInputSrc = InputNonClientPointerSource.GetForWindowId(this.AppWindow.Id);
|
||||
nonClientInputSrc.SetRegionRects(NonClientRegionKind.Passthrough, rectArray);
|
||||
|
||||
// Add a drag-able region on top
|
||||
var w = RootShellPage.ActualWidth;
|
||||
_ = RootShellPage.ActualHeight;
|
||||
var dragSides = new RectInt32[]
|
||||
{
|
||||
GetRect(new Rect(0, 0, w, topHeight), scaleAdjustment), // the top, {topHeight=16} tall
|
||||
};
|
||||
nonClientInputSrc.SetRegionRects(NonClientRegionKind.Caption, dragSides);
|
||||
}
|
||||
|
||||
private static RectInt32 GetRect(Rect bounds, double scale)
|
||||
{
|
||||
return new RectInt32(
|
||||
_X: (int)Math.Round(bounds.X * scale),
|
||||
_Y: (int)Math.Round(bounds.Y * scale),
|
||||
_Width: (int)Math.Round(bounds.Width * scale),
|
||||
_Height: (int)Math.Round(bounds.Height * scale));
|
||||
}
|
||||
|
||||
internal void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
|
||||
{
|
||||
if (args.WindowActivationState == WindowActivationState.Deactivated)
|
||||
{
|
||||
// If there's a debugger attached...
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
// ... then don't hide the window when it loses focus.
|
||||
return;
|
||||
}
|
||||
|
||||
// // Are we disabled? If we are, then we don't want to dismiss on focus lost.
|
||||
// // This can happen if an extension wanted to show a modal dialog on top of our
|
||||
// // window i.e. in the case of an MSAL auth window.
|
||||
// if (PInvoke.IsWindowEnabled(_hwnd) == 0)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // This will DWM cloak our window:
|
||||
// HideWindow();
|
||||
|
||||
// PowerToysTelemetry.Log.WriteEvent(new CmdPalDismissedOnLostFocus());
|
||||
}
|
||||
|
||||
if (_configurationSource != null)
|
||||
{
|
||||
_configurationSource.IsInputActive = args.WindowActivationState != WindowActivationState.Deactivated;
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleLaunch(AppActivationArguments? activatedEventArgs)
|
||||
{
|
||||
if (activatedEventArgs == null)
|
||||
{
|
||||
Activate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// try
|
||||
// {
|
||||
// if (activatedEventArgs.Kind == ExtendedActivationKind.StartupTask)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (activatedEventArgs.Kind == ExtendedActivationKind.Protocol)
|
||||
// {
|
||||
// if (activatedEventArgs.Data is IProtocolActivatedEventArgs protocolArgs)
|
||||
// {
|
||||
// if (protocolArgs.Uri.ToString() is string uri)
|
||||
// {
|
||||
// // was the URI "x-cmdpal://background" ?
|
||||
// if (uri.StartsWith("x-cmdpal://background", StringComparison.OrdinalIgnoreCase))
|
||||
// {
|
||||
// // we're running, we don't want to activate our window. bail
|
||||
// return;
|
||||
// }
|
||||
// else if (uri.StartsWith("x-cmdpal://settings", StringComparison.OrdinalIgnoreCase))
|
||||
// {
|
||||
// WeakReferenceMessenger.Default.Send<OpenSettingsMessage>(new());
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// catch (COMException ex)
|
||||
// {
|
||||
// // Accessing properties activatedEventArgs.Kind and activatedEventArgs.Data might cause COMException
|
||||
// // if the args are not valid or not passed correctly.
|
||||
// Logger.LogError("COM exception when activating the application", ex);
|
||||
// }
|
||||
|
||||
// Summon(string.Empty);
|
||||
// }
|
||||
|
||||
// public void Summon(string commandId) =>
|
||||
|
||||
// // The actual showing and hiding of the window will be done by the
|
||||
// // ShellPage. This is because we don't want to show the window if the
|
||||
// // user bound a hotkey to just an invokable command, which we can't
|
||||
// // know till the message is being handled.
|
||||
// WeakReferenceMessenger.Default.Send<HotkeySummonMessage>(new(commandId, _hwnd));
|
||||
|
||||
// private void UnregisterHotkeys()
|
||||
// {
|
||||
// _keyboardListener.ClearHotkeys();
|
||||
|
||||
// while (_hotkeys.Count > 0)
|
||||
// {
|
||||
// PInvoke.UnregisterHotKey(_hwnd, _hotkeys.Count - 1);
|
||||
// _hotkeys.RemoveAt(_hotkeys.Count - 1);
|
||||
// }
|
||||
// }
|
||||
|
||||
// private void SetupHotkey(SettingsModel settings)
|
||||
// {
|
||||
// UnregisterHotkeys();
|
||||
|
||||
// var globalHotkey = settings.Hotkey;
|
||||
// if (globalHotkey != null)
|
||||
// {
|
||||
// if (settings.UseLowLevelGlobalHotkey)
|
||||
// {
|
||||
// _keyboardListener.SetHotkeyAction(globalHotkey.Win, globalHotkey.Ctrl, globalHotkey.Shift, globalHotkey.Alt, (byte)globalHotkey.Code, string.Empty);
|
||||
|
||||
// _hotkeys.Add(new(globalHotkey, string.Empty));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var vk = globalHotkey.Code;
|
||||
// var modifiers =
|
||||
// (globalHotkey.Alt ? HOT_KEY_MODIFIERS.MOD_ALT : 0) |
|
||||
// (globalHotkey.Ctrl ? HOT_KEY_MODIFIERS.MOD_CONTROL : 0) |
|
||||
// (globalHotkey.Shift ? HOT_KEY_MODIFIERS.MOD_SHIFT : 0) |
|
||||
// (globalHotkey.Win ? HOT_KEY_MODIFIERS.MOD_WIN : 0)
|
||||
// ;
|
||||
|
||||
// var success = PInvoke.RegisterHotKey(_hwnd, _hotkeys.Count, modifiers, (uint)vk);
|
||||
// if (success)
|
||||
// {
|
||||
// _hotkeys.Add(new(globalHotkey, string.Empty));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// foreach (var commandHotkey in settings.CommandHotkeys)
|
||||
// {
|
||||
// var key = commandHotkey.Hotkey;
|
||||
|
||||
// if (key != null)
|
||||
// {
|
||||
// if (settings.UseLowLevelGlobalHotkey)
|
||||
// {
|
||||
// _keyboardListener.SetHotkeyAction(key.Win, key.Ctrl, key.Shift, key.Alt, (byte)key.Code, commandHotkey.CommandId);
|
||||
|
||||
// _hotkeys.Add(new(globalHotkey, string.Empty));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var vk = key.Code;
|
||||
// var modifiers =
|
||||
// (key.Alt ? HOT_KEY_MODIFIERS.MOD_ALT : 0) |
|
||||
// (key.Ctrl ? HOT_KEY_MODIFIERS.MOD_CONTROL : 0) |
|
||||
// (key.Shift ? HOT_KEY_MODIFIERS.MOD_SHIFT : 0) |
|
||||
// (key.Win ? HOT_KEY_MODIFIERS.MOD_WIN : 0)
|
||||
// ;
|
||||
|
||||
// var success = PInvoke.RegisterHotKey(_hwnd, _hotkeys.Count, modifiers, (uint)vk);
|
||||
// if (success)
|
||||
// {
|
||||
// _hotkeys.Add(commandHotkey);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// private void HandleSummon(string commandId)
|
||||
// {
|
||||
// var isRootHotkey = string.IsNullOrEmpty(commandId);
|
||||
// PowerToysTelemetry.Log.WriteEvent(new CmdPalHotkeySummoned(isRootHotkey));
|
||||
|
||||
// var isVisible = this.Visible;
|
||||
|
||||
// unsafe
|
||||
// {
|
||||
// // We need to check if our window is cloaked or not. A cloaked window is still
|
||||
// // technically visible, because SHOW/HIDE != iconic (minimized) != cloaked
|
||||
// // (these are all separate states)
|
||||
// long attr = 0;
|
||||
// PInvoke.DwmGetWindowAttribute(_hwnd, DWMWINDOWATTRIBUTE.DWMWA_CLOAKED, &attr, sizeof(long));
|
||||
// if (attr == 1 /* DWM_CLOAKED_APP */)
|
||||
// {
|
||||
// isVisible = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Note to future us: the wParam will have the index of the hotkey we registered.
|
||||
// // We can use that in the future to differentiate the hotkeys we've pressed
|
||||
// // so that we can bind hotkeys to individual commands
|
||||
// if (!isVisible || !isRootHotkey)
|
||||
// {
|
||||
// Activate();
|
||||
|
||||
// Summon(commandId);
|
||||
// }
|
||||
// else if (isRootHotkey)
|
||||
// {
|
||||
// // If there's a debugger attached...
|
||||
// if (System.Diagnostics.Debugger.IsAttached)
|
||||
// {
|
||||
// // ... then manually hide our window. When debugged, we won't get the cool cloaking,
|
||||
// // but that's the price to pay for having the HWND not light-dismiss while we're debugging.
|
||||
// Cloak();
|
||||
// this.Hide();
|
||||
|
||||
// return;
|
||||
// }
|
||||
|
||||
// HideWindow();
|
||||
// }
|
||||
// }
|
||||
|
||||
// private LRESULT HotKeyPrc(
|
||||
// HWND hwnd,
|
||||
// uint uMsg,
|
||||
// WPARAM wParam,
|
||||
// LPARAM lParam)
|
||||
// {
|
||||
// switch (uMsg)
|
||||
// {
|
||||
// // Prevent the window from maximizing when double-clicking the title bar area
|
||||
// case PInvoke.WM_NCLBUTTONDBLCLK:
|
||||
// return (LRESULT)IntPtr.Zero;
|
||||
// case PInvoke.WM_HOTKEY:
|
||||
// {
|
||||
// var hotkeyIndex = (int)wParam.Value;
|
||||
// if (hotkeyIndex < _hotkeys.Count)
|
||||
// {
|
||||
// if (_ignoreHotKeyWhenFullScreen)
|
||||
// {
|
||||
// // If we're in full screen mode, ignore the hotkey
|
||||
// if (WindowHelper.IsWindowFullscreen())
|
||||
// {
|
||||
// return (LRESULT)IntPtr.Zero;
|
||||
// }
|
||||
// }
|
||||
|
||||
// var hotkey = _hotkeys[hotkeyIndex];
|
||||
// HandleSummon(hotkey.CommandId);
|
||||
// }
|
||||
|
||||
// return (LRESULT)IntPtr.Zero;
|
||||
// }
|
||||
|
||||
// default:
|
||||
// if (uMsg == WM_TASKBAR_RESTART)
|
||||
// {
|
||||
// HotReloadSettings();
|
||||
// }
|
||||
|
||||
// break;
|
||||
// }
|
||||
|
||||
// return PInvoke.CallWindowProc(_originalWndProc, hwnd, uMsg, wParam, lParam);
|
||||
// }
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
|
||||
<Import Project="..\..\..\CmdPalVersion.props" />
|
||||
<Import Project="..\Microsoft.CmdPal.UI\CmdPal.pre.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>Microsoft.CmdPal.Core.UI</RootNamespace>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<PublishProfile>win-$(Platform).pubxml</PublishProfile>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
|
||||
<Version>$(CmdPalVersion)</Version>
|
||||
|
||||
<!-- OutputPath is set in CmdPal.Branding.props -->
|
||||
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Branding -->
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>$(SolutionDir)\src\modules\cmdpal\Microsoft.CmdPal.UI\Assets\Dev\icon.ico</ApplicationIcon>
|
||||
<CmdPalAssetSuffix>Dev</CmdPalAssetSuffix>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Images -->
|
||||
<Content Include="$(SolutionDir)\src\modules\cmdpal\Microsoft.CmdPal.UI\Assets\$(CmdPalAssetSuffix)\**\*">
|
||||
<DeploymentContent>true</DeploymentContent>
|
||||
<Link>Assets\%(RecursiveDir)%(FileName)%(Extension)</Link>
|
||||
</Content>
|
||||
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
|
||||
<AppxManifest Include="Package.appxmanifest" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- This lets us actually reference types from Microsoft.Terminal.UI -->
|
||||
<!-- <CsWinRTIncludes>Microsoft.Terminal.UI;</CsWinRTIncludes> -->
|
||||
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- This disables the auto-generated main, so we can be single-instanced -->
|
||||
<DefineConstants>DISABLE_XAML_GENERATED_MAIN</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- BODGY: XES Versioning and WinAppSDK get into a fight about the app manifest, which breaks WinAppSDK. -->
|
||||
<Target Name="RearrangeXefVersioningAndWinAppSDKResourceGeneration" DependsOnTargets="GetNewAppManifestValues;CreateWinRTRegistration" BeforeTargets="XesWriteVersionInfoResourceFile">
|
||||
<PropertyGroup>
|
||||
<!-- XES uses this property to store the "final" location of the app manifest, before it erases it.
|
||||
We have to update it to the value WinAppSDK set it to. -->
|
||||
<OriginalApplicationManifest>$(ApplicationManifest.Replace("$(MSBuildProjectDirectory)\",""))</OriginalApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<Message Importance="High" Text="Updated final manifest path to $(OriginalApplicationManifest)" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Converters" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Animations" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.Markdown" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" />
|
||||
<PackageReference Include="WinUIEx" />
|
||||
<PackageReference Include="Microsoft.Windows.CsWin32">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" />
|
||||
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
|
||||
<PackageReference Include="System.Private.Uri" />
|
||||
<PackageReference Include="System.Text.Json" />
|
||||
|
||||
<PackageReference Include="System.Text.RegularExpressions" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging
|
||||
Tools extension to be activated for this project even if the Windows App SDK Nuget
|
||||
package has not yet been restored.
|
||||
-->
|
||||
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<ProjectCapability Include="Msix" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<RdXmlFile Include="rd.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.CmdPal.Common\Microsoft.CmdPal.Common.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.CmdPal.Core.ViewModels\Microsoft.CmdPal.Core.ViewModels.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.CmdPal.Core.Control\Microsoft.CmdPal.Core.Control.csproj" />
|
||||
<ProjectReference Include="..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
|
||||
|
||||
<!-- As a test: -->
|
||||
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Shell\Microsoft.CmdPal.Ext.Shell.csproj" />
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,51 +0,0 @@
|
||||
GetPhysicallyInstalledSystemMemory
|
||||
GlobalMemoryStatusEx
|
||||
GetSystemInfo
|
||||
GetForegroundWindow
|
||||
SetForegroundWindow
|
||||
GetWindowRect
|
||||
GetCursorPos
|
||||
SetWindowPos
|
||||
HWND_TOPMOST
|
||||
HWND_BOTTOM
|
||||
IsIconic
|
||||
RegisterHotKey
|
||||
UnregisterHotKey
|
||||
SetWindowLongPtr
|
||||
CallWindowProc
|
||||
ShowWindow
|
||||
SetForegroundWindow
|
||||
EnableWindow
|
||||
IsWindowEnabled
|
||||
SetFocus
|
||||
SetActiveWindow
|
||||
MonitorFromWindow
|
||||
GetMonitorInfo
|
||||
GetDpiForMonitor
|
||||
CoAllowSetForegroundWindow
|
||||
WM_HOTKEY
|
||||
WM_NCLBUTTONDBLCLK
|
||||
|
||||
Shell_NotifyIcon
|
||||
LoadIcon
|
||||
WM_USER
|
||||
WM_WINDOWPOSCHANGING
|
||||
RegisterWindowMessageW
|
||||
ExtractIconEx
|
||||
TRACK_POPUP_MENU_FLAGS
|
||||
WM_COMMAND
|
||||
WM_RBUTTONUP
|
||||
WM_LBUTTONUP
|
||||
WM_LBUTTONDBLCLK
|
||||
CreatePopupMenu
|
||||
TrackPopupMenuEx
|
||||
InsertMenu
|
||||
|
||||
MessageBox
|
||||
DwmGetWindowAttribute
|
||||
DwmSetWindowAttribute
|
||||
DWM_CLOAKED_APP
|
||||
|
||||
CoWaitForMultipleObjects
|
||||
INFINITE
|
||||
CWMO_FLAGS
|
||||
@@ -1,91 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
|
||||
xmlns:uap4="http://schemas.microsoft.com/appx/manifest/uap/windows10/4"
|
||||
xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
|
||||
xmlns:uap7="http://schemas.microsoft.com/appx/manifest/uap/windows10/7"
|
||||
xmlns:uap17="http://schemas.microsoft.com/appx/manifest/uap/windows10/17"
|
||||
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
|
||||
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
|
||||
xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5"
|
||||
xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
xmlns:virtualization="http://schemas.microsoft.com/appx/manifest/virtualization/windows10"
|
||||
IgnorableNamespaces="uap mp rescap uap3 uap17 desktop6 virtualization">
|
||||
|
||||
<Identity
|
||||
Name="Microsoft.CommandPalette.Core"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="0.0.1.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="69b8faa1-5ada-484f-999d-4998c7ff2082" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>ms-resource:AppName</DisplayName>
|
||||
<PublisherDisplayName>A Lone Developer</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
<desktop6:RegistryWriteVirtualization>disabled</desktop6:RegistryWriteVirtualization>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.19041.0" MaxVersionTested="10.0.19041.0" />
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.19041.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate"/>
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="App"
|
||||
Executable="$targetnametoken$.exe"
|
||||
EntryPoint="$targetentrypoint$">
|
||||
<uap:VisualElements
|
||||
DisplayName="ms-resource:AppName"
|
||||
Description="ms-resource:AppDescription"
|
||||
BackgroundColor="transparent"
|
||||
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||
Square44x44Logo="Assets\Square44x44Logo.png">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square71x71Logo="Assets\SmallTile.png" Square310x310Logo="Assets\LargeTile.png"/>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
|
||||
<Extensions>
|
||||
|
||||
<!-- <uap3:Extension Category="windows.appExtensionHost">
|
||||
<uap3:AppExtensionHost>
|
||||
<uap3:Name>com.microsoft.commandpalette</uap3:Name>
|
||||
</uap3:AppExtensionHost>
|
||||
</uap3:Extension>
|
||||
|
||||
<uap5:Extension Category="windows.startupTask">
|
||||
<uap5:StartupTask
|
||||
TaskId="CmdPalStartup"
|
||||
Enabled="false"
|
||||
DisplayName="ms-resource:StartupTaskName" />
|
||||
</uap5:Extension> -->
|
||||
|
||||
|
||||
<!-- <uap:Extension Category="windows.protocol">
|
||||
<uap:Protocol Name="x-cmdpal">
|
||||
<uap:Logo>Assets\StoreLogo.png</uap:Logo>
|
||||
<uap:DisplayName>Command Palette URI scheme</uap:DisplayName>
|
||||
</uap:Protocol>
|
||||
</uap:Extension> -->
|
||||
|
||||
</Extensions>
|
||||
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
<rescap:Capability Name="unvirtualizedResources" />
|
||||
<rescap:Capability Name="appLicensing" />
|
||||
</Capabilities>
|
||||
</Package>
|
||||
@@ -1,134 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
// using ManagedCommon;
|
||||
// using Microsoft.CmdPal.UI.Events;
|
||||
// using Microsoft.PowerToys.Telemetry;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Windows.Win32;
|
||||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.System.Com;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.UI;
|
||||
|
||||
// cribbed heavily from
|
||||
//
|
||||
// https://github.com/microsoft/WindowsAppSDK-Samples/tree/main/Samples/AppLifecycle/Instancing/cs2/cs-winui-packaged/CsWinUiDesktopInstancing
|
||||
internal sealed class Program
|
||||
{
|
||||
private static DispatcherQueueSynchronizationContext? uiContext;
|
||||
private static App? app;
|
||||
|
||||
// LOAD BEARING
|
||||
//
|
||||
// Main cannot be async. If it is, then the clipboard won't work, and neither will narrator.
|
||||
// That means you, the person thinking about making this a MTA thread. Don't
|
||||
// do it. It won't work. That's not the solution.
|
||||
[STAThread]
|
||||
private static int Main(string[] args)
|
||||
{
|
||||
// if (Helpers.GpoValueChecker.GetConfiguredCmdPalEnabledValue() == Helpers.GpoRuleConfiguredValue.Disabled)
|
||||
// {
|
||||
// // There's a GPO rule configured disabling CmdPal. Exit as soon as possible.
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// try
|
||||
// {
|
||||
// Logger.InitializeLogger("\\CmdPal\\Logs\\");
|
||||
// }
|
||||
// catch (COMException e)
|
||||
// {
|
||||
// // This is unexpected. For the sake of debugging:
|
||||
// // pop a message box
|
||||
// PInvoke.MessageBox(
|
||||
// (HWND)IntPtr.Zero,
|
||||
// $"Failed to initialize the logger. COMException: \r{e.Message}",
|
||||
// "Command Palette",
|
||||
// MESSAGEBOX_STYLE.MB_OK | MESSAGEBOX_STYLE.MB_ICONERROR);
|
||||
// return 0;
|
||||
// }
|
||||
// catch (Exception e2)
|
||||
// {
|
||||
// // This is unexpected. For the sake of debugging:
|
||||
// // pop a message box
|
||||
// PInvoke.MessageBox(
|
||||
// (HWND)IntPtr.Zero,
|
||||
// $"Failed to initialize the logger. Unknown Exception: \r{e2.Message}",
|
||||
// "Command Palette",
|
||||
// MESSAGEBOX_STYLE.MB_OK | MESSAGEBOX_STYLE.MB_ICONERROR);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// Logger.LogDebug($"Starting at {DateTime.UtcNow}");
|
||||
// PowerToysTelemetry.Log.WriteEvent(new CmdPalProcessStarted());
|
||||
WinRT.ComWrappersSupport.InitializeComWrappers();
|
||||
var isRedirect = DecideRedirection();
|
||||
if (!isRedirect)
|
||||
{
|
||||
Microsoft.UI.Xaml.Application.Start((p) =>
|
||||
{
|
||||
uiContext = new DispatcherQueueSynchronizationContext(DispatcherQueue.GetForCurrentThread());
|
||||
SynchronizationContext.SetSynchronizationContext(uiContext);
|
||||
app = new App();
|
||||
});
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static bool DecideRedirection()
|
||||
{
|
||||
var isRedirect = false;
|
||||
var args = AppInstance.GetCurrent().GetActivatedEventArgs();
|
||||
var keyInstance = AppInstance.FindOrRegisterForKey("randomKey");
|
||||
|
||||
if (keyInstance.IsCurrent)
|
||||
{
|
||||
// PowerToysTelemetry.Log.WriteEvent(new ColdLaunch());
|
||||
keyInstance.Activated += OnActivated;
|
||||
}
|
||||
else
|
||||
{
|
||||
isRedirect = true;
|
||||
|
||||
// PowerToysTelemetry.Log.WriteEvent(new ReactivateInstance());
|
||||
RedirectActivationTo(args, keyInstance);
|
||||
}
|
||||
|
||||
return isRedirect;
|
||||
}
|
||||
|
||||
private static void RedirectActivationTo(AppActivationArguments args, AppInstance keyInstance)
|
||||
{
|
||||
// Do the redirection on another thread, and use a non-blocking
|
||||
// wait method to wait for the redirection to complete.
|
||||
var redirectSemaphore = new Semaphore(0, 1);
|
||||
Task.Run(() =>
|
||||
{
|
||||
keyInstance.RedirectActivationToAsync(args).AsTask().Wait();
|
||||
redirectSemaphore.Release();
|
||||
});
|
||||
_ = PInvoke.CoWaitForMultipleObjects(
|
||||
(uint)CWMO_FLAGS.CWMO_DEFAULT,
|
||||
PInvoke.INFINITE,
|
||||
[new HANDLE(redirectSemaphore.SafeWaitHandle.DangerousGetHandle())],
|
||||
out _);
|
||||
}
|
||||
|
||||
private static void OnActivated(object? sender, AppActivationArguments args)
|
||||
{
|
||||
// If we already have a form, display the message now.
|
||||
// Otherwise, add it to the collection for displaying later.
|
||||
if (App.Current is App thisApp)
|
||||
{
|
||||
if (thisApp.AppWindow is not null and
|
||||
MainWindow mainWindow)
|
||||
{
|
||||
uiContext?.Post(_ => mainWindow.HandleLaunch(args), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,431 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="AppName" xml:space="preserve">
|
||||
<value>Command Palette</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppNameDev" xml:space="preserve">
|
||||
<value>Command Palette Dev</value>
|
||||
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
|
||||
</data>
|
||||
<data name="AppNameCan" xml:space="preserve">
|
||||
<value>Command Palette Canary</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppNamePre" xml:space="preserve">
|
||||
<value>Command Palette Preview</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppStoreName" xml:space="preserve">
|
||||
<value>Windows Command Palette</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppStoreNameDev" xml:space="preserve">
|
||||
<value>Windows Command Palette Dev</value>
|
||||
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
|
||||
</data>
|
||||
<data name="AppStoreNameCan" xml:space="preserve">
|
||||
<value>Windows Command Palette Canary</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}. "Canary" in this context means an unstable or nightly build of a software product, not the bird.</comment>
|
||||
</data>
|
||||
<data name="AppStoreNamePre" xml:space="preserve">
|
||||
<value>Windows Command Palette Preview</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppShortName" xml:space="preserve">
|
||||
<value>Command Palette</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppShortNameDev" xml:space="preserve">
|
||||
<value>Command Palette Dev</value>
|
||||
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
|
||||
</data>
|
||||
<data name="AppShortNameCan" xml:space="preserve">
|
||||
<value>Command Palette Canary</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppShortNamePre" xml:space="preserve">
|
||||
<value>Command Palette Preview</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="AppDescription" xml:space="preserve">
|
||||
<value>The Windows Command Palette</value>
|
||||
</data>
|
||||
<data name="AppDescriptionDev" xml:space="preserve">
|
||||
<value>A dev build of the Command Palette</value>
|
||||
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
|
||||
</data>
|
||||
<data name="AppDescriptionCan" xml:space="preserve">
|
||||
<value>The Windows Command Palette (Canary build)</value>
|
||||
<comment>{Locked}</comment>
|
||||
</data>
|
||||
<data name="AppDescriptionPre" xml:space="preserve">
|
||||
<value>The Windows Command Palette (Preview build)</value>
|
||||
</data>
|
||||
<data name="StartupTaskName" xml:space="preserve">
|
||||
<value>Command Palette</value>
|
||||
<comment>{Locked=qps-ploc,qps-ploca,qps-plocm}</comment>
|
||||
</data>
|
||||
<data name="StartupTaskNameDev" xml:space="preserve">
|
||||
<value>Command Palette Dev</value>
|
||||
<comment>{Locked} The dev build will never be seen in multiple languages</comment>
|
||||
</data>
|
||||
<data name="Activation_Shortcut_Cancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="Activation_Shortcut_Description" xml:space="preserve">
|
||||
<value>Press a combination of keys to change this shortcut</value>
|
||||
</data>
|
||||
<data name="Activation_Shortcut_With_Disable_Description" xml:space="preserve">
|
||||
<value>Press a combination of keys to change this shortcut.
|
||||
Right-click to remove the key combination, thereby deactivating the shortcut.</value>
|
||||
</data>
|
||||
<data name="Activation_Shortcut_Reset" xml:space="preserve">
|
||||
<value>Reset</value>
|
||||
</data>
|
||||
<data name="Activation_Shortcut_Save" xml:space="preserve">
|
||||
<value>Save</value>
|
||||
</data>
|
||||
<data name="Activation_Shortcut_Title" xml:space="preserve">
|
||||
<value>Activation shortcut</value>
|
||||
</data>
|
||||
<data name="InvalidShortcut.Title" xml:space="preserve">
|
||||
<value>Invalid shortcut</value>
|
||||
</data>
|
||||
<data name="InvalidShortcutWarningLabel.Text" xml:space="preserve">
|
||||
<value>Only shortcuts that start with **Windows key**, **Ctrl**, **Alt** or **Shift** are valid.</value>
|
||||
<comment>The ** sequences are used for text formatting of the key names. Don't remove them on translation.</comment>
|
||||
</data>
|
||||
<data name="WarningShortcutAltGr.Title" xml:space="preserve">
|
||||
<value>Possible shortcut interference with Alt Gr</value>
|
||||
<comment>Alt Gr refers to the right alt key on some international keyboards</comment>
|
||||
</data>
|
||||
<data name="WarningShortcutAltGr.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Shortcuts with **Ctrl** and **Alt** may remove functionality from some international keyboards, because **Ctrl** + **Alt** = **Alt Gr** in those keyboards.</value>
|
||||
<comment>The ** sequences are used for text formatting of the key names. Don't remove them on translation.</comment>
|
||||
</data>
|
||||
<data name="CmdPalSettingsHeader.Text" xml:space="preserve">
|
||||
<value>Command Palette settings</value>
|
||||
<comment>A section header for app-wide settings. "Command Palette" is the name of the app.</comment>
|
||||
</data>
|
||||
<data name="AboutSettingsHeader.Text" xml:space="preserve">
|
||||
<value>About</value>
|
||||
<comment>A section header for information about the app</comment>
|
||||
</data>
|
||||
<data name="ExtensionAboutHeader.Text" xml:space="preserve">
|
||||
<value>About</value>
|
||||
<comment>A section header for information about the app</comment>
|
||||
</data>
|
||||
<data name="ExtensionSettingsHeader.Text" xml:space="preserve">
|
||||
<value>Extension settings</value>
|
||||
<comment>A section header for extension-specific settings.</comment>
|
||||
</data>
|
||||
<data name="ExtensionCommandsHeader.Text" xml:space="preserve">
|
||||
<value>Commands</value>
|
||||
<comment>A section header for information about the app</comment>
|
||||
</data>
|
||||
<data name="ExtensionFallbackCommandsHeader.Text" xml:space="preserve">
|
||||
<value>Fallback commands</value>
|
||||
<comment>A section header for information about the commands presented to the user when the search text doesn't exactly match the name of a command.</comment>
|
||||
</data>
|
||||
<data name="ExtensionDisabledHeader.Text" xml:space="preserve">
|
||||
<value>This extension is disabled</value>
|
||||
<comment>A header to inform the user that an extension is not currently active</comment>
|
||||
</data>
|
||||
<data name="ExtensionDisabledDetails.Text" xml:space="preserve">
|
||||
<value>Enable this extension to view commands and settings</value>
|
||||
<comment>Additional details for when an extension is disabled. Displayed under ExtensionDisabledHeader.Text</comment>
|
||||
</data>
|
||||
<data name="ExtensionDisabledText" xml:space="preserve">
|
||||
<value>Disabled</value>
|
||||
<comment>Displayed when an extension is disabled</comment>
|
||||
</data>
|
||||
<data name="ExtensionEnableCard.Header" xml:space="preserve">
|
||||
<value>Enable this extension</value>
|
||||
<comment>Displayed on a toggle controlling the extension's enabled / disabled state</comment>
|
||||
</data>
|
||||
<data name="ExtensionEnableCard.Description" xml:space="preserve">
|
||||
<value>Load commands and settings from this extension</value>
|
||||
<comment>Displayed on a toggle controlling the extension's enabled / disabled state</comment>
|
||||
</data>
|
||||
<data name="SettingsWindowTitle" xml:space="preserve">
|
||||
<value>Command Palette Settings</value>
|
||||
<comment>The title of the settings window for the app</comment>
|
||||
</data>
|
||||
<data name="ToastWindowTitle" xml:space="preserve">
|
||||
<value>Command Palette Toast</value>
|
||||
<comment>The title of the toast window for the command palette</comment>
|
||||
</data>
|
||||
<data name="DefaultSearchPlaceholderText" xml:space="preserve">
|
||||
<value>Type here to search...</value>
|
||||
</data>
|
||||
<data name="Run_PositionHeader.Header" xml:space="preserve">
|
||||
<value>Preferred monitor position</value>
|
||||
<comment>as in Show Command Palette on primary monitor</comment>
|
||||
</data>
|
||||
<data name="Run_PositionHeader.Description" xml:space="preserve">
|
||||
<value>If multiple monitors are in use, Command Palette can be launched on the desired monitor</value>
|
||||
<comment>as in Show Command Palette on primary monitor</comment>
|
||||
</data>
|
||||
<data name="Run_Radio_Position_Cursor.Content" xml:space="preserve">
|
||||
<value>Monitor with mouse cursor</value>
|
||||
</data>
|
||||
<data name="Run_Radio_Position_Focus.Content" xml:space="preserve">
|
||||
<value>Monitor with focused window</value>
|
||||
</data>
|
||||
<data name="Run_Radio_Position_Primary_Monitor.Content" xml:space="preserve">
|
||||
<value>Primary monitor</value>
|
||||
</data>
|
||||
<data name="Run_Radio_Position_In_Place.Content" xml:space="preserve">
|
||||
<value>Don't move</value>
|
||||
</data>
|
||||
<data name="ConfirmationDialog_ConfirmButtonText" xml:space="preserve">
|
||||
<value>Confirm</value>
|
||||
</data>
|
||||
<data name="ConfirmationDialog_CancelButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="Settings_ExtensionPage_GlobalHotkey_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Global hotkey</value>
|
||||
</data>
|
||||
<data name="Settings_ExtensionPage_GlobalHotkey_SettingsCard.Description" xml:space="preserve">
|
||||
<value>Directly open Command Palette to this command.</value>
|
||||
</data>
|
||||
<data name="Settings_ExtensionPage_Alias_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Alias</value>
|
||||
</data>
|
||||
<data name="Settings_ExtensionPage_Alias_SettingsCard.Description" xml:space="preserve">
|
||||
<value>Typing this alias will navigate to this command. Direct aliases navigate as soon as you type the alias. Indirect aliases navigate after typing a trailing space.</value>
|
||||
</data>
|
||||
<data name="Settings_ExtensionPage_Builtin_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Built-in</value>
|
||||
</data>
|
||||
<data name="Settings_ExtensionPage_Builtin_SettingsCard.Description" xml:space="preserve">
|
||||
<value>These commands are built-in to the Windows Command Palette.</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_ActivationKey_SettingsExpander.Header" xml:space="preserve">
|
||||
<value>Activation key</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_ActivationKey_SettingsExpander.Description" xml:space="preserve">
|
||||
<value>This key will open the Command Palette.</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_LowLevelHook_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Use low-level keyboard hook</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_LowLevelHook_SettingsCard.Description" xml:space="preserve">
|
||||
<value>Try this if there are issues with the shortcut (Command Palette might not get focus when triggered from an elevated window)</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_IgnoreShortcutWhenFullscreen_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Ignore shortcut in fullscreen mode</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_IgnoreShortcutWhenFullscreen_SettingsCard.Description" xml:space="preserve">
|
||||
<value>Preventing disruption of the program running in fullscreen by unintentional activation of shortcut</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_GoHome_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Go home when activated</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_GoHome_SettingsCard.Description" xml:space="preserve">
|
||||
<value>Automatically opens the home page upon activation</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_HighlightSearch_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Highlight search on activate</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_HighlightSearch_SettingsCard.Description" xml:space="preserve">
|
||||
<value>Selects the previous search text at launch</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_ShowAppDetails_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Show app details</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_ShowAppDetails_SettingsCard.Description" xml:space="preserve">
|
||||
<value>Controls if app details are automatically expanded or not.</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_BackspaceGoesBack_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Backspace goes back</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_BackspaceGoesBack_SettingsCard.Description" xml:space="preserve">
|
||||
<value>If the search field is empty, backspace returns to the previous page</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_SingleClickActivation_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Single-click activation</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_SingleClickActivation_SettingsCard.Description" xml:space="preserve">
|
||||
<value>Choose how to interact with list items: single-click to activate, or single-click to select and double-click to activate</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_About_SettingsExpander.Header" xml:space="preserve">
|
||||
<value>Windows Command Palette</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_About_SettingsExpander.Description" xml:space="preserve">
|
||||
<value>© 2025. All rights reserved.</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_About_GithubLink_Hyperlink.Content" xml:space="preserve">
|
||||
<value>View GitHub repository</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_About_SDKDocs_Hyperlink.Content" xml:space="preserve">
|
||||
<value>Extension SDK docs</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_SendFeedback_Hyperlink.Content" xml:space="preserve">
|
||||
<value>Send feedback</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_NavigationViewItem_General.Content" xml:space="preserve">
|
||||
<value>General</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_NavigationViewItem_Extensions.Content" xml:space="preserve">
|
||||
<value>Extensions</value>
|
||||
</data>
|
||||
<data name="SettingsButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Open Command Palette settings</value>
|
||||
</data>
|
||||
<data name="ActivationSettingsHeader.Text" xml:space="preserve">
|
||||
<value>Activation</value>
|
||||
</data>
|
||||
<data name="BehaviorSettingsHeader.Text" xml:space="preserve">
|
||||
<value>Behavior</value>
|
||||
</data>
|
||||
<data name="ContextFilterBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Search commands...</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_ShowSystemTrayIcon_SettingsCard.Header" xml:space="preserve">
|
||||
<value>Show system tray icon</value>
|
||||
</data>
|
||||
<data name="Settings_GeneralPage_ShowSystemTrayIcon_SettingsCard.Description" xml:space="preserve">
|
||||
<value>Choose if Command Palette is visible in the system tray</value>
|
||||
</data>
|
||||
<data name="BackButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Back</value>
|
||||
</data>
|
||||
<data name="BackButton.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Back</value>
|
||||
</data>
|
||||
<data name="MoreCommandsButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>More</value>
|
||||
</data>
|
||||
<data name="TrayMenu_Settings" xml:space="preserve">
|
||||
<value>Settings</value>
|
||||
</data>
|
||||
<data name="TrayMenu_Exit" xml:space="preserve">
|
||||
<value>Exit</value>
|
||||
</data>
|
||||
<data name="Settings_ExtensionPage_Alias_ToggleSwitch.OnContent" xml:space="preserve">
|
||||
<value>Direct</value>
|
||||
</data>
|
||||
<data name="Settings_ExtensionPage_Alias_ToggleSwitch.OffContent" xml:space="preserve">
|
||||
<value>Indirect</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1,158 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
<!-- Other merged dictionaries here -->
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<StaticResource x:Key="SubtleButtonBackground" ResourceKey="SubtleFillColorTransparent" />
|
||||
<StaticResource x:Key="SubtleButtonBackgroundPointerOver" ResourceKey="SubtleFillColorSecondary" />
|
||||
<StaticResource x:Key="SubtleButtonBackgroundPressed" ResourceKey="SubtleFillColorTertiary" />
|
||||
<StaticResource x:Key="SubtleButtonBackgroundDisabled" ResourceKey="SubtleFillColorTransparent" />
|
||||
|
||||
<StaticResource x:Key="SubtleButtonBorderBrush" ResourceKey="SubtleFillColorTransparent" />
|
||||
<StaticResource x:Key="SubtleButtonBorderBrushPointerOver" ResourceKey="SubtleFillColorSecondary" />
|
||||
<StaticResource x:Key="SubtleButtonBorderBrushPressed" ResourceKey="SubtleFillColorTertiary" />
|
||||
<StaticResource x:Key="SubtleButtonBorderBrushDisabled" ResourceKey="SubtleFillColorTransparent" />
|
||||
|
||||
<StaticResource x:Key="SubtleButtonForeground" ResourceKey="TextFillColorPrimary" />
|
||||
<StaticResource x:Key="SubtleButtonForegroundPointerOver" ResourceKey="TextFillColorPrimary" />
|
||||
<StaticResource x:Key="SubtleButtonForegroundPressed" ResourceKey="TextFillColorSecondary" />
|
||||
<StaticResource x:Key="SubtleButtonForegroundDisabled" ResourceKey="TextFillColorDisabled" />
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<StaticResource x:Key="SubtleButtonBackground" ResourceKey="SubtleFillColorTransparent" />
|
||||
<StaticResource x:Key="SubtleButtonBackgroundPointerOver" ResourceKey="SubtleFillColorSecondary" />
|
||||
<StaticResource x:Key="SubtleButtonBackgroundPressed" ResourceKey="SubtleFillColorTertiary" />
|
||||
<StaticResource x:Key="SubtleButtonBackgroundDisabled" ResourceKey="SubtleFillColorTransparent" />
|
||||
|
||||
<StaticResource x:Key="SubtleButtonBorderBrush" ResourceKey="SubtleFillColorTransparent" />
|
||||
<StaticResource x:Key="SubtleButtonBorderBrushPointerOver" ResourceKey="SubtleFillColorSecondary" />
|
||||
<StaticResource x:Key="SubtleButtonBorderBrushPressed" ResourceKey="SubtleFillColorTertiary" />
|
||||
<StaticResource x:Key="SubtleButtonBorderBrushDisabled" ResourceKey="SubtleFillColorTransparent" />
|
||||
|
||||
<StaticResource x:Key="SubtleButtonForeground" ResourceKey="TextFillColorPrimary" />
|
||||
<StaticResource x:Key="SubtleButtonForegroundPointerOver" ResourceKey="TextFillColorPrimary" />
|
||||
<StaticResource x:Key="SubtleButtonForegroundPressed" ResourceKey="TextFillColorSecondary" />
|
||||
<StaticResource x:Key="SubtleButtonForegroundDisabled" ResourceKey="TextFillColorDisabled" />
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="SubtleButtonBackground" ResourceKey="SystemColorWindowColorBrush" />
|
||||
<StaticResource x:Key="SubtleButtonBackgroundPointerOver" ResourceKey="SystemColorHighlightTextColorBrush" />
|
||||
<StaticResource x:Key="SubtleButtonBackgroundPressed" ResourceKey="SystemColorWindowColorBrush" />
|
||||
<StaticResource x:Key="SubtleButtonBackgroundDisabled" ResourceKey="SystemControlBackgroundBaseLowBrush" />
|
||||
|
||||
<StaticResource x:Key="SubtleButtonBorderBrush" ResourceKey="SystemColorWindowColorBrush" />
|
||||
<StaticResource x:Key="SubtleButtonBorderBrushPointerOver" ResourceKey="SystemColorHighlightColorBrush" />
|
||||
<StaticResource x:Key="SubtleButtonBorderBrushPressed" ResourceKey="SystemColorHighlightColorBrush" />
|
||||
<StaticResource x:Key="SubtleButtonBorderBrushDisabled" ResourceKey="SystemColorGrayTextColor" />
|
||||
|
||||
<StaticResource x:Key="SubtleButtonForeground" ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
<StaticResource x:Key="SubtleButtonForegroundPointerOver" ResourceKey="SystemControlHighlightBaseHighBrush" />
|
||||
<StaticResource x:Key="SubtleButtonForegroundPressed" ResourceKey="SystemControlHighlightBaseHighBrush" />
|
||||
<StaticResource x:Key="SubtleButtonForegroundDisabled" ResourceKey="SystemControlDisabledBaseMediumLowBrush" />
|
||||
</ResourceDictionary>
|
||||
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
<Style x:Key="SubtleButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="{ThemeResource SubtleButtonBackground}" />
|
||||
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource SubtleButtonForeground}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SubtleButtonBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />
|
||||
<Setter Property="Padding" Value="{StaticResource ButtonPadding}" />
|
||||
<Setter Property="HorizontalAlignment" Value="Left" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
|
||||
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
|
||||
<Setter Property="FocusVisualMargin" Value="-3" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<ContentPresenter
|
||||
x:Name="ContentPresenter"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
AnimatedIcon.State="Normal"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Background="{TemplateBinding Background}"
|
||||
BackgroundSizing="{TemplateBinding BackgroundSizing}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTransitions="{TemplateBinding ContentTransitions}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
Foreground="{TemplateBinding Foreground}">
|
||||
<ContentPresenter.BackgroundTransition>
|
||||
<BrushTransition Duration="0:0:0.083" />
|
||||
</ContentPresenter.BackgroundTransition>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonBackgroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonBorderBrushPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonForegroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ContentPresenter.(AnimatedIcon.State)" Value="PointerOver" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonBackgroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonBorderBrushPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonForegroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ContentPresenter.(AnimatedIcon.State)" Value="Pressed" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonBackgroundDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonBorderBrushDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SubtleButtonForegroundDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
<VisualState.Setters>
|
||||
<!-- DisabledVisual Should be handled by the control, not the animated icon. -->
|
||||
<Setter Target="ContentPresenter.(AnimatedIcon.State)" Value="Normal" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</ContentPresenter>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
@@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
<!-- Other merged dictionaries here -->
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<!-- For slightly adjust the LayerOnAcrylicFillColorDefault color so that the cursor of the searchbox shows -->
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<!-- This is a local copy of LayerOnAcrylicFillColorDefaultBrush -->
|
||||
<SolidColorBrush
|
||||
x:Key="LayerOnAcrylicPrimaryBackgroundBrush"
|
||||
Opacity="0.3"
|
||||
Color="#222222" />
|
||||
<SolidColorBrush
|
||||
x:Key="LayerOnAcrylicSecondaryBackgroundBrush"
|
||||
Opacity="0.0"
|
||||
Color="#222222" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<SolidColorBrush
|
||||
x:Key="LayerOnAcrylicPrimaryBackgroundBrush"
|
||||
Opacity="0.65"
|
||||
Color="#FFFFFF" />
|
||||
<!-- Because we are tweaking the LayerOnAcrylicPrimaryBackgroundBrush, we need to tweak the command bar background too. If not, it's too bright. -->
|
||||
<SolidColorBrush
|
||||
x:Key="LayerOnAcrylicSecondaryBackgroundBrush"
|
||||
Opacity="0.4"
|
||||
Color="#FFFFFF" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<!-- This is a local copy of LayerOnAcrylicFillColorDefaultBrush -->
|
||||
<SolidColorBrush x:Key="LayerOnAcrylicPrimaryBackgroundBrush" Color="{ThemeResource LayerOnAcrylicFillColorDefault}" />
|
||||
<SolidColorBrush x:Key="LayerOnAcrylicSecondaryBackgroundBrush" Color="Transparent" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
<!-- Other merged dictionaries here -->
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<x:Double x:Key="SettingsCardSpacing">4</x:Double>
|
||||
|
||||
<!-- Style (inc. the correct spacing) of a section header -->
|
||||
<Style
|
||||
x:Key="SettingsSectionHeaderTextBlockStyle"
|
||||
BasedOn="{StaticResource BodyStrongTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Style.Setters>
|
||||
<Setter Property="Margin" Value="1,30,0,6" />
|
||||
</Style.Setters>
|
||||
</Style>
|
||||
|
||||
<StackLayout
|
||||
x:Name="VerticalStackLayout"
|
||||
Orientation="Vertical"
|
||||
Spacing="{StaticResource SettingsCardSpacing}" />
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -1,94 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Microsoft.CmdPal.Core.Control.Controls">
|
||||
|
||||
<!--
|
||||
TODO! This file is a big dumb
|
||||
-->
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<StaticResource x:Key="TagBackground" ResourceKey="ControlFillColorSecondaryBrush" />
|
||||
<StaticResource x:Key="TagBorderBrush" ResourceKey="DividerStrokeColorDefaultBrush" />
|
||||
<StaticResource x:Key="TagForeground" ResourceKey="TextFillColorTertiaryBrush" />
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<StaticResource x:Key="TagBackground" ResourceKey="ControlFillColorSecondaryBrush" />
|
||||
<StaticResource x:Key="TagBorderBrush" ResourceKey="DividerStrokeColorDefaultBrush" />
|
||||
<StaticResource x:Key="TagForeground" ResourceKey="TextFillColorTertiaryBrush" />
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="TagBackground" ResourceKey="SystemColorButtonFaceColorBrush" />
|
||||
<StaticResource x:Key="TagBorderBrush" ResourceKey="ControlFillColorTransparent" />
|
||||
<StaticResource x:Key="TagForeground" ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
</ResourceDictionary>
|
||||
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
<Thickness x:Key="TagPadding">4,2,4,2</Thickness>
|
||||
<Thickness x:Key="TagBorderThickness">1</Thickness>
|
||||
|
||||
<Style BasedOn="{StaticResource DefaultTagStyle}" TargetType="local:Tag" />
|
||||
|
||||
<Style x:Key="DefaultTagStyle" TargetType="local:Tag">
|
||||
<Style.Setters>
|
||||
<Setter Property="Background" Value="{ThemeResource TagBackground}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource TagBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource TagBorderThickness}" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="AutomationProperties.AutomationControlType" Value="Custom" />
|
||||
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
|
||||
<Setter Property="Padding" Value="{ThemeResource TagPadding}" />
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource TagForeground}" />
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
|
||||
<Setter Property="FocusVisualMargin" Value="-3" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:Tag">
|
||||
<Grid
|
||||
x:Name="PART_RootGrid"
|
||||
MinWidth="{TemplateBinding MinWidth}"
|
||||
MinHeight="{TemplateBinding MinHeight}"
|
||||
MaxWidth="{TemplateBinding MaxWidth}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalAlignment}"
|
||||
AutomationProperties.Name="{TemplateBinding Text}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BackgroundSizing="{TemplateBinding BackgroundSizing}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<local:IconBox
|
||||
x:Name="PART_Icon"
|
||||
Grid.Column="0"
|
||||
Height="12"
|
||||
Margin="0,0,4,0"
|
||||
SourceKey="{TemplateBinding Icon}" />
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
Margin="0,-1,0,0"
|
||||
CharacterSpacing="{TemplateBinding CharacterSpacing}"
|
||||
FontFamily="{TemplateBinding FontFamily}"
|
||||
FontWeight="{TemplateBinding FontWeight}"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
Text="{TemplateBinding Text}" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style.Setters>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
@@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:converters="using:CommunityToolkit.WinUI.Converters">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
<!-- Other merged dictionaries here -->
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<Style
|
||||
x:Key="ContextItemTitleTextBlockCriticalStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemFillColorCriticalBrush}" />
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
x:Key="ContextItemCaptionTextBlockCriticalStyle"
|
||||
BasedOn="{StaticResource CaptionTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemFillColorCriticalBrush}" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -1,279 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:converters="using:CommunityToolkit.WinUI.Converters">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
<!-- Other merged dictionaries here -->
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<converters:StringVisibilityConverter
|
||||
x:Key="ReverseStringVisibilityConverter"
|
||||
EmptyValue="Visible"
|
||||
NotEmptyValue="Collapsed" />
|
||||
|
||||
<Style x:Key="SearchTextBoxStyle" TargetType="TextBox">
|
||||
<Setter Property="Foreground" Value="{ThemeResource TextControlForeground}" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
<Setter Property="SelectionHighlightColor" Value="{ThemeResource TextControlSelectionHighlightColor}" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
|
||||
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Auto" />
|
||||
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
|
||||
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" />
|
||||
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
|
||||
<Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}" />
|
||||
<Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}" />
|
||||
<Setter Property="Padding" Value="{ThemeResource TextControlThemePadding}" />
|
||||
<Setter Property="UseSystemFocusVisuals" Value="{ThemeResource IsApplicationFocusVisualKindReveal}" />
|
||||
<Setter Property="ContextFlyout" Value="{StaticResource TextControlCommandBarContextFlyout}" />
|
||||
<Setter Property="SelectionFlyout" Value="{StaticResource TextControlCommandBarSelectionFlyout}" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="TextBox">
|
||||
<Grid>
|
||||
<Grid.Resources>
|
||||
<Style x:Name="DeleteButtonStyle" TargetType="Button">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Grid
|
||||
x:Name="ButtonLayoutGrid"
|
||||
Margin="{ThemeResource TextBoxInnerButtonMargin}"
|
||||
Background="{ThemeResource TextControlButtonBackground}"
|
||||
BackgroundSizing="{TemplateBinding BackgroundSizing}"
|
||||
BorderBrush="{ThemeResource TextControlButtonBorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<TextBlock
|
||||
x:Name="GlyphElement"
|
||||
Margin="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="{ThemeResource TextBoxIconFontSize}"
|
||||
FontStyle="Normal"
|
||||
Foreground="{ThemeResource TextControlButtonForeground}"
|
||||
Text="" />
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBackgroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBorderBrushPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="GlyphElement" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonForegroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBackgroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBorderBrushPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="GlyphElement" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonForegroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="ButtonLayoutGrid"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="0"
|
||||
Duration="0" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ContentPresenter
|
||||
x:Name="HeaderContentPresenter"
|
||||
Margin="{ThemeResource TextBoxTopHeaderMargin}"
|
||||
VerticalAlignment="Center"
|
||||
x:DeferLoadStrategy="Lazy"
|
||||
Content="{TemplateBinding Header}"
|
||||
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||
FontWeight="Normal"
|
||||
Foreground="{ThemeResource TextControlHeaderForeground}"
|
||||
TextWrapping="Wrap"
|
||||
Visibility="Collapsed" />
|
||||
<Border
|
||||
x:Name="BorderElement"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="2"
|
||||
MinWidth="{TemplateBinding MinWidth}"
|
||||
MinHeight="{TemplateBinding MinHeight}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Control.IsTemplateFocusTarget="True"
|
||||
CornerRadius="{TemplateBinding CornerRadius}" />
|
||||
<ScrollViewer
|
||||
x:Name="ContentElement"
|
||||
Grid.Column="1"
|
||||
Margin="{TemplateBinding BorderThickness}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
|
||||
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
|
||||
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
|
||||
IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
|
||||
IsTabStop="False"
|
||||
IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
|
||||
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
|
||||
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
|
||||
ZoomMode="Disabled" />
|
||||
<TextBlock
|
||||
x:Name="PlaceholderTextContentPresenter"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="1"
|
||||
Margin="{TemplateBinding BorderThickness}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Foreground="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForeground}}"
|
||||
IsHitTestVisible="False"
|
||||
Text="{TemplateBinding PlaceholderText}"
|
||||
TextAlignment="{TemplateBinding TextAlignment}"
|
||||
TextWrapping="{TemplateBinding TextWrapping}"
|
||||
Visibility="{Binding Description, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ReverseStringVisibilityConverter}, Mode=OneWay}" />
|
||||
<Button
|
||||
x:Name="DeleteButton"
|
||||
Grid.Column="2"
|
||||
Margin="0,0,8,0"
|
||||
Padding="4"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
FontSize="{TemplateBinding FontSize}"
|
||||
IsTabStop="False"
|
||||
Style="{StaticResource DeleteButtonStyle}"
|
||||
Visibility="Collapsed" />
|
||||
<TextBlock
|
||||
x:Name="DescriptionPresenter"
|
||||
Grid.Column="1"
|
||||
Margin="{TemplateBinding BorderThickness}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
x:Load="False"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
CharacterSpacing="15"
|
||||
Foreground="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForeground}}"
|
||||
Text="{TemplateBinding Description}"
|
||||
TextWrapping="{TemplateBinding TextWrapping}" />
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlHeaderForegroundDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>-->
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="DescriptionPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForegroundDisabled}}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>-->
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForegroundPointerOver}}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="DescriptionPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForegroundPointerOver}}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Focused">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForegroundFocused}}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundFocused}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushFocused}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderThickness">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderThemeThicknessFocused}" />
|
||||
</ObjectAnimationUsingKeyFrames>-->
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundFocused}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="DescriptionPresenter" Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForegroundFocused}}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="ButtonStates">
|
||||
<VisualState x:Name="ButtonVisible">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="DeleteButton" Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0">
|
||||
<DiscreteObjectKeyFrame.Value>
|
||||
<Visibility>Visible</Visibility>
|
||||
</DiscreteObjectKeyFrame.Value>
|
||||
</DiscreteObjectKeyFrame>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="ButtonCollapsed" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="WindowsCommandPalette.app"/>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- The ID below informs the system that this application is compatible with OS features first introduced in Windows 10.
|
||||
It is necessary to support features in unpackaged applications, for example the custom titlebar implementation.
|
||||
For more info see https://docs.microsoft.com/windows/apps/windows-app-sdk/use-windows-app-sdk-run-time#declare-os-compatibility-in-your-application-manifest -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Windows.Foundation;
|
||||
@@ -59,7 +60,7 @@ public abstract partial class AppExtensionHost : IExtensionHost
|
||||
return Task.CompletedTask.AsAsyncAction();
|
||||
}
|
||||
|
||||
CoreLogger.LogDebug(message.Message);
|
||||
Logger.LogDebug(message.Message);
|
||||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@ using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Microsoft.Diagnostics.Utilities;
|
||||
using Windows.System;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
public static class CoreLogger
|
||||
{
|
||||
public static void InitializeLogger(ILogger implementation)
|
||||
{
|
||||
_logger = implementation;
|
||||
}
|
||||
|
||||
private static ILogger? _logger;
|
||||
|
||||
public static void LogError(string message, Exception ex, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
_logger?.LogError(message, ex, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
public static void LogError(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
_logger?.LogError(message, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
public static void LogWarning(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
_logger?.LogWarning(message, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
public static void LogInfo(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
_logger?.LogInfo(message, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
public static void LogDebug(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
_logger?.LogDebug(message, memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
|
||||
public static void LogTrace([System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
{
|
||||
_logger?.LogTrace(memberName, sourceFilePath, sourceLineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ILogger
|
||||
{
|
||||
void LogError(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
|
||||
|
||||
void LogError(string message, Exception ex, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
|
||||
|
||||
void LogWarning(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
|
||||
|
||||
void LogInfo(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
|
||||
|
||||
void LogDebug(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
|
||||
|
||||
void LogTrace([System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using ManagedCommon;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels;
|
||||
|
||||
@@ -83,7 +84,7 @@ public abstract partial class ExtensionObjectViewModel : ObservableObject
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CoreLogger.LogDebug(ex.ToString());
|
||||
Logger.LogDebug(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
|
||||
public CommandItemViewModel EmptyContent { get; private set; }
|
||||
|
||||
public bool IsMainPage { get; init; }
|
||||
|
||||
private bool _isDynamic;
|
||||
|
||||
private Task? _initializeItemsTask;
|
||||
@@ -370,6 +372,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
}
|
||||
|
||||
TextToSuggest = item.TextToSuggest;
|
||||
WeakReferenceMessenger.Default.Send<UpdateSuggestionMessage>(new(item.TextToSuggest));
|
||||
});
|
||||
|
||||
_lastSelectedItem = item;
|
||||
@@ -423,6 +426,8 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
|
||||
WeakReferenceMessenger.Default.Send<HideDetailsMessage>();
|
||||
|
||||
WeakReferenceMessenger.Default.Send<UpdateSuggestionMessage>(new(string.Empty));
|
||||
|
||||
TextToSuggest = string.Empty;
|
||||
});
|
||||
}
|
||||
@@ -570,4 +575,4 @@ public partial class ListViewModel : PageViewModel, IDisposable
|
||||
model.ItemsChanged -= Model_ItemsChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
|
||||
public record UpdateSuggestionMessage(string TextToSuggest)
|
||||
{
|
||||
}
|
||||
@@ -19,8 +19,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Windows.CsWinRT" />
|
||||
|
||||
<PackageReference Include="CommunityToolkit.Common" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||
|
||||
@@ -28,11 +26,15 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
<PackageReference Include="WyHash" />
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.CmdPal.Common\Microsoft.CmdPal.Common.csproj" />
|
||||
<ProjectReference Include="..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -43,4 +45,16 @@
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<!-- Just mark it as AOT compatible. Do not publish with AOT now. We need fully test before we really publish it as AOT enabled-->
|
||||
<!--<PropertyGroup>
|
||||
<SelfContained>true</SelfContained>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
<PublishTrimmed>true</PublishTrimmed>
|
||||
<PublishSingleFile>true</PublishSingleFile>
|
||||
--><!-- <DisableRuntimeMarshalling>true</DisableRuntimeMarshalling> --><!--
|
||||
<PublishAot>true</PublishAot>
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
</PropertyGroup>-->
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Models;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
@@ -48,7 +49,7 @@ public partial class ShellViewModel : ObservableObject,
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CoreLogger.LogError(ex.ToString());
|
||||
Logger.LogError(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,7 +139,7 @@ public partial class ShellViewModel : ObservableObject,
|
||||
// TODO: Handle failure case
|
||||
if (viewModel.InitializeCommand.ExecutionTask.Exception is AggregateException ex)
|
||||
{
|
||||
CoreLogger.LogError(ex.ToString());
|
||||
Logger.LogError(ex.ToString());
|
||||
}
|
||||
|
||||
// TODO GH #239 switch back when using the new MD text block
|
||||
@@ -195,7 +196,7 @@ public partial class ShellViewModel : ObservableObject,
|
||||
{
|
||||
if (command is IPage page)
|
||||
{
|
||||
CoreLogger.LogDebug($"Navigating to page");
|
||||
Logger.LogDebug($"Navigating to page");
|
||||
|
||||
var isMainPage = command == _rootPage;
|
||||
_isNested = !isMainPage;
|
||||
@@ -204,7 +205,7 @@ public partial class ShellViewModel : ObservableObject,
|
||||
var pageViewModel = _pageViewModelFactory.TryCreatePageViewModel(page, _isNested, host);
|
||||
if (pageViewModel == null)
|
||||
{
|
||||
CoreLogger.LogError($"Failed to create ViewModel for page {page.GetType().Name}");
|
||||
Logger.LogError($"Failed to create ViewModel for page {page.GetType().Name}");
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
@@ -218,7 +219,7 @@ public partial class ShellViewModel : ObservableObject,
|
||||
}
|
||||
else if (command is IInvokableCommand invokable)
|
||||
{
|
||||
CoreLogger.LogDebug($"Invoking command");
|
||||
Logger.LogDebug($"Invoking command");
|
||||
|
||||
WeakReferenceMessenger.Default.Send<BeginInvokeMessage>();
|
||||
StartInvoke(message, invokable, host);
|
||||
@@ -284,7 +285,7 @@ public partial class ShellViewModel : ObservableObject,
|
||||
}
|
||||
|
||||
var kind = result.Kind;
|
||||
CoreLogger.LogDebug($"handling {kind.ToString()}");
|
||||
Logger.LogDebug($"handling {kind.ToString()}");
|
||||
|
||||
WeakReferenceMessenger.Default.Send<CmdPalInvokeResultMessage>(new(kind));
|
||||
switch (kind)
|
||||
|
||||
@@ -21,8 +21,12 @@ public partial class AppStateModel : ObservableObject
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// STATE HERE
|
||||
// Make sure that you make the setters public (JsonSerializer.Deserialize will fail silently otherwise)!
|
||||
// Make sure that any new types you add are added to JsonSerializationContext!
|
||||
public RecentCommandsManager RecentCommands { get; set; } = new();
|
||||
|
||||
public List<string> RunHistory { get; set; } = [];
|
||||
|
||||
// END SETTINGS
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -86,7 +90,7 @@ public partial class AppStateModel : ObservableObject
|
||||
{
|
||||
foreach (var item in newSettings)
|
||||
{
|
||||
savedSettings[item.Key] = item.Value != null ? item.Value.DeepClone() : null;
|
||||
savedSettings[item.Key] = item.Value?.DeepClone();
|
||||
}
|
||||
|
||||
var serialized = savedSettings.ToJsonString(JsonSerializationContext.Default.AppStateModel.Options);
|
||||
@@ -121,20 +125,4 @@ public partial class AppStateModel : ObservableObject
|
||||
// now, the settings is just next to the exe
|
||||
return Path.Combine(directory, "state.json");
|
||||
}
|
||||
|
||||
// [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "<Pending>")]
|
||||
// private static readonly JsonSerializerOptions _serializerOptions = new()
|
||||
// {
|
||||
// WriteIndented = true,
|
||||
// Converters = { new JsonStringEnumConverter() },
|
||||
// };
|
||||
|
||||
// private static readonly JsonSerializerOptions _deserializerOptions = new()
|
||||
// {
|
||||
// PropertyNameCaseInsensitive = true,
|
||||
// IncludeFields = true,
|
||||
// AllowTrailingCommas = true,
|
||||
// PreferredObjectCreationHandling = JsonObjectCreationHandling.Populate,
|
||||
// ReadCommentHandling = JsonCommentHandling.Skip,
|
||||
// };
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public partial class CommandSettingsViewModel(ICommandSettings? _unsafeSettings,
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CoreLogger.LogError($"Failed to load settings page", ex: ex);
|
||||
Logger.LogError($"Failed to load settings page", ex: ex);
|
||||
}
|
||||
|
||||
Initialized = true;
|
||||
|
||||
@@ -263,7 +263,7 @@ public partial class MainListPage : DynamicListPage,
|
||||
{
|
||||
nameMatch,
|
||||
descriptionMatch,
|
||||
isFallback ? 1 : 0, // Always give fallbacks a chance...
|
||||
isFallback ? 1 : 0, // Always give fallbacks a chance
|
||||
};
|
||||
var max = scores.Max();
|
||||
|
||||
@@ -273,8 +273,7 @@ public partial class MainListPage : DynamicListPage,
|
||||
// above "git" from "whatever"
|
||||
max = max + extensionTitleMatch;
|
||||
|
||||
// ... but downweight them
|
||||
var matchSomething = (max / (isFallback ? 3 : 1))
|
||||
var matchSomething = max
|
||||
+ (isAliasMatch ? 9001 : (isAliasSubstringMatch ? 1 : 0));
|
||||
|
||||
// If we matched title, subtitle, or alias (something real), then
|
||||
|
||||
@@ -71,11 +71,6 @@ public partial class App : Application
|
||||
AppWindow?.Close();
|
||||
Environment.Exit(0);
|
||||
});
|
||||
|
||||
// Connect the PT logging to the core project's logging.
|
||||
// This way, log statements from the core project will be captured by the PT logs
|
||||
var logWrapper = new LogWrapper();
|
||||
CoreLogger.InitializeLogger(logWrapper);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -103,10 +98,13 @@ public partial class App : Application
|
||||
|
||||
// Built-in Commands. Order matters - this is the order they'll be presented by default.
|
||||
var allApps = new AllAppsCommandProvider();
|
||||
var files = new IndexerCommandsProvider();
|
||||
files.SuppressFallbackWhen(ShellCommandsProvider.SuppressFileFallbackIf);
|
||||
services.AddSingleton<ICommandProvider>(allApps);
|
||||
|
||||
services.AddSingleton<ICommandProvider, ShellCommandsProvider>();
|
||||
services.AddSingleton<ICommandProvider, CalculatorCommandProvider>();
|
||||
services.AddSingleton<ICommandProvider, IndexerCommandsProvider>();
|
||||
services.AddSingleton<ICommandProvider>(files);
|
||||
services.AddSingleton<ICommandProvider, BookmarksCommandProvider>();
|
||||
|
||||
services.AddSingleton<ICommandProvider, WindowWalkerCommandsProvider>();
|
||||
@@ -149,6 +147,7 @@ public partial class App : Application
|
||||
services.AddSingleton(state);
|
||||
services.AddSingleton<IExtensionService, ExtensionService>();
|
||||
services.AddSingleton<TrayIconService>();
|
||||
services.AddSingleton<IRunHistoryService, RunHistoryService>();
|
||||
|
||||
services.AddSingleton<IRootPageService, PowerToysRootPageService>();
|
||||
services.AddSingleton<IAppHostService, PowerToysAppHostService>();
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="Microsoft.CmdPal.Core.Control.Controls.CommandBar"
|
||||
x:Class="Microsoft.CmdPal.UI.Controls.CommandBar"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:animations="using:CommunityToolkit.WinUI.Animations"
|
||||
xmlns:cmdpalUI="using:Microsoft.CmdPal.Core.Control"
|
||||
xmlns:cmdpalUI="using:Microsoft.CmdPal.UI"
|
||||
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
|
||||
xmlns:cpcontrols="using:Microsoft.CmdPal.Core.Control.Controls"
|
||||
xmlns:coreViewModels="using:Microsoft.CmdPal.Core.ViewModels"
|
||||
xmlns:cpcontrols="using:Microsoft.CmdPal.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:help="using:Microsoft.CmdPal.Core.Control.Helpers"
|
||||
xmlns:help="using:Microsoft.CmdPal.UI.Helpers"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
xmlns:viewModels="using:Microsoft.CmdPal.Core.Control.ViewModels"
|
||||
xmlns:viewModels="using:Microsoft.CmdPal.UI.ViewModels"
|
||||
Background="Transparent"
|
||||
mc:Ignorable="d">
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.CmdPal.Core.Control.Views;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.Views;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Windows.System;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Controls;
|
||||
namespace Microsoft.CmdPal.UI.Controls;
|
||||
|
||||
public sealed partial class CommandBar : UserControl,
|
||||
IRecipient<OpenContextMenuMessage>,
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using ManagedCommon;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Controls;
|
||||
namespace Microsoft.CmdPal.UI.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// A helper control which takes an <see cref="IconSource"/> and creates the corresponding <see cref="IconElement"/>.
|
||||
@@ -17,7 +17,6 @@ public partial class ContentIcon : FontIcon
|
||||
{
|
||||
public UIElement Content
|
||||
{
|
||||
// [DynamicWindowsRuntimeCast(typeof(UIElement))]
|
||||
get => (UIElement)GetValue(ContentProperty);
|
||||
set => SetValue(ContentProperty, value);
|
||||
}
|
||||
@@ -44,7 +43,7 @@ public partial class ContentIcon : FontIcon
|
||||
}
|
||||
catch (COMException ex)
|
||||
{
|
||||
CoreLogger.LogError(ex.ToString());
|
||||
Logger.LogError(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="Microsoft.CmdPal.Core.Control.Controls.ContextMenu"
|
||||
x:Class="Microsoft.CmdPal.UI.Controls.ContextMenu"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:animations="using:CommunityToolkit.WinUI.Animations"
|
||||
xmlns:cmdpalUI="using:Microsoft.CmdPal.Core.Control"
|
||||
xmlns:cmdpalUI="using:Microsoft.CmdPal.UI"
|
||||
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
|
||||
xmlns:cpcontrols="using:Microsoft.CmdPal.Core.Control.Controls"
|
||||
xmlns:coreViewModels="using:Microsoft.CmdPal.Core.ViewModels"
|
||||
xmlns:cpcontrols="using:Microsoft.CmdPal.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:help="using:Microsoft.CmdPal.Core.Control.Helpers"
|
||||
xmlns:help="using:Microsoft.CmdPal.UI.Helpers"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
xmlns:viewModels="using:Microsoft.CmdPal.Core.Control.ViewModels"
|
||||
xmlns:coreViewModels="using:Microsoft.CmdPal.Core.ViewModels"
|
||||
xmlns:viewModels="using:Microsoft.CmdPal.UI.ViewModels"
|
||||
Background="Transparent"
|
||||
mc:Ignorable="d">
|
||||
|
||||
@@ -12,7 +12,7 @@ using Microsoft.UI.Xaml.Input;
|
||||
using Windows.System;
|
||||
using Windows.UI.Core;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Controls;
|
||||
namespace Microsoft.CmdPal.UI.Controls;
|
||||
|
||||
public sealed partial class ContextMenu : UserControl,
|
||||
IRecipient<OpenContextMenuMessage>,
|
||||
@@ -2,14 +2,16 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.Control.Deferred;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.UI.Deferred;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Controls;
|
||||
namespace Microsoft.CmdPal.UI.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// A helper control which takes an <see cref="IconSource"/> and creates the corresponding <see cref="IconElement"/>.
|
||||
@@ -49,8 +51,12 @@ public partial class IconBox : ContentControl
|
||||
/// </summary>
|
||||
public event TypedEventHandler<IconBox, SourceRequestedEventArgs>? SourceRequested;
|
||||
|
||||
// [DynamicWindowsRuntimeCast(typeof(FontIconSource))]
|
||||
// [DynamicWindowsRuntimeCast(typeof(IconSource))]
|
||||
public IconBox()
|
||||
{
|
||||
TabFocusNavigation = KeyboardNavigationMode.Once;
|
||||
IsTabStop = false;
|
||||
}
|
||||
|
||||
private static void OnSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is IconBox @this)
|
||||
@@ -81,7 +87,6 @@ public partial class IconBox : ContentControl
|
||||
}
|
||||
}
|
||||
|
||||
// [DynamicWindowsRuntimeCast(typeof(FontIconSource))]
|
||||
private static void OnSourceKeyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is IconBox @this)
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="Microsoft.CmdPal.Core.Control.Controls.SearchBar"
|
||||
x:Class="Microsoft.CmdPal.UI.Controls.SearchBar"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:cmdpalUi="using:Microsoft.CmdPal.Core.Control"
|
||||
xmlns:cmdpalUi="using:Microsoft.CmdPal.UI"
|
||||
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
|
||||
xmlns:cpcontrols="using:Microsoft.CmdPal.Core.Control.Controls"
|
||||
xmlns:cpcontrols="using:Microsoft.CmdPal.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
@@ -2,12 +2,11 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.CmdPal.Core.Control.Views;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.Views;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Input;
|
||||
using Microsoft.UI.Xaml;
|
||||
@@ -16,11 +15,12 @@ using Microsoft.UI.Xaml.Input;
|
||||
using CoreVirtualKeyStates = Windows.UI.Core.CoreVirtualKeyStates;
|
||||
using VirtualKey = Windows.System.VirtualKey;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Controls;
|
||||
namespace Microsoft.CmdPal.UI.Controls;
|
||||
|
||||
public sealed partial class SearchBar : UserControl,
|
||||
IRecipient<GoHomeMessage>,
|
||||
IRecipient<FocusSearchBoxMessage>,
|
||||
IRecipient<UpdateSuggestionMessage>,
|
||||
ICurrentPageAware
|
||||
{
|
||||
private readonly DispatcherQueue _queue = DispatcherQueue.GetForCurrentThread();
|
||||
@@ -31,6 +31,10 @@ public sealed partial class SearchBar : UserControl,
|
||||
private readonly DispatcherQueueTimer _debounceTimer = DispatcherQueue.GetForCurrentThread().CreateTimer();
|
||||
private bool _isBackspaceHeld;
|
||||
|
||||
private bool _inSuggestion;
|
||||
private string? _lastText;
|
||||
private string? _deletedSuggestion;
|
||||
|
||||
public PageViewModel? CurrentPageViewModel
|
||||
{
|
||||
get => (PageViewModel?)GetValue(CurrentPageViewModelProperty);
|
||||
@@ -69,6 +73,7 @@ public sealed partial class SearchBar : UserControl,
|
||||
this.InitializeComponent();
|
||||
WeakReferenceMessenger.Default.Register<GoHomeMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<FocusSearchBoxMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<UpdateSuggestionMessage>(this);
|
||||
}
|
||||
|
||||
public void ClearSearch()
|
||||
@@ -125,15 +130,6 @@ public sealed partial class SearchBar : UserControl,
|
||||
WeakReferenceMessenger.Default.Send<OpenContextMenuMessage>(new OpenContextMenuMessage(null, null, null, ContextMenuFilterLocation.Bottom));
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == VirtualKey.Right)
|
||||
{
|
||||
if (CurrentPageViewModel != null && !string.IsNullOrEmpty(CurrentPageViewModel.TextToSuggest))
|
||||
{
|
||||
FilterBox.Text = CurrentPageViewModel.TextToSuggest;
|
||||
FilterBox.Select(FilterBox.Text.Length, 0);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
else if (e.Key == VirtualKey.Escape)
|
||||
{
|
||||
if (string.IsNullOrEmpty(FilterBox.Text))
|
||||
@@ -200,12 +196,65 @@ public sealed partial class SearchBar : UserControl,
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == VirtualKey.Right)
|
||||
{
|
||||
if (_inSuggestion)
|
||||
{
|
||||
_inSuggestion = false;
|
||||
_lastText = null;
|
||||
DoFilterBoxUpdate();
|
||||
}
|
||||
}
|
||||
else if (e.Key == VirtualKey.Down)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send<NavigateNextCommand>();
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
if (_inSuggestion)
|
||||
{
|
||||
if (
|
||||
e.Key == VirtualKey.Back ||
|
||||
e.Key == VirtualKey.Delete
|
||||
)
|
||||
{
|
||||
_deletedSuggestion = FilterBox.Text;
|
||||
|
||||
FilterBox.Text = _lastText ?? string.Empty;
|
||||
FilterBox.Select(FilterBox.Text.Length, 0);
|
||||
|
||||
// Logger.LogInfo("deleting suggestion");
|
||||
_inSuggestion = false;
|
||||
_lastText = null;
|
||||
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var ignoreLeave =
|
||||
|
||||
e.Key == VirtualKey.Up ||
|
||||
e.Key == VirtualKey.Down ||
|
||||
|
||||
e.Key == VirtualKey.RightMenu ||
|
||||
e.Key == VirtualKey.LeftMenu ||
|
||||
e.Key == VirtualKey.Menu ||
|
||||
e.Key == VirtualKey.Shift ||
|
||||
e.Key == VirtualKey.RightShift ||
|
||||
e.Key == VirtualKey.LeftShift ||
|
||||
e.Key == VirtualKey.RightControl ||
|
||||
e.Key == VirtualKey.LeftControl ||
|
||||
e.Key == VirtualKey.Control;
|
||||
if (ignoreLeave)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Logger.LogInfo("leaving suggestion");
|
||||
_inSuggestion = false;
|
||||
_lastText = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void FilterBox_PreviewKeyUp(object sender, KeyRoutedEventArgs e)
|
||||
@@ -219,7 +268,7 @@ public sealed partial class SearchBar : UserControl,
|
||||
|
||||
private void FilterBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
Debug.WriteLine($"FilterBox_TextChanged: {FilterBox.Text}");
|
||||
// Logger.LogInfo($"FilterBox_TextChanged: {FilterBox.Text}");
|
||||
|
||||
// TERRIBLE HACK TODO GH #245
|
||||
// There's weird wacky bugs with debounce currently. We're trying
|
||||
@@ -228,23 +277,22 @@ public sealed partial class SearchBar : UserControl,
|
||||
// (otherwise aliases just stop working)
|
||||
if (FilterBox.Text.Length == 1)
|
||||
{
|
||||
if (CurrentPageViewModel != null)
|
||||
{
|
||||
CurrentPageViewModel.Filter = FilterBox.Text;
|
||||
}
|
||||
DoFilterBoxUpdate();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (_inSuggestion)
|
||||
{
|
||||
// Logger.LogInfo($"-- skipping, in suggestion --");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: We could encapsulate this in a Behavior if we wanted to bind to the Filter property.
|
||||
_debounceTimer.Debounce(
|
||||
() =>
|
||||
{
|
||||
// Actually plumb Filtering to the view model
|
||||
if (CurrentPageViewModel != null)
|
||||
{
|
||||
CurrentPageViewModel.Filter = FilterBox.Text;
|
||||
}
|
||||
DoFilterBoxUpdate();
|
||||
},
|
||||
//// Couldn't find a good recommendation/resource for value here. PT uses 50ms as default, so that is a reasonable default
|
||||
//// This seems like a useful testing site for typing times: https://keyboardtester.info/keyboard-latency-test/
|
||||
@@ -254,6 +302,21 @@ public sealed partial class SearchBar : UserControl,
|
||||
immediate: FilterBox.Text.Length <= 1);
|
||||
}
|
||||
|
||||
private void DoFilterBoxUpdate()
|
||||
{
|
||||
if (_inSuggestion)
|
||||
{
|
||||
// Logger.LogInfo($"--- skipping ---");
|
||||
return;
|
||||
}
|
||||
|
||||
// Actually plumb Filtering to the view model
|
||||
if (CurrentPageViewModel != null)
|
||||
{
|
||||
CurrentPageViewModel.Filter = FilterBox.Text;
|
||||
}
|
||||
}
|
||||
|
||||
// Used to handle the case when a ListPage's `SearchText` may have changed
|
||||
private void Page_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
@@ -290,4 +353,96 @@ public sealed partial class SearchBar : UserControl,
|
||||
public void Receive(GoHomeMessage message) => ClearSearch();
|
||||
|
||||
public void Receive(FocusSearchBoxMessage message) => FilterBox.Focus(Microsoft.UI.Xaml.FocusState.Programmatic);
|
||||
|
||||
public void Receive(UpdateSuggestionMessage message)
|
||||
{
|
||||
var suggestion = message.TextToSuggest;
|
||||
|
||||
_queue.TryEnqueue(new(() =>
|
||||
{
|
||||
var clearSuggestion = string.IsNullOrEmpty(suggestion);
|
||||
|
||||
if (clearSuggestion && _inSuggestion)
|
||||
{
|
||||
// Logger.LogInfo($"Cleared suggestion \"{_lastText}\" to {suggestion}");
|
||||
_inSuggestion = false;
|
||||
FilterBox.Text = _lastText ?? string.Empty;
|
||||
_lastText = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (clearSuggestion)
|
||||
{
|
||||
_deletedSuggestion = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (suggestion == _deletedSuggestion)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_deletedSuggestion = null;
|
||||
}
|
||||
|
||||
var currentText = _lastText ?? FilterBox.Text;
|
||||
|
||||
_lastText = currentText;
|
||||
|
||||
// if (_inSuggestion)
|
||||
// {
|
||||
// Logger.LogInfo($"Suggestion from \"{_lastText}\" to {suggestion}");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Logger.LogInfo($"Entering suggestion from \"{_lastText}\" to {suggestion}");
|
||||
// }
|
||||
_inSuggestion = true;
|
||||
|
||||
var matchedChars = 0;
|
||||
var suggestionStartsWithQuote = suggestion.Length > 0 && suggestion[0] == '"';
|
||||
var currentStartsWithQuote = currentText.Length > 0 && currentText[0] == '"';
|
||||
var skipCheckingFirst = suggestionStartsWithQuote && !currentStartsWithQuote;
|
||||
for (int i = skipCheckingFirst ? 1 : 0, j = 0;
|
||||
i < suggestion.Length && j < currentText.Length;
|
||||
i++, j++)
|
||||
{
|
||||
if (string.Equals(
|
||||
suggestion[i].ToString(),
|
||||
currentText[j].ToString(),
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
matchedChars++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var first = skipCheckingFirst ? "\"" : string.Empty;
|
||||
var second = currentText.AsSpan(0, matchedChars);
|
||||
var third = suggestion.AsSpan(matchedChars + (skipCheckingFirst ? 1 : 0));
|
||||
|
||||
var newText = string.Concat(
|
||||
first,
|
||||
second,
|
||||
third);
|
||||
|
||||
FilterBox.Text = newText;
|
||||
|
||||
var wrappedInQuotes = suggestionStartsWithQuote && suggestion.Last() == '"';
|
||||
if (wrappedInQuotes)
|
||||
{
|
||||
FilterBox.Select(
|
||||
(skipCheckingFirst ? 1 : 0) + matchedChars,
|
||||
Math.Max(0, suggestion.Length - matchedChars - 1 + (skipCheckingFirst ? -1 : 0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
FilterBox.Select(matchedChars, suggestion.Length - matchedChars);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using CommunityToolkit.Common.Deferred;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Controls;
|
||||
namespace Microsoft.CmdPal.UI.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="IconBox.SourceRequested"/> event.
|
||||
@@ -2,7 +2,7 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Microsoft.CmdPal.Core.Control.Controls">
|
||||
xmlns:local="using:Microsoft.CmdPal.UI.Controls">
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
@@ -2,17 +2,18 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.Control.Helpers;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.UI.Helpers;
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Controls;
|
||||
namespace Microsoft.CmdPal.UI.Controls;
|
||||
|
||||
[TemplatePart(Name = TagIconBox, Type = typeof(IconBox))]
|
||||
|
||||
public partial class Tag : Microsoft.UI.Xaml.Controls.Control
|
||||
public partial class Tag : Control
|
||||
{
|
||||
internal const string TagIconBox = "PART_Icon";
|
||||
|
||||
@@ -8,7 +8,7 @@ using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control;
|
||||
namespace Microsoft.CmdPal.UI;
|
||||
|
||||
internal sealed partial class ContextItemTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
@@ -18,7 +18,6 @@ internal sealed partial class ContextItemTemplateSelector : DataTemplateSelector
|
||||
|
||||
public DataTemplate? Separator { get; set; }
|
||||
|
||||
// [DynamicWindowsRuntimeCast(typeof(ListViewItem))]
|
||||
protected override DataTemplate? SelectTemplateCore(object item, DependencyObject dependencyObject)
|
||||
{
|
||||
DataTemplate? dataTemplate = Default;
|
||||
@@ -6,7 +6,7 @@ using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control;
|
||||
namespace Microsoft.CmdPal.UI;
|
||||
|
||||
public partial class DetailsDataTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
@@ -5,9 +5,9 @@
|
||||
using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Windows.System;
|
||||
using RS_ = Microsoft.CmdPal.Core.Control.Helpers.ResourceLoaderInstance;
|
||||
using RS_ = Microsoft.CmdPal.UI.Helpers.ResourceLoaderInstance;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control;
|
||||
namespace Microsoft.CmdPal.UI;
|
||||
|
||||
public partial class KeyChordToStringConverter : IValueConverter
|
||||
{
|
||||
@@ -6,11 +6,10 @@ using Microsoft.CommandPalette.Extensions;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control;
|
||||
namespace Microsoft.CmdPal.UI;
|
||||
|
||||
public partial class MessageStateToSeverityConverter : IValueConverter
|
||||
{
|
||||
// [DynamicWindowsRuntimeCast(typeof(MessageState))]
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is MessageState state)
|
||||
@@ -3,9 +3,9 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using RS_ = Microsoft.CmdPal.Core.Control.Helpers.ResourceLoaderInstance;
|
||||
using RS_ = Microsoft.CmdPal.UI.Helpers.ResourceLoaderInstance;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control;
|
||||
namespace Microsoft.CmdPal.UI;
|
||||
|
||||
public partial class PlaceholderTextConverter : IValueConverter
|
||||
{
|
||||
@@ -6,14 +6,10 @@ using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control;
|
||||
namespace Microsoft.CmdPal.UI;
|
||||
|
||||
public static class CleanupHelper
|
||||
{
|
||||
// [DynamicWindowsRuntimeCast(typeof(ItemsControl))]
|
||||
// [DynamicWindowsRuntimeCast(typeof(FrameworkElement))]
|
||||
// [DynamicWindowsRuntimeCast(typeof(ItemsRepeater))]
|
||||
// [DynamicWindowsRuntimeCast(typeof(TabView))]
|
||||
public static void Cleanup(FrameworkElement element)
|
||||
{
|
||||
var count = VisualTreeHelper.GetChildrenCount(element);
|
||||
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Page
|
||||
x:Class="Microsoft.CmdPal.Core.Control.ListPage"
|
||||
x:Class="Microsoft.CmdPal.UI.ListPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
|
||||
xmlns:cpcontrols="using:Microsoft.CmdPal.Core.Control.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:help="using:Microsoft.CmdPal.Core.Control.Helpers"
|
||||
xmlns:local="using:Microsoft.CmdPal.Core.Control"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:coreViewModels="using:Microsoft.CmdPal.Core.ViewModels"
|
||||
xmlns:viewModels="using:Microsoft.CmdPal.Core.Control.ViewModels"
|
||||
xmlns:cpcontrols="using:Microsoft.CmdPal.UI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:help="using:Microsoft.CmdPal.UI.Helpers"
|
||||
xmlns:local="using:Microsoft.CmdPal.UI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewModels="using:Microsoft.CmdPal.UI.ViewModels"
|
||||
Background="Transparent"
|
||||
mc:Ignorable="d">
|
||||
|
||||
@@ -4,15 +4,18 @@
|
||||
|
||||
using System.Diagnostics;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using ManagedCommon;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||
using Microsoft.CmdPal.UI.ViewModels;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control;
|
||||
namespace Microsoft.CmdPal.UI;
|
||||
|
||||
public sealed partial class ListPage : Page,
|
||||
IRecipient<NavigateNextCommand>,
|
||||
@@ -94,18 +97,16 @@ public sealed partial class ListPage : Page,
|
||||
{
|
||||
if (e.ClickedItem is ListItemViewModel item)
|
||||
{
|
||||
// TODO! settings?
|
||||
// var settings = App.Current.Services.GetService<SettingsModel>()!;
|
||||
// if (settings.SingleClickActivates)
|
||||
// {
|
||||
// ViewModel?.InvokeItemCommand.Execute(item);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
ViewModel?.UpdateSelectedItemCommand.Execute(item);
|
||||
WeakReferenceMessenger.Default.Send<FocusSearchBoxMessage>();
|
||||
|
||||
// }
|
||||
var settings = App.Current.Services.GetService<SettingsModel>()!;
|
||||
if (settings.SingleClickActivates)
|
||||
{
|
||||
ViewModel?.InvokeItemCommand.Execute(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
ViewModel?.UpdateSelectedItemCommand.Execute(item);
|
||||
WeakReferenceMessenger.Default.Send<FocusSearchBoxMessage>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,13 +114,11 @@ public sealed partial class ListPage : Page,
|
||||
{
|
||||
if (ItemsList.SelectedItem is ListItemViewModel vm)
|
||||
{
|
||||
// TODO! settings?
|
||||
// var settings = App.Current.Services.GetService<SettingsModel>()!;
|
||||
// if (!settings.SingleClickActivates)
|
||||
// {
|
||||
ViewModel?.InvokeItemCommand.Execute(vm);
|
||||
|
||||
// }
|
||||
var settings = App.Current.Services.GetService<SettingsModel>()!;
|
||||
if (!settings.SingleClickActivates)
|
||||
{
|
||||
ViewModel?.InvokeItemCommand.Execute(vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,7 +245,7 @@ public sealed partial class ListPage : Page,
|
||||
}
|
||||
else if (e.NewValue == null)
|
||||
{
|
||||
CoreLogger.LogDebug("cleared view model");
|
||||
Logger.LogDebug("cleared view model");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,6 +265,13 @@ public sealed partial class ListPage : Page,
|
||||
{
|
||||
ItemsList.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
// Always reset the selected item when the top-level list page changes
|
||||
// its items
|
||||
if (!sender.IsNested)
|
||||
{
|
||||
ItemsList.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void ViewModel_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
@@ -277,7 +283,6 @@ public sealed partial class ListPage : Page,
|
||||
}
|
||||
}
|
||||
|
||||
// [DynamicWindowsRuntimeCast(typeof(ScrollViewer))]
|
||||
private ScrollViewer? FindScrollViewer(DependencyObject parent)
|
||||
{
|
||||
if (parent is ScrollViewer)
|
||||
@@ -298,7 +303,6 @@ public sealed partial class ListPage : Page,
|
||||
return null;
|
||||
}
|
||||
|
||||
// [DynamicWindowsRuntimeCast(typeof(FrameworkElement))]
|
||||
private void ItemsList_RightTapped(object sender, RightTappedRoutedEventArgs e)
|
||||
{
|
||||
if (e.OriginalSource is FrameworkElement element &&
|
||||
@@ -2,10 +2,11 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.CmdPal.Core.Control.Controls;
|
||||
using Microsoft.CmdPal.Core.ViewModels;
|
||||
using Microsoft.CmdPal.UI.Controls;
|
||||
using Microsoft.CmdPal.UI.Helpers;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Helpers;
|
||||
namespace Microsoft.CmdPal.UI.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Common async event handler provides the cache lookup function for the <see cref="IconBox.SourceRequested"/> deferred event.
|
||||
@@ -10,7 +10,7 @@ using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media.Imaging;
|
||||
using Windows.Storage.Streams;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Helpers;
|
||||
namespace Microsoft.CmdPal.UI.Helpers;
|
||||
|
||||
public sealed class IconCacheService(DispatcherQueue dispatcherQueue)
|
||||
{
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace Microsoft.CmdPal.UI.Helpers;
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
internal static class NativeMethods
|
||||
{
|
||||
[DllImport("shell32.dll")]
|
||||
public static extern int SHQueryUserNotificationState(out UserNotificationState state);
|
||||
}
|
||||
|
||||
internal enum UserNotificationState : int
|
||||
{
|
||||
QUNS_NOT_PRESENT = 1,
|
||||
QUNS_BUSY,
|
||||
QUNS_RUNNING_D3D_FULL_SCREEN,
|
||||
QUNS_PRESENTATION_MODE,
|
||||
QUNS_ACCEPTS_NOTIFICATIONS,
|
||||
QUNS_QUIET_TIME,
|
||||
QUNS_APP,
|
||||
}
|
||||
@@ -7,7 +7,7 @@ using Microsoft.UI;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Color = Windows.UI.Color;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Helpers;
|
||||
namespace Microsoft.CmdPal.UI.Helpers;
|
||||
|
||||
public static partial class OptionalColorBrushCacheProvider
|
||||
{
|
||||
@@ -3,7 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
using Microsoft.Windows.ApplicationModel.Resources;
|
||||
|
||||
namespace Microsoft.CmdPal.Core.Control.Helpers;
|
||||
namespace Microsoft.CmdPal.UI.Helpers;
|
||||
|
||||
internal static class ResourceLoaderInstance
|
||||
{
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user