From ca47896204482bf4a6979e3838bf7f09f61cebeb Mon Sep 17 00:00:00 2001
From: giy <giy@omp-system.ru>
Date: Fri, 02 Sep 2022 14:16:56 +0300
Subject: [PATCH] Обновление до версии 2.9.0
---
vsconfig/2017.vsconfig | 48
Templates/quick/quick.vcxproj.filters | 4
Templates/widgetsclass/Properties/AssemblyInfo.cs | 67
QtVsTools.Package/Legacy/FormProjectQtSettings.resx | 120
QtVsTools.Wizards/ProjectWizard/Server/ServerWizard.cs | 170
Templates/qtclass/qtclass.vstemplate_TT | 71
GUIDELINES.using-directive.md | 54
QtVsTools.Package/Package/QtHelpLinkChooser.xaml.cs | 28
QtVsTools.Core/Legacy/QtProject.cs | 290
doc/images/qtvstools-quick-addressbook-mainwindow.png | 0
doc/images/qtvstools-remote-debugging.png | 0
Tests/Test_QtVsTools.Package/Test_QtVersionsPage.cs | 247
QtVsTools.Core/CommandLineParser.cs | 35
Templates/widget/QtTemplate.Item.Widget.csproj | 49
Tests/BigSolution/template/StaticLib/StaticLib.vcxproj | 93
QtVsTools.Package/QML/Parser/QmlParserInterop.cs | 16
QtVsTools.Core/OutputWindowPane.cs | 180
doc/images/front-help.png | 0
Templates/widgetsclass/widget.cpp | 11
QtVsTools.Core/QtModules.cs | 66
Tests/ProjectFormats/304/QtProjectV304.cpp | 10
Templates/qtclass/Properties/AssemblyInfo.cs | 67
QtVsTools.Core/QrcPrefix.cs | 2
QtVsTools.Core/LinkerToolWrapper.cs | 4
doc/images/front-gs.png | 0
Templates/console/QtTemplate.Project.Console.csproj | 47
Templates/console/console.vcxproj.filters | 6
QtVsTools.Package/QtVsTools.Icons.pkgdef | 20
Tests/ProjectFormats/304/QtProjectV304.vcxproj.filters | 48
Tests/BigSolution/template/loop_msbuild.bat | 36
Tests/Test_QtMsBuild.Tasks/Test_QtMsBuild.Tasks.csproj | 33
Tests/BigSolution/template/BigProjectNNN/BigProjectQtClassNNN.h | 2
QtVsTools.Package/Legacy/ChangeFor.cs | 32
Tests/ProjectFormats/100/QtProjectV100.qrc | 4
QtVsTools.Core/QtVSIPSettings.cs | 477
QtVsTools.Package/QML/Classification/QmlExpressionEvalClassifier.cs | 13
QtVsTools.Core/Common/QtVSIPSettingsShared.cs | 261
QtVsTools.Package/QtMsBuild/QtModulesPopup.xaml | 8
doc/images/qtvstools-msbuild-diagram.png | 0
QtVsTools.Core/ProFileContent.cs | 40
Templates/server/QtTemplate.Project.Server.csproj | 49
Tests/ProjectFormats/302/QtProjectV302.h | 15
QtVsTools.Wizards/ProjectWizard/Library/LibraryClassPage.xaml | 238
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4JsObject.cs | 1
QtVsTools.Wizards/ItemWizard/QtClass/QtClassWizard.cs | 193
Tests/ProjectFormats/300/main.cpp | 10
QtVsTools.Package/Legacy/FormChangeQtVersion.cs | 107
QtVsTools.Core/QMakeQuery.cs | 22
QtVsTools.RegExpr/Properties/AssemblyInfo.cs | 1
QtVsTools.Wizards/ProjectWizard/Server/ServerPage.xaml.cs | 64
QtVsTools.Wizards/Common/WizardWindow.xaml | 44
Tests/Test_QtVsTools.Package/Properties/AssemblyInfo.cs | 20
Tests/ProjectFormats/301/QtProjectV301.ui | 29
doc/tutorial/QuickAddressBook/QuickAddressBookTypes/AddressBookItem.qml | 59
QtVsTools.Package/Marketplace/Overview.html_TT | 39
QtVsTools.Core/MsBuildProject.cs | 104
QtVsTools.Package/Legacy/FormProjectQtSettings.cs | 166
Tests/Test_QtVsTools.RegExpr/Properties/AssemblyInfo.cs | 1
Tests/ProjectFormats/303/QtProjectV303.vcxproj | 106
doc/tutorial/QuickAddressBook/main.qml | 74
QtMSBuild/QtMsBuild/qt_settings.xml | 52
Tests/ProjectFormats/100/QtProjectV100.cpp | 10
QtVsTools.Wizards/Util/FileNameValidationRule.cs | 55
Templates/lib/QtTemplate.Project.Lib.csproj | 49
QtVsTools.Package/QML/Syntax/QmlSyntax.cs | 2
QtVsTools.Core/VisualStudio/InfoBarMessage.cs | 166
Templates/widgetsclass/widgetsclass.ico | 0
QtVsTools.Wizards/ProjectWizard/Designer/DesignerPage.xaml | 310
Tests/Test_QtVsTools.RegExpr/Test_QtVsTools.RegExpr.csproj | 6
Templates/qmldir/QtTemplate.Item.QMLDir.csproj | 49
QtVsTools.Package/Common/Timestamp.cs | 9
QtVsTools.Package/Package/QtItemContextMenu.cs | 41
QtVsTools.Wizards/ProjectWizard/Designer/DesignerWizard.cs | 179
Tests/Test_QtVsTools.Core/Test_LazyFactory.cs | 77
doc/qtvstools-online.qdocconf | 2
QtMSBuild/QtMsBuild/qt6.natvis.xml | 406
QtVsTools.Package/QML/Parser/QmlParserDiagnostics.cs | 4
QtVsTools.Core/Legacy/QtVersionManager.cs | 63
Templates/gui/gui.vcxproj.filters | 2
Tests/ProjectFormats/100/QtProjectV100.ui | 28
Tests/BigSolution/template/BigProjectNNN/BigProjectNNN.vcxproj | 8
Tests/ProjectFormats/200/QtProjectV200.vcxproj.filters | 75
QtVsTools.Package/Package/QtProjectContextMenu.cs | 128
QtVsTools.Package/QtMsBuild/QtVersionProvider.cs | 1
Tests/ProjectFormats/304/QtProjectV304.sln | 25
QtVsTools.Core/QMakeConf.cs | 16
.github/ISSUE_TEMPLATE/feature.md | 20
QtVsTools.Core/ProSolution.cs | 23
doc/tutorial/AddressBook/adddialog.h | 2
QtVsTools.Wizards/ProjectWizard/ConfigPage.xaml.cs | 489 +
Tests/Test_QtVsTools.RegExpr/Test_SubTokens.cs | 1
Tests/Test_QtVsTools.Core/Properties/AssemblyInfo.cs | 20
doc/images/qtvstools-qt-translation-file-wizard.png | 0
Tests/ProjectFormats/303/QtProjectV303.ui | 28
Tests/ProjectFormats/302/QtProjectV302.sln | 25
QtVsTools.Package/QtVsTools.Package.csproj | 166
QtVsTools.Core/QtVsTools.Core.csproj | 57
Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.vcxproj | 114
Tests/Test_QtMsBuild.Tasks/Test_Join.cs | 25
QtVsTools.Core/QtMsBuild.cs | 80
Tests/ProjectFormats/100/main.cpp | 10
doc/tutorial/QuickAddressBook/QuickAddressBookTypes/NewAddressPopup.qml | 88
Tests/ProjectFormats/100/QtProjectV100.vcxproj.filters | 95
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Engine.cs | 46
QtVsTools.RegExpr/expression/RegExprToken.cs | 18
Templates/translation/translation.ico | 0
QtVsTools.Wizards/ProjectWizard/ConfigPage.xaml | 298
doc/images/front-advanced.png | 0
QtVsTools.Wizards/Util/NativeMethods.cs | 41
Templates/widgetsclass/widget.ui | 22
Templates/dialogbuttonright/QtTemplate.Item.DialogButtonRight.csproj | 49
QtVsTools.Package/QML/Classification/QmlTag.cs | 18
Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.cpp | 33
Tests/BigSolution/generator/Program.cs | 115
.github/ISSUE_TEMPLATE/bug.md | 31
QtVsTools.Package/Package/Notifications.cs | 111
doc/tutorial/QuickAddressBook/main.cpp | 45
QtVsTools.Wizards/ItemWizard/QtClass/QtClassPage.xaml.cs | 68
QtVsTools.Package/QML/Classification/QmlSyntaxClassifier.cs | 4
doc/images/qtvstools-quick-addressbook-entries.png | 0
QtMSBuild/QtMsBuild/translation/qttranslation.targets | 16
QtVsTools.Package/QtMsBuild/QtProjectTracker.cs | 170
QtVsTools.Core/Resources.resx | 40
QtVsTools.Package/Package/QtHelpLinkChooser.xaml | 60
Tests/BigSolution/template/QtClassLibrary/qtclasslibrary_global.h | 41
Templates/mainwindow/QtTemplate.Item.MainWindow.csproj | 49
Templates/quick/QtTemplate.Project.Quick.csproj | 42
Tests/BigSolution/template/BigSolution.sln | 12
QtMSBuild/Tasks/QtRunTask.cs | 246
QtVsTools.Package/Common/Json/DeferredObject.cs | 2
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Continue.cs | 3
version.targets | 2
QtMSBuild/QtMsBuild/qt_private.props | 116
QtVsTools.Package/QtMenus.vsct_TT | 93
QtVsTools.Package/Common/Prototyped.cs | 9
QtVsTools.Package/qtmodules.xml | 56
Tests/Test_QtVsTools.RegExpr/Test_MacroParser.cs | 3
QtVsTools.Package/Icons/prf32.png | 0
QtVsTools.RegExpr/production/Production.cs | 14
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Program.cs | 80
QtVsTools.Package/Package/ExtLoader.cs | 19
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Expression.cs | 11
QtVsTools.Wizards/Common/WizardIntroPage.xaml.cs | 39
QtVsTools.Package/Common/PriorityQueue.cs | 19
Tests/ProjectFormats/100/QtProjectV100.pro | 6
Templates/server/server.vcxproj.filters | 2
Tests/ProjectFormats/302/QtProjectV302.ui | 28
Tests/ProjectFormats/303/QtProjectV303.cpp | 7
Templates/translation/translation.ts | 4
.editorconfig | 2
QtVsTools.Package/QtMsBuild/QtModulesPopup.xaml.cs | 8
QtVsTools.Core/VisualStudio/VsSearch.cs | 146
Templates/qml/QtTemplate.Item.QMLFile.csproj | 49
QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml.cs | 91
QtVsTools.Wizards/Common/WizardIntroPage.xaml | 102
Templates/translation/translation.vstemplate_TT | 69
README.md | 2
QtVsTest/QtVsTest.cs | 4
QtVsTools.Wizards/Common/WizardWindow.xaml.cs | 133
QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml | 149
QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Message.cs | 6
Templates/translation/Properties/AssemblyInfo.cs | 67
QtVsTools.Package/qt6modules.xml | 510 +
QtVsTools.Package/Icons/qml32.png | 0
QtVsTools.Wizards/Common/WizardData.cs | 68
Tests/ProjectFormats/302/QtProjectV302.vcxproj | 102
Templates/qtclass/qtclass.ico | 0
Tests/ProjectFormats/301/main.cpp | 10
Tests/ProjectFormats/304/main.cpp | 10
QtVsTools.Wizards/Common/WizardResult.cs | 37
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7InfoHelpers.cs | 10
QtVsTools.Core/FakeFilter.cs | 7
Tests/Test_QtMsBuild.Tasks/TestTaskLoggingHelper.cs | 4
QtVsTools.Package/Common/Json/Serializable.cs | 8
doc/tutorial/QuickAddressBook/QuickAddressBook.vcxproj.filters | 45
Tests/ProjectFormats/300/QtProjectV300.qrc | 4
QtVsTools.Core/ProjectImporter.cs | 112
QtVsTools.Core/ProFileOption.cs | 100
QtVsTools.Core/Resources.cs | 7
Tests/ProjectFormats/303/QtProjectV303.sln | 25
Tests/Test_QtVsTools.Core/Test_QtVsTools.Core.csproj | 129
QtVsTools.Core/RccOptions.cs | 15
Tests/ProjectFormats/304/QtProjectV304.qrc | 4
Tests/BigSolution/template/StaticLib/StaticLib.vcxproj.filters | 27
vstools.bat | 37
doc/images/front-projects.png | 0
QtVsTools.Package/Icons/pri32.png | 0
QtVsTools.Package/qt5.natvis.xml | 51
QtVsTools.Wizards/ProjectWizard/Library/LibraryWizard.cs | 142
QtVsTools.Core/VisualStudio/VsShell.cs | 107
QtVsTools.Wizards/ItemWizard/Translation/TranslationWizard.cs | 119
QtMSBuild/QtMsBuild/qt_vars.targets | 74
Templates/resource/QtTemplate.Item.Resource.csproj | 49
Tests/Test_QtMsBuild.Tasks/Properties/AssemblyInfo.cs | 1
Tests/Test_QtMsBuild.Tasks/Test_QtRunTask.cs | 90
vstools.sln | 99
Tests/ProjectFormats/304/QtProjectV304.h | 16
doc/tutorial/QuickAddressBook/QuickAddressBook.sln | 25
QtVsTools.Package/QtVsToolsPackage.cs | 82
Tests/ProjectFormats/300/QtProjectV300.cpp | 7
QtVsTools.Package/source.extension.vsixmanifest_TT | 18
Tests/ProjectFormats/ProjectFormats.md | 1324 ++
QtVsTools.Core/WaitDialog.cs | 41
QtVsTools.Package/Resources.resx | 39
QtVsTools.Package/Editors/Editor.QtDesigner.cs | 21
QtVsTools.Core/BuildConfig.cs | 1
QtVsTools.RegExpr/expression/CharClassSet.cs | 13
Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.h | 37
Tests/ProjectFormats/100/QtProjectV100.vcxproj | 215
QtVsTools.Core/QMake.cs | 30
QtVsTools.Package/Icons/Monikers.imagemanifest | 54
QtVsTools.Package/Package/QMakeWrapper.cs | 2
Tests/ProjectFormats/200/QtProjectV200.h | 15
QtVsTools.Core/HelperFunctions.cs | 629
Tests/ProjectFormats/302/main.cpp | 10
doc/tutorial/QuickAddressBook/QuickAddressBook.vcxproj | 135
QtVsTools.Core/ExportProjectDialog.cs | 6
QtVsTools.Core/VisualStudio/VsServiceProvider.cs | 9
Templates/gui/gui.vstemplate_TT | 2
Tests/ProjectFormats/200/QtProjectV200.sln | 22
QtMSBuild/QtMsBuild/qt_defaults.props | 7
Templates/gui/widget.cpp | 10
doc/config/style/qt5-sidebar.html | 51
QtVsTools.Package/QtMsBuild/QtProjectBuild.cs | 377
Tests/BigSolution/template/QtClassLibrary/QtClass.h | 41
QtVsTools.Package/Editors/Editor.cs | 100
QtVsTools.Package/QML/Debugging/QmlDebugger.cs | 47
QtVsTools.Core/CompilerToolWrapper.cs | 81
Templates/designer/widget.h | 2
doc/images/qtvstools-qt-project-settings.png | 0
QtVsTools.Package/Legacy/Translation.cs | 134
QtVsTools.Wizards/Common/UiClassInclusion.cs | 37
QtVsTools.Core/Common/LazyFactory.cs | 57
Tests/BigSolution/template/StaticLib/StaticLib.cpp | 31
Templates/widgetsclass/widget.h | 15
QtVsTools.Package/Common/ConcurrentStopwatch.cs | 2
QtVsTools.Package/Legacy/QtOptionsPage.cs | 161
QtVsTest/Macro.cs | 127
QtVsTools.Wizards/Common/GuiPage.xaml | 307
QtVsTools.Package/Options/QtVersionsTable.xaml | 24
QtVsTools.Core/ProjectExporter.cs | 85
Templates/server/header.h | 2
QtVsTools.Core/Messages.cs | 134
Сборка.md | 2
Templates/gui/widget.qrc | 4
QtVsTools.RegExpr/production/ProductionRule.cs | 5
Templates/translation/QtTemplate.Item.Translation.csproj | 155
QtVsTools.Wizards/QtVsTools.Wizards.csproj | 157
QtVsTools.Wizards/Util/ClassNameValidationRule.cs | 67
doc/images/qtvstools-qt-widget-class-wizard.png | 0
references.props | 163
QtVsTools.Package/Icons/pro32.png | 0
Tests/ProjectFormats/100/QtProjectV100.h | 16
Tests/ProjectFormats/304/QtProjectV304.vcxproj | 105
QtVsTools.Wizards/ItemWizard/WidgetsClass/WidgetsClassWizard.cs | 245
QtVsTools.Package/QML/Syntax/QmlAst.cs | 2
Tests/Test_QtVsTools.Package/QtVsTestClient.cs | 144
QtVsTools.Wizards/Util/VCRulePropertyStorageHelper.cs | 69
Tests/ProjectFormats/300/QtProjectV300.h | 15
Templates/widgetsclass/widgetsclass.vstemplate_TT | 70
QtVsTest/QtVsTest.csproj | 94
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Events.cs | 28
doc/images/front-coding.png | 0
vsconfig/2019.vsconfig | 44
QtVsTools.RegExpr/expression/RegExprAssert.cs | 4
Tests/Test_QtVsTools.RegExpr/Test_XmlIntParser.cs | 3
doc/images/qtvstools-quick-addressbook-popup.png | 0
.gitignore | 6
QtVsTools.Core/CxxStreamReader.cs | 4
QtVsTools.Core/MocCmdChecker.cs | 4
Tests/BigSolution/template/StaticLib/Header.h | 4
QtVsTools.RegExpr/expression/RegExprRepeat.cs | 1
QtVsTools.Package/Common/Concurrent.cs | 7
Tests/ProjectFormats/303/QtProjectV303.qrc | 4
Tests/ProjectFormats/200/QtProjectV200.cpp | 7
QtVsTools.Core/Extensions.cs | 9
QtVsTools.Wizards/ProjectWizard/Server/ServerPage.xaml | 259
QtVsTools.RegExpr/production/ProductionRuleAction.cs | 6
QtVsTools.Wizards/ProjectWizard/ProjectTemplateWizard.cs | 722 +
Tests/ProjectFormats/301/QtProjectV301.h | 15
Tests/ProjectFormats/301/QtProjectV301.qrc | 4
QtVsTools.Package/Legacy/FormChangeQtVersion.resx | 120
QtVsTools.RegExpr/utils/Consts.cs | 21
QtVsTools.Wizards/Util/UnsafeNativeMethods.cs | 41
vsconfig/2022.vsconfig | 42
doc/images/qtvstools-options-qt-general.png | 0
QtVsTools.Package/Common/Json/SerializableEnum.cs | 3
QtVsTools.Package/Options/QtOptionsPage.cs | 67
QtVsTools.Package/qt6.natvis.xml | 33
QtVsTools.Package/Options/QtVersionsPage.cs | 92
Tests/ProjectFormats/300/QtProjectV300.sln | 25
QtVsTools.Package/QML/Classification/QmlErrorClassifier.cs | 4
Templates/empty/QtTemplate.Project.Empty.csproj | 49
QtVsTools.Package/Legacy/FormChangeQtVersion.Designer.cs | 87
doc/images/front-preview.png | 0
Templates/lib/lib.vcxproj.filters | 6
Tests/ProjectFormats/303/QtProjectV303.h | 15
Tests/ProjectFormats/301/QtProjectV301.vcxproj | 109
QtVsTools.Package/Icons/qrc32.png | 0
QtVsTools.Package/QML/Classification/QmlAsyncClassifier.cs | 42
Tests/ProjectFormats/200/QtProjectV200.ui | 29
QtVsTools.Package/QML/Debugging/QmlFileSystem.cs | 15
QtVsTools.Wizards/Common/GuiPage.xaml.cs | 74
Tests/ProjectFormats/302/QtProjectV302.vcxproj.filters | 46
Tests/ProjectFormats/302/QtProjectV302.cpp | 7
QtVsTools.Package/Legacy/ProjectQtSettings.cs | 336
Tests/ProjectFormats/303/main.cpp | 10
QtVsTools.Wizards/Common/WizardPage.cs | 115
QtVsTools.Core/QtConfig.cs | 17
QtVsTools.Core/QtVersionManager.cs | 246
Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.vcxproj.filters | 42
Tests/BigSolution/template/QtClassLibrary/QtClass.cpp | 38
Templates/qtclass/header.h | 9
QtMSBuild/QtMsBuild/qt_globals.targets | 259
Templates/designer/QtTemplate.Project.Designer.csproj | 49
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Breakpoint.cs | 19
Tests/Test_QtVsTools.PriorityQueue/Test_QtVsTools.PriorityQueue.csproj | 6
Templates/designer/plugin.h | 2
QtVsTools.Package/QtMsBuild/QtProjectIntelliSense.cs | 32
QtVsTools.Core/QtProject.cs | 944 -
QtVsTools.Package/QML/Debugging/QmlDebugLauncher.cs | 63
QtVsTools.Wizards/ProjectWizard/Gui/GuiWizard.cs | 365
Changelog | 31
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Property.cs | 46
Tests/Test_QtVsTools.PriorityQueue/Properties/AssemblyInfo.cs | 1
QtVsTools.Core/MainWinWrapper.cs | 20
Tests/ProjectFormats/200/main.cpp | 10
QtVsTools.Core/Common/EnumExt.cs | 12
QtVsTools.RegExpr/expression/Renderer.cs | 1
QtVsTools.Wizards/ProjectWizard/Library/LibraryClassPage.xaml.cs | 64
Tests/Test_QtVsTools.Package/Test_QtVsTools.Package.csproj | 120
doc/images/qtvstools-qtquick-app-modules.png | 0
Templates/widgetsclass/QtTemplate.Item.WidgetsClass.csproj | 157
QtVsTools.RegExpr/parser/Parser.cs | 10
QtVsTools.Package/Package/QtSolutionContextMenu.cs | 107
Templates/qtclass/source.cpp | 8
Templates/gui/main.cpp | 2
Tests/ProjectFormats/300/QtProjectV300.vcxproj | 106
QtVsTools.Core/Filters.cs | 21
QtVsTools.Core/SR.cs | 29
QtVsTools.Package/Package/QtHelp.cs | 113
QtVsTools.Wizards/Util/UiClassInclusionConverter.cs | 43
QtVsTools.Package/Icons/ts32.png | 0
QMakeFileReader/evaluator/proitems.cpp | 2
QtMSBuild/QtMsBuild/qt_inner.targets | 138
QtVsTools.Package/QtMsBuild/QtModulesEditor.cs | 38
Tests/ProjectFormats/301/QtProjectV301.cpp | 7
QtMSBuild/Tasks/CriticalSection.cs | 2
Templates/qtclass/QtTemplate.Item.QtClass.csproj | 157
Tests/ProjectFormats/200/QtProjectV200.vcxproj | 133
doc/tutorial/QuickAddressBook/qmldir | 2
QtVsTools.Wizards/ItemWizard/QtClass/QtClassPage.xaml | 298
QtVsTools.Package/Common/NativeAPI.cs | 8
QtVsTools.RegExpr/parser/ParseTree.cs | 11
QtVsTools.Package/Icons/ui32.png | 0
doc/config/qtvstools-project.qdocconf | 8
QtVsTest/MacroParser.cs | 9
Tests/ProjectFormats/200/QtProjectV200.qrc | 4
QtVsTools.Wizards/Util/VCLanguageManagerValidationRule.cs | 53
Templates/dialogbuttonbottom/QtTemplate.Item.DialogButtonBottom.csproj | 49
QtVsTools.Package/Package/QtMainMenu.cs | 115
QtVsTools.Wizards/Util/FileExistsInFilterValidationRule.cs | 68
QtMSBuild/QtMsBuild/qt5.natvis.xml | 835 +
QtVsTools.Wizards/ProjectWizard/Quick/QuickWizard.cs | 75
Tests/ProjectFormats/303/QtProjectV303.vcxproj.filters | 49
QtVsTools.Core/QtModule.cs | 12
doc/tutorial/QuickAddressBook/qml.qrc | 8
Templates/designer/designer.vcxproj.filters | 6
Tests/Test_QtVsTools.PriorityQueue/Test_PriorityQueue.cs | 15
QtVsTools.Package/Package/DteEventsHandler.cs | 143
QtVsTools.RegExpr/QtVsTools.RegExpr.csproj | 11
Tests/ProjectFormats/300/QtProjectV300.vcxproj.filters | 50
QtVsTools.Package/QML/Debugging/V4/QmlDebugV4Client.cs | 32
Tests/ProjectFormats/300/QtProjectV300.ui | 29
QtVsTest/MacroServer.cs | 10
QtVsTools.Wizards/ProjectWizard/Console/ConsoleWizard.cs | 89
QtMSBuild/QtMSBuild.csproj | 47
QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7StackFrame.cs | 24
QtVsTools.Package/Package/Translation.cs | 171
Tests/ProjectFormats/301/QtProjectV301.vcxproj.filters | 50
QtVsTools.Core/Legacy/QtVSIPSettings.cs | 226
QtVsTools.Package/Legacy/QtMenu.cs | 109
QtVsTools.Package/Legacy/FormProjectQtSettings.Designer.cs | 159
Tests/ProjectFormats/302/QtProjectV302.qrc | 4
doc/src/qtvstools.qdoc | 868 +
QtVsTools.Wizards/ProjectWizard/Empty/EmptyWizard.cs | 75
QtVsTools.Package/Common/Json/Serializer.cs | 28
QtVsTools.Package/Options/QtVersionsTable.cs | 348
QtVsTools.Core/VersionInformation.cs | 25
QtVsTools.Package/Package/SR.cs | 53
QtVsTools.Package/Editors/Editor.QtResourceEditor.cs | 13
Tests/ProjectFormats/301/QtProjectV301.sln | 25
QtVsTools.Package/QML/Debugging/V4/QmlDebugV4Protocol.cs | 16
Tests/ProjectFormats/304/QtProjectV304.ui | 28
QtVsTools.Package/Package/QtMsBuildConverter.cs | 33
QtVsTools.Wizards/ProjectWizard/Designer/DesignerPage.xaml.cs | 70
Templates/gui/QtTemplate.Project.Gui.csproj | 55
Templates/gui/widget.h | 10
398 files changed, 23,085 insertions(+), 5,153 deletions(-)
diff --git a/.editorconfig b/.editorconfig
index e8c7721..5d522eb 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -19,7 +19,7 @@
# Organize usings
dotnet_separate_import_directive_groups = false
-dotnet_sort_system_directives_first = false
+dotnet_sort_system_directives_first = true
file_header_template = unset
# this. and Me. preferences
diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md
new file mode 100644
index 0000000..f7d109d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug.md
@@ -0,0 +1,31 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Desktop (please complete the following information):**
+ - Qt VS Tool Version [e.g. 2.7.1, 2.8.1, 2.8.1 (Rev.06)]
+ - Visual Studio version [e.g. VS2017, VS2019, VS2022]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md
new file mode 100644
index 0000000..72718d5
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.gitignore b/.gitignore
index 30aff55..9b2efd8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -315,3 +315,9 @@
QtNatvisPoC/*.txt
Tests/BigSolution/generated/
vstools.pri
+templates/widgetsclass/Properties/AssemblyInfo.tt.cs
+templates/widgetsclass/widgetsclass.vstemplate
+templates/qtclass/Properties/AssemblyInfo.tt.cs
+templates/qtclass/qtclass.vstemplate
+templates/translation/Properties/AssemblyInfo.tt.cs
+templates/translation/translation.vstemplate
diff --git a/Changelog b/Changelog
index 84198b6..811ebba 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,34 @@
+Qt Visual Studio Tools version 2.9.0:
+
+Changes
+-------
+ - Added QStringRef and QStringView debug visualizers
+ - Check if Qt translation tools are available
+ - New widget class wizards accessible from "Add New Item"
+ - New Qt class wizards accessible from "Add New Item"
+ - InfoBar notification of missing Qt installation
+ - InfoBar notification of recently installed new Qt VS Tools version
+ - Additional compiler options from Qt included in the build
+ - Enabled reporting issues and feature requests via GitHub
+ - Debug visualizer for Qt types added to PDB
+ - Improved intellisense performance for Qt projects
+- Fixed QTVSADDINBUG-626: Qt VS Tools does not generate the same code as Qt Creator
+- Fixed QTVSADDINBUG-707: Integrating the main window widget into the Qt Gui application wizard.
+- Fixed QTVSADDINBUG-884: QStringRef and QStringView have no natvis definitions
+- Fixed QTVSADDINBUG-925: Can't add an "add-on" module to project using GUI
+- Fixed QTVSADDINBUG-937: OpenGL Widgets module missing
+- Fixed QTVSADDINBUG-951: Can't build QT6 WebEngine example
+- Fixed QTVSADDINBUG-965: Pragma warning not working with "external header warning level" option
+- Fixed QTVSADDINBUG-966: Debug version of Qt Dlls are linked even if we asked for release mode
+- Fixed QTVSADDINBUG-970: Qt6 in Visual Studio plugin doesn't load qmake projects
+- Fixed QTVSADDINBUG-972: VS Plugin is ignoring module core5compat when loading project with QT6
+- Fixed QTVSADDINBUG-973: unable to add a new qt version with visual studio 2022
+- Fixed QTVSADDINBUG-979: Project Properties are overwritten by Qt Vs Tools
+- Fixed QTVSADDINBUG-980: The "Release Notes" link does not work
+- Fixed QTVSADDINBUG-982: Can't add new Qt Version
+
+
+
Qt Visual Studio Tools version 2.8.1:
Changes
diff --git a/GUIDELINES.using-directive.md b/GUIDELINES.using-directive.md
new file mode 100644
index 0000000..89c471b
--- /dev/null
+++ b/GUIDELINES.using-directive.md
@@ -0,0 +1,54 @@
+# Coding guidelines -- `using` directives
+
+Three kinds of `using` directives are available:
+ * **Reference**: `using <namespace>` -- _namespace_ can be omitted when referencing types.
+ * **Alias**: `using <alias> = <namespace|type>` -- _alias_ can be used in place of _namespace_
+ or _type_.
+ * **Static**: `using static <type>` -- all static members of _type_ are accessible without
+ having to specify the type name.
+
+The following conventions apply to `using` directives in the Qt VS Tools code:
+ * `using` directives are grouped by root namespace, and ordered alphabetically within each group.
+ * Directives that reference external namespaces are located at the start of the source file,
+ before the local namespace declaration.
+ * The order of external namespace groups is as follows:
+ 1. `System*` namespaces.
+ 2. `Microsoft*` namespaces.
+ 3. `EnvDTE*` namespaces.
+ 4. All other external namespaces.
+ * Directives referencing in-solution namespaces (i.e. `QtVsTools*` or `QtVsTest*` namespaces) are
+ nested within the local namespace block.
+ * In-solution reference directives will use an abbreviated form of the namespace, whenever
+ possible.
+ * Alias and static directives can be specified either at top-level or nested in the local
+ namespace.
+ * Alias directives are specified after all reference directives.
+ * Static directives are specified after all reference directives and all alias directives.
+ * Optionally, directives of different kinds can be separated with an empty line.
+
+## Example
+```csharp
+using System;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text.RegularExpressions;
+using Microsoft.VisualStudio;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
+using EnvDTE;
+using EnvDTE80;
+
+using Task = System.Threading.Tasks.Task;
+
+namespace QtVsTools
+{
+ using Core;
+ using QtMsBuild;
+
+ using RegExprParser = SyntaxAnalysis.RegExpr.Parser;
+
+ using static SyntaxAnalysis.RegExpr;
+
+ class ...
+```
diff --git a/QMakeFileReader/evaluator/proitems.cpp b/QMakeFileReader/evaluator/proitems.cpp
index 4212155..59ab2e0 100644
--- a/QMakeFileReader/evaluator/proitems.cpp
+++ b/QMakeFileReader/evaluator/proitems.cpp
@@ -341,7 +341,7 @@
totalLength += this_.at(i).size();
if (sz)
- totalLength += sepSize * (sz - 1);
+ totalLength += int(sepSize) * (sz - 1);
QString res(totalLength, Qt::Uninitialized);
QChar *ptr = (QChar *)res.constData();
diff --git a/QtMSBuild/QtMSBuild.csproj b/QtMSBuild/QtMSBuild.csproj
index 5898f7f..6f5d35c 100644
--- a/QtMSBuild/QtMSBuild.csproj
+++ b/QtMSBuild/QtMSBuild.csproj
@@ -67,24 +67,42 @@
<ItemGroup>
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
<Reference Include="System" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Runtime" />
<Reference Include="$(VCTargetsPath)\Application Type\Linux\1.0\Microsoft.Build.Linux.Tasks.dll" />
<Reference Include="$(VCTargetsPath)\Application Type\Linux\1.0\liblinux.dll" />
</ItemGroup>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
- // Version specific references
+ // General package references
// -->
<Import Project="$(SolutionDir)\references.props" />
<ItemGroup>
- <PackageReference Include="Microsoft.Build"
- Version="$(Version_Microsoft_Build)" />
- <PackageReference Include="Microsoft.Build.Framework"
- Version="$(Version_Microsoft_Build_Framework)" />
- <PackageReference Include="Microsoft.Build.Tasks.Core"
- Version="$(Version_Microsoft_Build_Tasks_Core)" />
- <PackageReference Include="Microsoft.Bcl.AsyncInterfaces"
- Version="$(Version_Microsoft_Bcl_AsyncInterfaces)" />
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ <PackageReference Include="$(Name_Microsoft_Build)" Version="$(Version_Microsoft_Build)" />
+ <PackageReference Include="$(Name_Microsoft_Build_Tasks_Core)" Version="$(Version_Microsoft_Build_Tasks_Core)" />
</ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_RpcContracts)" Version="$(Version_Microsoft_VisualStudio_RpcContracts)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
// Solution project references
@@ -112,6 +130,12 @@
<DesignTime>True</DesignTime>
<DependentUpon>AssemblyInfo.cs</DependentUpon>
</Compile>
+ <Content Include="QtMSBuild\qt5.natvis.xml">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="QtMSBuild\qt6.natvis.xml">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
<!--
///////////////////////////////////////////////////////////////////////////////////////////////
// Qt/MSBuild common property pages and targets
@@ -145,6 +169,10 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="QtMSBuild\qt_vars.targets">
+ <SubType>Designer</SubType>
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="QtMSBuild\qt_inner.targets">
<SubType>Designer</SubType>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
@@ -380,6 +408,7 @@
// Inline tasks
// -->
<Compile Include="Tasks\CriticalSection.cs" />
+ <Compile Include="Tasks\QtRunTask.cs" />
<Compile Include="Tasks\GetVarsFromMSBuild.cs" />
<Compile Include="Tasks\HostExec_LinuxWSL_Error.cs" />
<Compile Include="Tasks\HostTranslatePaths_LinuxWSL_Error.cs" />
diff --git a/QtMSBuild/QtMsBuild/qt5.natvis.xml b/QtMSBuild/QtMsBuild/qt5.natvis.xml
new file mode 100644
index 0000000..935d20b
--- /dev/null
+++ b/QtMSBuild/QtMsBuild/qt5.natvis.xml
@@ -0,0 +1,835 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ****************************************************************************
+ **
+ ** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************
+-->
+
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+
+ <Type Name="##NAMESPACE##::QPoint">
+ <AlternativeType Name="##NAMESPACE##::QPointF"/>
+ <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QRect">
+ <DisplayString>{{ x = {x1}, y = {y1}, width = {x2 - x1 + 1}, height = {y2 - y1 + 1} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">x1</Item>
+ <Item Name="[y]">y1</Item>
+ <Item Name="[width]">x2 - x1 + 1</Item>
+ <Item Name="[height]">y2 - y1 + 1</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QRectF">
+ <DisplayString>{{ x = {xp}, y = {yp}, width = {w}, height = {h} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ <Item Name="[width]">w</Item>
+ <Item Name="[height]">h</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSize">
+ <AlternativeType Name="##NAMESPACE##::QSizeF"/>
+ <DisplayString>{{ width = {wd}, height = {ht} }}</DisplayString>
+ <Expand>
+ <Item Name="[width]">wd</Item>
+ <Item Name="[height]">ht</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QLine">
+ <AlternativeType Name="##NAMESPACE##::QLineF"/>
+ <DisplayString>{{ start point = {pt1}, end point = {pt2} }}</DisplayString>
+ <Expand>
+ <Synthetic Name="[start point]">
+ <DisplayString>{pt1}</DisplayString>
+ <Expand>
+ <ExpandedItem>pt1</ExpandedItem>
+ </Expand>
+ </Synthetic>
+ <Synthetic Name="[end point]">
+ <DisplayString>{pt2}</DisplayString>
+ <Expand>
+ <ExpandedItem>pt2</ExpandedItem>
+ </Expand>
+ </Synthetic>
+
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPolygon">
+ <DisplayString>{{ size = {d->size} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d->size</Size>
+ <ValuePointer>(##NAMESPACE##::QPoint*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPolygonF">
+ <DisplayString>{{ size = {d->size} }}</DisplayString>
+ <Expand>
+ <Item Name="[closed]">
+ d->size > 0
+ && ((((##NAMESPACE##::QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).xp
+ == (((##NAMESPACE##::QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).xp)
+ && ((((##NAMESPACE##::QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).yp
+ == (((##NAMESPACE##::QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).yp)
+ </Item>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d->size</Size>
+ <ValuePointer>(##NAMESPACE##::QPointF*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name ="##NAMESPACE##::QVector2D">
+ <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name ="##NAMESPACE##::QVector3D">
+ <DisplayString>{{ x = {xp}, y = {yp}, z = {zp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ <Item Name="[z]">zp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name ="##NAMESPACE##::QVector4D">
+ <DisplayString>{{ x = {xp}, y = {yp}, z = {zp}, w = {wp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ <Item Name="[z]">zp</Item>
+ <Item Name="[w]">wp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name ="##NAMESPACE##::QMatrix">
+ <DisplayString>
+ {{ m11 = {_m11}, m12 = {_m12}, m21 = {_m21}, m22 = {_m22}, ... }}
+ </DisplayString>
+ <Expand>
+ <Item Name="[m11]">_m11</Item>
+ <Item Name="[m12]">_m12</Item>
+ <Item Name="[m21]">_m21</Item>
+ <Item Name="[m22]">_m22</Item>
+ <Item Name="[dx]">_dx</Item>
+ <Item Name="[dy]">_dy</Item>
+ </Expand>
+ </Type>
+
+ <Type Name ="##NAMESPACE##::QMatrix4x4">
+ <DisplayString>
+ {{ m11 = {m[0][0]}, m12 = {m[1][0]}, m13 = {m[2][0]}, m14 = {m[3][0]}, ... }}
+ </DisplayString>
+ <Expand>
+ <Item Name="[m11]">m[0][0]</Item>
+ <Item Name="[m12]">m[1][0]</Item>
+ <Item Name="[m13]">m[2][0]</Item>
+ <Item Name="[m14]">m[3][0]</Item>
+ <Item Name="[m21]">m[0][1]</Item>
+ <Item Name="[m22]">m[1][1]</Item>
+ <Item Name="[m23]">m[2][1]</Item>
+ <Item Name="[m24]">m[3][1]</Item>
+ <Item Name="[m31]">m[0][2]</Item>
+ <Item Name="[m32]">m[1][2]</Item>
+ <Item Name="[m33]">m[2][2]</Item>
+ <Item Name="[m34]">m[3][2]</Item>
+ <Item Name="[m41]">m[0][3]</Item>
+ <Item Name="[m42]">m[1][3]</Item>
+ <Item Name="[m43]">m[2][3]</Item>
+ <Item Name="[m44]">m[3][3]</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSizePolicy">
+ <DisplayString>
+ {{ horizontal = {static_cast<Policy>(bits.horPolicy)}, vertical = {static_cast<Policy>(bits.verPolicy)}, type = {ControlType(1 << bits.ctype)} }}
+ </DisplayString>
+ <Expand>
+ <Synthetic Name="[vertical policy]">
+ <DisplayString>##NAMESPACE##::QSizePolicy::Policy::{static_cast<Policy>(bits.verPolicy)}</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[horizontal policy]">
+ <DisplayString>##NAMESPACE##::QSizePolicy::Policy::{static_cast<Policy>(bits.horPolicy)}</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[control type]">
+ <DisplayString>##NAMESPACE##::QSizePolicy::ControlType::{ControlType(1 << bits.ctype)}</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[expanding directions]">
+ <DisplayString
+ Condition="(static_cast<Policy>(bits.verPolicy) & ExpandFlag)">
+ ##NAMESPACE##::Qt::Vertical (2)
+ </DisplayString>
+ <DisplayString
+ Condition="(static_cast<Policy>(bits.horPolicy) & ExpandFlag)">
+ ##NAMESPACE##::Qt::Horizontal (1)
+ </DisplayString>
+ </Synthetic>
+ <Item Name="[vertical stretch]">static_cast<int>(bits.verStretch)</Item>
+ <Item Name="[horizontal stretch]">static_cast<int>(bits.horStretch)</Item>
+ <Item Name="[has height for width]">bits.hfw == 1</Item>
+ <Item Name="[has width for height]">bits.wfh == 1</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QChar">
+ <DisplayString>{ucs,c}</DisplayString>
+ <StringView>ucs,c</StringView>
+ <Expand>
+ <Item Name="[latin 1]">ucs > 0xff ? '\0' : char(ucs),c</Item>
+ <Item Name="[unicode]">ucs,c</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QString">
+ <DisplayString>{((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub}</DisplayString>
+ <StringView>((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub</StringView>
+ <Expand>
+ <Item Name="[size]">d->size</Item>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d->size</Size>
+ <ValuePointer>((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),c</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringRef">
+ <Intrinsic Name="offset" Expression="(reinterpret_cast<char16_t*>(m_string->d))
+ + m_string->d->offset / 2" />
+ <DisplayString Condition="m_string == nullptr">{m_string,[m_size]} u""</DisplayString>
+ <DisplayString Condition="m_string != nullptr">{offset() + m_position,[m_size]}</DisplayString>
+ <Expand>
+ <Item Name="[position]" ExcludeView="simple">m_position</Item>
+ <Item Name="[size]" ExcludeView="simple">m_size</Item>
+ <ArrayItems Condition="m_string != nullptr">
+ <Size>m_size</Size>
+ <ValuePointer>offset()+m_position</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringView">
+ <DisplayString>{m_data,[m_size]}</DisplayString>
+ <StringView>m_data,[m_size]</StringView>
+ <Expand>
+ <Item Name="[size]" ExcludeView="simple">m_size</Item>
+ <ArrayItems>
+ <Size>m_size</Size>
+ <ValuePointer>m_data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QByteArray">
+ <DisplayString>{((reinterpret_cast<char*>(d)) + d->offset),sb}</DisplayString>
+ <StringView>((reinterpret_cast<char*>(d)) + d->offset),sb</StringView>
+ <Expand>
+ <Item Name="[size]">d->size</Item>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d->size</Size>
+ <ValuePointer>((reinterpret_cast<char*>(d)) + d->offset),c</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QUrl">
+ <Intrinsic Name="isEmpty" Expression="size==0">
+ <Parameter Name="size" Type="int"/>
+ </Intrinsic>
+ <Intrinsic Name="memberOffset" Expression="sizeof(QAtomicInt) + sizeof(int) + (sizeof(QString) * count)">
+ <Parameter Name="count" Type="int"/>
+ </Intrinsic>
+ <Intrinsic Name="scheme" Expression="*((QString*)(((char*)(d) + memberOffset(0))))" />
+ <Intrinsic Name="username" Expression="*((QString*)(((char*)(d) + memberOffset(1))))" />
+ <Intrinsic Name="password" Expression="*((QString*)(((char*)(d) + memberOffset(2))))" />
+ <Intrinsic Name="host" Expression="*((QString*)(((char*)(d) + memberOffset(3))))" />
+ <Intrinsic Name="path" Expression="*((QString*)(((char*)(d) + memberOffset(4))))" />
+ <Intrinsic Name="query" Expression="*((QString*)(((char*)(d) + memberOffset(5))))" />
+ <Intrinsic Name="fragment" Expression="*((QString*)(((char*)(d) + memberOffset(6))))" />
+
+ <DisplayString Condition="!isEmpty(scheme().d->size)">{scheme()}://{host()}{path()}</DisplayString>
+ <DisplayString Condition="isEmpty(scheme().d->size)">{path()}</DisplayString>
+ <Expand>
+ <Item Name="[scheme]">scheme()</Item>
+ <Item Name="[username]">username()</Item>
+ <Item Name="[password]">password()</Item>
+ <Item Name="[host]">host()</Item>
+ <Item Name="[path]">path()</Item>
+ <Item Name="[query]">query()</Item>
+ <Item Name="[fragment]">fragment()</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QBitArray">
+ <DisplayString>{{ size = {(d.d->size << 3) - *((reinterpret_cast<char*>(d.d)) + d.d->offset)} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d.d->ref.atomic._q_value</Item>
+ <IndexListItems>
+ <Size>(d.d->size << 3) - *((reinterpret_cast<char*>(d.d)) + d.d->offset)</Size>
+ <ValueNode>
+ (*(reinterpret_cast<const unsigned char*>((reinterpret_cast<char*>(d.d)) + d.d->offset) + 1
+ + ($i >> 3)) & (1 << ($i & 7))) != 0
+ </ValueNode>
+ </IndexListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVarLengthArray<*>">
+ <AlternativeType Name="##NAMESPACE##::QVarLengthArray<*, int>"/>
+ <DisplayString>{{ size = {s} }}</DisplayString>
+ <Expand>
+ <Item Name="[capacity]">a</Item>
+ <ArrayItems>
+ <Size>s</Size>
+ <ValuePointer>ptr</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QDate">
+ <DisplayString>{{ julian day = {jd} }}</DisplayString>
+ <Expand></Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QTime">
+ <DisplayString
+ Condition="mds == 1">{{ millisecond = {mds} }}</DisplayString>
+ <DisplayString
+ Condition="mds != 1">{{ milliseconds = {mds} }}</DisplayString>
+ <Expand>
+ <Item Name="[hour]"
+ Condition="(mds / 3600000) == 1">mds / 3600000, d</Item>
+ <Item Name="[hours]"
+ Condition="(mds / 3600000) != 1">mds / 3600000, d</Item>
+ <Item Name="[minute]"
+ Condition="((mds % 3600000) / 60000) == 1">(mds % 3600000) / 60000, d</Item>
+ <Item Name="[minutes]"
+ Condition="((mds % 3600000) / 60000) != 1">(mds % 3600000) / 60000, d</Item>
+ <Item Name="[second]"
+ Condition="((mds / 1000) % 60) == 1">(mds / 1000) % 60, d</Item>
+ <Item Name="[seconds]"
+ Condition="((mds / 1000) % 60) != 1">(mds / 1000) % 60, d</Item>
+ <Item Name="[millisecond]"
+ Condition="(mds % 1000) == 1">mds % 1000, d</Item>
+ <Item Name="[milliseconds]"
+ Condition="(mds % 1000) != 1">mds % 1000, d</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QRegularExpression">
+ <DisplayString>{d.pattern}</DisplayString>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSharedData">
+ <Expand>
+ <Item Name="[referenced]">ref._q_value</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSharedPointer<*>">
+ <DisplayString>strong reference to shared pointer of type {"$T1"}</DisplayString>
+ <Expand>
+ <Item Name="[is null]">value == 0</Item>
+ <Item Name="[weak referenced]">d->weakref._q_value</Item>
+ <Item Name="[strong referenced]">d->strongref._q_value</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSharedDataPointer<*>">
+ <DisplayString>pointer to implicit shared object of type {"$T1"}</DisplayString>
+ <Expand>
+ <ExpandedItem>d</ExpandedItem>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QExplicitlySharedDataPointer<*>">
+ <DisplayString>pointer to explicit shared object of type {"$T1"}</DisplayString>
+ <Expand>
+ <ExpandedItem>d</ExpandedItem>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPointer<*>">
+ <DisplayString>guarded pointer to subclass of QObject of type {"$T1"}</DisplayString>
+ <Expand>
+ <Item Name="[is null]">wp.d == 0 || wp.d->strongref._q_value == 0 || wp.value == 0</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QWeakPointer<*>">
+ <DisplayString>weak reference to shared pointer of type {"$T1"}</DisplayString>
+ <Expand>
+ <Item Name="[is null]">d == 0 || d->strongref._q_value == 0 || value == 0</Item>
+ <Item Name="[weak referenced]">d->weakref._q_value</Item>
+ <Item Name="[strong referenced]">d->strongref._q_value</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QScopedPointer<*>">
+ <DisplayString>scoped pointer to a dynamically allocated object of type {"$T1"}</DisplayString>
+ <Expand>
+ <Item Name="[is null]">!d</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QScopedArrayPointer<*>">
+ <DisplayString>scoped pointer to dynamically allocated array of objects of type {"$T1"}</DisplayString>
+ <Expand>
+ <Item Name="[is null]">!d</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPair<*,*>">
+ <DisplayString>({first}, {second})</DisplayString>
+ <Expand>
+ <Item Name="[first]">first</Item>
+ <Item Name="[second]">second</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVector<*>">
+ <AlternativeType Name="##NAMESPACE##::QStack<*>"></AlternativeType>
+ <DisplayString>{{ size = {d->size} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d->size</Size>
+ <ValuePointer>($T1*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QList<*>">
+ <AlternativeType Name="##NAMESPACE##::QQueue<*>"></AlternativeType>
+ <DisplayString>{{ size = {d->end - d->begin} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ <IndexListItems>
+ <Size>d->end - d->begin</Size>
+ <ValueNode>*reinterpret_cast<$T1*>((sizeof($T1) > sizeof(void*))
+ ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
+ : reinterpret_cast<$T1*>(d->array + d->begin + $i))
+ </ValueNode>
+ </IndexListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringList">
+ <DisplayString>{{ size = {d->end - d->begin} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ <IndexListItems>
+ <Size>d->end - d->begin</Size>
+ <ValueNode>
+ *reinterpret_cast<QString*>((sizeof(QString) > sizeof(void*))
+ ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
+ : reinterpret_cast<QString*>(d->array + d->begin + $i))
+ </ValueNode>
+ </IndexListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QList<QVariant>">
+ <DisplayString>{{ size = {d->end - d->begin} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ <IndexListItems>
+ <Size>d->end - d->begin</Size>
+ <ValueNode>
+ *reinterpret_cast<QVariant*>((sizeof(QVariant) > sizeof(void*))
+ ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
+ : reinterpret_cast<QVariant*>(d->array + d->begin + $i))
+ </ValueNode>
+ </IndexListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QLinkedList<*>">
+ <DisplayString>{{ size = {d->size} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ <LinkedListItems>
+ <Size>d->size</Size>
+ <HeadPointer>d->n</HeadPointer>
+ <NextPointer>n</NextPointer>
+ <ValueNode>(*(##NAMESPACE##::QLinkedListNode<$T1>*)this).t</ValueNode>
+ </LinkedListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QMapNode<*,*>">
+ <DisplayString>({key}, {value})</DisplayString>
+ <Expand>
+ <Item Name="[key]">key</Item>
+ <Item Name="[value]">value</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QMap<*,*>">
+ <AlternativeType Name="##NAMESPACE##::QMultiMap<*,*>"/>
+ <DisplayString>{{ size = {d->size} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ <TreeItems>
+ <Size>d->size</Size>
+ <HeadPointer>d->header.left</HeadPointer>
+ <LeftPointer>left</LeftPointer>
+ <RightPointer>right</RightPointer>
+ <ValueNode>*((##NAMESPACE##::QMapNode<$T1,$T2>*)this)</ValueNode>
+ </TreeItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QHashNode<*,*>">
+ <DisplayString Condition="next == 0">(empty)</DisplayString>
+ <DisplayString Condition="next != 0">({key}, {value})</DisplayString>
+ <Expand>
+ <Item Name="[key]" Condition="next != 0">key</Item>
+ <Item Name="[value]" Condition="next != 0">value</Item>
+ <Item Name="[next]" Condition="next != 0">next</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QHash<*,*>">
+ <AlternativeType Name="##NAMESPACE##::QMultiHash<*,*>"/>
+ <DisplayString>{{ size = {d->size} }}</DisplayString>
+ <Expand>
+ <ArrayItems IncludeView="buckets">
+ <Size>d->numBuckets</Size>
+ <ValuePointer>reinterpret_cast<Node **>(d->buckets)</ValuePointer>
+ </ArrayItems>
+ <CustomListItems ExcludeView="buckets">
+ <Variable Name="n" InitialValue="d->numBuckets"/>
+ <Variable Name="bucket" InitialValue="d->buckets"/>
+ <Variable Name="node" InitialValue="d->buckets[0]"/>
+ <Variable Name="keyValuePair" InitialValue="reinterpret_cast<Node *>(0)"/>
+ <Size>d->size</Size>
+ <Loop>
+ <Break Condition="n == 0"/>
+ <Exec>node = *(bucket++)</Exec>
+ <Exec>--n</Exec>
+ <Loop>
+ <Break Condition="!node || !node->next"/>
+ <Exec>keyValuePair = reinterpret_cast<Node *>(node)</Exec>
+ <Item Name="[{keyValuePair->key}]">keyValuePair->value</Item>
+ <Exec>node = node->next</Exec>
+ </Loop>
+ </Loop>
+ </CustomListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QHashNode<*,##NAMESPACE##::QHashDummyValue>">
+ <DisplayString Condition="next == 0">(empty)</DisplayString>
+ <DisplayString Condition="next != 0">({key})</DisplayString>
+ <Expand>
+ <Item Name="[key]" Condition="next != 0">key</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSet<*>">
+ <DisplayString>{{ size = {q_hash.d->size} }}</DisplayString>
+ <Expand>
+ <ExpandedItem>q_hash</ExpandedItem>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QCache<*,*>::Node">
+ <DisplayString>({*keyPtr}, {*t})</DisplayString>
+ <Expand>
+ <Item Name="[key]">*keyPtr</Item>
+ <Item Name="[value]">*t</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QCache<*,*>">
+ <DisplayString>{{ size = {hash.d->size} }}</DisplayString>
+ <Expand>
+ <Item Name="[max coast]">mx</Item>
+ <Item Name="[total coast]">total</Item>
+ <Item Name="[referenced]">hash.d->ref.atomic._q_value</Item>
+ <LinkedListItems>
+ <Size>hash.d->size</Size>
+ <HeadPointer>f</HeadPointer>
+ <NextPointer>n</NextPointer>
+ <ValueNode>*((Node*)this)</ValueNode>
+ </LinkedListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStandardItemPrivate">
+ <Intrinsic Name="memberOffset" Expression="sizeof(QStandardItemModel *)
+ + sizeof(QStandardItem *)
+ + sizeof(int *)
+ + sizeof(int *)
+ + (sizeof(int) * count)">
+ <Parameter Name="count" Type="int"/>
+ </Intrinsic>
+ <Intrinsic Name="rows" Expression="*((int*)(((char*)(this)) + memberOffset(0)))" />
+ <Intrinsic Name="columns" Expression="*((int*)(((char*)(this)) + memberOffset(1)))" />
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStandardItem">
+ <DisplayString>{{ row count = {(*d_ptr.d).rows()}, column count = {(*d_ptr.d).columns()} }}</DisplayString>
+ <Expand>
+ <Item Name="[d]">d_ptr.d,!</Item>
+ <Item Name="[row count]">(*d_ptr.d).rows()</Item>
+ <Item Name="[column count]">(*d_ptr.d).columns()</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVariant">
+ <!--Region DisplayString QVariant-->
+
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::UnknownType">Invalid</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::Bool">{d.data.b}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::Int">{d.data.i}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::UInt">{d.data.u}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::LongLong">{d.data.ll}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::ULongLong">{d.data.ull}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::Double">{d.data.d}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QChar">{d.data.c}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVariantMap">
+ {*((##NAMESPACE##::QMap<##NAMESPACE##::QString,##NAMESPACE##::QVariant>*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVariantList">
+ {*((##NAMESPACE##::QList<##NAMESPACE##::QVariant>*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QString">
+ {*((##NAMESPACE##::QString*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QStringList">
+ {*((##NAMESPACE##::QStringList*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QByteArray">
+ {*((##NAMESPACE##::QByteArray*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QBitArray">
+ {*((##NAMESPACE##::QBitArray*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QDate">
+ {*((##NAMESPACE##::QDate*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QTime">
+ {*((##NAMESPACE##::QTime*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QDateTime">DateTime</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QUrl">Url</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QLocale">Locale</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRect">
+ {*((##NAMESPACE##::QRect*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRectF">
+ {*((##NAMESPACE##::QRectF*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QSize">
+ {*((##NAMESPACE##::QSize*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QSizeF">
+ {*((##NAMESPACE##::QSizeF*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QLine">
+ {*((##NAMESPACE##::QLine*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QLineF">
+ {*((##NAMESPACE##::QLineF*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPoint">
+ {*((##NAMESPACE##::QPoint*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPointF">
+ {*((##NAMESPACE##::QPointF*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRegExp">RegExp</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRegularExpression">RegularExpression</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVariantHash">
+ {*((##NAMESPACE##::QHash<##NAMESPACE##::QString,##NAMESPACE##::QVariant>*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QEasingCurve">EasingCurve</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QUuid">Uuid</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QModelIndex">ModelIndex</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::LastCoreType">LastCoreType</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QFont">Font</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPixmap">Pixmap</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QBrush">Brush</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QColor">Color</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPalette">Palette</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QImage">Image</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPolygon">Polygon</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRegion">Region</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QBitmap">Bitmap</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QCursor">Cursor</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QKeySequence">KeySequence</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPen">Pen</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QTextLength">TextLength</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QTextFormat">TextFormat</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QMatrix">Matrix</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QTransform">Transform</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QMatrix4x4">Matrix4x4</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVector2D">Vector2D</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVector3D">Vector3D</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVector4D">Vector4D</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QQuaternion">Quaternion</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPolygonF">PolygonF</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QIcon">Icon</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::LastGuiType">LastGuiType</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QSizePolicy">SizePolicy</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::User">UserType</DisplayString>
+ <DisplayString Condition="d.type == 0xffffffff">LastType</DisplayString>
+
+ <!--End region DisplayString QVariant-->
+
+ <!--Region DisplayView QVariant-->
+
+ <StringView Condition="d.type == ##NAMESPACE##::QMetaType::QChar">d.data.c</StringView>
+
+ <StringView Condition="d.type == ##NAMESPACE##::QMetaType::QString">
+ *((##NAMESPACE##::QString*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </StringView>
+
+ <StringView Condition="d.type == ##NAMESPACE##::QMetaType::QByteArray">
+ *((##NAMESPACE##::QByteArray*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </StringView>
+
+ <!--End region DisplayView QVariant-->
+
+ <!--Region Expand QVariant-->
+
+ <Expand>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QVariantMap">
+ *((##NAMESPACE##::QMap<##NAMESPACE##::QString,##NAMESPACE##::QVariant>*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QVariantList">
+ *((##NAMESPACE##::QList<##NAMESPACE##::QVariant>*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QString">
+ *((##NAMESPACE##::QString*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QStringList">
+ *((##NAMESPACE##::QStringList*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QByteArray">
+ *((##NAMESPACE##::QByteArray*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QBitArray">
+ *((##NAMESPACE##::QBitArray*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QDate">
+ *((##NAMESPACE##::QDate*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QTime">
+ *((##NAMESPACE##::QTime*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QRect">
+ *((##NAMESPACE##::QRect*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QRectF">
+ *((##NAMESPACE##::QRectF*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QSize">
+ *((##NAMESPACE##::QSize*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QSizeF">
+ *((##NAMESPACE##::QSizeF*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QLine">
+ *((##NAMESPACE##::QLine*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QLineF">
+ *((##NAMESPACE##::QLineF*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QPoint">
+ *((##NAMESPACE##::QPoint*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QPointF">
+ *((##NAMESPACE##::QPointF*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QVariantHash">
+ *((##NAMESPACE##::QHash<##NAMESPACE##::QString,##NAMESPACE##::QVariant>*)(d.is_shared ? d.data.shared->ptr
+ : reinterpret_cast<const void *>(&d.data.ptr)))
+ </ExpandedItem>
+ </Expand>
+
+ <!--End region Expand QVariant-->
+ </Type>
+
+</AutoVisualizer>
diff --git a/QtMSBuild/QtMsBuild/qt6.natvis.xml b/QtMSBuild/QtMsBuild/qt6.natvis.xml
new file mode 100644
index 0000000..6f4a131
--- /dev/null
+++ b/QtMSBuild/QtMsBuild/qt6.natvis.xml
@@ -0,0 +1,406 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ****************************************************************************
+ **
+ ** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************
+-->
+
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+
+ <Type Name="##NAMESPACE##::QSpecialInteger<*>">
+ <DisplayString>{val}</DisplayString>
+ <Expand>
+ <Item Name="[value]">val</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QBasicAtomicInteger<*>">
+ <DisplayString>{_q_value}</DisplayString>
+ <Expand>
+ <Item Name="[value]">_q_value</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QBasicAtomicPointer<*>">
+ <Intrinsic Name="isNull" Expression="value()==0" />
+ <Intrinsic Name="value" Expression="_q_value.value()" />
+ <DisplayString Condition="isNull()">empty</DisplayString>
+ <DisplayString Condition="!isNull()">{_q_value}</DisplayString>
+ <Expand>
+ <Item Name=" " Condition="!isNull()">*value()</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPoint">
+ <AlternativeType Name="##NAMESPACE##::QPointF"/>
+ <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QRect">
+ <DisplayString>{{ x = {x1}, y = {y1}, width = {x2 - x1 + 1}, height = {y2 - y1 + 1} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">x1</Item>
+ <Item Name="[y]">y1</Item>
+ <Item Name="[width]">x2 - x1 + 1</Item>
+ <Item Name="[height]">y2 - y1 + 1</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QRectF">
+ <DisplayString>{{ x = {xp}, y = {yp}, width = {w}, height = {h} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ <Item Name="[width]">w</Item>
+ <Item Name="[height]">h</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSize">
+ <AlternativeType Name="##NAMESPACE##::QSizeF"/>
+ <DisplayString>{{ width = {wd}, height = {ht} }}</DisplayString>
+ <Expand>
+ <Item Name="[width]">wd</Item>
+ <Item Name="[height]">ht</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QLine">
+ <AlternativeType Name="##NAMESPACE##::QLineF"/>
+ <DisplayString>{{ start point = {pt1}, end point = {pt2} }}</DisplayString>
+ <Expand>
+ <Synthetic Name="[start point]">
+ <DisplayString>{pt1}</DisplayString>
+ <Expand>
+ <ExpandedItem>pt1</ExpandedItem>
+ </Expand>
+ </Synthetic>
+ <Synthetic Name="[end point]">
+ <DisplayString>{pt2}</DisplayString>
+ <Expand>
+ <ExpandedItem>pt2</ExpandedItem>
+ </Expand>
+ </Synthetic>
+
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPolygon">
+ <DisplayString>{{ size={d->size} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d->size</Size>
+ <ValuePointer>(QPoint*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPolygonF">
+ <DisplayString>{{ size={d->size} }}</DisplayString>
+ <Expand>
+ <Item Name="[closed]">
+ d->size > 0
+ && ((((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).xp
+ == (((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).xp)
+ && ((((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).yp
+ == (((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).yp)
+ </Item>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d->size</Size>
+ <ValuePointer>(QPointF*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVector2D">
+ <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVector3D">
+ <DisplayString>{{ x = {xp}, y = {yp}, z = {zp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ <Item Name="[z]">zp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVector4D">
+ <DisplayString>{{ x = {xp}, y = {yp}, z = {zp}, w = {wp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ <Item Name="[z]">zp</Item>
+ <Item Name="[w]">wp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QMatrix">
+ <DisplayString>
+ {{ m11 = {_m11}, m12 = {_m12}, m21 = {_m21}, m22 = {_m22}, ... }}
+ </DisplayString>
+ <Expand>
+ <Item Name="[m11]">_m11</Item>
+ <Item Name="[m12]">_m12</Item>
+ <Item Name="[m21]">_m21</Item>
+ <Item Name="[m22]">_m22</Item>
+ <Item Name="[dx]">_dx</Item>
+ <Item Name="[dy]">_dy</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QMatrix4x4">
+ <DisplayString>
+ {{ m11 = {m[0][0]}, m12 = {m[1][0]}, m13 = {m[2][0]}, m14 = {m[3][0]}, ... }}
+ </DisplayString>
+ <Expand>
+ <Item Name="[m11]">m[0][0]</Item>
+ <Item Name="[m12]">m[1][0]</Item>
+ <Item Name="[m13]">m[2][0]</Item>
+ <Item Name="[m14]">m[3][0]</Item>
+ <Item Name="[m21]">m[0][1]</Item>
+ <Item Name="[m22]">m[1][1]</Item>
+ <Item Name="[m23]">m[2][1]</Item>
+ <Item Name="[m24]">m[3][1]</Item>
+ <Item Name="[m31]">m[0][2]</Item>
+ <Item Name="[m32]">m[1][2]</Item>
+ <Item Name="[m33]">m[2][2]</Item>
+ <Item Name="[m34]">m[3][2]</Item>
+ <Item Name="[m41]">m[0][3]</Item>
+ <Item Name="[m42]">m[1][3]</Item>
+ <Item Name="[m43]">m[2][3]</Item>
+ <Item Name="[m44]">m[3][3]</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSizePolicy">
+ <DisplayString>
+ {{ horizontal = {static_cast<Policy>(bits.horPolicy)}, vertical = {static_cast<Policy>(bits.verPolicy)}, type = {ControlType(1 << bits.ctype)} }}
+ </DisplayString>
+ <Expand>
+ <Synthetic Name="[vertical policy]">
+ <DisplayString>QSizePolicy::Policy::{static_cast<Policy>(bits.verPolicy)}</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[horizontal policy]">
+ <DisplayString>QSizePolicy::Policy::{static_cast<Policy>(bits.horPolicy)}</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[control type]">
+ <DisplayString>QSizePolicy::ControlType::{ControlType(1 << bits.ctype)}</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[expanding directions]">
+ <DisplayString
+ Condition="(static_cast<Policy>(bits.verPolicy) & ExpandFlag)">
+ Qt::Vertical (2)
+ </DisplayString>
+ <DisplayString
+ Condition="(static_cast<Policy>(bits.horPolicy) & ExpandFlag)">
+ Qt::Horizontal (1)
+ </DisplayString>
+ </Synthetic>
+ <Item Name="[vertical stretch]">static_cast<int>(bits.verStretch)</Item>
+ <Item Name="[horizontal stretch]">static_cast<int>(bits.horStretch)</Item>
+ <Item Name="[has height for width]">bits.hfw == 1</Item>
+ <Item Name="[has width for height]">bits.wfh == 1</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QChar">
+ <DisplayString>{ucs,c}</DisplayString>
+ <StringView>ucs,c</StringView>
+ <Expand>
+ <Item Name="[latin 1]">ucs > 0xff ? '\0' : char(ucs),c</Item>
+ <Item Name="[unicode]">ucs,c</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QString">
+ <DisplayString>"{(reinterpret_cast<unsigned short*>(d.ptr)),sub}"</DisplayString>
+ <StringView>(reinterpret_cast<unsigned short*>(d.ptr)),sub</StringView>
+ <Expand>
+ <Item Name="[size]">d.size</Item>
+ <ArrayItems>
+ <Size>d.size</Size>
+ <ValuePointer>d.ptr</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringRef">
+ <DisplayString Condition="m_string == nullptr">{m_string,[m_size]} u""</DisplayString>
+ <DisplayString Condition="m_string != nullptr">{m_string->d.ptr+m_position,[m_size]}</DisplayString>
+ <StringView Condition="m_string == nullptr">""</StringView>
+ <StringView Condition="m_string != nullptr">m_string,[m_position+m_size]</StringView>
+ <Expand>
+ <Item Name="[position]" ExcludeView="simple">m_position</Item>
+ <Item Name="[size]" ExcludeView="simple">m_size</Item>
+ <ArrayItems Condition="m_string != nullptr">
+ <Size>m_size</Size>
+ <ValuePointer>m_string->d.ptr+m_position</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringView">
+ <DisplayString>{m_data,[m_size]}</DisplayString>
+ <StringView>m_data,[m_size]</StringView>
+ <Expand>
+ <Item Name="[size]" ExcludeView="simple">m_size</Item>
+ <ArrayItems>
+ <Size>m_size</Size>
+ <ValuePointer>m_data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QByteArray">
+ <DisplayString>"{((reinterpret_cast<char*>(d.ptr))),sb}"</DisplayString>
+ <StringView>((reinterpret_cast<char*>(d.ptr))),sb</StringView>
+ <Expand>
+ <Item Name="[size]">d.size</Item>
+ <ArrayItems>
+ <Size>d.size</Size>
+ <ValuePointer>d.ptr</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QUrl">
+ <Intrinsic Name="isEmpty" Expression="size==0">
+ <Parameter Name="size" Type="int"/>
+ </Intrinsic>
+ <Intrinsic Name="memberOffset" Expression="sizeof(QAtomicInt) + sizeof(int) + (sizeof(QString) * count)">
+ <Parameter Name="count" Type="int"/>
+ </Intrinsic>
+ <Intrinsic Name="scheme" Expression="*((QString*)(((char*)(d) + memberOffset(0))))" />
+ <Intrinsic Name="username" Expression="*((QString*)(((char*)(d) + memberOffset(1))))" />
+ <Intrinsic Name="password" Expression="*((QString*)(((char*)(d) + memberOffset(2))))" />
+ <Intrinsic Name="host" Expression="*((QString*)(((char*)(d) + memberOffset(3))))" />
+ <Intrinsic Name="path" Expression="*((QString*)(((char*)(d) + memberOffset(4))))" />
+ <Intrinsic Name="query" Expression="*((QString*)(((char*)(d) + memberOffset(5))))" />
+ <Intrinsic Name="fragment" Expression="*((QString*)(((char*)(d) + memberOffset(6))))" />
+
+ <DisplayString Condition="!isEmpty(scheme().d->size)">{scheme()}://{host()}{path()}</DisplayString>
+ <DisplayString Condition="isEmpty(scheme().d->size)">{path()}</DisplayString>
+ <Expand>
+ <Item Name="[scheme]">scheme()</Item>
+ <Item Name="[username]">username()</Item>
+ <Item Name="[password]">password()</Item>
+ <Item Name="[host]">host()</Item>
+ <Item Name="[path]">path()</Item>
+ <Item Name="[query]">query()</Item>
+ <Item Name="[fragment]">fragment()</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QDate">
+ <DisplayString>{{ julian day = {jd} }}</DisplayString>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QTime">
+ <Intrinsic Name="hour" Expression="mds / 3600000" />
+ <Intrinsic Name="minute" Expression="(mds % 3600000) / 60000" />
+ <Intrinsic Name="second" Expression="(mds / 1000) % 60" />
+ <Intrinsic Name="millisecond" Expression="mds % 1000" />
+ <DisplayString Condition="mds == 1">{{ millisecond = {mds} }}</DisplayString>
+ <DisplayString Condition="mds != 1">{{ milliseconds = {mds} }}</DisplayString>
+ <Expand>
+ <Item Name="[hour]"
+ Condition="(mds / 3600000) == 1">hour(), d</Item>
+ <Item Name="[hours]"
+ Condition="(mds / 3600000) != 1">hour(), d</Item>
+ <Item Name="[minute]"
+ Condition="((mds % 3600000) / 60000) == 1">minute(), d</Item>
+ <Item Name="[minutes]"
+ Condition="((mds % 3600000) / 60000) != 1">minute(), d</Item>
+ <Item Name="[second]"
+ Condition="((mds / 1000) % 60) == 1">second(), d</Item>
+ <Item Name="[seconds]"
+ Condition="((mds / 1000) % 60) != 1">second(), d</Item>
+ <Item Name="[millisecond]"
+ Condition="(mds % 1000) == 1">millisecond(), d</Item>
+ <Item Name="[milliseconds]"
+ Condition="(mds % 1000) != 1">millisecond(), d</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPair<*,*>">
+ <DisplayString>({first}, {second})</DisplayString>
+ <Expand>
+ <Item Name="[first]">first</Item>
+ <Item Name="[second]">second</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QList<*>">
+ <AlternativeType Name="##NAMESPACE##::QVector<*>"/>
+ <DisplayString>{{ size={d.size} }}</DisplayString>
+ <Expand>
+ <ArrayItems>
+ <Size>d.size</Size>
+ <ValuePointer>reinterpret_cast<$T1*>(d.ptr)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVarLengthArray<*>">
+ <DisplayString>{{ size={s} }}</DisplayString>
+ <Expand>
+ <Item Name="[capacity]">a</Item>
+ <ArrayItems>
+ <Size>s</Size>
+ <ValuePointer>ptr</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QMap<*,*>">
+ <AlternativeType Name="##NAMESPACE##::QMultiMap<*,*>"/>
+ <DisplayString>{{ size={d.d->m._Mypair._Myval2._Myval2._Mysize} }}</DisplayString>
+ <Expand>
+ <Item Name="[std::map]">d.d->m</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QHash<*,*>">
+ <AlternativeType Name="##NAMESPACE##::QMultiHash<*,*>"/>
+ <DisplayString>{{ size = {d->size} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d->ref.atomic._q_value</Item>
+ </Expand>
+ </Type>
+
+</AutoVisualizer>
diff --git a/QtMSBuild/QtMsBuild/qt_defaults.props b/QtMSBuild/QtMsBuild/qt_defaults.props
index d351b61..ee94d6b 100644
--- a/QtMSBuild/QtMsBuild/qt_defaults.props
+++ b/QtMSBuild/QtMsBuild/qt_defaults.props
@@ -71,6 +71,9 @@
<QtPathBinaries>bin</QtPathBinaries>
<QtPathLibraryExecutables>bin</QtPathLibraryExecutables>
+ <!--// Run Qt tools during design-time build -->
+ <QtToolsDesignTime>true</QtToolsDesignTime>
+
<!--// qmake template -->
<QtQMakeTemplate>vcapp</QtQMakeTemplate>
@@ -89,6 +92,7 @@
DEFINES=/Project/ItemDefinitionGroup/ClCompile/PreprocessorDefinitions;
INCLUDEPATH=/Project/ItemDefinitionGroup/ClCompile/AdditionalIncludeDirectories;
STDCPP=/Project/ItemDefinitionGroup/ClCompile/LanguageStandard;
+ RUNTIME=/Project/ItemDefinitionGroup/ClCompile/RuntimeLibrary;
CL_OPTIONS=/Project/ItemDefinitionGroup/ClCompile/AdditionalOptions;
LIBS=/Project/ItemDefinitionGroup/Link/AdditionalDependencies;
LINK_OPTIONS=/Project/ItemDefinitionGroup/Link/AdditionalOptions;
@@ -103,6 +107,9 @@
<!--// Qt build config -->
<QtBuildConfig Condition="'$(Configuration)' == 'Debug'">debug</QtBuildConfig>
<QtBuildConfig Condition="'$(Configuration)' != 'Debug'">release</QtBuildConfig>
+
+ <!--// Qt Plugin default-->
+ <QtPlugin>false</QtPlugin>
</PropertyGroup>
<!--
diff --git a/QtMSBuild/QtMsBuild/qt_globals.targets b/QtMSBuild/QtMsBuild/qt_globals.targets
index a8cb31c..966a084 100644
--- a/QtMSBuild/QtMsBuild/qt_globals.targets
+++ b/QtMSBuild/QtMsBuild/qt_globals.targets
@@ -84,6 +84,29 @@
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
+ // Set up inner build if Qt vars property file is outdated
+ // -->
+ <PropertyGroup Condition="'$(QtInnerBuild)' == ''">
+ <QtVarsOutdated>false</QtVarsOutdated>
+ <QtVarsOutdated
+ Condition="!Exists('$(QtVarsFilePath)')
+ OR '$(QtBkup_QtInstall)' != '$(QtInstall)'
+ OR '$(QtBkup_QtModules)' != '$(QtModules)'
+ OR '$(QtBkup_QtPathBinaries)' != '$(QtPathBinaries)'
+ OR '$(QtBkup_QtPathLibraryExecutables)' != '$(QtPathLibraryExecutables)'
+ OR '$(QtBkup_QtHeaderSearchPath)' != '$(QtHeaderSearchPath)'
+ OR '$(QtBkup_QtLibrarySearchPath)' != '$(QtLibrarySearchPath)'
+ OR '$(QtBkup_QtVars)' != '$(QtVars)'
+ OR '$(QtBkup_QMakeCodeLines)' != '$(QMakeCodeLines)'
+ OR '$(QtBkup_QtBuildConfig)' != '$(QtBuildConfig)'"
+ >true</QtVarsOutdated>
+ </PropertyGroup>
+
+ <!-- // Enable inner build targets -->
+ <Import Condition="'$(QtVarsOutdated)' == 'true'" Project="qt_inner.targets"/>
+
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
/// TARGET QtGetDefaultClCompile
/////////////////////////////////////////////////////////////////////////////////////////////////
// Get default C++ properties
@@ -201,7 +224,8 @@
OR ('$(project_changed)' == 'true' AND '$(log_hash)' != '$(work_hash)')"
>true</do_work>
<skip_work
- Condition="'$(do_work)' != 'true' OR '$(DesignTimeBuild)' == 'true'"
+ Condition="'$(do_work)' != 'true'
+ OR ('$(QtDesignTimeBuild)' == 'true' AND '$(QtToolsDesignTime)' != 'true')"
>true</skip_work>
</PropertyGroup>
@@ -268,8 +292,7 @@
// -->
<QtRunWork
Condition="'$(ApplicationType)' != 'Linux' AND '@(QtWork)' != ''
- AND '%(QtWork.ParallelBuild)' == 'true'
- AND '$(DesignTimeBuild)' != 'true'"
+ AND '%(QtWork.ParallelBuild)' == 'true'"
QtWork="@(QtWork)" QtMaxProcs="$(QtMaxProcs)" QtDebug="$(QtDebug)">
<Output TaskParameter="Result" ItemName="QtWorkResult" />
</QtRunWork>
@@ -280,8 +303,7 @@
// -->
<QtRunWork
Condition="'$(ApplicationType)' != 'Linux' AND '@(QtWork)' != ''
- AND '%(QtWork.ParallelBuild)' != 'true'
- AND '$(DesignTimeBuild)' != 'true'"
+ AND '%(QtWork.ParallelBuild)' != 'true'"
QtWork="@(QtWork)" QtMaxProcs="1" QtDebug="$(QtDebug)">
<Output TaskParameter="Result" ItemName="QtWorkResult" />
</QtRunWork>
@@ -293,13 +315,13 @@
<!-- // Translate local paths to host paths -->
<Flatten
Condition="'$(ApplicationType)' == 'Linux'
- AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'"
+ AND '@(QtWork)' != '' AND '$(QtDesignTimeBuild)' != 'true'"
Items="@(QtWork)" Metadata="ResourceFiles">
<Output TaskParameter="Result" ItemName="ResourceFiles"/>
</Flatten>
<ItemGroup
Condition="'$(ApplicationType)' == 'Linux'
- AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'">
+ AND '@(QtWork)' != '' AND '$(QtDesignTimeBuild)' != 'true'">
<LocalPath Include="%(QtWork.Identity)">
<Name>InputPath</Name>
<Item>%(QtWork.Identity)</Item>
@@ -320,7 +342,7 @@
</ItemGroup>
<HostTranslatePaths
Condition="'$(ApplicationType)' == 'Linux'
- AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'"
+ AND '@(QtWork)' != '' AND '$(QtDesignTimeBuild)' != 'true'"
Items="@(LocalPath)" Names="InputPath;OutputPath">
<Output TaskParameter="Result" ItemName="HostPath"/>
</HostTranslatePaths>
@@ -332,7 +354,7 @@
<!-- // Run command -->
<HostExec
Condition="'$(ApplicationType)' == 'Linux'
- AND '%(Identity)' != '' AND '$(DesignTimeBuild)' != 'true'"
+ AND '%(Identity)' != '' AND '$(QtDesignTimeBuild)' != 'true'"
Message="@(QtWork->'%(WorkType) %(Identity)')"
Command="@(QtWork->'%(ToolPath) %(Options)')"
Inputs="@(InputPath)"
@@ -344,7 +366,7 @@
<!-- // Generate result item -->
<ItemGroup
Condition="'$(ApplicationType)' == 'Linux'
- AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'">
+ AND '@(QtWork)' != '' AND '$(QtDesignTimeBuild)' != 'true'">
<QtWorkResult Include="@(QtWork)">
<ExitCode>0</ExitCode>
</QtWorkResult>
@@ -354,9 +376,11 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// Save tracking log of files read during build; used by VS to check the up-to-date status
// -->
- <ItemGroup Condition="'$(DesignTimeBuild)' != 'true' AND '$(QtVSToolsBuild)' != 'true'">
+ <ItemGroup>
<read_log Include="^%(QtWorkResult.FullPath);%(QtWorkResult.AdditionalDependencies)"
- Condition="'%(QtWorkResult.ExitCode)' == '0' AND '%(QtWorkResult.DisableLog)' != 'true'">
+ Condition="'%(QtWorkResult.ExitCode)' == '0'
+ AND '%(QtWorkResult.DisableLog)' != 'true'
+ AND '%(QtWorkResult.Skipped)' != 'true'">
<WorkType>%(QtWorkResult.WorkType)</WorkType>
</read_log>
<read_log>
@@ -377,9 +401,11 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// Save tracking log of files written during build; used by VS to check the up-to-date status
// -->
- <ItemGroup Condition="'$(DesignTimeBuild)' != 'true' AND '$(QtVSToolsBuild)' != 'true'">
+ <ItemGroup>
<write_log Include="^%(QtWorkResult.FullPath);%(QtWorkResult.OutputFile)"
- Condition="'%(QtWorkResult.ExitCode)' == '0' AND '%(QtWorkResult.DisableLog)' != 'true'">
+ Condition="'%(QtWorkResult.ExitCode)' == '0'
+ AND '%(QtWorkResult.DisableLog)' != 'true'
+ AND '%(QtWorkResult.Skipped)' != 'true'">
<WorkType>%(QtWorkResult.WorkType)</WorkType>
</write_log>
<write_log>
@@ -398,7 +424,7 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// Log output files; this is used by VS to determine what files to delete on "Clean"
// -->
- <ItemGroup Condition="'$(DesignTimeBuild)' != 'true' AND '$(QtVSToolsBuild)' != 'true'">
+ <ItemGroup>
<clean_log Include="%(QtWorkResult.OutputFile)"
Condition="'%(QtWorkResult.ExitCode)' == '0'">
<Source>@(QtWorkResult, '|')</Source>
@@ -414,7 +440,7 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// Log calls to Qt tools; used in QtWorkPrepare to detect changes to the options of Qt tools
// -->
- <WriteLinesToFile Condition="'@(QtWorkLog)' != '' AND '$(DesignTimeBuild)' != 'true'"
+ <WriteLinesToFile Condition="'@(QtWorkLog)' != ''"
File="$(QtLogFilePath)"
Lines="@(QtWorkLog->'%(Identity)|%(Hash)')"
Overwrite="true" Encoding="Unicode"/>
@@ -425,8 +451,7 @@
// -->
<Error
Condition="'%(QtWorkResult.ExitCode)' != ''
- AND '%(QtWorkResult.ExitCode)' != '0'
- AND '$(DesignTimeBuild)' != 'true'"
+ AND '%(QtWorkResult.ExitCode)' != '0'"
File="%(QtWorkResult.Identity)" Code="%(QtWorkResult.ExitCode)"
Text="%(QtWorkResult.WorkType) (%(QtWorkResult.ToolPath))"/>
@@ -513,6 +538,7 @@
// Clean-up
// -->
<ItemGroup>
+ <ClCompile Remove="DefaultClCompile" />
<QtWork Remove="@(QtWork)"/>
<QtWorkResult Remove="@(QtWorkResult)"/>
<QtWorkLog Remove="@(QtWorkLog)"/>
@@ -524,51 +550,158 @@
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
- /// TARGET Qt
+ /// TARGET QtSetAdditionalOptions
/////////////////////////////////////////////////////////////////////////////////////////////////
- // Root Qt target
+ // Adds additional compiler options flowing from Qt.
+ // Skips options that are already specified in the user project.
// -->
- <Target Name="Qt" DependsOnTargets="QtPrepare;QtWork" BeforeTargets="FixupCLCompileOptions">
+ <Target Name="QtSetAdditionalOptions" Condition="'@(ClCompile)' != ''">
+
+ <!-- Command line parser regex -->
+ <PropertyGroup>
+ <CmdLineParser>"[^"]*"|[^\s]+</CmdLineParser>
+ </PropertyGroup>
+
+ <!-- Parse compiler options from Qt -->
+ <PropertyGroup>
+ <QtCmdLine
+ >$([System.Text.RegularExpressions.Regex]::Matches(
+ '$(Qt_CL_OPTIONS_)', '$(CmdLineParser)'))</QtCmdLine>
+ </PropertyGroup>
+
+ <!-- Calculate command line for each source file in the project -->
+ <QtRunTask
+ Items="@(ClCompile)"
+ AssemblyPath="$(VCTargetsPath)\Microsoft.Build.CPPTasks.Common.dll"
+ TaskName="Microsoft.Build.CPPTasks.CLCommandLine"
+ TaskInput="Sources"
+ TaskOutput="CommandLines"
+ NewMetadata="ProjectOptions">
+ <Output TaskParameter="Result" ItemName="ClCompile_CmdLine" />
+ </QtRunTask>
+
+ <!-- Append excluded Qt options to calculated command line -->
<ItemGroup>
- <ClCompile Remove="DefaultClCompile" />
+ <ClCompile_CmdLine Condition="'$(QtExcludedOptions)' != ''">
+ <ProjectOptions>%(ProjectOptions) $(QtExcludedOptions)</ProjectOptions>
+ </ClCompile_CmdLine>
</ItemGroup>
- <CriticalSection Lock="false" Name="$(ProjectGuid)" />
- <OnError ExecuteTargets="QtLeaveCriticalSection_OnError"/>
+
+ <!-- Parse compiler command line of each source file -->
+ <ItemGroup>
+ <ClCompile_CmdLine>
+ <ProjectOptions
+ >$([System.Text.RegularExpressions.Regex]::Matches(
+ '%(ProjectOptions)', '$(CmdLineParser)'))</ProjectOptions>
+ </ClCompile_CmdLine>
+ </ItemGroup>
+
+ <!-- Add (previously parsed) Qt options to each source file -->
+ <ItemGroup>
+ <ClCompile_CmdLine>
+ <QtOptions>$(QtCmdLine)</QtOptions>
+ </ClCompile_CmdLine>
+ </ItemGroup>
+
+ <!-- Result of parsing command lines, per source file:
+ * ClCompile_CmdLine ::= (Item x ProjectOptions x QtOptions), where:
+ * Item ::= source file
+ * ProjectOptions ::= list of tokens from the compiler command line for Item
+ * QtOptions ::= list of tokens from the Qt additional options -->
+
+ <!-- Flatten results into a list of tokens per source file:
+ * ClOptions ::= (Item x Name x Value), where:
+ * Item ::= source file
+ * Name ::= token origin: from compiler command line or from Qt
+ * Value ::= token value -->
+ <Flatten Items="@(ClCompile_CmdLine)" Metadata="ProjectOptions;QtOptions">
+ <Output TaskParameter="Result" ItemName="ClOptions" />
+ </Flatten>
+
+ <!-- Remove non-switch tokens, i.e. tokens that do not start with '/' or '-' -->
+ <ItemGroup>
+ <ClOptions
+ Remove="@(ClOptions)"
+ Condition="!$([System.String]::Copy('%(Value)').StartsWith('-'))
+ AND !$([System.String]::Copy('%(Value)').StartsWith('/'))"/>
+ </ItemGroup>
+
+ <!-- Calculate option id: token without leading '/' or '-', and without trailing '-' -->
+ <ItemGroup>
+ <ClOptions>
+ <OptionId>$([System.String]::Copy('%(Value)').Substring(1).TrimEnd('-'))</OptionId>
+ </ClOptions>
+ </ItemGroup>
+
+ <!-- Split into list of Qt options and list of project options -->
+ <ItemGroup>
+ <QtOptions
+ Include="@(ClOptions->'%(Item)')"
+ Condition="'%(ClOptions.Name)' == 'QtOptions'"/>
+ <ProjectOptions
+ Include="@(ClOptions->'%(Item)')"
+ Condition="'%(ClOptions.Name)' == 'ProjectOptions'"/>
+ </ItemGroup>
+
+ <!-- Find conflicting options, i.e. defined both in Qt options and project options -->
+ <ItemGroup>
+ <QtOptions
+ Condition="'@(QtOptions)' != ''
+ AND '@(ProjectOptions)' != ''
+ AND '%(Item)' != ''
+ AND '%(OptionId)' != ''">
+ <Conflict>true</Conflict>
+ </QtOptions>
+ </ItemGroup>
+
+ <!-- Set additional compiler options for all source files -->
+ <ItemGroup>
+ <ClCompile Condition="'%(Identity)' != '' AND '%(QtOptions.Conflict)' != 'true'">
+ <AdditionalOptions
+ >@(QtOptions->'%(Value)', ' ') @(ClCompile->'%(AdditionalOptions)')</AdditionalOptions>
+ </ClCompile>
+ <ClCompile Condition="'%(AdditionalOptions)' != ''">
+ <AdditionalOptions
+ >$([System.String]::Copy('%(AdditionalOptions)').Trim())</AdditionalOptions>
+ </ClCompile>
+ </ItemGroup>
+
+ <!-- Print result to build log, if requested -->
+ <Message
+ Condition="'$(QtOptionsBuildLog)' == 'true'"
+ Importance="High"
+ Text=" Qt - Additional Compiler Options"/>
+ <Message
+ Condition="'$(QtOptionsBuildLog)' == 'true'
+ AND '%(Identity)' != '' AND '%(QtOptions.Conflict)' != 'true'"
+ Importance="High"
+ Text=" [%(Identity)]: @(QtOptions->'%(Value)', ' ')"/>
+
+ <!-- Clean-up -->
+ <PropertyGroup>
+ <CmdLineParser/>
+ <QtCmdLine/>
+ </PropertyGroup>
+ <ItemGroup>
+ <ClCompile_CmdLine Remove="@(ClCompile_CmdLine)"/>
+ <ClOptions Remove="@(ClOptions)"/>
+ <ProjectOptions Remove="@(ProjectOptions)"/>
+ <QtOptions Remove="@(QtOptions)"/>
+ </ItemGroup>
</Target>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
- /// TARGET QtOuterBuild
+ /// TARGET Qt
/////////////////////////////////////////////////////////////////////////////////////////////////
- // Run targets in $(QtOuterBuildDependsOn) and then recursively invoke build
+ // Root Qt target
// -->
- <Target Name="QtOuterBuild" DependsOnTargets="$(QtOuterBuildDependsOn)">
- <!--// Invoke inner build: recursive build in second MSBuild instance -->
- <MSBuild
- Projects="$(MSBuildProjectFullPath)"
- Targets="Build"
- Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
- </MSBuild>
+ <Target
+ Name="Qt"
+ DependsOnTargets="QtPrepare;QtWork;QtSetAdditionalOptions">
+ <CriticalSection Lock="false" Name="$(ProjectGuid)" />
<OnError ExecuteTargets="QtLeaveCriticalSection_OnError"/>
</Target>
-
- <PropertyGroup
- Condition="'$(QtInnerBuild)' == '' AND '$(DesignTimeBuild)' != 'true'">
- <!--// Outer build: invoke inner build -->
- <BuildDependsOn>
- $(QtOuterBuildPrepare);
- QtOuterBuild;
- $(QtOuterBuildFinalize)
- </BuildDependsOn>
- <QtInnerBuild>$(MSBuildProjectFullPath)</QtInnerBuild>
- <RandomFileName>$([System.IO.Path]::GetRandomFileName())</RandomFileName>
- </PropertyGroup>
-
- <PropertyGroup
- Condition="'$(QtInnerBuild)' != '$(MSBuildProjectFullPath)' AND '$(DesignTimeBuild)' != 'true'">
- <!--// Dependent project inner build: skip build -->
- <BuildDependsOn>$(QtOuterBuildPrepare);$(QtOuterBuildFinalize)</BuildDependsOn>
- </PropertyGroup>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
@@ -633,4 +766,28 @@
<Target Name="QtLeaveCriticalSection_OnError">
<CriticalSection Lock="false" Name="$(ProjectGuid)" />
</Target>
+
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ /// TARGET QtNatvis
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Copies the .natvis file matching the Qt version and replaces the namespace placeholder
+ // -->
+ <Target Name="QtNatvis" BeforeTargets="Link"
+ Condition="'$(Configuration)' == 'Debug' AND '$(LinkNatvisFile)' == 'true'"
+ Inputs="$(MSBuildProjectFile);$(QtMsBuild)\qt$(QtVersionMajor).natvis.xml"
+ Outputs="$(IntDir)\qt.natvis">
+ <PropertyGroup>
+ <InputFile>$(QtMsBuild)\qt$(QtVersionMajor).natvis.xml</InputFile>
+ </PropertyGroup>
+ <WriteLinesToFile Condition="'$(QtNamespace)' == ''"
+ Overwrite="true"
+ File="$(IntDir)\qt.natvis"
+ Lines="$([System.IO.File]::ReadAllText($(InputFile)).Replace('##NAMESPACE##::',''))" />
+ <WriteLinesToFile Condition="'$(QtNamespace)' != ''"
+ Overwrite="true"
+ File="$(IntDir)\qt.natvis"
+ Lines="$([System.IO.File]::ReadAllText($(InputFile)).Replace('##NAMESPACE##','$(QtNamespace)'))" />
+ </Target>
+
</Project>
diff --git a/QtMSBuild/QtMsBuild/qt_inner.targets b/QtMSBuild/QtMsBuild/qt_inner.targets
new file mode 100644
index 0000000..06f88c7
--- /dev/null
+++ b/QtMSBuild/QtMsBuild/qt_inner.targets
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+-->
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <PropertyGroup
+ Condition="'$(QtInnerBuild)' == ''">
+ <!--// Outer build: invoke inner build -->
+ <BuildDependsOn>
+ $(QtOuterBuildPrepare);
+ QtOuterBuild;
+ $(QtOuterBuildFinalize)
+ </BuildDependsOn>
+ <QtInnerBuild>$(MSBuildProjectFullPath)</QtInnerBuild>
+ <RandomFileName>$([System.IO.Path]::GetRandomFileName())</RandomFileName>
+ </PropertyGroup>
+
+ <PropertyGroup
+ Condition="'$(QtInnerBuild)' != '$(MSBuildProjectFullPath)'">
+ <!--// Dependent project inner build: skip build -->
+ <BuildDependsOn>$(QtOuterBuildPrepare);$(QtOuterBuildFinalize)</BuildDependsOn>
+ </PropertyGroup>
+
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ /// TARGET QtOuterBuild
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Run targets in $(QtOuterBuildDependsOn) and then recursively invoke build
+ // -->
+ <Target Name="QtOuterBuild" DependsOnTargets="$(QtOuterBuildDependsOn)">
+ <!--// Invoke inner build: recursive build in second MSBuild instance -->
+ <MSBuild
+ Projects="$(MSBuildProjectFullPath)"
+ Targets="Build"
+ Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
+ </MSBuild>
+ <OnError ExecuteTargets="QtLeaveCriticalSection_OnError"/>
+ </Target>
+
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ /// TARGET GetClCommandLineForReference
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // -->
+ <Target
+ Name="GetClCommandLineForReference"
+ DependsOnTargets="$(QtOuterBuildDependsOn)"
+ Returns="@(ClCommandLineForReference)">
+ <MSBuild
+ Projects="$(MSBuildProjectFullPath)"
+ Targets="GetClCommandLineForReference"
+ Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
+ <Output TaskParameter="TargetOutputs" ItemName="ClCommandLineForReference"/>
+ </MSBuild>
+ </Target>
+
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ /// TARGET GetGeneratedFiles
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // -->
+ <Target
+ Name="GetGeneratedFiles"
+ DependsOnTargets="$(QtOuterBuildDependsOn)"
+ Returns="@(_GeneratedFiles)">
+ <MSBuild
+ Projects="$(MSBuildProjectFullPath)"
+ Targets="GetGeneratedFiles"
+ Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
+ <Output TaskParameter="TargetOutputs" ItemName="_GeneratedFiles"/>
+ </MSBuild>
+ </Target>
+
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ /// TARGET GetProjectReferencesInfo
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // -->
+ <Target
+ Name="GetProjectReferencesInfo"
+ DependsOnTargets="$(QtOuterBuildDependsOn)"
+ Returns="@(_ProjectReferencesInfo)">
+ <MSBuild
+ Projects="$(MSBuildProjectFullPath)"
+ Targets="GetProjectReferencesInfo"
+ Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
+ <Output TaskParameter="TargetOutputs" ItemName="_ProjectReferencesInfo"/>
+ </MSBuild>
+ </Target>
+
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ /// TARGET GetClCommandLines
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // -->
+ <Target
+ Name="GetClCommandLines"
+ DependsOnTargets="$(QtOuterBuildDependsOn)"
+ Returns="@(ClCommandLines)">
+ <MSBuild
+ Projects="$(MSBuildProjectFullPath)"
+ Targets="GetClCommandLines"
+ Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
+ <Output TaskParameter="TargetOutputs" ItemName="ClCommandLines"/>
+ </MSBuild>
+ </Target>
+</Project>
diff --git a/QtMSBuild/QtMsBuild/qt_private.props b/QtMSBuild/QtMsBuild/qt_private.props
index c1303e0..eb76f1f 100644
--- a/QtMSBuild/QtMsBuild/qt_private.props
+++ b/QtMSBuild/QtMsBuild/qt_private.props
@@ -57,6 +57,18 @@
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
+ // Check if design-time build
+ // -->
+ <PropertyGroup>
+ <QtDesignTimeBuild>false</QtDesignTimeBuild>
+ <QtDesignTimeBuild
+ Condition="'$(DesignTimeBuild)' == 'true'
+ OR '$(QtVSToolsBuild)' == 'true'"
+ >true</QtDesignTimeBuild>
+ </PropertyGroup>
+
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
// Setup Qt installation path
// -->
<PropertyGroup Condition="'$(QtVsProjectSettings)' == 'true'">
@@ -112,21 +124,29 @@
>$([System.String]::Copy($([System.IO.File]::ReadAllText('$(QtVarsIndexPathDesignTime)'))).Replace('
',''))</QtVarsDesignTime>
</PropertyGroup>
- <!--// Import Qt variables (full build) -->
- <Import
- Condition="'$(DesignTimeBuild)' != 'true' AND Exists('$(QtVarsFilePath)')"
- Project="$(QtVarsFilePath)"/>
+ <PropertyGroup>
+ <!--// Path to Qt variables .props: full build -->
+ <QtVarsImportPath
+ Condition="'$(QtDesignTimeBuild)' != 'true'
+ AND Exists('$(QtVarsFilePath)')"
+ >$(QtVarsFilePath)</QtVarsImportPath>
- <!--// Import Qt variables (design-time build) -->
- <Import
- Condition="'$(DesignTimeBuild)' == 'true' AND Exists('$(QtVarsDesignTime)')"
- Project="$(QtVarsDesignTime)"/>
+ <!--// Path to Qt variables .props: design-time build -->
+ <QtVarsImportPath
+ Condition="'$(QtDesignTimeBuild)' == 'true'
+ AND Exists('$(QtVarsDesignTime)')"
+ >$(QtVarsDesignTime)</QtVarsImportPath>
- <!--// Import Qt variables (fall-back) -->
- <Import
- Condition=
-"'$(DesignTimeBuild)' == 'true' AND !Exists('$(QtVarsDesignTime)') AND Exists('$(QtVarsFilePath)')"
- Project="$(QtVarsFilePath)"/>
+ <!--// Path to Qt variables .props: fall-back -->
+ <QtVarsImportPath
+ Condition="'$(QtDesignTimeBuild)' == 'true'
+ AND !Exists('$(QtVarsDesignTime)')
+ AND Exists('$(QtVarsFilePath)')"
+ >$(QtVarsFilePath)</QtVarsImportPath>
+ </PropertyGroup>
+
+ <!--// Import Qt vars property file -->
+ <Import Condition="Exists('$(QtVarsImportPath)')" Project="$(QtVarsImportPath)"/>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
@@ -175,6 +195,61 @@
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
+ // Normalize QtVars (incl. backup)
+ // -->
+ <PropertyGroup>
+ <QtVars
+ Condition="'$(QtVars)' !=''"
+ >$(QtVars
+ .Replace(' ', '')
+ .Replace('%0a', '')
+ .Replace('%0d', '')
+ .Trim(';'))</QtVars>
+ <QtBkup_QtVars
+ Condition="'$(QtBkup_QtVars)' !=''"
+ >$(QtBkup_QtVars
+ .Replace(' ', '')
+ .Replace('%0a', '')
+ .Replace('%0d', '')
+ .Trim(';'))</QtBkup_QtVars>
+ </PropertyGroup>
+
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Figure out depending on the user settings if we need to link the .natvis file into the PDB
+ // file. Reads the content of qconfig.pri to find Qt's namespace if set. Predefines the path to
+ // the .natvis file used during link which corresponds to the final output generated by the
+ // QtNatvis target.
+ // Evaluation order: first look at the project settings, if empty take from the global settings.
+ // -->
+ <PropertyGroup>
+ <LinkNatvisFile>$(QtLinkNatvisFile)</LinkNatvisFile>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(QtLinkNatvisFile)' == ''">
+ <LinkNatvisRegValue>$([MSBuild]::GetRegistryValue(
+ 'HKEY_CURRENT_USER\SOFTWARE\Digia\Qt5VS2017','LinkNatvis'
+ ))</LinkNatvisRegValue>
+ <LinkNatvisFile>true</LinkNatvisFile>
+ <LinkNatvisFile Condition="'$(LinkNatvisRegValue)' == '0'">false</LinkNatvisFile>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)' == 'Debug'
+ AND '$(LinkNatvisFile)' == 'true' AND '$(QtInstallDir)' != ''">
+ <QConfigPriPath>$([System.IO.Path]::Combine('$(QtInstallDir)',
+ 'mkspecs', 'qconfig.pri'
+ ))</QConfigPriPath>
+ <QConfigPriContent>$([MSBuild]::Unescape(
+ $([System.IO.File]::ReadAllText('$(QConfigPriPath)')
+ .Replace('
', ';')
+ .Replace(' =', '=')
+ .Replace('= ', '='))
+ ))</QConfigPriContent>
+ <QtNamespace>$([System.Text.RegularExpressions.Regex]::Match($(QConfigPriContent),
+ 'QT_NAMESPACE=([a-zA-Z0-9]+)').get_Groups().get_Item(1)
+ )</QtNamespace>
+ </PropertyGroup>
+
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
// Default item metadata
// -->
<ItemDefinitionGroup>
@@ -186,24 +261,27 @@
<PreprocessorDefinitions Condition="'$(QtQMLDebugEnable)' == 'true'"
>QT_QML_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Qt_INCLUDEPATH_)' != ''"
- >$(Qt_INCLUDEPATH_);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ >%(AdditionalIncludeDirectories);$(Qt_INCLUDEPATH_)</AdditionalIncludeDirectories>
<LanguageStandard Condition="'$(Qt_STDCPP_)' != ''"
>$(Qt_STDCPP_)</LanguageStandard>
- <AdditionalOptions Condition="'$(Qt_CL_OPTIONS_)' != ''"
- >$(Qt_CL_OPTIONS_) %(AdditionalOptions)</AdditionalOptions>
+ <RuntimeLibrary Condition="'$(Qt_RUNTIME_)' != ''"
+ >$(Qt_RUNTIME_)</RuntimeLibrary>
</ClCompile>
<!--// Linker (.obj files) -->
<Link>
<AdditionalDependencies Condition="'$(Qt_LIBS_)' != ''"
- >$(Qt_LIBS_);%(AdditionalDependencies)</AdditionalDependencies>
+ >%(AdditionalDependencies);$(Qt_LIBS_)</AdditionalDependencies>
<AdditionalLibraryDirectories Condition="'$(Qt_LIBPATH_)' != ''"
- >$(Qt_LIBPATH_);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ >%(AdditionalLibraryDirectories);$(Qt_LIBPATH_)</AdditionalLibraryDirectories>
<SharedLibrarySearchPath Condition="'$(Qt_LIBPATH_)' != ''"
- >$(Qt_LIBPATH_);%(SharedLibrarySearchPath)</SharedLibrarySearchPath>
+ >%(SharedLibrarySearchPath);$(Qt_LIBPATH_)</SharedLibrarySearchPath>
<AdditionalOptions Condition="'$(Qt_LINK_OPTIONS_)' != ''"
>$(Qt_LINK_OPTIONS_) %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)' == 'Debug' AND '$(LinkNatvisFile)' == 'true'"
+ >/NATVIS:"$(IntDir)\qt.natvis" %(AdditionalOptions)</AdditionalOptions>
</Link>
+
</ItemDefinitionGroup>
<!--
diff --git a/QtMSBuild/QtMsBuild/qt_settings.xml b/QtMSBuild/QtMsBuild/qt_settings.xml
index d078dc6..37ed382 100644
--- a/QtMSBuild/QtMsBuild/qt_settings.xml
+++ b/QtMSBuild/QtMsBuild/qt_settings.xml
@@ -43,6 +43,8 @@
<Category Name="QtSettings_02_Paths" DisplayName="Paths"/>
<Category Name="QtSettings_03_QMake" DisplayName="qmake"/>
<Category Name="QtSettings_04_QML" DisplayName="QML"/>
+ <Category Name="QtSettings_05_AdditionalOptions" DisplayName="Qt Additional Compiler Options"/>
+ <Category Name="QtSettings_06_AdditionalLinkOptions" DisplayName="Qt Additional Linker Options"/>
</Rule.Categories>
<EnumProperty
Name="Keyword"
@@ -85,6 +87,12 @@
<ValueEditor EditorType="QtModulesEditor" DisplayName="<Select Modules...>" />
</StringListProperty.ValueEditors>
</StringListProperty>
+ <BoolProperty
+ Name="QtPlugin"
+ Category="QtSettings_01_General"
+ DisplayName="Qt Plugin"
+ Description="Select whether this project is used to generate a Qt plugin.">
+ </BoolProperty>
<EnumProperty
Name="QtBuildConfig"
Category="QtSettings_01_General"
@@ -98,6 +106,14 @@
Category="QtSettings_01_General"
DisplayName="Run Deployment Tool"
Description="Select whether Qt for Windows Deployment Tool (windeployqt) should be called after build."/>
+ <EnumProperty
+ Name="QtToolsDesignTime"
+ Category="QtSettings_01_General"
+ DisplayName="Design Time Build"
+ Description="Run Qt tools during IntelliSense builds.">
+ <EnumValue Name="true" DisplayName="Run Qt Tools"/>
+ <EnumValue Name="false" DisplayName="Skip Qt Tools"/>
+ </EnumProperty>
<StringProperty
Name="QtPathBinaries"
Category="QtSettings_02_Paths"
@@ -145,4 +161,38 @@
DisplayName="Enable QML Debugging"
Description="Select whether to launch a QML session when debugging.">
</BoolProperty>
-</Rule>
+ <StringProperty
+ Name="Qt_CL_OPTIONS_"
+ ReadOnly="true"
+ Category="QtSettings_05_AdditionalOptions"
+ DisplayName="Additional Options"
+ Description="
+Additional compiler options required by Qt. These options will be passed
+to the compiler, unless specifically excluded in the next field." />
+ <StringProperty
+ Name="QtExcludedOptions"
+ Category="QtSettings_05_AdditionalOptions"
+ DisplayName="Excluded Options"
+ Description="
+Options to exclude from the above compiler options required by Qt.
+These options will NOT be passed to the compiler. Prefix options
+with '/' or '-', and separate them with spaces." />
+ <BoolProperty
+ Name="QtOptionsBuildLog"
+ Category="QtSettings_05_AdditionalOptions"
+ DisplayName="Show in Build Log"
+ Description="
+Print to the build log the list of additional options passed to the compiler." />
+ <EnumProperty
+ Name="QtLinkNatvisFile"
+ Category="QtSettings_06_AdditionalLinkOptions"
+ DisplayName="Embed .natvis file into PDB"
+ Description=
+"Embeds the debugger visualizations (.natvis file) into the PDB file
+generated by LINK. While setting this option, the embedded Natvis file
+will take precedence over user-specific Natvis files (for example the
+files located in %USERPROFILE%\\Documents\\Visual Studio 2022\\Visualizers).">
+ <EnumValue Name="false" DisplayName="No" />
+ <EnumValue Name="true" DisplayName="Yes" />
+ </EnumProperty>
+ </Rule>
diff --git a/QtMSBuild/QtMsBuild/qt_vars.targets b/QtMSBuild/QtMsBuild/qt_vars.targets
index 80c141c..2ad7445 100644
--- a/QtMSBuild/QtMsBuild/qt_vars.targets
+++ b/QtMSBuild/QtMsBuild/qt_vars.targets
@@ -199,7 +199,8 @@
<ItemGroup>
<QMakeArgsList Condition="'$(QMakeOptionEarly)' == 'true'" Include="-early"/>
<QMakeArgsList Include="CONFIG -= debug release debug_and_release"/>
- <QMakeArgsList Include="CONFIG += $(QtBuildConfig)"/>
+ <QMakeArgsList Include="CONFIG += $(QtBuildConfig) warn_off"/>
+ <QMakeArgsList Condition="'$(QtPlugin)' == 'true'" Include="CONFIG += plugin"/>
<QMakeArgsList Include="$(QMakeExtraArgs)"/>
</ItemGroup>
<ItemGroup>
@@ -281,7 +282,32 @@
$(QtVarsProFileInput)
DEFINES -= UNICODE _UNICODE
</QtVarsProFileInput>
+ <!--
+# Add dummy QML object if needed -->
+ <QtVarsProFileInput Condition="$(QtModules.Contains('quick'))">
+ $(QtVarsProFileInput)
+ RESOURCES += qml.qrc
+ </QtVarsProFileInput>
</PropertyGroup>
+
+ <!--// Write dummy QML and QRC files -->
+ <WriteLinesToFile
+ Condition="$(QtModules.Contains('quick'))"
+ File="$(QtVarsWorkDir)\main.qml"
+ Lines="
+import QtQuick
+DummyQmlObject { }
+"/>
+ <WriteLinesToFile
+ Condition="$(QtModules.Contains('quick'))"
+ File="$(QtVarsWorkDir)\qml.qrc"
+ Lines="
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ </qresource>
+</RCC>
+"/>
<!--// Write .pro file to temp path -->
<WriteLinesToFile
@@ -313,6 +339,7 @@
<Cmd><![CDATA["$(QtToolsPath)/qmake" $(QMakeArgs) qtvars.pro]]></Cmd>
</PropertyGroup>
<HostExec
+ Condition="'$(ApplicationType)' == 'Linux'"
Command="$(Cmd)" RedirectStdOut="qtvars.log" RedirectStdErr="STDOUT"
WorkingDirectory="@(WorkDir->'%(HostPath)')"
Inputs="@(QMakeProj)"
@@ -322,6 +349,45 @@
IgnoreExitCode="true">
<Output TaskParameter="ExitCode" PropertyName="ErrorLevel"/>
</HostExec>
+
+ <!--// Run qmake in Windows: set %CD% to subfolder of %TEMP% -->
+ <PropertyGroup
+ Condition="'$(ApplicationType)' != 'Linux'">
+ <QMakeTempDir>$(Temp)\$([System.IO.Path]::GetRandomFileName())</QMakeTempDir>
+ </PropertyGroup>
+ <MakeDir
+ Condition="'$(ApplicationType)' != 'Linux'"
+ Directories="$(QMakeTempDir)" />
+ <Copy
+ Condition="'$(ApplicationType)' != 'Linux'"
+ SourceFiles="$(QtVarsWorkDir)\qtvars.pro"
+ DestinationFolder="$(QMakeTempDir)" />
+ <Copy
+ Condition="'$(ApplicationType)' != 'Linux' AND Exists('$(QtVarsWorkDir)\main.qml')"
+ SourceFiles="$(QtVarsWorkDir)\main.qml"
+ DestinationFolder="$(QMakeTempDir)" />
+ <Copy
+ Condition="'$(ApplicationType)' != 'Linux' AND Exists('$(QtVarsWorkDir)\qml.qrc')"
+ SourceFiles="$(QtVarsWorkDir)\qml.qrc"
+ DestinationFolder="$(QMakeTempDir)" />
+ <HostExec
+ Condition="'$(ApplicationType)' != 'Linux'"
+ Command="$(Cmd)" RedirectStdOut="qtvars.log" RedirectStdErr="STDOUT"
+ WorkingDirectory="$(QMakeTempDir)"
+ IgnoreExitCode="true">
+ <Output TaskParameter="ExitCode" PropertyName="ErrorLevel"/>
+ </HostExec>
+ <ItemGroup>
+ <QMakeGeneratedFiles Include="$(QMakeTempDir)\*" />
+ </ItemGroup>
+ <Copy
+ Condition="'$(ApplicationType)' != 'Linux'"
+ SkipUnchangedFiles="true"
+ SourceFiles="@(QMakeGeneratedFiles)"
+ DestinationFolder="$(QtVarsWorkDir)" />
+ <RemoveDir
+ Condition="'$(ApplicationType)' != 'Linux'"
+ Directories="$(QMakeTempDir)" />
<!--// Check qmake result -->
<PropertyGroup
@@ -501,15 +567,15 @@
<!--// In design-time, copy generated .props to randomly named file -->
<PropertyGroup>
<QtVarsDesignTimeNew
- Condition="'$(ErrorLevel)' == '0' AND '$(QtVSToolsBuild)' == 'true'"
+ Condition="'$(ErrorLevel)' == '0' AND '$(QtDesignTimeBuild)' == 'true'"
>$([System.IO.Path]::Combine('$(TEMP)','$([System.IO.Path]::GetRandomFileName()).designtime.props'))
</QtVarsDesignTimeNew>
</PropertyGroup>
<Copy
- Condition="'$(ErrorLevel)' == '0' AND '$(QtVSToolsBuild)' == 'true'"
+ Condition="'$(ErrorLevel)' == '0' AND '$(QtDesignTimeBuild)' == 'true'"
SourceFiles="$(QtVarsFilePath)" DestinationFiles="$(QtVarsDesignTimeNew)"/>
<WriteLinesToFile
- Condition="'$(ErrorLevel)' == '0' AND '$(QtVSToolsBuild)' == 'true'"
+ Condition="'$(ErrorLevel)' == '0' AND '$(QtDesignTimeBuild)' == 'true'"
File="$(QtVarsIndexPathDesignTime)" Overwrite="true" Lines="$(QtVarsDesignTimeNew)"/>
<!--// Clean-up -->
diff --git a/QtMSBuild/QtMsBuild/translation/qttranslation.targets b/QtMSBuild/QtMsBuild/translation/qttranslation.targets
index 6b599f9..4f15175 100644
--- a/QtMSBuild/QtMsBuild/translation/qttranslation.targets
+++ b/QtMSBuild/QtMsBuild/translation/qttranslation.targets
@@ -90,10 +90,14 @@
<QtTranslation>
<InputFiles
>$(QtTranslationInput)</InputFiles>
- <LUpdate
+ <LUpdate Condition="'$(ApplicationType)' == 'Linux'"
>$(QtToolsPath)/lupdate</LUpdate>
- <LRelease
+ <LRelease Condition="'$(ApplicationType)' == 'Linux'"
>$(QtToolsPath)/lrelease</LRelease>
+ <LUpdate Condition="'$(ApplicationType)' != 'Linux'"
+ >$(QtToolsPath)/lupdate.exe</LUpdate>
+ <LRelease Condition="'$(ApplicationType)' != 'Linux'"
+ >$(QtToolsPath)/lrelease.exe</LRelease>
<TsFile
>%(Identity)</TsFile>
<QmFile
@@ -395,6 +399,7 @@
<Cmd>$(Cmd.Trim())</Cmd>
</PropertyGroup>
<HostExec
+ Condition="Exists(@(Options->'%(CmdExec)', ''))"
Message="%(QtTranslationUpdate.UpdateDescription)"
Command="$(Cmd)"
Inputs="@(Options->'%(InputListFile)');@(Options->'%(InputFiles)')"
@@ -402,6 +407,9 @@
RemoteTarget="$(ResolvedRemoteTarget)"
RemoteProjectDir="$(_ResolvedRemoteProjectDir)">
</HostExec>
+ <Warning
+ Condition="!Exists(@(Options->'%(CmdExec)', ''))"
+ File="%(QtTranslationUpdate.Identity)" Text="'lupdate' not found; skipping" />
<!--
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -556,6 +564,7 @@
<Cmd>$(Cmd.Trim())</Cmd>
</PropertyGroup>
<HostExec
+ Condition="Exists(@(Options->'%(CmdExec)', ''))"
Message="%(QtTranslationRelease.ReleaseDescription)"
Command="$(Cmd)"
Inputs="@(Options->'%(InputFile)')"
@@ -563,6 +572,9 @@
RemoteTarget="$(ResolvedRemoteTarget)"
RemoteProjectDir="$(_ResolvedRemoteProjectDir)">
</HostExec>
+ <Warning
+ Condition="!Exists(@(Options->'%(CmdExec)', ''))"
+ File="%(QtTranslationRelease.Identity)" Text="'lrelease' not found; skipping" />
<!--
///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/QtMSBuild/Tasks/CriticalSection.cs b/QtMSBuild/Tasks/CriticalSection.cs
index e2a44d6..53423f3 100644
--- a/QtMSBuild/Tasks/CriticalSection.cs
+++ b/QtMSBuild/Tasks/CriticalSection.cs
@@ -84,8 +84,6 @@
if (Lock) {
// Wait until locked
if (!buildLock.WaitOne(1000)) {
- // Issue waiting warning
- Log.LogWarning("Qt::BuildLock[{0}]: Waiting...", Name);
var t = Stopwatch.StartNew();
do {
// Check for build errors
diff --git a/QtMSBuild/Tasks/QtRunTask.cs b/QtMSBuild/Tasks/QtRunTask.cs
new file mode 100644
index 0000000..447543e
--- /dev/null
+++ b/QtMSBuild/Tasks/QtRunTask.cs
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#region Task TaskName="QtRunTask"
+
+#region Reference
+//System.Runtime
+#endregion
+
+#region Using
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+#endregion
+
+#region Comment
+/////////////////////////////////////////////////////////////////////////////////////////////////
+/// TASK QtRunTask
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// Execute a task from the specified assembly, taking as input a list of items. Each item
+// metadata is copied to a task property with the same name. After the task is executed, the
+// result for each item is then stored in a new metadata for that item. The final output is the
+// list of modified items.
+// Parameters /////////////////////////////////////////////////////////////////////////////////
+// in ITaskItem[] Items........................List of source items.
+// in String AssemblyPath.................Path to assembly containing the task.
+// in String TaskName.....................Full name of task, including namespace.
+// in String TaskInput....................Name of task input property.
+// in String TaskOutput (optional)........Name of task output property.
+// If unspecified, task output is ignored.
+// in String NewMetadata (optional).......Name of new item metadata to store result.
+// If unspecified, defaults to TaskOutput.
+// out ITaskItem[] Result.......................Output list of modified items.
+// If TaskOutput is unspecified, Result will be empty.
+// Example //////////////////////////////////////////////////////////////////////////////////////
+// Items = {
+// ClCompile {
+// Identity = "main.cpp",
+// ...
+// EnforceTypeConversionRules = False,
+// ...
+// }
+// }
+// AssemblyPath = "$(VCTargetsPath)\Microsoft.Build.CPPTasks.Common.dll"
+// TaskName = "Microsoft.Build.CPPTasks.CLCommandLine"
+// TaskInput = "Sources"
+// TaskOutput = "CommandLines"
+// NewMetadata = "CommandLine"
+// Result = {
+// ClCompile_Modified {
+// Identity = "main.cpp",
+// ...
+// EnforceTypeConversionRules = False,
+// ...
+// CommandLine = "... /Zc:rvalueCast- ..."
+// }
+// }
+#endregion
+
+namespace QtVsTools.QtMsBuild.Tasks
+{
+ public static class QtRunTask
+ {
+ public static QtMSBuild.ITaskLoggingHelper Log { get; set; }
+ public static IBuildEngine BuildEngine { get; set; }
+ public static ITaskHost HostObject { get; set; }
+
+ public static bool Execute(
+ #region Parameters
+ Microsoft.Build.Framework.ITaskItem[] Items,
+ System.String AssemblyPath,
+ System.String TaskName,
+ System.String TaskInput,
+ out Microsoft.Build.Framework.ITaskItem[] Result,
+ System.String TaskOutput = null,
+ System.String NewMetadata = null)
+ #endregion
+ {
+ #region Code
+ var reserved = new HashSet<string>
+ {
+ "AccessedTime", "CreatedTime", "DefiningProjectDirectory",
+ "DefiningProjectExtension", "DefiningProjectFullPath", "DefiningProjectName",
+ "Directory", "Extension", "Filename", "FullPath", "Identity", "ModifiedTime",
+ "RecursiveDir", "RelativeDir", "RootDir",
+ };
+
+ // Output default values
+ Result = null;
+
+ // Load specified assembly
+ var taskAssembly = Assembly.LoadFile(AssemblyPath);
+ if (taskAssembly == null)
+ throw new ArgumentException("AssemblyPath");
+
+ // Access task type
+ var taskType = taskAssembly.GetType(TaskName);
+ if (taskType == null)
+ throw new ArgumentException("TaskName");
+
+ // Task type has the following requirements:
+ // * Must be a descendant of the ToolTask type
+ // * Cannot be an abstract class
+ // * Cannot have generic type arguments
+ // * Must have a public default constructor
+ if (!typeof(ToolTask).IsAssignableFrom(taskType))
+ throw new NotSupportedException("Not a ToolTask derived type");
+ if (taskType.IsAbstract)
+ throw new NotSupportedException("Abstract class");
+ if (taskType.ContainsGenericParameters)
+ throw new NotSupportedException("Generic class");
+ var ctorInfo = ((TypeInfo)taskType).DeclaredConstructors
+ .Where(x => x.GetParameters().Length == 0)
+ .FirstOrDefault();
+ if (ctorInfo == null)
+ throw new NotSupportedException("No default constructor");
+
+ // Access input property of task type
+ var inputProperty = taskType.GetProperty(TaskInput);
+ if (inputProperty == null)
+ throw new ArgumentException("TaskInput");
+ if (inputProperty.PropertyType != typeof(ITaskItem)
+ && inputProperty.PropertyType != typeof(ITaskItem[])) {
+ throw new NotSupportedException("Input property type is not supported");
+ }
+
+ // If output was specified, access corresponding property of task type
+ PropertyInfo outputProperty = null;
+ if (TaskOutput != null) {
+ outputProperty = taskType.GetProperty(TaskOutput);
+ if (outputProperty == null)
+ throw new ArgumentException("TaskOutput");
+ if (outputProperty.PropertyType != typeof(string)
+ && outputProperty.PropertyType != typeof(string[])
+ && outputProperty.PropertyType != typeof(ITaskItem[])) {
+ throw new NotSupportedException("Output property type is not supported");
+ }
+ if (NewMetadata == null)
+ NewMetadata = TaskOutput;
+ }
+
+ var resultItems = new List<ITaskItem>();
+ foreach (var item in Items) {
+ // For each source item ...
+
+ // Instantiate task
+ var task = ctorInfo.Invoke(new object[0]) as ToolTask;
+ task.BuildEngine = BuildEngine;
+ task.HostObject = HostObject;
+
+ // Set task input property to the source item
+ var inputPropertyType = inputProperty.PropertyType;
+ if (inputPropertyType == typeof(ITaskItem)) {
+ inputProperty.SetValue(task, item);
+ } else if (inputPropertyType == typeof(ITaskItem[])) {
+ inputProperty.SetValue(task, new ITaskItem[] { item });
+ }
+
+ var names = item.MetadataNames.Cast<string>()
+ .Where(x => !reserved.Contains(x));
+ foreach (var name in names) {
+ // For each metadata in the source item ...
+
+ // Try to obtain a task property with the same name
+ var taskProperty = taskType.GetProperty(name);
+ if (taskProperty != null) {
+ // If the property exists, set it to the metadata value
+ string metadataValue = item.GetMetadata(name);
+ var propertyType = taskProperty.PropertyType;
+ if (propertyType == typeof(bool)) {
+ taskProperty.SetValue(task, metadataValue.Equals("true",
+ StringComparison.InvariantCultureIgnoreCase));
+ } else if (propertyType == typeof(string)) {
+ taskProperty.SetValue(task, metadataValue);
+ } else if (propertyType == typeof(string[])) {
+ taskProperty.SetValue(task, metadataValue.Split(';'));
+ }
+ }
+ }
+
+ // Run task
+ if (!task.Execute())
+ throw new Exception(string.Format("Task failed ({0})", item.ItemSpec));
+
+ // Record task output
+ if (TaskOutput != null) {
+ // Create output item as copy of source item
+ var resultItem = new TaskItem(item);
+
+ // Set new metadata and add output item to the result list
+ string outputValue;
+ object propertyValue = outputProperty.GetValue(task);
+ if (propertyValue == null)
+ outputValue = string.Empty;
+ else if (outputProperty.PropertyType == typeof(string))
+ outputValue = propertyValue as string;
+ else if (outputProperty.PropertyType == typeof(string[]))
+ outputValue = (propertyValue as string[]).FirstOrDefault();
+ else if (outputProperty.PropertyType == typeof(ITaskItem[]))
+ outputValue = (propertyValue as ITaskItem[]).FirstOrDefault().ItemSpec;
+ else
+ outputValue = string.Empty;
+ if (NewMetadata != null)
+ resultItem.SetMetadata(NewMetadata, outputValue);
+ resultItems.Add(resultItem);
+ }
+ }
+
+ // Return the list of output items
+ Result = resultItems.ToArray();
+
+ #endregion
+
+ return true;
+ }
+ }
+}
+#endregion
diff --git a/QtVsTest/Macro.cs b/QtVsTest/Macro.cs
index 1c1004d..e4477e8 100644
--- a/QtVsTest/Macro.cs
+++ b/QtVsTest/Macro.cs
@@ -82,7 +82,7 @@
/// <summary>
/// Name of reusable macro
/// </summary>
- public string Name { get; private set; }
+ private string Name { get; set; }
/// <summary>
/// True if macro compilation was successful
@@ -104,8 +104,9 @@
/// </summary>
public bool QuitWhenDone { get; private set; }
- AsyncPackage Package { get; set; }
- EnvDTE80.DTE2 Dte { get; set; }
+ AsyncPackage Package { get; }
+ EnvDTE80.DTE2 Dte { get; }
+ IntPtr MainWindowHWnd { get; }
AutomationElement UiRoot => AutomationElement.RootElement;
@@ -115,65 +116,55 @@
get
{
if (_UiVsRoot == null)
-#if VS2022
- _UiVsRoot = AutomationElement.FromHandle(Dte.MainWindow.HWnd);
-#else
- _UiVsRoot = AutomationElement.FromHandle(new IntPtr(Dte.MainWindow.HWnd));
-#endif
+ _UiVsRoot = AutomationElement.FromHandle(MainWindowHWnd);
return _UiVsRoot;
}
}
- JoinableTaskFactory JoinableTaskFactory { get; set; }
- CancellationToken ServerLoop { get; set; }
+ JoinableTaskFactory JoinableTaskFactory { get; }
+ CancellationToken ServerLoop { get; }
string Message { get; set; }
static MacroParser Parser { get; set; }
MacroLines MacroLines { get; set; }
- List<string> SelectedAssemblies { get { return _SelectedAssemblies; } }
- List<string> _SelectedAssemblies =
- new List<string>
- {
- "QtVsTest",
- "System.Core",
- };
+ private List<string> SelectedAssemblies { get; } = new List<string>
+ {
+ typeof(Macro).Assembly.FullName,
+ typeof(EnvDTE.DTE).Assembly.FullName,
+ typeof(AutomationElement).Assembly.FullName,
+ "System.Core",
+ };
IEnumerable<string> RefAssemblies { get; set; }
- List<string> Namespaces { get { return _Namespaces; } }
- List<string> _Namespaces =
- new List<string>
- {
- "System",
- "System.Linq",
- "System.Reflection",
- "Task = System.Threading.Tasks.Task",
- "System.Windows.Automation",
- "EnvDTE",
- "EnvDTE80",
- };
+ private List<string> Namespaces { get; } = new List<string>
+ {
+ "System",
+ "System.Linq",
+ "System.Reflection",
+ "Task = System.Threading.Tasks.Task",
+ "System.Windows.Automation",
+ "EnvDTE",
+ "EnvDTE80",
+ };
- Dictionary<string, VSServiceRef> ServiceRefs { get { return _ServiceRefs; } }
- Dictionary<string, VSServiceRef> _ServiceRefs =
- new Dictionary<string, VSServiceRef>
+ private Dictionary<string, VSServiceRef> ServiceRefs { get; } = new Dictionary<string, VSServiceRef>
+ {
{
- {
- "Dte", new VSServiceRef
+ "Dte", new VSServiceRef
{ Name = "Dte", Interface = "DTE2", Type = "DTE" }
- },
- };
+ },
+ };
- Dictionary<string, GlobalVar> GlobalVars { get { return _GlobalVars; } }
- Dictionary<string, GlobalVar> _GlobalVars =
- new Dictionary<string, GlobalVar>
+ private Dictionary<string, GlobalVar> GlobalVars { get; } = new Dictionary<string, GlobalVar>
+ {
{
- {
- "Result", new GlobalVar
+ "Result", new GlobalVar
{ Type = "string", Name = "Result", InitialValueExpr = "string.Empty" }
- },
- };
+ },
+ };
string CSharpMethodCode { get; set; }
string CSharpClassCode { get; set; }
@@ -187,10 +178,10 @@
const BindingFlags PUBLIC_STATIC = BindingFlags.Public | BindingFlags.Static;
const StringComparison IGNORE_CASE = StringComparison.InvariantCultureIgnoreCase;
- static ConcurrentDictionary<string, Macro> Macros
+ static readonly ConcurrentDictionary<string, Macro> Macros
= new ConcurrentDictionary<string, Macro>();
- static ConcurrentDictionary<string, object> Globals
+ static readonly ConcurrentDictionary<string, object> Globals
= new ConcurrentDictionary<string, object>();
/// <summary>
@@ -202,6 +193,7 @@
public Macro(
AsyncPackage package,
EnvDTE80.DTE2 dte,
+ IntPtr mainWindowHWnd,
JoinableTaskFactory joinableTaskFactory,
CancellationToken serverLoop)
{
@@ -209,6 +201,7 @@
JoinableTaskFactory = joinableTaskFactory;
ServerLoop = serverLoop;
Dte = dte;
+ MainWindowHWnd = mainWindowHWnd;
ErrorMsg("Uninitialized");
}
@@ -510,6 +503,8 @@
return false;
break;
}
+
+ csharp.AppendLine();
return true;
}
@@ -615,6 +610,38 @@
csharp.AppendFormat(@"
await WaitExpr({0}, () => UiContext = {1});", timeout, context);
+
+ } else if (s.Args[0].Equals("find", IGNORE_CASE)) {
+ //# ui find [all] [_var_name_] [_timeout_] => <_scope_>, <_condition_>
+
+ var args = new Queue<string>(s.Args.Skip(1));
+
+ bool findAll = false;
+ if (args.Any() && args.Peek().Equals("all", IGNORE_CASE)) {
+ findAll = true;
+ args.Dequeue();
+ }
+ string funcName = findAll ? "FindAll" : "FindFirst";
+ string varType = findAll ? "AutomationElementCollection" : "AutomationElement";
+
+ string varName = null;
+ if (args.Any() && !char.IsDigit(args.Peek()[0]))
+ varName = args.Dequeue();
+ if (findAll && string.IsNullOrEmpty(varName))
+ return ErrorMsg("Invalid #ui statement");
+
+ int timeout = 3000;
+ if (args.Any() && char.IsDigit(args.Peek()[0]))
+ timeout = int.Parse(args.Dequeue());
+
+ if (varName == null) {
+ varName = "UiContext";
+ } else {
+ csharp.Append($@"
+ {varType} {varName} = null;");
+ }
+ csharp.Append($@"
+ await WaitExpr({timeout}, () => {varName} = UiContext.{funcName}({s.Code}));");
} else if (s.Args[0].Equals("pattern", IGNORE_CASE)) {
//# ui pattern <_TypeName_> <_VarName_> [ => _string_ [, _string_, ... ] ]
@@ -790,7 +817,9 @@
File.Delete(macroDllPath);
return ErrorMsg(string.Join("\r\n",
CompilerResults.Errors.Cast<CompilerError>()
- .Select(x => x.ErrorText)));
+ .Select(x => $"{x.Line}: {x.ErrorText}")
+ .Append(CSharpClassCode)
+ .Union(RefAssemblies)));
}
MacroAssembly = AppDomain.CurrentDomain.Load(File.ReadAllBytes(macroDllPath));
@@ -927,8 +956,7 @@
foreach (var globalVar in GlobalVars.Values) {
string varName = globalVar.Name;
Type varType = globalVar.FieldInfo.FieldType;
- object value;
- if (Globals.TryGetValue(varName, out value)) {
+ if (Globals.TryGetValue(varName, out object value)) {
Type valueType = value.GetType();
if (!varType.IsAssignableFrom(valueType)) {
throw new InvalidCastException(string.Format(
@@ -968,8 +996,7 @@
static Macro GetMacro(string name)
{
- Macro macro;
- if (!Macros.TryGetValue(name, out macro))
+ if (!Macros.TryGetValue(name, out Macro macro))
return null;
return macro;
}
diff --git a/QtVsTest/MacroParser.cs b/QtVsTest/MacroParser.cs
index 4f8d240..3d67713 100644
--- a/QtVsTest/MacroParser.cs
+++ b/QtVsTest/MacroParser.cs
@@ -27,17 +27,18 @@
****************************************************************************/
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
+using QtVsTools.SyntaxAnalysis;
namespace QtVsTest.Macros
{
- using System.Collections;
- using static QtVsTools.SyntaxAnalysis.RegExpr;
+ using static RegExpr;
class MacroLines : IEnumerable<MacroLine>
{
- List<MacroLine> Lines = new List<MacroLine>();
+ readonly List<MacroLine> Lines = new List<MacroLine>();
public void Add(MacroLine line) { Lines.Add(line); }
@@ -120,7 +121,7 @@
public class CodeLine : MacroLine
{
- public string Code;
+ public readonly string Code;
public CodeLine(string code)
{
Code = code;
diff --git a/QtVsTest/MacroServer.cs b/QtVsTest/MacroServer.cs
index 24f0033..b00fba5 100644
--- a/QtVsTest/MacroServer.cs
+++ b/QtVsTest/MacroServer.cs
@@ -46,10 +46,10 @@
/// </summary>
class MacroServer
{
- public CancellationTokenSource Loop { get; private set; }
+ public CancellationTokenSource Loop { get; }
- AsyncPackage Package { get; set; }
- JoinableTaskFactory JoinableTaskFactory { get; set; }
+ AsyncPackage Package { get; }
+ JoinableTaskFactory JoinableTaskFactory { get; }
/// <summary>
/// Macro server constructor
@@ -70,6 +70,7 @@
{
await JoinableTaskFactory.SwitchToMainThreadAsync(Loop.Token);
var DTE = await Package.GetServiceAsync(typeof(DTE)) as DTE2;
+ var mainWindowHWnd = new IntPtr((long)DTE.MainWindow.HWnd);
await TaskScheduler.Default;
var pipeName = string.Format("QtVSTest_{0}", Process.GetCurrentProcess().Id);
@@ -97,7 +98,8 @@
if (Loop.Token.IsCancellationRequested)
break;
- var macro = new Macro(Package, DTE, JoinableTaskFactory, Loop.Token);
+ var macro = new Macro(
+ Package, DTE, mainWindowHWnd, JoinableTaskFactory, Loop.Token);
await macro.CompileAsync(Encoding.UTF8.GetString(data));
if (macro.AutoRun)
await macro.RunAsync();
diff --git a/QtVsTest/QtVsTest.cs b/QtVsTest/QtVsTest.cs
index 74a7939..15ed031 100644
--- a/QtVsTest/QtVsTest.cs
+++ b/QtVsTest/QtVsTest.cs
@@ -27,6 +27,7 @@
****************************************************************************/
using System;
+using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.VisualStudio.Shell;
@@ -38,7 +39,6 @@
namespace QtVsTest
{
using Macros;
- using System.IO;
[Guid(PackageGuidString)]
[InstalledProductRegistration(
@@ -53,7 +53,7 @@
public sealed class QtVsTest : AsyncPackage
{
public const string PackageGuidString = "0e258dce-fc8a-49a2-81c5-c9e138bfe500";
- MacroServer MacroServer { get; set; }
+ MacroServer MacroServer { get; }
public QtVsTest()
{
diff --git a/QtVsTest/QtVsTest.csproj b/QtVsTest/QtVsTest.csproj
index c1c2aa4..d9a4894 100644
--- a/QtVsTest/QtVsTest.csproj
+++ b/QtVsTest/QtVsTest.csproj
@@ -2,7 +2,7 @@
<!--
/****************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -69,6 +69,8 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
+ <PlatformTarget Condition="'$(VisualStudioVersion)' == '17.0'">x64</PlatformTarget>
+ <PlatformTarget Condition="'$(VisualStudioVersion)' != '17.0'">x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -87,55 +89,36 @@
<Reference Include="System" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
- <Reference Include="Microsoft.VisualStudio.ProjectSystem">
- <HintPath>$(VsInstallRoot)\Common7\IDE\CommonExtensions\Microsoft\Project\Microsoft.VisualStudio.ProjectSystem.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Composition">
- <HintPath>$(VsInstallRoot)\Common7\IDE\PrivateAssemblies\Microsoft.VisualStudio.Composition.dll</HintPath>
- </Reference>
</ItemGroup>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
- // Version specific references
+ // General package references
// -->
<Import Project="$(SolutionDir)\references.props" />
<ItemGroup>
- <PackageReference Include="System.ComponentModel.Composition"
- Version="$(Version_System_ComponentModel_Composition)" />
- <PackageReference Include="Stub.System.Data.SQLite.Core.NetFramework"
- Version="$(Version_Stub_System_Data_SQLite_Core_NetFramework)" />
- <PackageReference Include="Newtonsoft.Json"
- Version="$(Version_Newtonsoft_Json)" />
- <PackageReference Include="Microsoft.Build"
- Version="$(Version_Microsoft_Build)" />
- <PackageReference Include="Microsoft.Build.Framework"
- Version="$(Version_Microsoft_Build_Framework)" />
- <PackageReference Include="Microsoft.Build.Tasks.Core"
- Version="$(Version_Microsoft_Build_Tasks_Core)" />
- <PackageReference Include="Microsoft.VisualStudio.SDK"
- Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
- <PackageReference Include="Microsoft.VSSDK.BuildTools"
- Version="$(Version_Microsoft_VSSDK_BuildTools)" />
- <PackageReference Include="Microsoft.VisualStudio.Shell.Framework"
- Version="$(Version_Microsoft_VisualStudio_Shell_Framework)" />
- <PackageReference Include="Microsoft.VisualStudio.Validation"
- Version="$(Version_Microsoft_VisualStudio_Validation)" />
- <PackageReference Include="$(Name_Microsoft_VisualStudio_Threading)"
- Version="$(Version_Microsoft_VisualStudio_Threading)" />
- <PackageReference Include="System.Collections.Immutable"
- Version="$(Version_System_Collections_Immutable)" />
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_ProjectSystem)" Version="$(Version_Microsoft_VisualStudio_ProjectSystem)" />
</ItemGroup>
- <ItemGroup Condition="'$(VisualStudioVersion)'=='17.0'">
- <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
- Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
- </ItemGroup>
- <ItemGroup Condition="'$(VisualStudioVersion)'=='16.0'">
- <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
- Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
- </ItemGroup>
- <ItemGroup Condition="'$(VisualStudioVersion)'=='15.0'">
- <Reference Include="Microsoft.VisualStudio.VCProjectEngine" />
- </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
// Solution project references
@@ -210,6 +193,26 @@
</Content>
</ItemGroup>
<Choose>
+ <When Condition="Exists('$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.22000.0')">
+ <PropertyGroup>
+ <Win10SDKPath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.22000.0</Win10SDKPath>
+ </PropertyGroup>
+ </When>
+ <When Condition="Exists('$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.20348.0')">
+ <PropertyGroup>
+ <Win10SDKPath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.20348.0</Win10SDKPath>
+ </PropertyGroup>
+ </When>
+ <When Condition="Exists('$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.19041.0')">
+ <PropertyGroup>
+ <Win10SDKPath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.19041.0</Win10SDKPath>
+ </PropertyGroup>
+ </When>
+ <When Condition="Exists('$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.18362.0')">
+ <PropertyGroup>
+ <Win10SDKPath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.18362.0</Win10SDKPath>
+ </PropertyGroup>
+ </When>
<When Condition="Exists('$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.17763.0')">
<PropertyGroup>
<Win10SDKPath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.17763.0</Win10SDKPath>
@@ -232,7 +235,7 @@
</When>
</Choose>
<PropertyGroup Condition="'$(Win10SDKPath)' != ''">
- <UIAVerifyPath>$(Win10SDKPath)\x86\UIAVerify</UIAVerifyPath>
+ <UIAVerifyPath>$(Win10SDKPath)\$(PlatformTarget)\UIAVerify</UIAVerifyPath>
</PropertyGroup>
<ItemGroup Condition="'$(UIAVerifyPath)' != ''">
<Reference Include="Interop.UIAutomationClient">
@@ -246,9 +249,6 @@
<Aliases>global</Aliases>
<EmbedInteropTypes>False</EmbedInteropTypes>
</Reference>
- </ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
diff --git a/QtVsTools.Core/BuildConfig.cs b/QtVsTools.Core/BuildConfig.cs
index 713e9f8..ac8647c 100644
--- a/QtVsTools.Core/BuildConfig.cs
+++ b/QtVsTools.Core/BuildConfig.cs
@@ -30,7 +30,6 @@
{
public struct BuildConfig
{
- public const uint Both = 0x03;
public const uint Release = 0x01;
public const uint Debug = 0x02;
diff --git a/QtVsTools.Core/CommandLineParser.cs b/QtVsTools.Core/CommandLineParser.cs
index 7380cc8..995d064 100644
--- a/QtVsTools.Core/CommandLineParser.cs
+++ b/QtVsTools.Core/CommandLineParser.cs
@@ -29,10 +29,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
-using System.IO;
namespace QtVsTools.Core.CommandLine
{
@@ -40,13 +40,12 @@
public class Parser
{
-
- List<Option> commandLineOptionList = new List<Option>();
- Dictionary<string, int> nameHash = new Dictionary<string, int>();
- Dictionary<int, List<string>> optionValuesHash = new Dictionary<int, List<string>>();
- List<string> optionNames = new List<string>();
- List<string> positionalArgumentList = new List<string>();
- List<string> unknownOptionNames = new List<string>();
+ readonly List<Option> commandLineOptionList = new List<Option>();
+ readonly Dictionary<string, int> nameHash = new Dictionary<string, int>();
+ readonly Dictionary<int, List<string>> optionValuesHash = new Dictionary<int, List<string>>();
+ readonly List<string> optionNames = new List<string>();
+ readonly List<string> positionalArgumentList = new List<string>();
+ readonly List<string> unknownOptionNames = new List<string>();
bool needsParsing = true;
public enum SingleDashWordOptionMode
@@ -118,8 +117,7 @@
IEnumerable<string> Aliases(string optionName)
{
- int optionIndex;
- if (!nameHash.TryGetValue(optionName, out optionIndex)) {
+ if (!nameHash.TryGetValue(optionName, out int optionIndex)) {
return new List<string>();
}
return commandLineOptionList[optionIndex].Names;
@@ -204,8 +202,7 @@
IEnumerator<string> argumentEnumerator, ref bool atEnd)
{
const char assignChar = '=';
- int optionOffset;
- if (nameHash.TryGetValue(optionName, out optionOffset)) {
+ if (nameHash.TryGetValue(optionName, out int optionOffset)) {
int assignPos = argument.IndexOf(assignChar);
bool withValue = !string.IsNullOrEmpty(
commandLineOptionList[optionOffset].ValueName);
@@ -267,7 +264,7 @@
var optFilePath = macros.ExpandString(argData.Substring(1));
string[] additionalArgs = File.ReadAllLines(
Path.Combine(workingDir, optFilePath));
- if (additionalArgs != null) {
+ if (additionalArgs.Length != 0) {
var additionalArgsString = string.Join(" ", additionalArgs
.Select(x => "\"" + x.Replace("\"", "\\\"") + "\""));
arguments.AddRange(TokenizeArgs(additionalArgsString, macros));
@@ -356,10 +353,9 @@
if (!RegisterFoundOption(optionName)) {
error = true;
} else {
- int optionOffset;
Trace.Assert(nameHash.TryGetValue(
optionName,
- out optionOffset));
+ out int optionOffset));
bool withValue = !string.IsNullOrEmpty(
commandLineOptionList[optionOffset].ValueName);
if (withValue) {
@@ -397,10 +393,9 @@
if (argument.Length > 2) {
string possibleShortOptionStyleName = argument.Substring(1, 1);
- int shortOptionIdx;
if (nameHash.TryGetValue(
possibleShortOptionStyleName,
- out shortOptionIdx)) {
+ out int shortOptionIdx)) {
var arg = commandLineOptionList[shortOptionIdx];
if ((arg.Flags & Option.Flag.ShortOptionStyle) != 0) {
RegisterFoundOption(possibleShortOptionStyleName);
@@ -466,8 +461,7 @@
public IEnumerable<string> Values(string optionName)
{
CheckParsed("Values");
- int optionOffset;
- if (nameHash.TryGetValue(optionName, out optionOffset)) {
+ if (nameHash.TryGetValue(optionName, out int optionOffset)) {
var values = optionValuesHash[optionOffset];
return values;
}
@@ -525,7 +519,6 @@
public IEnumerable<string> Names
{
get;
- private set;
}
public string ValueName
@@ -558,7 +551,7 @@
static class Lexer
{
- static Regex lexer = new Regex(
+ static readonly Regex lexer = new Regex(
/* Newline */ @"(\n)" +
/* Unquoted */ @"|((?:(?:[^\s\""])|(?:(?<=\\)\""))+)" +
/* Quoted */ @"|(?:\""((?:(?:[^\""])|(?:(?<=\\)\""))+)\"")" +
diff --git a/QtVsTools.Core/Common/EnumExt.cs b/QtVsTools.Core/Common/EnumExt.cs
index 0406e2c..c05f7bc 100644
--- a/QtVsTools.Core/Common/EnumExt.cs
+++ b/QtVsTools.Core/Common/EnumExt.cs
@@ -40,6 +40,8 @@
/// </summary>
public static class EnumExt
{
+ static LazyFactory StaticLazy { get; } = new LazyFactory();
+
/// <summary>
/// Wrapper for enum cast values.
/// </summary>
@@ -64,7 +66,7 @@
[AttributeUsage(AttributeTargets.All)]
public sealed class StringAttribute : Attribute, ICast<string>
{
- public string Value { get; private set; }
+ public string Value { get; }
public StringAttribute(string str) { Value = str; }
}
@@ -128,8 +130,7 @@
/// </summary>
public static TEnum Cast<T, TEnum>(this T valueT, TEnum defaultValue) where TEnum : struct
{
- TEnum value;
- return TryCast(valueT, out value) ? value : defaultValue;
+ return TryCast(valueT, out TEnum value) ? value : defaultValue;
}
/// <summary>
@@ -201,15 +202,14 @@
.FirstOrDefault();
}
- static IEnumerable<Type> _CastAttribTypes;
/// <summary>
/// List of cast attribute types.
/// </summary>
/// <remarks>
/// Future cast attribute types need to be added to this list.
/// </remarks>
- static IEnumerable<Type> CastAttribTypes => _CastAttribTypes
- ?? (_CastAttribTypes = new[]
+ static IEnumerable<Type> CastAttribTypes => StaticLazy.Get(() =>
+ CastAttribTypes, () => new[]
{
typeof(StringAttribute)
});
diff --git a/QtVsTools.Core/Common/LazyFactory.cs b/QtVsTools.Core/Common/LazyFactory.cs
new file mode 100644
index 0000000..c914cee
--- /dev/null
+++ b/QtVsTools.Core/Common/LazyFactory.cs
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Concurrent;
+using System.Diagnostics;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace QtVsTools.Common
+{
+ public class LazyFactory
+ {
+ private Lazy<ConcurrentDictionary<PropertyInfo, Lazy<object>>> LazyObjs { get; }
+ private ConcurrentDictionary<PropertyInfo, Lazy<object>> Objs => LazyObjs.Value;
+
+ public LazyFactory()
+ {
+ LazyObjs = new Lazy<ConcurrentDictionary<PropertyInfo, Lazy<object>>>();
+ }
+
+ public T Get<T>(Expression<Func<T>> propertyRef, Func<T> initFunc) where T : class
+ {
+ var lazyPropertyExpr = propertyRef?.Body as MemberExpression;
+ var lazyProperty = lazyPropertyExpr?.Member as PropertyInfo;
+ if (lazyProperty == null)
+ throw new ArgumentException("Invalid property reference", "propertyRef");
+ var lazyObj = Objs.GetOrAdd(lazyProperty, (_) => new Lazy<object>(() => initFunc()));
+ return lazyObj.Value as T;
+ }
+ }
+}
diff --git a/QtVsTools.Core/Common/QtVSIPSettingsShared.cs b/QtVsTools.Core/Common/QtVSIPSettingsShared.cs
new file mode 100644
index 0000000..5d86492
--- /dev/null
+++ b/QtVsTools.Core/Common/QtVSIPSettingsShared.cs
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
+using Microsoft.Win32;
+using QtVsTools.Core;
+
+namespace QtVsTools.Common
+{
+ public static class QtVSIPSettingsShared
+ {
+ private static readonly Dictionary<string, string> mocDirCache
+ = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+ private static readonly Dictionary<string, string> uicDirCache
+ = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+ private static readonly Dictionary<string, string> rccDirCache
+ = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+
+ public static string GetDirectory(EnvDTE.Project project, string type)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ // check for directory in following order:
+ // - stored in project
+ // - stored in cache
+ // - retrieve from moc/uic steps
+ // - fall-back on hard-coded directory
+
+ var fullName = project?.FullName;
+ if (string.IsNullOrEmpty(fullName))
+ return GetDirectory(type); // - fall-back on hard-coded directory
+
+ if (project.Globals.get_VariablePersists(type)) // - stored in project
+ return HelperFunctions.NormalizeRelativeFilePath(project.Globals[type] as string);
+
+ switch (type) { // - stored in cache
+ case Resources.mocDirKeyword:
+ if (mocDirCache.ContainsKey(fullName))
+ return mocDirCache[fullName];
+ break;
+ case Resources.uicDirKeyword:
+ if (uicDirCache.ContainsKey(fullName))
+ return uicDirCache[fullName];
+ break;
+ case Resources.rccDirKeyword:
+ if (rccDirCache.ContainsKey(fullName))
+ return rccDirCache[fullName];
+ break;
+ default:
+ return GetDirectory(type); // - fall-back on hard-coded directory
+ }
+
+ try {
+ string configName = null;
+ string platformName = null;
+ QtCustomBuildTool tool = null;
+ foreach (VCFile vcfile in (project.Object as VCProject).Files as IVCCollection) {
+ var name = vcfile?.Name;
+ if (string.IsNullOrEmpty(name))
+ continue;
+ if (!(HelperFunctions.IsHeaderFile(name) || HelperFunctions.IsMocFile(name)
+ || HelperFunctions.IsUicFile(name) || HelperFunctions.IsQrcFile(name)))
+ continue;
+
+ foreach (VCFileConfiguration config in vcfile?.FileConfigurations as IVCCollection) {
+ tool = new QtCustomBuildTool(config);
+ if (tool == null)
+ continue;
+ configName = config.Name.Remove(config.Name.IndexOf('|'));
+ var vcConfig = config.ProjectConfiguration as VCConfiguration;
+ platformName = (vcConfig.Platform as VCPlatform).Name;
+ var cmd = tool.CommandLine;
+ if (cmd.Contains("moc.exe") || cmd.Contains("uic.exe") || cmd.Contains("rcc.exe"))
+ break;
+ tool = null;
+ }
+
+ if (tool != null)
+ break;
+ }
+
+ if (tool == null)
+ return GetDirectory(type); // - fall-back on hard-coded directory
+
+ var dir = ".";
+ var lastindex = tool.Outputs.LastIndexOf('\\');
+ if (tool.Outputs.LastIndexOf('/') > lastindex)
+ lastindex = tool.Outputs.LastIndexOf('/');
+
+ if (lastindex != -1)
+ dir = tool.Outputs.Substring(0, lastindex);
+ dir = dir.Replace("\"", "");
+
+ if (type == Resources.mocDirKeyword) {
+ int index = dir.IndexOf(configName, StringComparison.OrdinalIgnoreCase);
+ if (index != -1)
+ dir = dir.Replace(dir.Substring(index, configName.Length), "$(ConfigurationName)");
+
+ index = dir.IndexOf(platformName, StringComparison.OrdinalIgnoreCase);
+ if (index != -1)
+ dir = dir.Replace(dir.Substring(index, platformName.Length), "$(PlatformName)");
+ dir = HelperFunctions.NormalizeRelativeFilePath(dir);
+
+ mocDirCache.Add(fullName, dir);
+ } else if (type == Resources.uicDirKeyword) {
+ dir = HelperFunctions.NormalizeRelativeFilePath(dir);
+ uicDirCache.Add(fullName, dir);
+ } else if (type == Resources.rccDirKeyword) {
+ dir = HelperFunctions.NormalizeRelativeFilePath(dir);
+ rccDirCache.Add(fullName, dir);
+ } else {
+ dir = HelperFunctions.NormalizeRelativeFilePath(dir);
+ }
+
+ CleanUpCache(project);
+ return dir; // - retrieved from moc/uic/rcc steps
+ } catch { }
+ return GetDirectory(type); // - fall-back on hard-coded directory
+ }
+
+ private const string registryPath = "SOFTWARE\\" + Resources.registryPackagePath;
+
+ public static string GetDirectory(string type)
+ {
+ try {
+ var key = Registry.CurrentUser.OpenSubKey(registryPath);
+ if (key != null) {
+ if (key.GetValue(type, null) is string path)
+ return HelperFunctions.NormalizeRelativeFilePath(path);
+ }
+ } catch { }
+ if (type == Resources.mocDirKeyword)
+ return Resources.generatedFilesDir + "\\$(ConfigurationName)";
+ return Resources.generatedFilesDir;
+ }
+
+ public static string GetOption(EnvDTE.Project project, string type)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ // check for directory in following order:
+ // - stored in project
+ // - globally defined default option
+ // - empty options
+ if (project != null && project.Globals.get_VariablePersists(type))
+ return project.Globals[type] as string;
+ return GetOption(type);
+ }
+
+ public static string GetOption(string type)
+ {
+ try {
+ var key = Registry.CurrentUser.OpenSubKey(registryPath);
+ if (key != null) {
+ if (key.GetValue(type, null) is string opt)
+ return opt;
+ }
+ } catch { }
+ return null;
+ }
+
+ public static bool GetBoolValue(EnvDTE.Project project, string type)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ // check for directory in following order:
+ // - stored in project
+ // - globally defined default option
+ // - empty options
+ if (project != null && project.Globals.get_VariablePersists(type))
+ return Convert.ToInt32(project.Globals[type] as string) > 0;
+ return GetBoolValue(type, false);
+ }
+
+ public static bool GetBoolValue(string key, bool defaultValue)
+ {
+ var regKey = Registry.CurrentUser.OpenSubKey(registryPath);
+ if (regKey == null)
+ return defaultValue;
+ return ((int)regKey.GetValue(key, defaultValue ? 1 : 0)) > 0;
+ }
+
+ public static bool ValueExists(string key)
+ {
+ var regKey = Registry.CurrentUser.OpenSubKey(registryPath);
+ if (regKey != null) {
+ foreach (var s in regKey.GetValueNames()) {
+ if (s == key)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static string GetProjectQtSetting(EnvDTE.Project project, string propertyName)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ var activeConfig = project?.ConfigurationManager?.ActiveConfiguration;
+ if (activeConfig == null)
+ return null;
+ var activeConfigId = $"{activeConfig.ConfigurationName}|{activeConfig.PlatformName}";
+
+ try {
+ var props = project.Object as VCProject as IVCBuildPropertyStorage;
+ return props?.GetPropertyValue(propertyName, activeConfigId, "ProjectFile");
+ } catch {
+ return null;
+ }
+ }
+
+ public static void CleanUpCache(EnvDTE.Project project)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ var projects = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+ foreach (var p in HelperFunctions.ProjectsInSolution(project.DTE))
+ projects.Add(p.FullName);
+
+ mocDirCache.RemoveValues(projects);
+ uicDirCache.RemoveValues(projects);
+ rccDirCache.RemoveValues(projects);
+ }
+
+ static void RemoveValues(this Dictionary<string, string> cache, HashSet<string> projects)
+ {
+ foreach (var key in cache.Keys) {
+ if (projects.Contains(key))
+ cache.Remove(key);
+ }
+ }
+ }
+}
diff --git a/QtVsTools.Core/CompilerToolWrapper.cs b/QtVsTools.Core/CompilerToolWrapper.cs
index b9d95fc..f502f62 100644
--- a/QtVsTools.Core/CompilerToolWrapper.cs
+++ b/QtVsTools.Core/CompilerToolWrapper.cs
@@ -26,11 +26,11 @@
**
****************************************************************************/
-using Microsoft.VisualStudio.VCProjectEngine;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
+using Microsoft.VisualStudio.VCProjectEngine;
namespace QtVsTools.Core
{
@@ -44,7 +44,7 @@
/// Using VCCLCompilerTool directly will break the VS integration for Win CE.
class CompilerToolWrapper
{
- private VCCLCompilerTool compilerTool;
+ private readonly VCCLCompilerTool compilerTool;
private readonly Object compilerObj;
private readonly Type compilerType;
@@ -302,13 +302,6 @@
return GetStringProperty("AdditionalIncludeDirectories");
}
- public string GetPrecompiledHeaderFile()
- {
- if (compilerTool != null)
- return compilerTool.PrecompiledHeaderFile;
- return GetStringProperty("PrecompiledHeaderFile");
- }
-
public string GetPrecompiledHeaderThrough()
{
if (compilerTool != null)
@@ -326,20 +319,6 @@
if (obj == null)
return pchOption.pchNone;
return (pchOption)obj;
- }
-
- public void SetDebugInformationFormat(debugOption value)
- {
- if (compilerTool != null) {
- compilerTool.DebugInformationFormat = value;
- } else {
- compilerType.InvokeMember(
- "DebugInformationFormat",
- BindingFlags.SetProperty,
- null,
- compilerObj,
- new object[] { value });
- }
}
public runtimeLibraryOption RuntimeLibrary
@@ -364,62 +343,6 @@
} else {
compilerTool.RuntimeLibrary = value;
}
- }
- }
-
- public void SetOptimization(optimizeOption value)
- {
- if (compilerTool != null) {
- compilerTool.Optimization = value;
- } else {
- compilerType.InvokeMember(
- "Optimization",
- BindingFlags.SetProperty,
- null,
- compilerObj,
- new object[] { value });
- }
- }
-
- public void SetTreatWChar_tAsBuiltInType(bool value)
- {
- if (compilerTool != null) {
- compilerTool.TreatWChar_tAsBuiltInType = value;
- } else {
- compilerType.InvokeMember(
- "TreatWChar_tAsBuiltInType",
- BindingFlags.SetProperty,
- null,
- compilerObj,
- new object[] { value });
- }
- }
-
- public void SetPrecompiledHeaderFile(string file)
- {
- if (compilerTool != null) {
- compilerTool.PrecompiledHeaderFile = file;
- } else {
- compilerType.InvokeMember(
- "PrecompiledHeaderFile",
- BindingFlags.SetProperty,
- null,
- compilerObj,
- new object[] { file });
- }
- }
-
- public void SetPrecompiledHeaderThrough(string value)
- {
- if (compilerTool != null) {
- compilerTool.PrecompiledHeaderThrough = value;
- } else {
- compilerType.InvokeMember(
- "PrecompiledHeaderThrough",
- BindingFlags.SetProperty,
- null,
- compilerObj,
- new object[] { value });
}
}
diff --git a/QtVsTools.Core/CxxStreamReader.cs b/QtVsTools.Core/CxxStreamReader.cs
index eb758eb..b3a6394 100644
--- a/QtVsTools.Core/CxxStreamReader.cs
+++ b/QtVsTools.Core/CxxStreamReader.cs
@@ -42,12 +42,12 @@
Normal, Comment, String
}
private State state = State.Normal;
- private StreamReader sr;
+ private readonly StreamReader sr;
private string partialLine;
bool disposed;
int _lineNum;
- string[] _lines;
+ readonly string[] _lines;
public CxxStreamReader(string[] lines)
{
diff --git a/QtVsTools.Core/ExportProjectDialog.cs b/QtVsTools.Core/ExportProjectDialog.cs
index 13aea35..2c5d3ad 100644
--- a/QtVsTools.Core/ExportProjectDialog.cs
+++ b/QtVsTools.Core/ExportProjectDialog.cs
@@ -68,11 +68,7 @@
optionTextBox.Text = "";
openCheckBox.Text = SR.GetString("ExportProjectDialog_Open");
createPriFileCheckBox.Text = SR.GetString("ExportProjectDialog_CreatePri");
-
- if (SR.LanguageName == "de")
- Size = new Size(470, 300);
- else
- Size = new Size(400, 300);
+ Size = new Size(400, 300);
ShowInTaskbar = false;
Shown += ExportProjectDialog_Shown;
diff --git a/QtVsTools.Core/Extensions.cs b/QtVsTools.Core/Extensions.cs
index 4f14aa6..dee20a0 100644
--- a/QtVsTools.Core/Extensions.cs
+++ b/QtVsTools.Core/Extensions.cs
@@ -32,15 +32,6 @@
{
public static class Extensions
{
- public static string Quoute(this string input)
- {
- if (!input.StartsWith("\"", StringComparison.Ordinal))
- input = "\"" + input;
- if (!input.EndsWith("\"", StringComparison.Ordinal))
- input += "\"";
- return input;
- }
-
public static string Replace(this string original, string oldValue, string newValue,
StringComparison comparison)
{
diff --git a/QtVsTools.Core/FakeFilter.cs b/QtVsTools.Core/FakeFilter.cs
index 8851174..a557d09 100644
--- a/QtVsTools.Core/FakeFilter.cs
+++ b/QtVsTools.Core/FakeFilter.cs
@@ -34,11 +34,6 @@
public string Filter { get; set; }
public string UniqueIdentifier { get; set; }
- private bool parseFiles = true;
- public bool ParseFiles
- {
- get { return parseFiles; }
- set { parseFiles = value; }
- }
+ public bool ParseFiles { get; set; } = true;
}
}
diff --git a/QtVsTools.Core/Filters.cs b/QtVsTools.Core/Filters.cs
index ab55d55..7746152 100644
--- a/QtVsTools.Core/Filters.cs
+++ b/QtVsTools.Core/Filters.cs
@@ -71,17 +71,6 @@
};
}
- public static FakeFilter TranslationFiles()
- {
- return new FakeFilter
- {
- UniqueIdentifier = "{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}",
- Name = SR.GetString("Resources_TranslationFiles"),
- Filter = "ts",
- ParseFiles = false
- };
- }
-
public static FakeFilter GeneratedFiles()
{
return new FakeFilter
@@ -89,16 +78,6 @@
UniqueIdentifier = "{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}",
Name = SR.GetString("Resources_GeneratedFiles"),
Filter = "moc;h;cpp",
- };
- }
-
- public static FakeFilter OtherFiles()
- {
- return new FakeFilter
- {
- UniqueIdentifier = "{B67473BF-9FA1-4674-831E-CB28F72D4791}",
- Name = SR.GetString("Resources_OtherFiles"),
- Filter = "*",
};
}
}
diff --git a/QtVsTools.Core/HelperFunctions.cs b/QtVsTools.Core/HelperFunctions.cs
index b6fe0ff..a07fa89 100644
--- a/QtVsTools.Core/HelperFunctions.cs
+++ b/QtVsTools.Core/HelperFunctions.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,10 +26,6 @@
**
****************************************************************************/
-using EnvDTE;
-using Microsoft.VisualStudio.VCProjectEngine;
-using Microsoft.Win32;
-using QtVsTools.Core.QtMsBuild;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -40,105 +36,31 @@
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
+#if VS2017
+using Microsoft.Win32;
+#endif
+using EnvDTE;
using Process = System.Diagnostics.Process;
namespace QtVsTools.Core
{
+ using QtMsBuild;
+
public static class HelperFunctions
{
- public static string FindQtDirWithTools(Project project)
- {
- var versionManager = QtVersionManager.The();
- string projectQtVersion = null;
- if (IsQtProject(project))
- projectQtVersion = versionManager.GetProjectQtVersion(project);
- return FindQtDirWithTools(projectQtVersion);
- }
-
- public static string FindQtDirWithTools(string projectQtVersion)
- {
- string tool = null;
- return FindQtDirWithTools(tool, projectQtVersion);
- }
-
- public static string FindQtDirWithTools(string tool, string projectQtVersion)
- {
- if (!string.IsNullOrEmpty(tool)) {
- if (!tool.StartsWith("\\bin\\", StringComparison.OrdinalIgnoreCase))
- tool = "\\bin\\" + tool;
- if (!tool.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
- tool += ".exe";
- }
-
- var versionManager = QtVersionManager.The();
- string qtDir = null;
- if (projectQtVersion != null)
- qtDir = versionManager.GetInstallPath(projectQtVersion);
-
- if (qtDir == null)
- qtDir = Environment.GetEnvironmentVariable("QTDIR");
-
- var found = false;
- if (tool == null) {
- found = File.Exists(qtDir + "\\bin\\designer.exe")
- && File.Exists(qtDir + "\\bin\\linguist.exe");
- } else {
- found = File.Exists(qtDir + tool);
- }
- if (!found) {
- VersionInformation exactlyMatchingVersion = null;
- VersionInformation matchingVersion = null;
- VersionInformation somehowMatchingVersion = null;
- var viProjectQtVersion = versionManager.GetVersionInfo(projectQtVersion);
- foreach (var qtVersion in versionManager.GetVersions()) {
- var vi = versionManager.GetVersionInfo(qtVersion);
- if (tool == null) {
- found = File.Exists(vi.qtDir + "\\bin\\designer.exe")
- && File.Exists(vi.qtDir + "\\bin\\linguist.exe");
- } else {
- found = File.Exists(vi.qtDir + tool);
- }
- if (!found)
- continue;
-
- if (viProjectQtVersion != null
- && vi.qtMajor == viProjectQtVersion.qtMajor
- && vi.qtMinor == viProjectQtVersion.qtMinor) {
- exactlyMatchingVersion = vi;
- break;
- }
- if (matchingVersion == null
- && viProjectQtVersion != null
- && vi.qtMajor == viProjectQtVersion.qtMajor) {
- matchingVersion = vi;
- }
- if (somehowMatchingVersion == null)
- somehowMatchingVersion = vi;
- }
-
- if (exactlyMatchingVersion != null)
- qtDir = exactlyMatchingVersion.qtDir;
- else if (matchingVersion != null)
- qtDir = matchingVersion.qtDir;
- else if (somehowMatchingVersion != null)
- qtDir = somehowMatchingVersion.qtDir;
- else
- qtDir = null;
- }
- return qtDir;
- }
-
static readonly HashSet<string> _sources = new HashSet<string>(new[] { ".c", ".cpp", ".cxx" },
StringComparer.OrdinalIgnoreCase);
- static public bool IsSourceFile(string fileName)
+ public static bool IsSourceFile(string fileName)
{
return _sources.Contains(Path.GetExtension(fileName));
}
static readonly HashSet<string> _headers = new HashSet<string>(new[] { ".h", ".hpp", ".hxx" },
StringComparer.OrdinalIgnoreCase);
- static public bool IsHeaderFile(string fileName)
+ public static bool IsHeaderFile(string fileName)
{
return _headers.Contains(Path.GetExtension(fileName));
}
@@ -173,23 +95,28 @@
return ".qml".Equals(Path.GetExtension(fileName), StringComparison.OrdinalIgnoreCase);
}
- static public void SetDebuggingEnvironment(Project prj)
+ public static void SetDebuggingEnvironment(Project prj)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
SetDebuggingEnvironment(prj, string.Empty);
}
- static public void SetDebuggingEnvironment(Project prj, string solutionConfig)
+ public static void SetDebuggingEnvironment(Project prj, string solutionConfig)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
SetDebuggingEnvironment(prj, "PATH=$(QTDIR)\\bin;$(PATH)", false, solutionConfig);
}
- static public void SetDebuggingEnvironment(Project prj, string envpath, bool overwrite)
+ public static void SetDebuggingEnvironment(Project prj, string envpath, bool overwrite)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
SetDebuggingEnvironment(prj, envpath, overwrite, string.Empty);
}
- static public void SetDebuggingEnvironment(Project prj, string envpath, bool overwrite, string solutionConfig)
+ public static void SetDebuggingEnvironment(Project prj, string envpath, bool overwrite, string solutionConfig)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (QtProject.GetFormatVersion(prj) >= Resources.qtMinFormatVersion_Settings)
return;
@@ -252,28 +179,29 @@
}
}
- public static bool IsProjectInSolution(DTE dteObject, string fullName)
+ public static Project ProjectFromSolution(DTE dteObject, string fullName)
{
- var fi = new FileInfo(fullName);
+ ThreadHelper.ThrowIfNotOnUIThread();
+ fullName = new FileInfo(fullName).FullName;
foreach (var p in ProjectsInSolution(dteObject)) {
- if (p.FullName.ToLower() == fi.FullName.ToLower())
- return true;
+ if (p.FullName.Equals(fullName, StringComparison.OrdinalIgnoreCase))
+ return p;
}
- return false;
+ return null;
}
/// <summary>
/// Returns the normalized file path of a given file.
/// </summary>
/// <param name="name">file name</param>
- static public string NormalizeFilePath(string name)
+ public static string NormalizeFilePath(string name)
{
var fi = new FileInfo(name);
return fi.FullName;
}
- static public string NormalizeRelativeFilePath(string path)
+ public static string NormalizeRelativeFilePath(string path)
{
if (path == null)
return ".\\";
@@ -299,7 +227,7 @@
return path;
}
- static public bool IsAbsoluteFilePath(string path)
+ public static bool IsAbsoluteFilePath(string path)
{
path = path.Trim();
if (path.Length >= 2 && path[1] == ':')
@@ -316,7 +244,7 @@
/// </summary>
/// <param name="streamReader"></param>
/// <returns>the composite string</returns>
- static private string ReadProFileLine(StreamReader streamReader)
+ private static string ReadProFileLine(StreamReader streamReader)
{
var line = streamReader.ReadLine();
if (line == null)
@@ -337,7 +265,7 @@
/// </summary>
/// <param name="profile">full name of .pro file to read</param>
/// <returns>true if this is a subdirs file</returns>
- static public bool IsSubDirsFile(string profile)
+ public static bool IsSubDirsFile(string profile)
{
StreamReader sr = null;
try {
@@ -407,55 +335,6 @@
}
/// <summary>
- /// Replaces a string in the commandLine, description, outputs and additional dependencies
- /// in all Custom build tools of the project
- /// </summary>
- /// <param name="project">Project</param>
- /// <param name="oldString">String, which is going to be replaced</param>
- /// <param name="oldString">String, which is going to replace the other one</param>
- /// <returns></returns>
- public static void ReplaceInCustomBuildTools(Project project, string oldString, string replaceString)
- {
- var vcPro = (VCProject)project.Object;
- if (vcPro == null)
- return;
-
- var qtMsBuild = new QtMsBuildContainer(new VCPropertyStorageProvider());
- qtMsBuild.BeginSetItemProperties();
- foreach (VCFile vcfile in (IVCCollection)vcPro.Files) {
- foreach (VCFileConfiguration config in (IVCCollection)vcfile.FileConfigurations) {
- try {
- if (vcfile.ItemType == "CustomBuild") {
- var tool = GetCustomBuildTool(config);
- if (tool == null)
- continue;
-
- tool.CommandLine = tool.CommandLine
- .Replace(oldString, replaceString,
- StringComparison.OrdinalIgnoreCase);
- tool.Description = tool.Description
- .Replace(oldString, replaceString,
- StringComparison.OrdinalIgnoreCase);
- tool.Outputs = tool.Outputs
- .Replace(oldString, replaceString,
- StringComparison.OrdinalIgnoreCase);
- tool.AdditionalDependencies = tool.AdditionalDependencies
- .Replace(oldString, replaceString,
- StringComparison.OrdinalIgnoreCase);
- } else {
- var tool = new QtCustomBuildTool(config, qtMsBuild);
- tool.CommandLine = tool.CommandLine
- .Replace(oldString, replaceString,
- StringComparison.OrdinalIgnoreCase);
- }
- } catch (Exception) {
- }
- }
- }
- qtMsBuild.EndSetItemProperties();
- }
-
- /// <summary>
/// Since VS2010 it is possible to have VCCustomBuildTools without commandlines
/// for certain filetypes. We are not interested in them and thus try to read the
/// tool's commandline. If this causes an exception, we ignore it.
@@ -463,23 +342,19 @@
/// </summary>
/// <param name="config">File configuration</param>
/// <returns></returns>
- static public VCCustomBuildTool GetCustomBuildTool(VCFileConfiguration config)
+ public static VCCustomBuildTool GetCustomBuildTool(VCFileConfiguration config)
{
- var file = config.File as VCFile;
- if (file == null || file.ItemType != "CustomBuild")
- return null;
-
- var tool = config.Tool as VCCustomBuildTool;
- if (tool == null)
- return null;
-
- try {
- // TODO: The return value is not used at all?
- var cmdLine = tool.CommandLine;
- } catch {
- return null;
+ if (config.File is VCFile file
+ && file.ItemType == "CustomBuild"
+ && config.Tool is VCCustomBuildTool tool) {
+ try {
+ _ = tool.CommandLine;
+ } catch {
+ return null;
+ }
+ return tool;
}
- return tool;
+ return null;
}
/// <summary>
@@ -488,8 +363,10 @@
/// has to be "CustomBuild"
/// </summary>
/// <param name="projectItem">Project Item which needs to have custom build tool</param>
- static public void EnsureCustomBuildToolAvailable(ProjectItem projectItem)
+ public static void EnsureCustomBuildToolAvailable(ProjectItem projectItem)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
foreach (Property prop in projectItem.Properties) {
if (prop.Name == "ItemType") {
if ((string)prop.Value != "CustomBuild")
@@ -499,169 +376,10 @@
}
}
- /// <summary>
- /// As Qmake -tp vc Adds the full path to the additional dependencies
- /// we need to do the same when toggling project kind to qmake generated.
- /// </summary>
- /// <returns></returns>
- private static string AddFullPathToAdditionalDependencies(string qtDir, string additionalDependencies)
- {
- var returnString = additionalDependencies;
- returnString =
- Regex.Replace(returnString, "Qt(\\S+5?)\\.lib", qtDir + "\\lib\\Qt${1}.lib");
- returnString =
- Regex.Replace(returnString, "(qtmaind?5?)\\.lib", qtDir + "\\lib\\${1}.lib");
- returnString =
- Regex.Replace(returnString, "(enginiod?5?)\\.lib", qtDir + "\\lib\\${1}.lib");
- return returnString;
- }
-
- /// <summary>
- /// Toggles the kind of a project. If the project is a QMake generated project (qmake -tp vc)
- /// it is transformed to an Qt VS Tools project and vice versa.
- /// </summary>
- /// <param name="project">Project</param>
- /// <returns></returns>
- public static void ToggleProjectKind(Project project)
- {
- if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_Settings)
- return;
-
- string qtDir = null;
- var vcPro = (VCProject)project.Object;
- if (!IsQMakeProject(project))
- return;
- if (IsQtProject(project)) {
- // TODO: qtPro is never used.
- var qtPro = QtProject.Create(project);
- var vm = QtVersionManager.The();
- qtDir = vm.GetInstallPath(project);
-
- foreach (var global in (string[])project.Globals.VariableNames) {
- if (global.StartsWith("Qt5Version", StringComparison.Ordinal))
- project.Globals.set_VariablePersists(global, false);
- }
-
- foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
- var compiler = CompilerToolWrapper.Create(config);
- var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
- var librarian = (VCLibrarianTool)((IVCCollection)config.Tools).Item("VCLibrarianTool");
- if (compiler != null) {
- var additionalIncludes = compiler.GetAdditionalIncludeDirectories();
- additionalIncludes = additionalIncludes.Replace("$(QTDIR)", qtDir,
- StringComparison.OrdinalIgnoreCase);
- compiler.SetAdditionalIncludeDirectories(additionalIncludes);
- }
- if (linker != null) {
- linker.AdditionalLibraryDirectories = linker.AdditionalLibraryDirectories.
- Replace("$(QTDIR)", qtDir, StringComparison.OrdinalIgnoreCase);
- linker.AdditionalDependencies = AddFullPathToAdditionalDependencies(qtDir, linker.AdditionalDependencies);
- } else {
- librarian.AdditionalLibraryDirectories = librarian.AdditionalLibraryDirectories
- .Replace("$(QTDIR)", qtDir, StringComparison.OrdinalIgnoreCase);
- librarian.AdditionalDependencies = AddFullPathToAdditionalDependencies(qtDir, librarian.AdditionalDependencies);
- }
- }
-
- ReplaceInCustomBuildTools(project, "$(QTDIR)", qtDir);
- } else {
- qtDir = GetQtDirFromQMakeProject(project);
-
- var vm = QtVersionManager.The();
- var qtVersion = vm.GetQtVersionFromInstallDir(qtDir);
- if (qtVersion == null)
- qtVersion = vm.GetDefaultVersion();
- if (qtDir == null)
- qtDir = vm.GetInstallPath(qtVersion);
- var vi = vm.GetVersionInfo(qtVersion);
- var platformName = vi.GetVSPlatformName();
- vm.SaveProjectQtVersion(project, qtVersion, platformName);
- var qtPro = QtProject.Create(project);
- if (!qtPro.SelectSolutionPlatform(platformName) || !qtPro.HasPlatform(platformName)) {
- var newProject = false;
- qtPro.CreatePlatform("Win32", platformName, null, vi, ref newProject);
- if (!qtPro.SelectSolutionPlatform(platformName))
- Messages.Print("Can't select the platform " + platformName + ".");
- }
-
- var activeConfig = project.ConfigurationManager.ActiveConfiguration.ConfigurationName;
- var activeVCConfig = (VCConfiguration)((IVCCollection)qtPro.VCProject.Configurations).Item(activeConfig);
- if (activeVCConfig.ConfigurationType == ConfigurationTypes.typeDynamicLibrary) {
- var compiler = CompilerToolWrapper.Create(activeVCConfig);
- var linker = (VCLinkerTool)((IVCCollection)activeVCConfig.Tools).Item("VCLinkerTool");
- var ppdefs = compiler.GetPreprocessorDefinitions();
- if (ppdefs != null
- && ppdefs.IndexOf("QT_PLUGIN", StringComparison.Ordinal) > -1
- && ppdefs.IndexOf("QDESIGNER_EXPORT_WIDGETS", StringComparison.Ordinal) > -1
- && ppdefs.IndexOf("QtDesigner", StringComparison.Ordinal) > -1
- && linker.AdditionalDependencies != null
- && linker.AdditionalDependencies.IndexOf("QtDesigner", StringComparison.Ordinal) > -1) {
- qtPro.MarkAsDesignerPluginProject();
- }
- }
-
- CleanupQMakeDependencies(project);
-
- foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
- var compiler = CompilerToolWrapper.Create(config);
- var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
-
- if (compiler != null) {
- var additionalIncludes = compiler.AdditionalIncludeDirectories;
- if (additionalIncludes != null) {
- ReplaceDirectory(ref additionalIncludes, qtDir, "$(QTDIR)", project);
- compiler.AdditionalIncludeDirectories = additionalIncludes;
- }
- }
- if (linker != null) {
- var linkerToolWrapper = new LinkerToolWrapper(linker);
- var paths = linkerToolWrapper.AdditionalLibraryDirectories;
- if (paths != null) {
- ReplaceDirectory(ref paths, qtDir, "$(QTDIR)", project);
- linkerToolWrapper.AdditionalLibraryDirectories = paths;
- }
- }
- }
-
- ReplaceInCustomBuildTools(project, qtDir, "$(QTDIR)");
- qtPro.TranslateFilterNames();
- }
- project.Save(project.FullName);
- }
-
- /// <summary>
- /// Replaces every occurrence of oldDirectory with replacement in the array of strings.
- /// Parameter oldDirectory must be an absolute path.
- /// This function converts relative directories to absolute paths internally
- /// and replaces them, if necessary. If no replacement is done, the path isn't altered.
- /// </summary>
- /// <param name="project">The project is needed to convert relative paths to absolute paths.</param>
- private static void ReplaceDirectory(ref List<string> paths, string oldDirectory, string replacement, Project project)
- {
- for (var i = 0; i < paths.Count; ++i) {
- var dirName = paths[i];
- if (dirName.StartsWith("\"", StringComparison.Ordinal) && dirName.EndsWith("\"", StringComparison.Ordinal)) {
- dirName = dirName.Substring(1, dirName.Length - 2);
- }
- if (!Path.IsPathRooted(dirName)) {
- // convert to absolute path
- dirName = Path.Combine(Path.GetDirectoryName(project.FullName), dirName);
- dirName = Path.GetFullPath(dirName);
- var alteredDirName = dirName.Replace(oldDirectory, replacement, StringComparison
- .OrdinalIgnoreCase);
- if (alteredDirName == dirName)
- continue;
- dirName = alteredDirName;
- } else {
- dirName = dirName.Replace(oldDirectory, replacement, StringComparison
- .OrdinalIgnoreCase);
- }
- paths[i] = dirName;
- }
- }
-
public static string GetQtDirFromQMakeProject(Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var vcProject = project.Object as VCProject;
if (vcProject == null)
return null;
@@ -742,13 +460,25 @@
}
/// <summary>
- /// Return true if the project is a Qt project, otherwise false.
+ /// Return true if the project is a VS tools project; false otherwise.
/// </summary>
/// <param name="proj">project</param>
- /// <returns></returns>
- public static bool IsQtProject(VCProject proj)
+ public static bool IsVsToolsProject(Project proj)
{
- if (!IsQMakeProject(proj))
+ ThreadHelper.ThrowIfNotOnUIThread(); // C++ Project Type GUID
+ if (proj == null || proj.Kind != "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")
+ return false;
+ return IsVsToolsProject(proj.Object as VCProject);
+ }
+
+ /// <summary>
+ /// Return true if the project is a VS tools project; false otherwise.
+ /// </summary>
+ /// <param name="proj">project</param>
+ public static bool IsVsToolsProject(VCProject proj)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ if (!IsQtProject(proj))
return false;
if (QtProject.GetFormatVersion(proj) >= Resources.qtMinFormatVersion_Settings)
@@ -759,95 +489,39 @@
return false;
foreach (var global in envPro.Globals.VariableNames as string[]) {
- if (global.StartsWith("Qt5Version", StringComparison.Ordinal) && envPro.Globals.get_VariablePersists(global))
+ if (global.StartsWith("Qt5Version", StringComparison.Ordinal)
+ && envPro.Globals.get_VariablePersists(global)) {
return true;
+ }
}
return false;
}
/// <summary>
- /// Returns true if the specified project is a Qt Project.
+ /// Return true if the project is a Qt project; false otherwise.
/// </summary>
/// <param name="proj">project</param>
public static bool IsQtProject(Project proj)
{
- try {
- if (proj != null && proj.Kind == "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")
- return IsQtProject(proj.Object as VCProject);
- } catch { }
- return false;
+ ThreadHelper.ThrowIfNotOnUIThread(); //C++ Project Type GUID
+ if (proj == null || proj.Kind != "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")
+ return false;
+ return IsQtProject(proj.Object as VCProject);
}
/// <summary>
- /// Return true if the project is a QMake -tp vc project, otherwise false.
+ /// Return true if the project is a Qt project; false otherwise.
/// </summary>
/// <param name="proj">project</param>
- /// <returns></returns>
- public static bool IsQMakeProject(VCProject proj)
+ public static bool IsQtProject(VCProject proj)
{
if (proj == null)
return false;
var keyword = proj.keyword;
- if (keyword == null ||
- (!keyword.StartsWith(Resources.qtProjectV2Keyword, StringComparison.Ordinal)
- && !keyword.StartsWith(Resources.qtProjectKeyword, StringComparison.Ordinal))) {
+ if (string.IsNullOrEmpty(keyword))
return false;
- }
-
- return true;
- }
-
- /// <summary>
- /// Returns true if the specified project is a QMake -tp vc Project.
- /// </summary>
- /// <param name="proj">project</param>
- public static bool IsQMakeProject(Project proj)
- {
- try {
- if (proj != null && proj.Kind == "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")
- return IsQMakeProject(proj.Object as VCProject);
- } catch { }
- return false;
- }
-
- public static void CleanupQMakeDependencies(Project project)
- {
- var vcPro = (VCProject)project.Object;
- // clean up qmake mess
- var rxp1 = new Regex("\\bQt\\w+d?5?\\.lib\\b");
- var rxp2 = new Regex("\\bQAx\\w+\\.lib\\b");
- var rxp3 = new Regex("\\bqtmaind?.lib\\b");
- var rxp4 = new Regex("\\benginiod?.lib\\b");
- foreach (VCConfiguration cfg in (IVCCollection)vcPro.Configurations) {
- var linker = (VCLinkerTool)((IVCCollection)cfg.Tools).Item("VCLinkerTool");
- if (linker == null || linker.AdditionalDependencies == null)
- continue;
- var linkerWrapper = new LinkerToolWrapper(linker);
- var deps = linkerWrapper.AdditionalDependencies;
- var newDeps = new List<string>();
- foreach (var lib in deps) {
- var m1 = rxp1.Match(lib);
- var m2 = rxp2.Match(lib);
- var m3 = rxp3.Match(lib);
- var m4 = rxp4.Match(lib);
- if (m1.Success)
- newDeps.Add(m1.ToString());
- else if (m2.Success)
- newDeps.Add(m2.ToString());
- else if (m3.Success)
- newDeps.Add(m3.ToString());
- else if (m4.Success)
- newDeps.Add(m4.ToString());
- else
- newDeps.Add(lib);
- }
- // Remove Duplicates
- var uniques = new Dictionary<string, int>();
- foreach (var dep in newDeps)
- uniques[dep] = 1;
- var uniqueList = new List<string>(uniques.Keys);
- linkerWrapper.AdditionalDependencies = uniqueList;
- }
+ return keyword.StartsWith(Resources.qtProjectKeyword, StringComparison.Ordinal)
+ || keyword.StartsWith(Resources.qtProjectV2Keyword, StringComparison.Ordinal);
}
/// <summary>
@@ -951,6 +625,30 @@
}
}
+ /// <summary>
+ /// Converts all directory separators of the path to the alternate character
+ /// directory separator. For instance, FromNativeSeparators("c:\\winnt\\system32")
+ /// returns "c:/winnt/system32".
+ /// </summary>
+ /// <param name="path">The path to convert.</param>
+ /// <returns>Returns path using '/' as file separator.</returns>
+ public static string FromNativeSeparators(string path)
+ {
+ return path.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
+ }
+
+ /// <summary>
+ /// Converts all alternate directory separators characters of the path to the native
+ /// directory separator. For instance, ToNativeSeparators("c:/winnt/system32")
+ /// returns "c:\\winnt\\system32".
+ /// </summary>
+ /// <param name="path">The path to convert.</param>
+ /// <returns>Returns path using '\' as file separator.</returns>
+ public static string ToNativeSeparator(string path)
+ {
+ return path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
+ }
+
public static string ChangePathFormat(string path)
{
return path.Replace('\\', '/');
@@ -981,6 +679,8 @@
public static void CollapseFilter(UIHierarchyItem item, UIHierarchy hierarchy, string nodeToCollapseFilter)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (string.IsNullOrEmpty(nodeToCollapseFilter))
return;
@@ -994,6 +694,8 @@
public static void CollapseFilter(UIHierarchyItem item, UIHierarchy hierarchy)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var subItems = item.UIHierarchyItems;
if (subItems != null) {
foreach (UIHierarchyItem innerItem in subItems) {
@@ -1042,7 +744,7 @@
public static List<string> GetProjectFiles(Project pro, FilesToList filter)
{
- var fileList = new List<string>();
+ ThreadHelper.ThrowIfNotOnUIThread();
VCProject vcpro;
try {
@@ -1052,6 +754,7 @@
return null;
}
+ var fileList = new List<string>();
var configurationName = pro.ConfigurationManager.ActiveConfiguration.ConfigurationName;
foreach (VCFile vcfile in (IVCCollection)vcpro.Files) {
@@ -1120,21 +823,24 @@
/// <param name="fileName"></param>
public static void RemoveFileInProject(VCProject vcpro, string fileName)
{
- var qtProj = QtProject.Create(vcpro);
- var fi = new FileInfo(fileName);
+ ThreadHelper.ThrowIfNotOnUIThread();
+ fileName = new FileInfo(fileName).FullName;
foreach (VCFile vcfile in (IVCCollection)vcpro.Files) {
- if (vcfile.FullPath.ToLower() == fi.FullName.ToLower()) {
+ if (vcfile.FullPath.Equals(fileName, StringComparison.OrdinalIgnoreCase)) {
vcpro.RemoveFile(vcfile);
- qtProj.MoveFileToDeletedFolder(vcfile);
+ QtProject.Create(vcpro)?.MoveFileToDeletedFolder(vcfile);
}
}
}
public static Project GetSelectedProject(DTE dteObject)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (dteObject == null)
return null;
+
Array prjs = null;
try {
prjs = (Array)dteObject.ActiveSolutionProjects;
@@ -1146,30 +852,23 @@
return null;
// don't handle multiple selection... use the first one
- if (prjs.GetValue(0) is Project)
- return (Project)prjs.GetValue(0);
+ if (prjs.GetValue(0) is Project project)
+ return project;
return null;
}
public static Project GetActiveDocumentProject(DTE dteObject)
{
- if (dteObject == null)
- return null;
- var doc = dteObject.ActiveDocument;
- if (doc == null)
- return null;
-
- if (doc.ProjectItem == null)
- return null;
-
- return doc.ProjectItem.ContainingProject;
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return dteObject?.ActiveDocument?.ProjectItem?.ContainingProject;
}
public static Project GetSingleProjectInSolution(DTE dteObject)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var projectList = ProjectsInSolution(dteObject);
- if (dteObject == null || dteObject.Solution == null ||
- projectList.Count != 1)
+ if (projectList.Count != 1)
return null; // no way to know which one to select
return projectList[0];
@@ -1182,22 +881,24 @@
/// </summary>
public static Project GetSelectedQtProject(DTE dteObject)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
// can happen sometimes shortly after starting VS
- if (dteObject == null || dteObject.Solution == null
- || ProjectsInSolution(dteObject).Count == 0)
+ if (ProjectsInSolution(dteObject).Count == 0)
return null;
- Project pro;
-
- if ((pro = GetSelectedProject(dteObject)) == null) {
+ var pro = GetSelectedProject(dteObject);
+ if (pro == null) {
if ((pro = GetSingleProjectInSolution(dteObject)) == null)
pro = GetActiveDocumentProject(dteObject);
}
- return IsQtProject(pro) ? pro : null;
+ return IsVsToolsProject(pro) ? pro : null;
}
public static VCFile[] GetSelectedFiles(DTE dteObject)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (GetSelectedQtProject(dteObject) == null)
return null;
@@ -1239,6 +940,8 @@
public static RccOptions ParseRccOptions(string cmdLine, VCFile qrcFile)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var pro = VCProjectToProject((VCProject)qrcFile.project);
var rccOpts = new RccOptions(pro, qrcFile);
@@ -1261,11 +964,17 @@
public static Project VCProjectToProject(VCProject vcproj)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
return (Project)vcproj.Object;
}
public static List<Project> ProjectsInSolution(DTE dteObject)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (dteObject == null)
+ return new List<Project>();
+
var projects = new List<Project>();
var solution = dteObject.Solution;
if (solution != null) {
@@ -1287,6 +996,8 @@
private static void addSubProjects(Project prj, ref List<Project> projects)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
// If the actual object of the project is null then the project was probably unloaded.
if (prj.Object == null)
return;
@@ -1303,6 +1014,8 @@
private static void addSubProjects(ProjectItems subItems, ref List<Project> projects)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (subItems == null)
return;
@@ -1393,21 +1106,6 @@
return true;
}
- public static string FindFileInPATH(string fileName)
- {
- var envPATH = Environment.ExpandEnvironmentVariables("%PATH%");
- var directories = envPATH.Split(';');
- foreach (var directory in directories) {
- var fullFilePath = directory;
- if (!fullFilePath.EndsWith("\\", StringComparison.Ordinal))
- fullFilePath += '\\';
- fullFilePath += fileName;
- if (File.Exists(fullFilePath))
- return fullFilePath;
- }
- return null;
- }
-
/// <summary>
/// This method copies the specified directory and all its child directories and files to
/// the specified destination. The destination directory is created if it does not exist.
@@ -1453,13 +1151,14 @@
string platformName,
string filePath = null)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (project == null
|| string.IsNullOrEmpty(configName)
|| string.IsNullOrEmpty(platformName))
return false;
var vcProject = project.Object as VCProject;
-
if (filePath == null) {
var vcConfig = (from VCConfiguration _config
in (IVCCollection)vcProject.Configurations
@@ -1503,12 +1202,10 @@
VCProject vcProj = null;
VCFile vcFile = null;
string configName = "", platformName = "";
- var vcConfig = config as VCConfiguration;
- if (vcConfig != null) {
+ if (config is VCConfiguration vcConfig) {
vcProj = vcConfig.project as VCProject;
configName = vcConfig.ConfigurationName;
- var vcPlatform = vcConfig.Platform as VCPlatform;
- if (vcPlatform != null)
+ if (vcConfig.Platform is VCPlatform vcPlatform)
platformName = vcPlatform.Name;
try {
expanded = vcConfig.Evaluate(expanded);
@@ -1520,11 +1217,9 @@
vcFile = vcFileConfig.File as VCFile;
if (vcFile != null)
vcProj = vcFile.project as VCProject;
- var vcProjConfig = vcFileConfig.ProjectConfiguration as VCConfiguration;
- if (vcProjConfig != null) {
+ if (vcFileConfig.ProjectConfiguration is VCConfiguration vcProjConfig) {
configName = vcProjConfig.ConfigurationName;
- var vcPlatform = vcProjConfig.Platform as VCPlatform;
- if (vcPlatform != null)
+ if (vcProjConfig.Platform is VCPlatform vcPlatform)
platformName = vcPlatform.Name;
}
try {
@@ -1637,6 +1332,7 @@
return true;
}
+#if VS2017
private static string GetRegistrySoftwareString(string subKeyName, string valueName)
{
var keyName = new StringBuilder();
@@ -1644,28 +1340,25 @@
if (System.Environment.Is64BitOperatingSystem && IntPtr.Size == 4)
keyName.Append(@"WOW6432Node\");
keyName.Append(subKeyName);
-
try {
using (var key = Registry.LocalMachine.OpenSubKey(keyName.ToString(), false)) {
if (key == null)
return ""; //key not found
-
RegistryValueKind valueKind = key.GetValueKind(valueName);
if (valueKind != RegistryValueKind.String
&& valueKind != RegistryValueKind.ExpandString) {
return ""; //wrong value kind
}
-
Object objValue = key.GetValue(valueName);
if (objValue == null)
return ""; //error getting value
-
return objValue.ToString();
}
} catch {
return "";
}
}
+#endif
public static string GetWindows10SDKVersion()
{
@@ -1713,11 +1406,6 @@
string vcPath = Path.Combine(vsPath, "VC");
#endif
return vcPath;
- }
-
- public static bool SetVCVars(ProcessStartInfo startInfo)
- {
- return SetVCVars(null, startInfo);
}
public static bool SetVCVars(VersionInformation VersionInfo, ProcessStartInfo startInfo)
@@ -1820,8 +1508,21 @@
}
}
}
+
+ // Get PATH
string envPath = startInfo.EnvironmentVariables["PATH"];
- string clPath = envPath.Split(';')
+
+ // Remove invalid chars
+ envPath = string.Join("", envPath.Split(Path.GetInvalidPathChars()));
+
+ // Split into list of paths
+ var paths = envPath
+ .Split(';')
+ .Where(x => !string.IsNullOrEmpty(x))
+ .Select(x => x.Trim());
+
+ // Check if cl.exe is in PATH
+ string clPath = paths
.Select(path => Path.Combine(path, "cl.exe"))
.Where(pathToCl => File.Exists(pathToCl))
.FirstOrDefault();
@@ -1872,12 +1573,6 @@
} else {
return canonicalPath;
}
- }
-
- public static bool PathEquals(string path1, string path2)
- {
- return (CanonicalPath(path1).Equals(CanonicalPath(path2),
- StringComparison.InvariantCultureIgnoreCase));
}
public static bool PathIsRelativeTo(string path, string subPath)
diff --git a/QtVsTools.Core/Legacy/QtProject.cs b/QtVsTools.Core/Legacy/QtProject.cs
new file mode 100644
index 0000000..0d02208
--- /dev/null
+++ b/QtVsTools.Core/Legacy/QtProject.cs
@@ -0,0 +1,290 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using EnvDTE;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
+
+namespace QtVsTools.Core.Legacy
+{
+ using Core;
+
+ public static class QtProject
+ {
+ public static void MarkAsDesignerPluginProject(Core.QtProject qtPro)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ qtPro.Project.Globals["IsDesignerPlugin"] = true.ToString();
+ if (!qtPro.Project.Globals.get_VariablePersists("IsDesignerPlugin"))
+ qtPro.Project.Globals.set_VariablePersists("IsDesignerPlugin", true);
+ }
+
+ public static bool PromptChangeQtVersion(Project project, string oldVersion, string newVersion)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ var versionManager = Core.QtVersionManager.The();
+ var viOld = versionManager.GetVersionInfo(oldVersion);
+ var viNew = versionManager.GetVersionInfo(newVersion);
+
+ if (viOld == null || viNew == null)
+ return true;
+
+ var oldIsWinRt = viOld.isWinRT();
+ var newIsWinRt = viNew.isWinRT();
+
+ if (newIsWinRt == oldIsWinRt || newIsWinRt == IsWinRT(project))
+ return true;
+
+ var caption = string.Format("Change Qt Version ({0})", project.Name);
+ var text = string.Format(
+ "Changing Qt version from {0} to {1}.\r\n" +
+ "Project might not build. Are you sure?",
+ newIsWinRt ? "Win32" : "WinRT",
+ newIsWinRt ? "WinRT" : "Win32"
+ );
+
+ return MessageBox.Show(text, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
+ == DialogResult.Yes;
+ }
+
+ public static bool HasModule(Project project, int id, string qtVersion = null)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ var foundInIncludes = false;
+ var foundInLibs = false;
+
+ var vm = Core.QtVersionManager.The();
+ var versionInfo = qtVersion != null ? vm.GetVersionInfo(qtVersion)
+ : vm.GetVersionInfo(project);
+ if (versionInfo == null)
+ versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
+ if (versionInfo == null)
+ return false; // neither a default or project Qt version
+ var info = QtModules.Instance.Module(id, versionInfo.qtMajor);
+ if (info == null)
+ return false;
+
+ var vcPro = project.Object as VCProject;
+ foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
+ var compiler = CompilerToolWrapper.Create(config);
+ var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
+
+ if (compiler != null) {
+ if (compiler.GetAdditionalIncludeDirectories() == null)
+ continue;
+ var incPathList = info.GetIncludePath();
+ var includeDirs = compiler.GetAdditionalIncludeDirectoriesList();
+ foundInIncludes = (incPathList.Count > 0);
+ foreach (var incPath in incPathList) {
+ var fixedIncludeDir = FixFilePathForComparison(incPath);
+ if (!includeDirs.Any(dir =>
+ FixFilePathForComparison(dir) == fixedIncludeDir)) {
+ foundInIncludes = false;
+ break;
+ }
+ }
+ }
+
+ if (foundInIncludes)
+ break;
+
+ List<string> libs = null;
+ if (linker != null) {
+ var linkerWrapper = new LinkerToolWrapper(linker);
+ libs = linkerWrapper.AdditionalDependencies;
+ }
+
+ if (libs != null) {
+ var moduleLibs = info.GetLibs(IsDebugConfiguration(config), versionInfo);
+ foundInLibs = moduleLibs.All(moduleLib => libs.Contains(moduleLib));
+ }
+ }
+ return foundInIncludes || foundInLibs;
+ }
+
+ public static void AddModule(Project project, int id)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (HasModule(project, id))
+ return;
+
+ var vm = Core.QtVersionManager.The();
+ var versionInfo = vm.GetVersionInfo(project);
+ if (versionInfo == null)
+ versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
+
+ var vcPro = project.Object as VCProject;
+ foreach (VCConfiguration config in vcPro.Configurations as IVCCollection) {
+
+ var info = QtModules.Instance.Module(id, versionInfo.qtMajor);
+ if (Core.QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_Settings) {
+ var config3 = config as VCConfiguration3;
+ if (config3 == null)
+ continue;
+ if (!string.IsNullOrEmpty(info.proVarQT)) {
+ var qtModulesValue = config.GetUnevaluatedPropertyValue("QtModules");
+ var qtModules = new HashSet<string>(
+ !string.IsNullOrEmpty(qtModulesValue)
+ ? qtModulesValue.Split(';')
+ : new string[] { });
+ qtModules.UnionWith(info.proVarQT.Split(' '));
+ config3.SetPropertyValue(Resources.projLabelQtSettings, true,
+ "QtModules", string.Join(";", qtModules));
+ }
+ // In V3 project format, compiler and linker options
+ // required by modules are set by Qt/MSBuild.
+ continue;
+ }
+
+ var compiler = CompilerToolWrapper.Create(config);
+ var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
+
+ if (compiler != null) {
+ foreach (var define in info.Defines)
+ compiler.AddPreprocessorDefinition(define);
+
+ var incPathList = info.GetIncludePath();
+ foreach (var incPath in incPathList)
+ compiler.AddAdditionalIncludeDirectories(incPath);
+ }
+ if (linker != null) {
+ var moduleLibs = info.GetLibs(IsDebugConfiguration(config), versionInfo);
+ var linkerWrapper = new LinkerToolWrapper(linker);
+ var additionalDeps = linkerWrapper.AdditionalDependencies;
+ var dependenciesChanged = false;
+ if (additionalDeps == null || additionalDeps.Count == 0) {
+ additionalDeps = moduleLibs;
+ dependenciesChanged = true;
+ } else {
+ foreach (var moduleLib in moduleLibs) {
+ if (!additionalDeps.Contains(moduleLib)) {
+ additionalDeps.Add(moduleLib);
+ dependenciesChanged = true;
+ }
+ }
+ }
+ if (dependenciesChanged)
+ linkerWrapper.AdditionalDependencies = additionalDeps;
+ }
+ }
+ }
+
+ public static void RemoveModule(Project project, int id)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ var vm = Core.QtVersionManager.The();
+ var versionInfo = vm.GetVersionInfo(project);
+ if (versionInfo == null)
+ versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
+
+ var vcPro = project.Object as VCProject;
+ foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
+ var compiler = CompilerToolWrapper.Create(config);
+ var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
+
+ var info = QtModules.Instance.Module(id, versionInfo.qtMajor);
+ if (compiler != null) {
+ foreach (var define in info.Defines)
+ compiler.RemovePreprocessorDefinition(define);
+ var additionalIncludeDirs = compiler.AdditionalIncludeDirectories;
+ if (additionalIncludeDirs != null) {
+ var lst = new List<string>(additionalIncludeDirs);
+ foreach (var includePath in info.IncludePath) {
+ lst.Remove(includePath);
+ lst.Remove('\"' + includePath + '\"');
+ }
+ compiler.AdditionalIncludeDirectories = lst;
+ }
+ }
+ if (linker != null && linker.AdditionalDependencies != null) {
+ var linkerWrapper = new LinkerToolWrapper(linker);
+ var moduleLibs = info.GetLibs(IsDebugConfiguration(config), versionInfo);
+ var additionalDependencies = linkerWrapper.AdditionalDependencies;
+ var dependenciesChanged = false;
+ foreach (var moduleLib in moduleLibs)
+ dependenciesChanged |= additionalDependencies.Remove(moduleLib);
+ if (dependenciesChanged)
+ linkerWrapper.AdditionalDependencies = additionalDependencies;
+ }
+ }
+ }
+
+ internal static bool IsDesignerPluginProject(Core.QtProject qtPro)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ var b = false;
+ if (qtPro.Project.Globals.get_VariablePersists("IsDesignerPlugin")) {
+ var s = qtPro.Project.Globals["IsDesignerPlugin"] as string;
+ try {
+ b = bool.Parse(s);
+ } catch { }
+ }
+ return b;
+ }
+
+
+ private static bool IsWinRT(Project project)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ try {
+ var vcProject = project.Object as VCProject;
+ var vcConfigs = vcProject.Configurations as IVCCollection;
+ var vcConfig = vcConfigs.Item(1) as VCConfiguration;
+ var appType = vcConfig.GetEvaluatedPropertyValue("ApplicationType");
+ if (appType == "Windows Store")
+ return true;
+ } catch { }
+ return false;
+ }
+
+ private static string FixFilePathForComparison(string path)
+ {
+ return HelperFunctions.NormalizeRelativeFilePath(path).ToLower();
+ }
+
+ private static bool IsDebugConfiguration(VCConfiguration conf)
+ {
+ var tool = CompilerToolWrapper.Create(conf);
+ if (tool != null) {
+ return tool.RuntimeLibrary == runtimeLibraryOption.rtMultiThreadedDebug
+ || tool.RuntimeLibrary == runtimeLibraryOption.rtMultiThreadedDebugDLL;
+ }
+ return false;
+ }
+ }
+}
diff --git a/QtVsTools.Core/Legacy/QtVSIPSettings.cs b/QtVsTools.Core/Legacy/QtVSIPSettings.cs
new file mode 100644
index 0000000..b54940d
--- /dev/null
+++ b/QtVsTools.Core/Legacy/QtVSIPSettings.cs
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using Microsoft.VisualStudio.Shell;
+using QtVsTools.Common;
+
+namespace QtVsTools.Core.Legacy
+{
+ public static class QtVSIPSettings
+ {
+ #region UIC
+
+ public static string GetUicDirectory(EnvDTE.Project project)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return QtVSIPSettingsShared.GetDirectory(project, Resources.uicDirKeyword);
+ }
+
+ public static void SaveUicDirectory(EnvDTE.Project project, string directory)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (directory == null)
+ directory = QtVSIPSettingsShared.GetDirectory(project, Resources.uicDirKeyword);
+ SaveDirectory(project, Resources.uicDirKeyword, directory);
+ }
+ #endregion
+
+ #region MOC
+
+ public static string GetMocDirectory(EnvDTE.Project project)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return QtVSIPSettingsShared.GetDirectory(project, Resources.mocDirKeyword);
+ }
+
+ public static void SaveMocDirectory(EnvDTE.Project project, string directory)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (directory == null)
+ directory = QtVSIPSettingsShared.GetDirectory(project, Resources.mocDirKeyword);
+ SaveDirectory(project, Resources.mocDirKeyword, directory);
+ }
+
+ public static string GetMocOptions()
+ {
+ return QtVSIPSettingsShared.GetOption(Resources.mocOptionsKeyword);
+ }
+
+ public static string GetMocOptions(EnvDTE.Project project)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return QtVSIPSettingsShared.GetOption(project, Resources.mocOptionsKeyword);
+ }
+
+ public static void SaveMocOptions(EnvDTE.Project project, string options)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (options == null)
+ options = GetMocOptions();
+
+ SaveOption(project, Resources.mocOptionsKeyword, options);
+ }
+ #endregion
+
+ #region LUpdate
+
+ public static bool GetLUpdateOnBuild(EnvDTE.Project project)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (QtVSIPSettingsShared.GetProjectQtSetting(project, "QtRunLUpdateOnBuild") == "true")
+ return true;
+ return QtVSIPSettingsShared.GetBoolValue(project, Resources.lupdateKeyword);
+ }
+
+ public static void SaveLUpdateOnBuild(EnvDTE.Project project, bool value)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ SetBoolValue(project, Resources.lupdateKeyword, value);
+ }
+
+ public static string GetLUpdateOptions()
+ {
+ return QtVSIPSettingsShared.GetOption(Resources.lupdateOptionsKeyword);
+ }
+
+ public static string GetLUpdateOptions(EnvDTE.Project project)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ string qtLUpdateOptions = QtVSIPSettingsShared.GetProjectQtSetting(project, "QtLUpdateOptions");
+ if (!string.IsNullOrEmpty(qtLUpdateOptions))
+ return qtLUpdateOptions;
+ return QtVSIPSettingsShared.GetOption(project, Resources.lupdateOptionsKeyword);
+ }
+
+ public static void SaveLUpdateOptions(EnvDTE.Project project, string options)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (options == null)
+ options = GetLUpdateOptions();
+
+ SaveOption(project, Resources.lupdateOptionsKeyword, options);
+ }
+ #endregion
+
+ #region LRelease
+
+ public static string GetLReleaseOptions()
+ {
+ return QtVSIPSettingsShared.GetOption(Resources.lreleaseOptionsKeyword);
+ }
+
+ public static string GetLReleaseOptions(EnvDTE.Project project)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ string qtLReleaseOptions = QtVSIPSettingsShared.GetProjectQtSetting(project, "QtLReleaseOptions");
+ if (!string.IsNullOrEmpty(qtLReleaseOptions))
+ return qtLReleaseOptions;
+ return QtVSIPSettingsShared.GetOption(project, Resources.lreleaseOptionsKeyword);
+ }
+
+ public static void SaveLReleaseOptions(EnvDTE.Project project, string options)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (options == null)
+ options = GetLReleaseOptions();
+
+ SaveOption(project, Resources.lreleaseOptionsKeyword, options);
+ }
+ #endregion
+
+ #region RCC
+
+ public static string GetRccDirectory(EnvDTE.Project project)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return QtVSIPSettingsShared.GetDirectory(project, Resources.rccDirKeyword);
+ }
+
+ public static void SaveRccDirectory(EnvDTE.Project project, string directory)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (directory == null)
+ directory = QtVSIPSettingsShared.GetDirectory(project, Resources.rccDirKeyword);
+ SaveDirectory(project, Resources.rccDirKeyword, directory);
+ }
+ #endregion
+
+ #region QML
+
+ public static bool GetQmlDebug(EnvDTE.Project project)
+ {
+ return Core.QtProject.Create(project).QmlDebug;
+ }
+
+ public static void SaveQmlDebug(EnvDTE.Project project, bool enabled)
+ {
+ Core.QtProject.Create(project).QmlDebug = enabled;
+ }
+ #endregion
+
+ private static void SaveDirectory(EnvDTE.Project project, string type, string dir)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ dir = HelperFunctions.NormalizeRelativeFilePath(dir);
+ project.Globals[type] = dir;
+ if (!project.Globals.get_VariablePersists(type))
+ project.Globals.set_VariablePersists(type, true);
+
+ QtVSIPSettingsShared.CleanUpCache(project);
+ }
+
+ private static void SaveOption(EnvDTE.Project project, string type, string option)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ project.Globals[type] = option;
+ if (!project.Globals.get_VariablePersists(type))
+ project.Globals.set_VariablePersists(type, true);
+ }
+
+ private static void SetBoolValue(EnvDTE.Project project, string type, bool value)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ project.Globals[type] = Convert.ToInt32(value).ToString();
+ if (!project.Globals.get_VariablePersists(type))
+ project.Globals.set_VariablePersists(type, true);
+ }
+ }
+}
diff --git a/QtVsTools.Core/Legacy/QtVersionManager.cs b/QtVsTools.Core/Legacy/QtVersionManager.cs
new file mode 100644
index 0000000..940dbea
--- /dev/null
+++ b/QtVsTools.Core/Legacy/QtVersionManager.cs
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using Microsoft.VisualStudio.Shell;
+
+namespace QtVsTools.Core.Legacy
+{
+ public static class QtVersionManager
+ {
+ public static string GetSolutionQtVersion(EnvDTE.Solution solution)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (solution == null)
+ return null;
+
+ if (solution.Globals.get_VariableExists("Qt5Version")) {
+ var version = (string)solution.Globals["Qt5Version"];
+ return Core.QtVersionManager.The().VerifyIfQtVersionExists(version) ? version : null;
+ }
+
+ return null;
+ }
+
+ public static bool SaveSolutionQtVersion(EnvDTE.Solution solution, string version)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (!Core.QtVersionManager.The().IsVersionAvailable(version) && version != "$(DefaultQtVersion)")
+ return false;
+
+ solution.Globals["Qt5Version"] = version;
+ if (!solution.Globals.get_VariablePersists("Qt5Version"))
+ solution.Globals.set_VariablePersists("Qt5Version", true);
+ return true;
+ }
+ }
+}
diff --git a/QtVsTools.Core/LinkerToolWrapper.cs b/QtVsTools.Core/LinkerToolWrapper.cs
index cc57a34..7db3506 100644
--- a/QtVsTools.Core/LinkerToolWrapper.cs
+++ b/QtVsTools.Core/LinkerToolWrapper.cs
@@ -26,11 +26,11 @@
**
****************************************************************************/
-using Microsoft.VisualStudio.VCProjectEngine;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
+using Microsoft.VisualStudio.VCProjectEngine;
namespace QtVsTools.Core
{
@@ -39,7 +39,7 @@
/// </summary>
public class LinkerToolWrapper
{
- private VCLinkerTool linker;
+ private readonly VCLinkerTool linker;
public LinkerToolWrapper(VCLinkerTool linkerTool)
{
diff --git a/QtVsTools.Core/MainWinWrapper.cs b/QtVsTools.Core/MainWinWrapper.cs
index f42ca31..2da7105 100644
--- a/QtVsTools.Core/MainWinWrapper.cs
+++ b/QtVsTools.Core/MainWinWrapper.cs
@@ -28,30 +28,18 @@
using System;
using System.Windows.Forms;
+using Microsoft.VisualStudio.Shell;
namespace QtVsTools.Core
{
public class MainWinWrapper : IWin32Window
{
- private readonly EnvDTE.DTE dteObject;
+ public IntPtr Handle { get; }
public MainWinWrapper(EnvDTE.DTE dte)
{
- dteObject = dte;
- }
-
- public IntPtr Handle
- {
- get
- {
- if (dteObject != null)
-#if VS2022
- return dteObject.MainWindow.HWnd;
-#else
- return new IntPtr(dteObject.MainWindow.HWnd);
-#endif
- return new IntPtr(0);
- }
+ ThreadHelper.ThrowIfNotOnUIThread();
+ Handle = new IntPtr((long)dte.MainWindow.HWnd);
}
}
}
diff --git a/QtVsTools.Core/Messages.cs b/QtVsTools.Core/Messages.cs
index c5eea32..507bcbb 100644
--- a/QtVsTools.Core/Messages.cs
+++ b/QtVsTools.Core/Messages.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,34 +26,25 @@
**
****************************************************************************/
-using EnvDTE;
+using System;
using System.Collections.Concurrent;
-using System.Diagnostics;
-using System.Linq;
using System.Threading;
-using Thread = System.Threading.Thread;
using System.Windows.Forms;
-using System.Threading.Tasks;
+using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Threading;
-using QtVsTools.VisualStudio;
+
+using Task = System.Threading.Tasks.Task;
namespace QtVsTools.Core
{
+ using VisualStudio;
+
public static class Messages
{
- private static OutputWindow Window { get; set; }
private static OutputWindowPane Pane { get; set; }
- private static OutputWindowPane _BuildPane;
- private static OutputWindowPane BuildPane
- {
- get
- {
- return _BuildPane ?? (_BuildPane = Window.OutputWindowPanes.Cast<OutputWindowPane>()
- .Where(pane => pane.Guid == "{1BD8A850-02D1-11D1-BEE7-00A0C913D1F8}")
- .FirstOrDefault());
- }
- }
+ private static readonly string PaneName = "Qt VS Tools";
+ private static readonly Guid PaneGuid = new Guid("8f6a1e44-fa0b-49e5-9934-1c050555350e");
/// <summary>
/// Show a message on the output pane.
@@ -69,13 +60,15 @@
FlushMessages();
}
- static void OutputWindowPane_Print(string text)
+ public static void Log(this Exception exception, bool clear = false, bool activate = false)
{
- OutputWindowPane_Init();
- Pane.OutputString(text + "\r\n");
- // show buildPane if a build is in progress
- if (Dte.Solution.SolutionBuild.BuildState == vsBuildState.vsBuildStateInProgress)
- BuildPane?.Activate();
+ msgQueue.Enqueue(new Msg()
+ {
+ Clear = clear,
+ Text = ExceptionToString(exception),
+ Activate = activate
+ });
+ FlushMessages();
}
/// <summary>
@@ -90,50 +83,44 @@
FlushMessages();
}
- static void OutputWindowPane_Activate()
+ static async Task OutputWindowPane_ActivateAsync()
{
- OutputWindowPane_Init();
- Pane?.Activate();
+ await OutputWindowPane_InitAsync();
+ await Pane?.ActivateAsync();
}
- private static string ExceptionToString(System.Exception e)
+ private static string ExceptionToString(System.Exception exception)
{
- return e.Message + "\r\n" + "(" + e.StackTrace.Trim() + ")";
+ return $"An exception ({exception.GetType().Name}) occurred.\r\n"
+ + $"Message:\r\n {exception.Message}\r\n"
+ + $"Stack Trace:\r\n {exception.StackTrace.Trim()}\r\n";
}
private static readonly string ErrorString = SR.GetString("Messages_ErrorOccured");
private static readonly string WarningString = SR.GetString("Messages_Warning");
private static readonly string SolutionString = SR.GetString("Messages_SolveProblem");
- static public void DisplayCriticalErrorMessage(System.Exception e)
- {
- MessageBox.Show(ErrorString +
- ExceptionToString(e),
- SR.GetString("Resources_QtVsTools"), MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
-
- static public void DisplayCriticalErrorMessage(string msg)
+ public static void DisplayCriticalErrorMessage(string msg)
{
MessageBox.Show(ErrorString +
msg,
SR.GetString("Resources_QtVsTools"), MessageBoxButtons.OK, MessageBoxIcon.Error);
}
- static public void DisplayErrorMessage(System.Exception e)
+ public static void DisplayErrorMessage(System.Exception e)
{
- MessageBox.Show(ErrorString +
- ExceptionToString(e),
+ MessageBox.Show(ExceptionToString(e),
SR.GetString("Resources_QtVsTools"), MessageBoxButtons.OK, MessageBoxIcon.Error);
}
- static public void DisplayErrorMessage(string msg)
+ public static void DisplayErrorMessage(string msg)
{
MessageBox.Show(ErrorString +
msg,
SR.GetString("Resources_QtVsTools"), MessageBoxButtons.OK, MessageBoxIcon.Error);
}
- static public void DisplayWarningMessage(System.Exception e, string solution)
+ public static void DisplayWarningMessage(System.Exception e, string solution)
{
MessageBox.Show(WarningString +
ExceptionToString(e) +
@@ -142,7 +129,7 @@
SR.GetString("Resources_QtVsTools"), MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
- static public void DisplayWarningMessage(string msg)
+ public static void DisplayWarningMessage(string msg)
{
MessageBox.Show(WarningString +
msg,
@@ -158,10 +145,10 @@
FlushMessages();
}
- static void OutputWindowPane_Clear()
+ static async Task OutputWindowPane_ClearAsync()
{
- OutputWindowPane_Init();
- Pane?.Clear();
+ await OutputWindowPane_InitAsync();
+ await Pane?.ClearAsync();
}
class Msg
@@ -171,33 +158,20 @@
public bool Activate { get; set; } = false;
}
- static bool shuttingDown = false;
- static ConcurrentQueue<Msg> msgQueue = new ConcurrentQueue<Msg>();
- static DTE Dte { get; set; } = null;
+ static readonly ConcurrentQueue<Msg> msgQueue = new ConcurrentQueue<Msg>();
- private static void OnBeginShutdown()
+ private static async Task OutputWindowPane_InitAsync()
{
- shuttingDown = true;
- }
-
- private static void OutputWindowPane_Init()
- {
- if (Dte == null)
- Dte = VsServiceProvider.GetService<DTE>();
- var t = Stopwatch.StartNew();
- while (Pane == null && t.ElapsedMilliseconds < 5000) {
- try {
- Window = Dte.Windows.Item(Constants.vsWindowKindOutput).Object as OutputWindow;
- Pane = Window?.OutputWindowPanes.Add(SR.GetString("Resources_QtVsTools"));
- } catch {
- }
+ try {
if (Pane == null)
- Thread.Yield();
+ Pane = await OutputWindowPane.CreateAsync(PaneName, PaneGuid);
+ } catch (Exception ex) {
+ System.Diagnostics.Debug.WriteLine(ex);
}
- Dte.Events.DTEEvents.OnBeginShutdown += OnBeginShutdown;
}
public static JoinableTaskFactory JoinableTaskFactory { get; set; }
+
static readonly object staticCriticalSection = new object();
static Task FlushTask { get; set; }
static EventWaitHandle MessageReady { get; set; }
@@ -209,27 +183,21 @@
MessageReady = new EventWaitHandle(false, EventResetMode.AutoReset);
FlushTask = Task.Run(async () =>
{
- while (!shuttingDown) {
+ var package = VsServiceProvider.Instance as Package;
+ while (!package.Zombied) {
if (!await MessageReady.ToTask(3000))
continue;
while (!msgQueue.IsEmpty) {
- Msg msg;
- if (!msgQueue.TryDequeue(out msg)) {
+ if (!msgQueue.TryDequeue(out Msg msg)) {
await Task.Yield();
continue;
}
- ////////////////////////////////////////////////////////////////////
- // Switch to main (UI) thread
- await JoinableTaskFactory.SwitchToMainThreadAsync();
if (msg.Clear)
- OutputWindowPane_Clear();
+ await OutputWindowPane_ClearAsync();
if (msg.Text != null)
- OutputWindowPane_Print(msg.Text);
+ await OutputWindowPane_PrintAsync(msg.Text);
if (msg.Activate)
- OutputWindowPane_Activate();
- ////////////////////////////////////////////////////////////////////
- // Switch to background thread
- await TaskScheduler.Default;
+ await OutputWindowPane_ActivateAsync();
}
}
});
@@ -237,5 +205,15 @@
}
MessageReady.Set();
}
+
+ static async Task OutputWindowPane_PrintAsync(string text)
+ {
+ var active = await OutputWindowPane.GetActiveAsync();
+
+ await OutputWindowPane_InitAsync();
+ await Pane.PrintAsync(text);
+
+ (active?.ActivateAsync()).Forget();
+ }
}
}
diff --git a/QtVsTools.Core/MocCmdChecker.cs b/QtVsTools.Core/MocCmdChecker.cs
index dc0df1b..16ffaba 100644
--- a/QtVsTools.Core/MocCmdChecker.cs
+++ b/QtVsTools.Core/MocCmdChecker.cs
@@ -34,8 +34,8 @@
{
class MocCmdChecker
{
- private Regex backslashRegEx = new Regex(@"\\+\.?\\+");
- private Regex endRegEx = new Regex(@"\\\.?$");
+ private readonly Regex backslashRegEx = new Regex(@"\\+\.?\\+");
+ private readonly Regex endRegEx = new Regex(@"\\\.?$");
private string NormalizePath(string path)
{
diff --git a/QtVsTools.Core/MsBuildProject.cs b/QtVsTools.Core/MsBuildProject.cs
index 3b11f34..3eff430 100644
--- a/QtVsTools.Core/MsBuildProject.cs
+++ b/QtVsTools.Core/MsBuildProject.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -30,22 +30,22 @@
using System.IO;
using System.Collections.Generic;
using System.Text;
+using System.Text.RegularExpressions;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
-using QtVsTools.Core.QtMsBuild;
-using System.Text.RegularExpressions;
using Microsoft.Build.Construction;
using Microsoft.Build.Execution;
using Microsoft.Build.Evaluation;
-using QtVsTools.VisualStudio;
-using QtVsTools.SyntaxAnalysis;
-using EnvDTE;
+using Microsoft.VisualStudio.Shell;
namespace QtVsTools.Core
{
+ using QtMsBuild;
+ using SyntaxAnalysis;
+
using static HelperFunctions;
- using static RegExpr;
+ using static SyntaxAnalysis.RegExpr;
public class MsBuildProject
{
@@ -65,7 +65,8 @@
User,
Count
}
- MsBuildXmlFile[] files = new MsBuildXmlFile[(int)Files.Count];
+
+ readonly MsBuildXmlFile[] files = new MsBuildXmlFile[(int)Files.Count];
MsBuildProject()
{
@@ -94,7 +95,7 @@
}
}
- private static XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
+ private static readonly XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
public static MsBuildProject Load(string pathToProject)
{
@@ -293,12 +294,8 @@
if (ConfigCondition == null)
return false;
- // Get default Qt dir
- string defaultQtDir = null;
var defaultVersionName = QtVersionManager.The().GetDefaultVersion();
var defaultVersion = QtVersionManager.The().GetVersionInfo(defaultVersionName);
- if (defaultVersion != null)
- defaultQtDir = defaultVersion.qtDir;
// Get project configurations
var configs = this[Files.Project].xml
@@ -314,15 +311,6 @@
.FirstOrDefault();
if (globals == null)
return false;
-
- // Get project configuration properties
- var configProps = this[Files.Project].xml
- .Elements(ns + "Project")
- .Elements(ns + "PropertyGroup")
- .Where(pg =>
- (string)pg.Attribute("Label") == "Configuration"
- && pg.Attribute("Condition") != null)
- .ToDictionary(pg => (string)pg.Attribute("Condition"));
// Set Qt project format version
var projKeyword = globals
@@ -386,10 +374,8 @@
foreach (var pg in uncategorizedPropertyGroups) {
foreach (var p in pg.Elements().ToList()) {
var condition = p.Attribute("Condition") ?? pg.Attribute("Condition");
- XElement configPropertyGroup = null;
- if (condition != null)
- propertyGroups.TryGetValue((string)condition, out configPropertyGroup);
- if (configPropertyGroup != null) {
+ if (condition != null && propertyGroups
+ .TryGetValue((string)condition, out XElement configPropertyGroup)) {
p.Remove();
p.SetAttributeValue("Condition", null);
configPropertyGroup.Add(p);
@@ -535,12 +521,10 @@
foreach (var configQtSettings in qtSettings) {
var configCondition = (string)configQtSettings.Attribute("Condition");
- XElement oldConfigQtInstall;
- if (oldQtInstall.TryGetValue(configCondition, out oldConfigQtInstall))
+ if (oldQtInstall.TryGetValue(configCondition, out XElement oldConfigQtInstall))
configQtSettings.Add(oldConfigQtInstall);
- XElement oldConfigQtSettings;
- if (oldQtSettings.TryGetValue(configCondition, out oldConfigQtSettings)) {
+ if (oldQtSettings.TryGetValue(configCondition, out XElement oldConfigQtSettings)) {
foreach (var qtSetting in oldConfigQtSettings.Elements())
configQtSettings.Add(qtSetting);
}
@@ -600,6 +584,11 @@
.Elements(ns + "ItemDefinitionGroup")
.Elements(ns + "Link");
+ var resourceCompiler = this[Files.Project].xml
+ .Elements(ns + "Project")
+ .Elements(ns + "ItemDefinitionGroup")
+ .Elements(ns + "ResourceCompile");
+
// Qt module names, to copy to QtModules property
var moduleNames = new HashSet<string>();
@@ -613,9 +602,9 @@
var moduleLibs = new HashSet<string>();
// Go through all known Qt modules and check which ones are currently being used
- foreach (var module in QtModules.Instance.GetAvailableModules()) {
+ foreach (var module in QtModules.Instance.GetAvailableModules(defaultVersion.qtMajor)) {
- if (IsModuleUsed(module, compiler, linker)) {
+ if (IsModuleUsed(module, compiler, linker, resourceCompiler)) {
// Qt module names, to copy to QtModules property
if (!string.IsNullOrEmpty(module.proVarQT))
@@ -670,6 +659,12 @@
.Select(x => Unquote(x))
// Exclude paths rooted on $(QTDIR)
.Where(x => !x.StartsWith("$(QTDIR)", IGNORE_CASE))));
+ }
+
+ // Remove Qt module macros from resource compiler properties
+ foreach (var defines in resourceCompiler.Elements(ns + "PreprocessorDefinitions")) {
+ defines.SetValue(string.Join(";", defines.Value.Split(';')
+ .Where(x => !moduleDefines.Contains(x))));
}
// Add Qt module names to QtModules project property
@@ -778,7 +773,8 @@
bool IsModuleUsed(
QtModule module,
IEnumerable<XElement> compiler,
- IEnumerable<XElement> linker)
+ IEnumerable<XElement> linker,
+ IEnumerable<XElement> resourceCompiler)
{
// Module .lib is present in linker additional dependencies
if (linker.Elements(ns + "AdditionalDependencies")
@@ -788,8 +784,15 @@
return true;
}
- // Module macro is present in pre-processor definitions
+ // Module macro is present in the compiler pre-processor definitions
if (compiler.Elements(ns + "PreprocessorDefinitions")
+ .SelectMany(x => x.Value.Split(';'))
+ .Any(x => module.Defines.Contains(x))) {
+ return true;
+ }
+
+ // Module macro is present in resource compiler pre-processor definitions
+ if (resourceCompiler.Elements(ns + "PreprocessorDefinitions")
.SelectMany(x => x.Value.Split(';'))
.Any(x => module.Defines.Contains(x))) {
return true;
@@ -958,9 +961,9 @@
commandLine = replace(row.itemName, commandLine);
//
// * Configuration/platform, e.g. x64\Debug --> $(Platform)\$(Configuration)
- commandLine = commandLine
- .Replace(configName, "$(Configuration)",
- StringComparison.InvariantCultureIgnoreCase)
+ // * ignore any word other than the expected configuration, e.g. lrelease.exe
+ commandLine = Regex.Replace(commandLine, @"\b" + configName + @"\b",
+ "$(Configuration)", RegexOptions.IgnoreCase)
.Replace(platformName, "$(Platform)",
StringComparison.InvariantCultureIgnoreCase);
@@ -969,8 +972,7 @@
evaluator.Properties.Add(configProp.Name.LocalName, (string)configProp);
if (!qtMsBuild.SetCommandLine(itemType, item, commandLine, evaluator)) {
int lineNumber = 1;
- var errorLine = row.command as IXmlLineInfo;
- if (errorLine != null && errorLine.HasLineInfo())
+ if (row.command is IXmlLineInfo errorLine && errorLine.HasLineInfo())
lineNumber = errorLine.LineNumber;
Messages.Print(string.Format(
@@ -1059,8 +1061,7 @@
return (string)cbt.Attribute("Include");
}
}
- string ouputFile;
- if (!properties.TryGetValue(QtMoc.Property.InputFile, out ouputFile))
+ if (!properties.TryGetValue(QtMoc.Property.InputFile, out string ouputFile))
return (string)cbt.Attribute("Include");
return ouputFile;
}
@@ -1085,8 +1086,7 @@
Path.IsPathRooted(x) ? x : Path.Combine(projDir, x)));
var outputItems = new List<XElement>();
foreach (var outputFile in outputFiles) {
- List<XElement> mocOutput = null;
- if (projItemsByPath.TryGetValue(outputFile, out mocOutput)) {
+ if (projItemsByPath.TryGetValue(outputFile, out List<XElement> mocOutput)) {
outputItems.AddRange(mocOutput);
hasGeneratedFiles |= hasGeneratedFiles ? true : mocOutput
.Where(x => !x.Elements(ns + "ExcludedFromBuild")
@@ -1469,17 +1469,16 @@
class MSBuildEvaluator : IVSMacroExpander, IDisposable
{
- MsBuildXmlFile projFile;
- string tempProjFilePath;
- XElement evaluateTarget;
- XElement evaluateProperty;
- ProjectRootElement projRoot;
- public Dictionary<string, string> expansionCache;
+ private readonly MsBuildXmlFile projFile;
+ private string tempProjFilePath;
+ private XElement evaluateTarget;
+ private XElement evaluateProperty;
+ private ProjectRootElement projRoot;
+ private readonly Dictionary<string, string> expansionCache;
public Dictionary<string, string> Properties
{
get;
- private set;
}
public MSBuildEvaluator(MsBuildXmlFile projFile)
@@ -1522,8 +1521,7 @@
public string ExpandString(string stringToExpand)
{
- string expandedString;
- if (TryExpansionCache(stringToExpand, out expandedString))
+ if (TryExpansionCache(stringToExpand, out string expandedString))
return expandedString;
if (evaluateTarget == null) {
@@ -1649,7 +1647,7 @@
return true;
}
- static Regex ConditionParser =
+ static readonly Regex ConditionParser =
new Regex(@"\'\$\(Configuration[^\)]*\)\|\$\(Platform[^\)]*\)\'\=\=\'([^\']+)\'");
class MsBuildConverterProvider : IPropertyStorageProvider
diff --git a/QtVsTools.Core/OutputWindowPane.cs b/QtVsTools.Core/OutputWindowPane.cs
new file mode 100644
index 0000000..1563acb
--- /dev/null
+++ b/QtVsTools.Core/OutputWindowPane.cs
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+using Microsoft.VisualStudio.Threading;
+
+using Task = System.Threading.Tasks.Task;
+
+namespace QtVsTools.Core
+{
+ using VisualStudio;
+
+ public class OutputWindowPane
+ {
+ public enum VSOutputWindowPane
+ {
+ General,
+ Build,
+ Debug,
+ }
+
+ public static Task<OutputWindowPane> GetVSOutputWindowPaneAsync(VSOutputWindowPane pane)
+ {
+ switch (pane) {
+ case VSOutputWindowPane.General:
+ return GetAsync(VSConstants.OutputWindowPaneGuid.GeneralPane_guid);
+ case VSOutputWindowPane.Build:
+ return GetAsync(VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid);
+ case VSOutputWindowPane.Debug:
+ return GetAsync(VSConstants.OutputWindowPaneGuid.DebugPane_guid);
+ default:
+ throw new InvalidOperationException("Unsupported Visual Studio output pane");
+ };
+ }
+
+ public static async Task<OutputWindowPane> GetAsync(Guid guid)
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ try {
+ IVsOutputWindow w = null;
+ if (guid == VSConstants.OutputWindowPaneGuid.GeneralPane_guid) {
+ w = await VsServiceProvider.GetServiceAsync<SVsGeneralOutputWindowPane,
+ IVsOutputWindow>();
+ } else {
+ w = await VsServiceProvider.GetServiceAsync<SVsOutputWindow, IVsOutputWindow>();
+ }
+ ErrorHandler.ThrowOnFailure(w.GetPane(guid, out IVsOutputWindowPane pane));
+
+ return new OutputWindowPane(guid, pane);
+ } catch (Exception ex) {
+ System.Diagnostics.Debug.WriteLine(ex);
+ return null;
+ }
+ }
+
+ public static async Task<OutputWindowPane> CreateAsync(string name, Guid guid)
+ {
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentNullException($"{ nameof(name) } cannot be null");
+
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ try {
+ var w = await VsServiceProvider.GetServiceAsync<SVsOutputWindow, IVsOutputWindow>();
+
+ const int visible = 1, clear = 1;
+ ErrorHandler.ThrowOnFailure(w.CreatePane(guid, name, visible, clear));
+ ErrorHandler.ThrowOnFailure(w.GetPane(guid, out IVsOutputWindowPane pane));
+
+ return new OutputWindowPane(guid, pane);
+ } catch (Exception ex) {
+ System.Diagnostics.Debug.WriteLine(ex);
+ return null;
+ }
+ }
+
+ public static async Task<OutputWindowPane> GetActiveAsync()
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ try {
+ var w2 = await VsServiceProvider
+ .GetServiceAsync<SVsOutputWindow, IVsOutputWindow>() as IVsOutputWindow2;
+ ErrorHandler.ThrowOnFailure(w2.GetActivePaneGUID(out Guid guid));
+
+ IVsOutputWindow w = w2 as IVsOutputWindow;
+ ErrorHandler.ThrowOnFailure(w.GetPane(guid, out IVsOutputWindowPane pane));
+
+ return new OutputWindowPane(guid, pane);
+ } catch (Exception ex) {
+ System.Diagnostics.Debug.WriteLine(ex);
+ return null;
+ }
+ }
+
+ private Guid Guid { get; }
+ private IVsOutputWindowPane Pane { get; set; } = null;
+
+ private OutputWindowPane(Guid guid, IVsOutputWindowPane pane)
+ {
+ Guid = guid;
+ Pane = pane;
+ }
+
+ public async Task ActivateAsync()
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ if (Pane == null)
+ throw new InvalidOperationException($"{ nameof(Pane) } cannot be null");
+ Pane.Activate();
+ }
+
+ public async Task HideAsync()
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ if (Pane == null)
+ throw new InvalidOperationException($"{ nameof(Pane) } cannot be null");
+ Pane.Hide();
+ }
+
+ public async Task ClearAsync()
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ if (Pane == null)
+ throw new InvalidOperationException($"{ nameof(Pane) } cannot be null");
+ Pane.Clear();
+ }
+
+ public void Print()
+ {
+ ThreadHelper.JoinableTaskFactory.Run(async () => { await PrintAsync(""); });
+ }
+
+ public void Print(string value)
+ {
+ ThreadHelper.JoinableTaskFactory.Run(async () => { await PrintAsync(value); });
+ }
+
+ public Task PrintAsync()
+ {
+ return PrintAsync("");
+ }
+
+ public async Task PrintAsync(string value)
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ if (Pane is IVsOutputWindowPaneNoPump noPumpPane)
+ noPumpPane.OutputStringNoPump(value + Environment.NewLine);
+ else
+ ErrorHandler.ThrowOnFailure(Pane.OutputStringThreadSafe(value + Environment.NewLine));
+ }
+ }
+}
diff --git a/QtVsTools.Core/ProFileContent.cs b/QtVsTools.Core/ProFileContent.cs
index 8bd3d2b..a505a16 100644
--- a/QtVsTools.Core/ProFileContent.cs
+++ b/QtVsTools.Core/ProFileContent.cs
@@ -35,46 +35,20 @@
{
public ProFileContent(VCProject proj)
{
- export = true;
- vcproj = proj;
- options = new List<ProFileOption>();
+ Export = true;
+ Project = proj;
+ Options = new List<ProFileOption>();
}
public override string ToString()
{
- return vcproj.Name;
+ return Project.Name;
}
- public VCProject Project
- {
- get
- {
- return vcproj;
- }
- }
+ public VCProject Project { get; }
- public bool Export
- {
- get
- {
- return export;
- }
- set
- {
- export = value;
- }
- }
+ public bool Export { get; set; }
- public List<ProFileOption> Options
- {
- get
- {
- return options;
- }
- }
-
- private VCProject vcproj;
- private bool export;
- private List<ProFileOption> options;
+ public List<ProFileOption> Options { get; }
}
}
diff --git a/QtVsTools.Core/ProFileOption.cs b/QtVsTools.Core/ProFileOption.cs
index 54468ef..8a5ad3d 100644
--- a/QtVsTools.Core/ProFileOption.cs
+++ b/QtVsTools.Core/ProFileOption.cs
@@ -34,95 +34,33 @@
{
public ProFileOption(string optname)
{
- name = optname;
- astype = AssignType.AT_PlusEquals;
- comment = null;
- shortComment = "Default";
- incComment = false;
- newOpt = " \\\r\n ";
- list = new List<string>();
+ Name = optname;
+ AssignSymbol = AssignType.AT_PlusEquals;
+ Comment = null;
+ ShortComment = "Default";
+ IncludeComment = false;
+ NewOption = " \\\r\n ";
+ List = new List<string>();
}
public override string ToString()
{
- return shortComment;
+ return ShortComment;
}
- public string Comment
- {
- get
- {
- return comment;
- }
- set
- {
- comment = value;
- }
- }
+ public string Comment { get; set; }
- public string ShortComment
- {
- get
- {
- return shortComment;
- }
- set
- {
- shortComment = value;
- }
- }
+ public string ShortComment { get; set; }
- public AssignType AssignSymbol
- {
- get
- {
- return astype;
- }
- set
- {
- astype = value;
- }
- }
+ public AssignType AssignSymbol { get; set; }
- public string NewOption
- {
- get
- {
- return newOpt;
- }
- set
- {
- newOpt = value;
- }
- }
+ public string NewOption { get; set; }
- public string Name
- {
- get
- {
- return name;
- }
- }
+ public string Name { get; }
- public List<string> List
- {
- get
- {
- return list;
- }
- }
+ public List<string> List { get; }
- public bool IncludeComment
- {
- get
- {
- return incComment;
- }
- set
- {
- incComment = value;
- }
- }
+ public bool IncludeComment { get; set; }
public enum AssignType
{
@@ -131,13 +69,5 @@
AT_MinusEquals = 3,
AT_Function = 4
}
-
- private AssignType astype;
- private string shortComment;
- private bool incComment;
- private string comment;
- private string newOpt;
- private string name;
- private List<string> list;
}
}
diff --git a/QtVsTools.Core/ProSolution.cs b/QtVsTools.Core/ProSolution.cs
index 497f213..2eb9990 100644
--- a/QtVsTools.Core/ProSolution.cs
+++ b/QtVsTools.Core/ProSolution.cs
@@ -35,27 +35,12 @@
{
public ProSolution(Solution sln)
{
- prosln = sln;
- proFiles = new List<ProFileContent>();
+ ProjectSolution = sln;
+ ProFiles = new List<ProFileContent>();
}
- public List<ProFileContent> ProFiles
- {
- get
- {
- return proFiles;
- }
- }
+ public List<ProFileContent> ProFiles { get; }
- public Solution ProjectSolution
- {
- get
- {
- return prosln;
- }
- }
-
- private List<ProFileContent> proFiles;
- private Solution prosln;
+ public Solution ProjectSolution { get; }
}
}
diff --git a/QtVsTools.Core/ProjectExporter.cs b/QtVsTools.Core/ProjectExporter.cs
index 681bd33..357c713 100644
--- a/QtVsTools.Core/ProjectExporter.cs
+++ b/QtVsTools.Core/ProjectExporter.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,15 +26,16 @@
**
****************************************************************************/
-using EnvDTE;
-using EnvDTE80;
-using Microsoft.VisualStudio.VCProjectEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
+using EnvDTE;
+using EnvDTE80;
namespace QtVsTools.Core
{
@@ -43,7 +44,7 @@
/// </summary>
public class ProjectExporter
{
- private DTE dteObject;
+ private readonly DTE dteObject;
public ProjectExporter(DTE dte)
{
@@ -91,13 +92,15 @@
private ProSolution CreateProFileSolution(Solution sln)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
ProFileContent content;
var prosln = new ProSolution(sln);
foreach (var proj in HelperFunctions.ProjectsInSolution(sln.DTE)) {
try {
// only add qt projects
- if (HelperFunctions.IsQtProject(proj)) {
+ if (HelperFunctions.IsVsToolsProject(proj)) {
content = CreateProFileContent(proj);
prosln.ProFiles.Add(content);
} else if (proj.Kind == ProjectKinds.vsProjectKindSolutionFolder) {
@@ -113,9 +116,11 @@
private void addProjectsInFolder(Project solutionFolder, ProSolution sln)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
foreach (ProjectItem pi in solutionFolder.ProjectItems) {
var containedProject = pi.Object as Project;
- if (HelperFunctions.IsQtProject(containedProject)) {
+ if (HelperFunctions.IsVsToolsProject(containedProject)) {
var content = CreateProFileContent(containedProject);
sln.ProFiles.Add(content);
} else if (containedProject.Kind == ProjectKinds.vsProjectKindSolutionFolder) {
@@ -126,6 +131,8 @@
private static ProFileContent CreateProFileContent(Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
ProFileOption option;
var qtPro = QtProject.Create(project);
var content = new ProFileContent(qtPro.VCProject);
@@ -192,8 +199,7 @@
if (config.ConfigurationType == ConfigurationTypes.typeStaticLibrary)
option.List.Add("staticlib");
if (linker != null) {
- var linkerRule = linker as IVCRulePropertyStorage;
- var generateDebugInformation = (linkerRule != null) ?
+ var generateDebugInformation = (linker is IVCRulePropertyStorage linkerRule) ?
linkerRule.GetUnevaluatedPropertyValue("GenerateDebugInformation") : null;
if (generateDebugInformation != "false")
option.List.Add("debug");
@@ -213,10 +219,12 @@
}
}
- if (qtPro.IsDesignerPluginProject()) {
- option.List.Add("designer");
+ var legacyDesigner = Legacy.QtProject.IsDesignerPluginProject(qtPro);
+ var plugin = legacyDesigner | Core.QtProject.IsQtPlugin(qtPro);
+ if (plugin)
option.List.Add("plugin");
- }
+ if (legacyDesigner)
+ option.List.Add("designer");
// add defines
option = new ProFileOption("DEFINES");
@@ -323,12 +331,18 @@
option.List.Add(project.Name + ".rc");
}
- if (qtPro.IsDesignerPluginProject()) {
+ if (plugin) {
option = new ProFileOption("target.path");
- option.ShortComment = "Install the plugin in the designer plugins directory.";
+ if (legacyDesigner)
+ option.ShortComment = "Installs the plugin in the designer plugins directory.";
+ else
+ option.ShortComment = "Installs the plugin in the plugins directory.";
option.IncludeComment = true;
option.AssignSymbol = ProFileOption.AssignType.AT_Equals;
- option.List.Add("$$[QT_INSTALL_PLUGINS]/designer");
+ if (legacyDesigner)
+ option.List.Add("$$[QT_INSTALL_PLUGINS]/designer");
+ else
+ option.List.Add("$$[QT_INSTALL_PLUGINS]");
content.Options.Add(option);
option = new ProFileOption("INSTALLS");
@@ -343,6 +357,8 @@
private static ProFileContent CreatePriFileContent(Project project, string priFileDirectory)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
ProFileOption option;
var qtPro = QtProject.Create(project);
var content = new ProFileContent(qtPro.VCProject);
@@ -417,6 +433,8 @@
private static void AddIncludePaths(Project project, ProFileOption option, string includePaths)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_ClProperties)
return;
@@ -437,10 +455,7 @@
if (!d.StartsWith("$(qtdir)\\include", StringComparison.OrdinalIgnoreCase) &&
!d.StartsWith(qtDir + "\\include", StringComparison.OrdinalIgnoreCase) &&
!d.EndsWith("win32-msvc2005", StringComparison.OrdinalIgnoreCase)) {
-
- var vcConfig = project.ConfigurationManager.ActiveConfiguration.Object
- as VCConfiguration;
- if (vcConfig != null)
+ if (project.ConfigurationManager.ActiveConfiguration.Object is VCConfiguration vcConfig)
HelperFunctions.ExpandString(ref d, vcConfig);
if (HelperFunctions.IsAbsoluteFilePath(d))
d = HelperFunctions.GetRelativePath(project.FullName, d);
@@ -461,8 +476,9 @@
qtDir = Environment.GetEnvironmentVariable("QTDIR");
if (qtDir == null)
qtDir = "";
-
qtDir = HelperFunctions.NormalizeRelativeFilePath(qtDir);
+
+ ThreadHelper.ThrowIfNotOnUIThread();
if (paths != null) {
foreach (var s in paths.Split(';', ',')) {
@@ -491,7 +507,14 @@
private static void AddModules(QtProject qtPrj, ProFileOption optionQT, ProFileOption optionCONFIG)
{
- foreach (var module in QtModules.Instance.GetAvailableModules()) {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ var vm = QtVersionManager.The();
+ var versionInfo = vm.GetVersionInfo(qtPrj.Project);
+ if (versionInfo == null)
+ versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
+
+ foreach (var module in QtModules.Instance.GetAvailableModules(versionInfo.qtMajor)) {
if (!qtPrj.HasModule(module.Id))
continue;
@@ -504,6 +527,8 @@
private void WriteProSolution(ProSolution prosln, bool openFile)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var sln = prosln.ProjectSolution;
if (string.IsNullOrEmpty(sln.FileName))
return;
@@ -573,6 +598,8 @@
private void WriteProFile(ProFileContent content, string proFile, string priFileToInclude, bool openFile)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
StreamWriter sw;
if (File.Exists(proFile)) {
if (MessageBox.Show(SR.GetString("ExportProject_ExistsOverwriteQuestion", proFile),
@@ -605,8 +632,7 @@
WriteProFileOptions(sw, content.Options);
}
- // open the file in vs
- if (openFile)
+ if (openFile) // open the file in vs
dteObject.OpenFile(Constants.vsViewKindTextView, proFile).Activate();
}
@@ -705,6 +731,8 @@
public static void SyncIncludeFiles(VCProject vcproj, List<string> priFiles,
List<string> projFiles, DTE dte, bool flat, FakeFilter fakeFilter)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var cmpPriFiles = new List<string>(priFiles.Count);
foreach (var s in priFiles)
cmpPriFiles.Add(HelperFunctions.NormalizeFilePath(s).ToLower());
@@ -779,7 +807,7 @@
public void ExportToProFile()
{
- var expDlg = new ExportProjectDialog();
+ ThreadHelper.ThrowIfNotOnUIThread();
var sln = dteObject.Solution;
var prosln = CreateProFileSolution(sln);
@@ -789,6 +817,7 @@
return;
}
+ var expDlg = new ExportProjectDialog();
expDlg.ProFileSolution = prosln;
expDlg.StartPosition = FormStartPosition.CenterParent;
var ww = new MainWinWrapper(dteObject);
@@ -814,9 +843,10 @@
public string ExportToPriFile(Project proj)
{
- VCProject vcproj;
+ ThreadHelper.ThrowIfNotOnUIThread();
- if (HelperFunctions.IsQtProject(proj)) {
+ VCProject vcproj;
+ if (HelperFunctions.IsVsToolsProject(proj)) {
try {
vcproj = (VCProject)proj.Object;
} catch (Exception e) {
@@ -844,8 +874,9 @@
public void ExportToPriFile(Project proj, string fileName)
{
- var priFile = new FileInfo(fileName);
+ ThreadHelper.ThrowIfNotOnUIThread();
+ var priFile = new FileInfo(fileName);
var content = CreatePriFileContent(proj, priFile.DirectoryName);
WritePriFile(content, priFile.FullName);
}
diff --git a/QtVsTools.Core/ProjectImporter.cs b/QtVsTools.Core/ProjectImporter.cs
index bd5da86..8d14767 100644
--- a/QtVsTools.Core/ProjectImporter.cs
+++ b/QtVsTools.Core/ProjectImporter.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,18 +26,19 @@
**
****************************************************************************/
-using EnvDTE;
-using Microsoft.VisualStudio.VCProjectEngine;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
+using Microsoft.VisualStudio.Shell;
+using EnvDTE;
+using Microsoft.VisualStudio.VCProjectEngine;
namespace QtVsTools.Core
{
public class ProjectImporter
{
- private DTE dteObject;
+ private readonly DTE dteObject;
const string projectFileExtension = ".vcxproj";
public ProjectImporter(DTE dte)
@@ -47,6 +48,8 @@
public void ImportProFile(string qtVersion)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
FileDialog toOpen = new OpenFileDialog();
toOpen.FilterIndex = 1;
toOpen.CheckFileExists = true;
@@ -78,6 +81,8 @@
private void ImportSolution(FileInfo mainInfo, string qtVersion)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var versionInfo = QtVersionManager.The().GetVersionInfo(qtVersion);
var VCInfo = RunQmake(mainInfo, ".sln", true, versionInfo);
if (null == VCInfo)
@@ -88,7 +93,7 @@
if (CheckQtVersion(versionInfo)) {
dteObject.Solution.Open(VCInfo.FullName);
if (qtVersion != null) {
- QtVersionManager.The().SaveSolutionQtVersion(dteObject.Solution, qtVersion);
+ Legacy.QtVersionManager.SaveSolutionQtVersion(dteObject.Solution, qtVersion);
foreach (var prj in HelperFunctions.ProjectsInSolution(dteObject)) {
QtVersionManager.The().SaveProjectQtVersion(prj, qtVersion);
var qtPro = QtProject.Create(prj);
@@ -100,12 +105,14 @@
Messages.Print("--- (Import): Finished opening " + VCInfo.Name);
} catch (Exception e) {
- Messages.DisplayCriticalErrorMessage(e);
+ Messages.DisplayErrorMessage(e);
}
}
public void ImportProject(FileInfo mainInfo, string qtVersion)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var versionInfo = QtVersionManager.The().GetVersionInfo(qtVersion);
var VCInfo = RunQmake(mainInfo, projectFileExtension, false, versionInfo);
if (null == VCInfo)
@@ -116,9 +123,11 @@
try {
if (CheckQtVersion(versionInfo)) {
// no need to add the project again if it's already there...
- if (!HelperFunctions.IsProjectInSolution(dteObject, VCInfo.FullName)) {
+ var fullName = VCInfo.FullName;
+ var pro = HelperFunctions.ProjectFromSolution(dteObject, fullName);
+ if (pro == null) {
try {
- dteObject.Solution.AddFromFile(VCInfo.FullName, false);
+ pro = dteObject.Solution.AddFromFile(fullName, false);
} catch (Exception /*exception*/) {
Messages.Print("--- (Import): Generated project could not be loaded.");
Messages.Print("--- (Import): Please look in the output above for errors and warnings.");
@@ -129,13 +138,6 @@
Messages.Print("Project already in Solution");
}
- Project pro = null;
- foreach (var p in HelperFunctions.ProjectsInSolution(dteObject)) {
- if (p.FullName.ToLower() == VCInfo.FullName.ToLower()) {
- pro = p;
- break;
- }
- }
if (pro != null) {
var qtPro = QtProject.Create(pro);
qtPro.SetQtEnvironment();
@@ -151,21 +153,16 @@
Messages.Print("Can't select the platform " + platformName + ".");
}
- // try to figure out if the project is a plugin project
- try {
- var activeConfig = pro.ConfigurationManager.ActiveConfiguration.ConfigurationName;
- var config = (VCConfiguration)((IVCCollection)qtPro.VCProject.Configurations).Item(activeConfig);
- if (config.ConfigurationType == ConfigurationTypes.typeDynamicLibrary) {
- var compiler = CompilerToolWrapper.Create(config);
- var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
- if (compiler.GetPreprocessorDefinitions().IndexOf("QT_PLUGIN", StringComparison.Ordinal) > -1
- && compiler.GetPreprocessorDefinitions().IndexOf("QDESIGNER_EXPORT_WIDGETS", StringComparison.Ordinal) > -1
- && compiler.GetAdditionalIncludeDirectories().IndexOf("QtDesigner", StringComparison.Ordinal) > -1
- && linker.AdditionalDependencies.IndexOf("QtDesigner", StringComparison.Ordinal) > -1) {
- qtPro.MarkAsDesignerPluginProject();
- }
- }
- } catch (Exception) { }
+ // figure out if the imported project is a plugin project
+ var tmp = qtPro.Project.ConfigurationManager.ActiveConfiguration
+ .ConfigurationName;
+ var vcConfig = (qtPro.VCProject.Configurations as IVCCollection).Item(tmp)
+ as VCConfiguration;
+ var def = CompilerToolWrapper.Create(vcConfig)?.GetPreprocessorDefinitions();
+ if (!string.IsNullOrEmpty(def)
+ && def.IndexOf("QT_PLUGIN", StringComparison.Ordinal) > -1) {
+ QtProject.MarkAsQtPlugin(qtPro);
+ }
qtPro.SetQtEnvironment();
ApplyPostImportSteps(qtPro);
@@ -222,18 +219,19 @@
if (ok)
ok = xmlProject.UpdateProjectFormatVersion();
- if (!ok) {
- Messages.Print(
- SR.GetString("ImportProject_CannotConvertProject", projectFile.Name));
+ if (ok) {
+ xmlProject.Save();
+ // Initialize Qt variables
+ xmlProject.BuildTarget("QtVarsDesignTime");
+ } else {
+ Messages.Print($"Could not convert project file {projectFile.Name} to Qt/MSBuild.");
}
- xmlProject.Save();
-
- // Initialize Qt variables
- xmlProject.BuildTarget("QtVarsDesignTime");
}
private static void ApplyPostImportSteps(QtProject qtProject)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
qtProject.RemoveResFilesFromGeneratedFilesFilter();
qtProject.TranslateFilterNames();
@@ -249,32 +247,38 @@
private FileInfo RunQmake(FileInfo mainInfo, string ext, bool recursive, VersionInformation vi)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var name = mainInfo.Name.Remove(mainInfo.Name.IndexOf('.'));
- var VCInfo = new FileInfo(mainInfo.DirectoryName + "\\" + name + ext);
-
- if (!VCInfo.Exists || DialogResult.Yes == MessageBox.Show(SR.GetString("ExportProject_ProjectExistsRegenerateOrReuse", VCInfo.Name),
- SR.GetString("ProjectExists"), MessageBoxButtons.YesNo, MessageBoxIcon.Question)) {
- Messages.Print("--- (Import): Generating new project of " + mainInfo.Name + " file");
-
- var waitDialog = WaitDialog.Start(
- "Open Qt Project File",
- "Generating Visual Studio project...", delay: 2);
-
- var qmake = new QMakeImport(vi, mainInfo.FullName, recursive, dteObject);
- int exitCode = qmake.Run(setVCVars: true);
- waitDialog.Stop();
-
- if (exitCode == 0)
- return VCInfo;
+ var vcxproj = new FileInfo(mainInfo.DirectoryName + "\\" + name + ext);
+ if (vcxproj.Exists) {
+ var result = MessageBox.Show($@"{vcxproj.Name} already exists. Select 'OK' to " +
+ "regenerate the file or 'Cancel' to quit importing the project.",
+ "Project file already exists.",
+ MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
+ if (result == DialogResult.Cancel)
+ return null;
}
+ Messages.Print("--- (Import): Generating new project of " + mainInfo.Name + " file");
+
+ var waitDialog = WaitDialog.Start("Open Qt Project File",
+ "Generating Visual Studio project...", delay: 2);
+
+ var qmake = new QMakeImport(vi, mainInfo.FullName, recursive, dteObject);
+ int exitCode = qmake.Run(setVCVars: true);
+
+ waitDialog.Stop();
+
+ if (exitCode == 0)
+ return vcxproj;
return null;
}
private static bool CheckQtVersion(VersionInformation vi)
{
- if (!vi.qt5Version) {
+ if (vi.qtMajor < 5) {
Messages.DisplayWarningMessage(SR.GetString("ExportProject_EditProjectFileManually"));
return false;
}
diff --git a/QtVsTools.Core/QMake.cs b/QtVsTools.Core/QMake.cs
index 4c0a985..3ee46d5 100644
--- a/QtVsTools.Core/QMake.cs
+++ b/QtVsTools.Core/QMake.cs
@@ -32,23 +32,24 @@
using System.IO;
using System.Linq;
using System.Text;
-using QtVsTools.VisualStudio;
namespace QtVsTools.Core
{
+ using VisualStudio;
+
public abstract class QMake
{
public Dictionary<string, string> Vars { get; protected set; }
public string OutputFile { get; protected set; }
- public uint DebugLevel { get; protected set; }
+ private uint DebugLevel { get; set; }
public string TemplatePrefix { get; protected set; }
public bool Recursive { get; protected set; }
public string ProFile { get; protected set; }
public string Query { get; protected set; }
public bool DisableWarnings { get; set; }
- protected VersionInformation QtVersion { get; private set; }
- protected EnvDTE.DTE Dte { get; private set; }
+ protected VersionInformation QtVersion { get; }
+ private EnvDTE.DTE Dte { get; }
public QMake(VersionInformation qtVersion, EnvDTE.DTE dte = null)
{
@@ -196,14 +197,27 @@
exitCode = qmakeProc.ExitCode;
InfoExit(qmakeProc);
}
- } catch (Exception e) {
- ErrMsg(string.Format("Exception \"{0}\":\r\n{1}",
- e.Message,
- e.StackTrace));
+ } catch (Exception exception) {
+ exception.Log();
}
}
return exitCode;
}
+
+ public static bool Exists(string path)
+ {
+ var possibleQMakePaths = new[] {
+ // Path points to qmake.exe
+ path,
+ // Path points to folder containing qmake.exe
+ Path.Combine(path, "qmake.exe"),
+ // Path points to folder containing bin\qmake.exe
+ Path.Combine(path, "bin", "qmake.exe"),
+ };
+ return possibleQMakePaths.Where(p => File.Exists(p)
+ && Path.GetFileName(p).Equals("qmake.exe", StringComparison.OrdinalIgnoreCase))
+ .Any();
+ }
}
public class QMakeImport : QMake
diff --git a/QtVsTools.Core/QMakeConf.cs b/QtVsTools.Core/QMakeConf.cs
index c66a6c6..c719314 100644
--- a/QtVsTools.Core/QMakeConf.cs
+++ b/QtVsTools.Core/QMakeConf.cs
@@ -29,13 +29,14 @@
using System;
using System.Collections;
using System.IO;
+using Microsoft.VisualStudio.Shell;
namespace QtVsTools.Core
{
public class QMakeConf
{
- public Hashtable Entries { get; private set; }
- public string QMakeSpecDirectory { get; private set; }
+ public Hashtable Entries { get; }
+ public string QMakeSpecDirectory { get; }
public QMakeConf(VersionInformation versionInfo, QMakeQuery qmakeQuery = null)
{
@@ -64,6 +65,17 @@
qmakeConf = Path.Combine(qtPrefix, qtArchData, "mkspecs", qmakeXSpec, "qmake.conf");
+ if (!File.Exists(qmakeConf)) {
+ // Check if this is a shadow build of Qt.
+ qtPrefix = qmakeQuery["QT_INSTALL_PREFIX/src"];
+ if (string.IsNullOrEmpty(qtPrefix))
+ throw new QtVSException("qmake error: no value for QT_INSTALL_PREFIX/src");
+ qtArchData = qmakeQuery["QT_INSTALL_ARCHDATA/src"];
+ if (string.IsNullOrEmpty(qtArchData))
+ throw new QtVSException("qmake error: no value for QT_INSTALL_ARCHDATA/src");
+
+ qmakeConf = Path.Combine(qtPrefix, qtArchData, "mkspecs", qmakeXSpec, "qmake.conf");
+ }
if (!File.Exists(qmakeConf))
throw new QtVSException("qmake.conf expected at " + qmakeConf + " not found");
}
diff --git a/QtVsTools.Core/QMakeQuery.cs b/QtVsTools.Core/QMakeQuery.cs
index 2dc1be5..1534deb 100644
--- a/QtVsTools.Core/QMakeQuery.cs
+++ b/QtVsTools.Core/QMakeQuery.cs
@@ -26,18 +26,15 @@
**
****************************************************************************/
-using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.IO;
using System.Linq;
using System.Text;
-using System.Threading;
-using QtVsTools.SyntaxAnalysis;
+using Microsoft.VisualStudio.Shell;
namespace QtVsTools.Core
{
- using static RegExpr;
+ using static SyntaxAnalysis.RegExpr;
public class QMakeQuery : QMake
{
@@ -58,7 +55,6 @@
public Dictionary<string, string> QueryAllValues()
{
- string result = string.Empty;
stdOutput = new StringBuilder();
Query = " ";
@@ -78,16 +74,20 @@
{
get
{
- string value = string.Empty;
- if (Properties.TryGetValue(name, out value))
+ if (Properties.TryGetValue(name, out string value))
return value;
- else
- return null;
+ return null;
}
}
Dictionary<string, string> _Properties;
- Dictionary<string, string> Properties => _Properties ?? (_Properties = QueryAllValues());
+ Dictionary<string, string> Properties
+ {
+ get
+ {
+ return _Properties ?? (_Properties = QueryAllValues());
+ }
+ }
Parser _PropertyParser;
Parser PropertyParser
diff --git a/QtVsTools.Core/QrcPrefix.cs b/QtVsTools.Core/QrcPrefix.cs
index 79686a5..bb11eec 100644
--- a/QtVsTools.Core/QrcPrefix.cs
+++ b/QtVsTools.Core/QrcPrefix.cs
@@ -34,7 +34,7 @@
{
public string Prefix { get; set; }
public string Language { get; set; }
- public List<QrcItem> Items { get; private set; }
+ public List<QrcItem> Items { get; }
public QrcPrefix()
{
diff --git a/QtVsTools.Core/QtConfig.cs b/QtVsTools.Core/QtConfig.cs
index d3a3682..5cb6974 100644
--- a/QtVsTools.Core/QtConfig.cs
+++ b/QtVsTools.Core/QtConfig.cs
@@ -44,17 +44,18 @@
/// </summary>
class QtConfig
{
- public BuildType BuildType { get; private set; }
+ public BuildType BuildType { get; }
- public string LibInfix { get; private set; }
+ public string LibInfix { get; }
- public bool Is64Bit { get; private set; }
+ public bool Is64Bit { get; }
- public string Namespace { get; private set; }
+ public string Namespace { get; }
- public uint VersionMajor { get; private set; }
- public uint VersionMinor { get; private set; }
- public uint VersionPatch { get; private set; }
+ public uint VersionMajor { get; }
+ public uint VersionMinor { get; }
+ public uint VersionPatch { get; }
+ public string VersionString { get; }
public QtConfig(string qtdir)
{
@@ -110,6 +111,8 @@
Is64Bit = (data == "x86_64");
} else if (name == "QT_NAMESPACE") {
Namespace = data;
+ } else if (name == "QT_VERSION") {
+ VersionString = data;
} else if (name == "QT_MAJOR_VERSION") {
if (uint.TryParse(data, out uint versionMajor))
VersionMajor = versionMajor;
diff --git a/QtVsTools.Core/QtModule.cs b/QtVsTools.Core/QtModule.cs
index 812b6d5..d4ad594 100644
--- a/QtVsTools.Core/QtModule.cs
+++ b/QtVsTools.Core/QtModule.cs
@@ -28,7 +28,6 @@
using System;
using System.Collections.Generic;
-using System.IO;
namespace QtVsTools.Core
{
@@ -38,12 +37,12 @@
public bool Selectable;
public List<string> Defines = new List<string>();
public string LibraryPrefix = string.Empty;
- public bool HasDLL = true;
public List<string> AdditionalLibraries = new List<string>();
public List<string> AdditionalLibrariesDebug = new List<string>();
public List<string> IncludePath = new List<string>();
public string proVarQT;
public string proVarCONFIG;
+ private string majorVersion;
public string LibRelease
{
@@ -51,7 +50,7 @@
{
return
LibraryPrefix.StartsWith("Qt", StringComparison.Ordinal)
- ? "Qt5" + LibraryPrefix.Substring(2) + ".lib"
+ ? "Qt" + majorVersion + LibraryPrefix.Substring(2) + ".lib"
: LibraryPrefix + ".lib";
}
}
@@ -62,14 +61,15 @@
{
return
LibraryPrefix.StartsWith("Qt", StringComparison.Ordinal)
- ? "Qt5" + LibraryPrefix.Substring(2) + "d.lib"
+ ? "Qt" + majorVersion + LibraryPrefix.Substring(2) + "d.lib"
: LibraryPrefix + "d.lib";
}
}
- public QtModule(int id)
+ public QtModule(int id, string major)
{
Id = id;
+ majorVersion = major;
}
public int Id { get; } = -1;
@@ -90,7 +90,7 @@
var libs = new List<string>();
var libName = LibraryPrefix;
if (libName.StartsWith("Qt", StringComparison.Ordinal))
- libName = "Qt5" + libName.Substring(2);
+ libName = "Qt" + majorVersion + libName.Substring(2);
libName += libInfix;
if (isDebugCfg)
libName += "d";
diff --git a/QtVsTools.Core/QtModules.cs b/QtVsTools.Core/QtModules.cs
index 0b1bdde..8634ece 100644
--- a/QtVsTools.Core/QtModules.cs
+++ b/QtVsTools.Core/QtModules.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -38,37 +38,58 @@
{
public class QtModules
{
- private static QtModules instance = new QtModules();
- private readonly Dictionary<int, QtModule> modules = new Dictionary<int, QtModule>();
+ public static QtModules Instance { get; } = new QtModules();
- public static QtModules Instance
- {
- get { return instance; }
- }
+ private List<QtModule> qt5list = null, qt6list = null;
+ private readonly Dictionary<int, QtModule> qt5modules = new Dictionary<int, QtModule>();
+ private readonly Dictionary<int, QtModule> qt6modules = new Dictionary<int, QtModule>();
- public QtModule Module(int id)
+ public QtModule Module(int id, uint major)
{
- QtModule module;
- modules.TryGetValue(id, out module);
+ QtModule module = null;
+ if (major < 6)
+ qt5modules.TryGetValue(id, out module);
+ if (major == 6)
+ qt6modules.TryGetValue(id, out module);
+ if (major > 6)
+ throw new QtVSException("Unsupported Qt version.");
return module;
}
- public List<QtModule> GetAvailableModules()
+ public List<QtModule> GetAvailableModules(uint major)
{
- var lst = new List<QtModule>(modules.Count);
- foreach (var entry in modules)
- lst.Add(entry.Value);
- return lst;
+ if (major < 6) {
+ if (qt5list == null) {
+ qt5list = new List<QtModule>(qt5modules.Count);
+ foreach (var entry in qt5modules)
+ qt5list.Add(entry.Value);
+ }
+ return qt5list;
+ }
+ if (major == 6) {
+ if (qt6list == null) {
+ qt6list = new List<QtModule>(qt6modules.Count);
+ foreach (var entry in qt6modules)
+ qt6list.Add(entry.Value);
+ }
+ return qt6list;
+ }
+ if (major > 6)
+ throw new QtVSException("Unsupported Qt version.");
+ return null;
}
private QtModules()
{
- var uri = new Uri(
- System.Reflection.Assembly.GetExecutingAssembly().EscapedCodeBase);
- var pkgInstallPath = Path.GetDirectoryName(
- Uri.UnescapeDataString(uri.AbsolutePath)) + @"\";
+ var uri = new Uri(System.Reflection.Assembly.GetExecutingAssembly().EscapedCodeBase);
+ var pkgInstallPath = Path.GetDirectoryName(Uri.UnescapeDataString(uri.AbsolutePath));
- var modulesFile = Path.Combine(pkgInstallPath, "qtmodules.xml");
+ FillModules(Path.Combine(pkgInstallPath, "qtmodules.xml"), "5", ref qt5modules);
+ FillModules(Path.Combine(pkgInstallPath, "qt6modules.xml"), "6", ref qt6modules);
+ }
+
+ private void FillModules(string modulesFile, string major, ref Dictionary<int, QtModule> dict)
+ {
if (!File.Exists(modulesFile))
return;
@@ -85,11 +106,10 @@
foreach (var xModule in xml.Elements("QtVsTools").Elements("Module")) {
int id = (int)xModule.Attribute("Id");
- QtModule module = new QtModule(id);
+ QtModule module = new QtModule(id, major);
module.Name = (string)xModule.Element("Name");
module.Selectable = ((string)xModule.Element("Selectable") == "true");
module.LibraryPrefix = (string)xModule.Element("LibraryPrefix");
- module.HasDLL = ((string)xModule.Element("HasDLL") == "true");
module.proVarQT = (string)xModule.Element("proVarQT");
module.proVarCONFIG = (string)xModule.Element("proVarCONFIG");
module.IncludePath = xModule.Elements("IncludePath")
@@ -106,7 +126,7 @@
Messages.Print("\r\nCritical error: incorrect format of qtmodules.xml");
throw new QtVSException("qtmodules.xml");
}
- modules.Add(id, module);
+ dict.Add(id, module);
}
}
}
diff --git a/QtVsTools.Core/QtMsBuild.cs b/QtVsTools.Core/QtMsBuild.cs
index 45ce0b9..02a1d99 100644
--- a/QtVsTools.Core/QtMsBuild.cs
+++ b/QtVsTools.Core/QtMsBuild.cs
@@ -26,17 +26,17 @@
**
****************************************************************************/
+using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Text;
-using System;
-using System.IO;
-
-using CommandLineParser = QtVsTools.Core.CommandLine.Parser;
-using CommandLineOption = QtVsTools.Core.CommandLine.Option;
namespace QtVsTools.Core.QtMsBuild
{
+ using CommandLineParser = CommandLine.Parser;
+ using CommandLineOption = CommandLine.Option;
+
public interface IVSMacroExpander
{
string ExpandString(string stringToExpand);
@@ -84,8 +84,7 @@
public class QtMsBuildContainer
{
-
- IPropertyStorageProvider provider;
+ readonly IPropertyStorageProvider provider;
public QtMsBuildContainer(IPropertyStorageProvider provider)
{
this.provider = provider;
@@ -198,16 +197,15 @@
return provider.GetProjectConfiguration(GetProject(), configName);
}
- Dictionary<string, ItemPropertyChange> itemPropertyChanges
+ readonly Dictionary<string, ItemPropertyChange> itemPropertyChanges
= new Dictionary<string, ItemPropertyChange>();
- Dictionary<string, List<ItemPropertyChange>> itemPropertyChangesGrouped
+ readonly Dictionary<string, List<ItemPropertyChange>> itemPropertyChangesGrouped
= new Dictionary<string, List<ItemPropertyChange>>();
bool pendingChanges = false;
void AddChange(ItemPropertyChange newChange)
{
- ItemPropertyChange oldChange;
- if (itemPropertyChanges.TryGetValue(newChange.Key, out oldChange)) {
+ if (itemPropertyChanges.TryGetValue(newChange.Key, out ItemPropertyChange oldChange)) {
if (oldChange.GroupKey == newChange.GroupKey) {
oldChange.CopyFrom(newChange);
return;
@@ -509,7 +507,8 @@
#region QtRcc
static QtRcc qtRccInstance;
- public static QtRcc QtRccInstance
+
+ private static QtRcc QtRccInstance
{
get
{
@@ -558,7 +557,8 @@
#region QtRepc
static QtRepc qtRepcInstance;
- public static QtRepc QtRepcInstance
+
+ private static QtRepc QtRepcInstance
{
get
{
@@ -607,7 +607,8 @@
#region QtUic
static QtUic qtUicInstance;
- public static QtUic QtUicInstance
+
+ private static QtUic QtUicInstance
{
get
{
@@ -658,10 +659,10 @@
public abstract class QtTool
{
- protected CommandLineParser parser;
- protected CommandLineOption outputOption;
- protected CommandLineOption helpOption;
- protected CommandLineOption versionOption;
+ protected readonly CommandLineParser parser;
+ private readonly CommandLineOption outputOption;
+ private CommandLineOption helpOption;
+ private CommandLineOption versionOption;
protected QtTool(bool defaultInputOutput = true)
{
@@ -779,7 +780,7 @@
AdditionalDependencies,
}
- Dictionary<Property, CommandLineOption> options
+ readonly Dictionary<Property, CommandLineOption> options
= new Dictionary<Property, CommandLineOption>();
public QtMoc() : base()
@@ -881,14 +882,13 @@
{
properties = new Dictionary<Property, string>();
- string qtDir, inputPath, outputPath;
if (!ParseCommandLine(
commandLine,
macros,
ToolExecName,
- out qtDir,
- out inputPath,
- out outputPath)) {
+ out string qtDir,
+ out string inputPath,
+ out string outputPath)) {
return false;
}
@@ -1078,7 +1078,7 @@
AdditionalDependencies,
}
- Dictionary<Property, CommandLineOption> options
+ readonly Dictionary<Property, CommandLineOption> options
= new Dictionary<Property, CommandLineOption>();
public QtRcc() : base()
@@ -1130,14 +1130,13 @@
{
properties = new Dictionary<Property, string>();
- string qtDir, inputPath, outputPath;
if (!ParseCommandLine(
commandLine,
macros,
ToolExecName,
- out qtDir,
- out inputPath,
- out outputPath)) {
+ out string qtDir,
+ out string inputPath,
+ out string outputPath)) {
return false;
}
@@ -1157,8 +1156,7 @@
properties[Property.Root] = parser.Value(options[Property.Root]);
if (parser.IsSet(options[Property.Compression])) {
- int level;
- if (!int.TryParse(parser.Value(options[Property.Compression]), out level))
+ if (!int.TryParse(parser.Value(options[Property.Compression]), out int level))
return false;
if (level < 1 || 9 < level)
return false;
@@ -1272,7 +1270,7 @@
PrintDebug,
}
- Dictionary<Property, CommandLineOption> options
+ readonly Dictionary<Property, CommandLineOption> options
= new Dictionary<Property, CommandLineOption>();
public QtRepc() : base(defaultInputOutput: false)
@@ -1330,14 +1328,13 @@
{
properties = new Dictionary<Property, string>();
- string qtDir, inputPath, outputPath;
if (!ParseCommandLine(
commandLine,
macros,
ToolExecName,
- out qtDir,
- out inputPath,
- out outputPath)) {
+ out string qtDir,
+ out string inputPath,
+ out string outputPath)) {
return false;
}
@@ -1385,8 +1382,8 @@
GenerateCommandLineOption(cmd, options[Property.InputFileType], inputType);
var outputType = container.GetPropertyValue(propertyStorage, Property.OutputFileType);
- if (!string.IsNullOrEmpty(inputType))
- GenerateCommandLineOption(cmd, options[Property.InputFileType], inputType);
+ if (!string.IsNullOrEmpty(outputType))
+ GenerateCommandLineOption(cmd, options[Property.OutputFileType], outputType);
string value = container.GetPropertyValue(propertyStorage, Property.IncludePath);
if (!string.IsNullOrEmpty(value))
@@ -1436,7 +1433,7 @@
AdditionalDependencies,
}
- Dictionary<Property, CommandLineOption> options
+ readonly Dictionary<Property, CommandLineOption> options
= new Dictionary<Property, CommandLineOption>();
public QtUic() : base()
@@ -1473,14 +1470,13 @@
{
properties = new Dictionary<Property, string>();
- string qtDir, inputPath, outputPath;
if (!ParseCommandLine(
commandLine,
macros,
ToolExecName,
- out qtDir,
- out inputPath,
- out outputPath)) {
+ out string qtDir,
+ out string inputPath,
+ out string outputPath)) {
return false;
}
diff --git a/QtVsTools.Core/QtProject.cs b/QtVsTools.Core/QtProject.cs
index 613b4e5..a935f54 100644
--- a/QtVsTools.Core/QtProject.cs
+++ b/QtVsTools.Core/QtProject.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,22 +26,22 @@
**
****************************************************************************/
-using EnvDTE;
-using Microsoft.VisualStudio.VCProjectEngine;
using System;
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
-using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
-using QtVsTools.Core.QtMsBuild;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
+using EnvDTE;
namespace QtVsTools.Core
{
+ using QtMsBuild;
+
/// <summary>
/// QtProject holds the Qt specific properties for a Visual Studio project.
/// There exists at most one QtProject per EnvDTE.Project.
@@ -54,13 +54,14 @@
private VCProject vcPro;
private MocCmdChecker mocCmdChecker;
private Array lastConfigurationRowNames;
- private static Dictionary<Project, QtProject> instances = new Dictionary<Project, QtProject>();
- private QtMsBuildContainer qtMsBuild;
+ private static readonly Dictionary<Project, QtProject> instances = new Dictionary<Project, QtProject>();
+ private readonly QtMsBuildContainer qtMsBuild;
public static QtVsTools.VisualStudio.IProjectTracker ProjectTracker { get; set; }
public static QtProject Create(VCProject vcProject)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
return Create((Project)vcProject.Object);
}
@@ -81,6 +82,8 @@
private QtProject(Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (project == null)
throw new QtVSException(SR.GetString("QtProject_CannotConstructWithoutValidProject"));
envPro = project;
@@ -105,35 +108,10 @@
return string.Empty;
try {
return config.GetEvaluatedPropertyValue(itemType + "RuleName");
- } catch (Exception e) {
- System.Diagnostics.Debug.WriteLine(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
return string.Empty;
}
- }
-
- public static string GetRuleName(VCProject project, string itemType)
- {
- if (project == null)
- return string.Empty;
- var configs = project.Configurations as IVCCollection;
- if (configs.Count == 0)
- return string.Empty;
- try {
- var firstConfig = configs.Item(1) as VCConfiguration;
- if (firstConfig == null)
- return string.Empty;
- return GetRuleName(firstConfig, itemType);
- } catch (Exception e) {
- System.Diagnostics.Debug.WriteLine(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
- return string.Empty;
- }
- }
-
- public string GetRuleName(string itemType)
- {
- return GetRuleName(vcPro, itemType);
}
public static bool IsQtMsBuildEnabled(VCProject project)
@@ -157,6 +135,8 @@
public static bool IsQtMsBuildEnabled(Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (project == null)
return false;
return IsQtMsBuildEnabled(project.Object as VCProject);
@@ -165,6 +145,8 @@
private bool? isQtMsBuildEnabled = null;
public bool IsQtMsBuildEnabled()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (!isQtMsBuildEnabled.HasValue) {
if (vcPro != null)
isQtMsBuildEnabled = IsQtMsBuildEnabled(vcPro);
@@ -192,6 +174,8 @@
{
get
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var ret = false;
if (lastConfigurationRowNames == null) {
lastConfigurationRowNames = envPro.ConfigurationManager.ConfigurationRowNames as Array;
@@ -213,6 +197,8 @@
/// <param name="uiFile">name of the ui file</param>
public string GetUiGeneratedFileName(string uiFile)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var fi = new FileInfo(uiFile);
var file = fi.Name;
if (HelperFunctions.IsUicFile(file)) {
@@ -248,8 +234,11 @@
/// replaced by the value of configName.
/// <param name="file">full file name of either the header or the source file</param>
/// <returns></returns>
- private string GetRelativeMocFilePath(string file, string configName, string platformName)
+ private string GetRelativeMocFilePath(string file, string configName = null,
+ string platformName = null)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var fileName = GetMocFileName(file);
if (fileName == null)
return null;
@@ -260,65 +249,38 @@
return mocDir;
}
- /// <summary>
- /// Returns the file name of the generated moc file relative to the
- /// project directory.
- /// </summary>
- /// The returned file path may contain the macros $(ConfigurationName) and $(PlatformName).
- /// <param name="file">full file name of either the header or the source file</param>
- /// <returns></returns>
- private string GetRelativeMocFilePath(string file)
- {
- return GetRelativeMocFilePath(file, null, null);
- }
-
- /// <summary>
- /// Marks the specified project as a Qt project.
- /// </summary>
- public void MarkAsQtProject()
- {
- vcPro.keyword = string.Format("{0}_v{1}",
- Resources.qtProjectKeyword, Resources.qtProjectFormatVersion);
- }
-
public static int GetFormatVersion(VCProject vcPro)
{
if (vcPro == null)
return 0;
- if (vcPro.keyword.StartsWith(Resources.qtProjectKeyword,
- StringComparison.InvariantCultureIgnoreCase)) {
+ if (vcPro.keyword.StartsWith(Resources.qtProjectKeyword, StringComparison.Ordinal))
return Convert.ToInt32(vcPro.keyword.Substring(6));
- } else if (vcPro.keyword.StartsWith(Resources.qtProjectV2Keyword,
- StringComparison.InvariantCultureIgnoreCase)) {
+ if (vcPro.keyword.StartsWith(Resources.qtProjectV2Keyword, StringComparison.Ordinal))
return 200;
- } else {
- return 0;
- }
+ return 0;
}
public static int GetFormatVersion(Project pro)
{
- if (pro == null)
- return 0;
- return GetFormatVersion(pro.Object as VCProject);
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return GetFormatVersion(pro?.Object as VCProject);
}
- public int FormatVersion { get { return GetFormatVersion(Project); } }
-
- public string GetPropertyValue(string propName)
+ public int FormatVersion
{
- return GetPropertyValue(Project, propName);
- }
-
- public string GetPropertyValue(string configName, string platformName, string propName)
- {
- return GetPropertyValue(Project, configName, platformName, propName);
+ get
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return GetFormatVersion(Project);
+ }
}
public static string GetPropertyValue(
EnvDTE.Project dteProject,
string propName)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var activeConfig = dteProject.ConfigurationManager?.ActiveConfiguration;
if (activeConfig == null)
return null;
@@ -331,6 +293,8 @@
EnvDTE.Configuration dteConfig,
string propName)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (dteProject == null || dteConfig == null)
return null;
return GetPropertyValue(
@@ -338,16 +302,6 @@
dteConfig.ConfigurationName,
dteConfig.PlatformName,
propName);
- }
-
- public static string GetPropertyValue(
- EnvDTE.Project dteProject,
- string configName,
- string platformName,
- string propName)
- {
- return GetPropertyValue(
- dteProject.Object as VCProject, configName, platformName, propName);
}
public static string GetPropertyValue(
@@ -374,123 +328,10 @@
return vcConfig.GetEvaluatedPropertyValue(propName);
}
- public void AddDefine(string define, uint bldConf)
- {
- foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
- var compiler = CompilerToolWrapper.Create(config);
-
- if (((!IsDebugConfiguration(config)) && ((bldConf & BuildConfig.Release) != 0)) ||
- ((IsDebugConfiguration(config)) && ((bldConf & BuildConfig.Debug) != 0))) {
- compiler.AddPreprocessorDefinition(define);
- }
- }
- }
-
- public void AddModule(int id)
- {
- if (HasModule(id))
- return;
-
- var vm = QtVersionManager.The();
- var versionInfo = vm.GetVersionInfo(Project);
- if (versionInfo == null)
- versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
-
- foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
-
- var info = QtModules.Instance.Module(id);
- if (FormatVersion >= Resources.qtMinFormatVersion_Settings) {
- var config3 = config as VCConfiguration3;
- if (config3 == null)
- continue;
- if (!string.IsNullOrEmpty(info.proVarQT)) {
- var qtModulesValue = config.GetUnevaluatedPropertyValue("QtModules");
- var qtModules = new HashSet<string>(
- !string.IsNullOrEmpty(qtModulesValue)
- ? qtModulesValue.Split(';')
- : new string[] { });
- qtModules.UnionWith(info.proVarQT.Split(' '));
- config3.SetPropertyValue(Resources.projLabelQtSettings, true,
- "QtModules", string.Join(";", qtModules));
- }
- // In V3 project format, compiler and linker options
- // required by modules are set by Qt/MSBuild.
- continue;
- }
-
- var compiler = CompilerToolWrapper.Create(config);
- var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
-
- if (compiler != null) {
- foreach (var define in info.Defines)
- compiler.AddPreprocessorDefinition(define);
-
- var incPathList = info.GetIncludePath();
- foreach (var incPath in incPathList)
- compiler.AddAdditionalIncludeDirectories(incPath);
- }
- if (linker != null) {
- var moduleLibs = info.GetLibs(IsDebugConfiguration(config), versionInfo);
- var linkerWrapper = new LinkerToolWrapper(linker);
- var additionalDeps = linkerWrapper.AdditionalDependencies;
- var dependenciesChanged = false;
- if (additionalDeps == null || additionalDeps.Count == 0) {
- additionalDeps = moduleLibs;
- dependenciesChanged = true;
- } else {
- foreach (var moduleLib in moduleLibs) {
- if (!additionalDeps.Contains(moduleLib)) {
- additionalDeps.Add(moduleLib);
- dependenciesChanged = true;
- }
- }
- }
- if (dependenciesChanged)
- linkerWrapper.AdditionalDependencies = additionalDeps;
- }
- }
- }
-
- public void RemoveModule(int id)
- {
- foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
- var compiler = CompilerToolWrapper.Create(config);
- var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
-
- var info = QtModules.Instance.Module(id);
- if (compiler != null) {
- foreach (var define in info.Defines)
- compiler.RemovePreprocessorDefinition(define);
- var additionalIncludeDirs = compiler.AdditionalIncludeDirectories;
- if (additionalIncludeDirs != null) {
- var lst = new List<string>(additionalIncludeDirs);
- foreach (var includePath in info.IncludePath) {
- lst.Remove(includePath);
- lst.Remove('\"' + includePath + '\"');
- }
- compiler.AdditionalIncludeDirectories = lst;
- }
- }
- if (linker != null && linker.AdditionalDependencies != null) {
- var linkerWrapper = new LinkerToolWrapper(linker);
- var vm = QtVersionManager.The();
- var versionInfo = vm.GetVersionInfo(Project);
- if (versionInfo == null)
- versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
-
- var moduleLibs = info.GetLibs(IsDebugConfiguration(config), versionInfo);
- var additionalDependencies = linkerWrapper.AdditionalDependencies;
- var dependenciesChanged = false;
- foreach (var moduleLib in moduleLibs)
- dependenciesChanged |= additionalDependencies.Remove(moduleLib);
- if (dependenciesChanged)
- linkerWrapper.AdditionalDependencies = additionalDependencies;
- }
- }
- }
-
public void UpdateModules(VersionInformation oldVersion, VersionInformation newVersion)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
@@ -500,7 +341,7 @@
var additionalDependencies = linkerWrapper.AdditionalDependencies;
var libsDesktop = new List<string>();
- foreach (var module in QtModules.Instance.GetAvailableModules()) {
+ foreach (var module in QtModules.Instance.GetAvailableModules(newVersion.qtMajor)) {
if (HasModule(module.Id))
libsDesktop.AddRange(module.AdditionalLibraries);
}
@@ -538,133 +379,11 @@
}
}
+ // TODO: remove once all callers are moved into Legacy namespace
public bool HasModule(int id)
{
- var foundInIncludes = false;
- var foundInLibs = false;
-
- var vm = QtVersionManager.The();
- var versionInfo = vm.GetVersionInfo(Project);
- if (versionInfo == null)
- versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
- if (versionInfo == null)
- return false; // neither a default or project Qt version
- var info = QtModules.Instance.Module(id);
- if (info == null)
- return false;
-
- foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
- var compiler = CompilerToolWrapper.Create(config);
- var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
-
- if (compiler != null) {
- if (compiler.GetAdditionalIncludeDirectories() == null)
- continue;
- var incPathList = info.GetIncludePath();
- var includeDirs = compiler.GetAdditionalIncludeDirectoriesList();
- foundInIncludes = (incPathList.Count > 0);
- foreach (var incPath in incPathList) {
- var fixedIncludeDir = FixFilePathForComparison(incPath);
- if (!includeDirs.Any(dir =>
- FixFilePathForComparison(dir) == fixedIncludeDir)) {
- foundInIncludes = false;
- break;
- }
- }
- }
-
- if (foundInIncludes)
- break;
-
- List<string> libs = null;
- if (linker != null) {
- var linkerWrapper = new LinkerToolWrapper(linker);
- libs = linkerWrapper.AdditionalDependencies;
- }
-
- if (libs != null) {
- var moduleLibs = info.GetLibs(IsDebugConfiguration(config), versionInfo);
- foundInLibs = moduleLibs.All(moduleLib => libs.Contains(moduleLib));
- }
- }
- return foundInIncludes || foundInLibs;
- }
-
- public void WriteProjectBasicConfigurations(uint type, bool usePrecompiledHeader)
- {
- WriteProjectBasicConfigurations(type, usePrecompiledHeader, null);
- }
-
- public void WriteProjectBasicConfigurations(uint type, bool usePrecompiledHeader, VersionInformation vi)
- {
- var configType = ConfigurationTypes.typeApplication;
- var targetExtension = ".exe";
- string qtVersion = null;
- var vm = QtVersionManager.The();
- if (vi == null) {
- qtVersion = vm.GetDefaultVersion();
- vi = vm.GetVersionInfo(qtVersion);
- }
-
- switch (type & TemplateType.ProjectType) {
- case TemplateType.DynamicLibrary:
- configType = ConfigurationTypes.typeDynamicLibrary;
- targetExtension = ".dll";
- break;
- case TemplateType.StaticLibrary:
- configType = ConfigurationTypes.typeStaticLibrary;
- targetExtension = ".lib";
- break;
- }
-
- foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
- config.ConfigurationType = configType;
- var compiler = CompilerToolWrapper.Create(config);
- var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
- var librarian = (VCLibrarianTool)((IVCCollection)config.Tools).Item("VCLibrarianTool");
-
- if (linker != null) {
- if ((type & TemplateType.ConsoleSystem) != 0)
- linker.SubSystem = subSystemOption.subSystemConsole;
- else
- linker.SubSystem = subSystemOption.subSystemWindows;
-
- linker.OutputFile = "$(OutDir)\\$(ProjectName)" + targetExtension;
- } else {
- librarian.OutputFile = "$(OutDir)\\$(ProjectName)" + targetExtension;
- }
-
- if ((type & TemplateType.PluginProject) != 0)
- compiler.AddPreprocessorDefinition("QT_PLUGIN");
-
- var isDebugConfiguration = false;
- if (config.Name.StartsWith("Release", StringComparison.Ordinal)) {
- compiler.SetDebugInformationFormat(debugOption.debugDisabled);
- compiler.RuntimeLibrary = runtimeLibraryOption.rtMultiThreadedDLL;
- } else if (config.Name.StartsWith("Debug", StringComparison.Ordinal)) {
- isDebugConfiguration = true;
- compiler.SetOptimization(optimizeOption.optimizeDisabled);
- compiler.SetDebugInformationFormat(debugOption.debugEnabled);
- compiler.RuntimeLibrary = runtimeLibraryOption.rtMultiThreadedDebugDLL;
- }
-
- compiler.SetTreatWChar_tAsBuiltInType(true);
-
- if (linker != null)
- linker.GenerateDebugInformation = isDebugConfiguration;
-
- if (usePrecompiledHeader)
- UsePrecompiledHeaders(config);
- }
- if ((type & TemplateType.PluginProject) != 0)
- MarkAsDesignerPluginProject();
- }
-
- public void MarkAsDesignerPluginProject()
- {
- Project.Globals["IsDesignerPlugin"] = true.ToString();
- if (!Project.Globals.get_VariablePersists("IsDesignerPlugin"))
- Project.Globals.set_VariablePersists("IsDesignerPlugin", true);
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return Legacy.QtProject.HasModule(envPro, id);
}
public void AddUic4BuildStepMsBuild(
@@ -672,8 +391,7 @@
string description,
string outputFile)
{
- var file = config.File as VCFile;
- if (file != null)
+ if (config.File is VCFile file)
file.ItemType = QtUic.ItemTypeName;
qtMsBuild.SetItemProperty(config, QtUic.Property.ExecutionDescription, description);
qtMsBuild.SetItemProperty(config, QtUic.Property.OutputFile, outputFile);
@@ -701,6 +419,8 @@
/// <param name="file">file</param>
public void AddUic4BuildStep(VCFile file)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (GetFormatVersion(vcPro) >= Resources.qtMinFormatVersion_Settings) {
file.ItemType = QtUic.ItemTypeName;
return;
@@ -736,7 +456,7 @@
}
}
if (toolSettings == CustomTool.CustomBuildStep && !uiFileExists)
- AddFileInFilter(Filters.GeneratedFiles(), uiFile);
+ AddFileInFilter(Filters.GeneratedFiles(), uiFile, false);
} catch {
throw new QtVSException(SR.GetString("QtProject_CannotAddUicStep", file.FullPath));
}
@@ -796,15 +516,15 @@
public string GetDefines(VCFileConfiguration conf)
{
var defines = string.Empty;
- var propsFile = conf.Tool as IVCRulePropertyStorage;
- var projectConfig = conf.ProjectConfiguration as VCConfiguration;
- var propsProject = projectConfig.Rules.Item("CL") as IVCRulePropertyStorage;
- if (propsFile != null) {
+ if (conf.Tool is IVCRulePropertyStorage propsFile) {
try {
defines = propsFile.GetUnevaluatedPropertyValue("PreprocessorDefinitions");
} catch { }
}
- if (string.IsNullOrEmpty(defines) && propsProject != null) {
+
+ var projectConfig = conf.ProjectConfiguration as VCConfiguration;
+ if (string.IsNullOrEmpty(defines)
+ && projectConfig?.Rules.Item("CL") is IVCRulePropertyStorage propsProject) {
try {
defines = propsProject.GetUnevaluatedPropertyValue("PreprocessorDefinitions");
} catch { }
@@ -846,12 +566,11 @@
var projectConfig = conf.ProjectConfiguration as VCConfiguration;
includeList.AddRange(GetIncludesFromCompilerTool(CompilerToolWrapper.Create(projectConfig)));
- var propertySheets = projectConfig.PropertySheets as IVCCollection;
- if (propertySheets != null) {
+ if (projectConfig.PropertySheets is IVCCollection propertySheets) {
foreach (VCPropertySheet sheet in propertySheets)
includeList.AddRange(GetIncludesFromPropertySheet(sheet));
}
-
+
var ompModified = new List<string>();
string sDir = "$(SolutionDir)";
foreach (string inc in includeList) {
@@ -884,8 +603,7 @@
private List<string> GetIncludesFromPropertySheet(VCPropertySheet sheet)
{
var includeList = GetIncludesFromCompilerTool(CompilerToolWrapper.Create(sheet));
- var propertySheets = sheet.PropertySheets as IVCCollection;
- if (propertySheets != null) {
+ if (sheet.PropertySheets is IVCCollection propertySheets) {
foreach (VCPropertySheet subSheet in propertySheets)
includeList.AddRange(GetIncludesFromPropertySheet(subSheet));
}
@@ -903,18 +621,10 @@
return new List<string>();
}
- private static bool IsDebugConfiguration(VCConfiguration conf)
- {
- var tool = CompilerToolWrapper.Create(conf);
- if (tool != null) {
- return tool.RuntimeLibrary == runtimeLibraryOption.rtMultiThreadedDebug
- || tool.RuntimeLibrary == runtimeLibraryOption.rtMultiThreadedDebugDLL;
- }
- return false;
- }
-
private string GetPCHMocOptions(VCFile file, CompilerToolWrapper compiler)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
// As .moc files are included, we should not add anything there
if (!HelperFunctions.IsHeaderFile(file.Name))
return string.Empty;
@@ -941,12 +651,13 @@
VCFileConfiguration workFileConfig,
VCFile mocFile)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var hasDifferentMocFilePerConfig =
QtVSIPSettings.HasDifferentMocFilePerConfig(envPro);
var hasDifferentMocFilePerPlatform =
QtVSIPSettings.HasDifferentMocFilePerPlatform(envPro);
- var workFile = workFileConfig.File as VCFile;
var mocFileName = GetMocFileName(sourceFile.FullPath);
var mocableIsCPP = HelperFunctions.IsMocFile(mocFileName);
var vcConfig = workFileConfig.ProjectConfiguration as VCConfiguration;
@@ -1025,6 +736,8 @@
string includes,
string description)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var workFile = workFileConfig.File as VCFile;
var mocFileName = GetMocFileName(sourceFile.FullPath);
var mocableIsCPP = HelperFunctions.IsMocFile(mocFileName);
@@ -1068,6 +781,7 @@
+ mocFileName + "))";
var regExp = new Regex(pattern);
var matchList = regExp.Matches(tool.Outputs.Replace(ProjectMacros.Name, baseFileName));
+
if (matchList.Count > 0) {
if (matchList[0].Length > 0)
outputMocFile = matchList[0].ToString();
@@ -1202,6 +916,8 @@
string includes,
string description)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var baseFileName = sourceFile.Name.Remove(sourceFile.Name.LastIndexOf('.'));
var outputMocFile = GetRelativeMocFilePath(sourceFile.FullPath);
var outputMocPath = Path.GetDirectoryName(outputMocFile);
@@ -1233,7 +949,8 @@
VCFileConfiguration workConfig,
CustomTool toolSettings)
{
- var workFile = workConfig.File as VCFile;
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var mocFileName = GetMocFileName(sourceFile.FullPath);
var mocableIsCPP = HelperFunctions.IsMocFile(mocFileName);
var vcConfig = workConfig.ProjectConfiguration as VCConfiguration;
@@ -1316,6 +1033,8 @@
/// <param name="file">file</param>
public void AddMocStep(VCFile file)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (GetFormatVersion(vcPro) >= Resources.qtMinFormatVersion_Settings) {
file.ItemType = QtMoc.ItemTypeName;
if (HelperFunctions.IsSourceFile(file.FullPath)) {
@@ -1343,8 +1062,7 @@
File.WriteAllText(cbtFullPath, string.Format(
"This is a dummy file needed to create {0}", mocFileName));
file = AddFileInSubfilter(Filters.GeneratedFiles(), null, cbtFullPath, true);
- var mocFileItem = file.Object as ProjectItem;
- if (mocFileItem != null)
+ if (file.Object is ProjectItem mocFileItem)
HelperFunctions.EnsureCustomBuildToolAvailable(mocFileItem);
}
@@ -1417,6 +1135,8 @@
public bool HasMocStep(VCFile file, string mocOutDir = null)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (file.ItemType == QtMoc.ItemTypeName)
return true;
@@ -1452,6 +1172,8 @@
public void RefreshRccSteps()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
Messages.Print("\r\n=== Update rcc steps ===");
var files = GetResourceFiles();
@@ -1482,6 +1204,8 @@
public void RefreshRccSteps(string oldRccDir)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
RefreshRccSteps();
UpdateCompilerIncludePaths(oldRccDir, QtVSIPSettings.GetRccDirectory(envPro));
}
@@ -1493,8 +1217,7 @@
string nameOnly,
string qrcCppFile)
{
- var file = vfc.File as VCFile;
- if (file != null)
+ if (vfc.File is VCFile file)
file.ItemType = QtRcc.ItemTypeName;
qtMsBuild.SetItemProperty(vfc,
QtRcc.Property.ExecutionDescription, "Rcc'ing " + ProjectMacros.FileName + "...");
@@ -1509,16 +1232,15 @@
string nameOnly,
string qrcCppFile)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var qrcFile = vfc.File as VCFile;
var rccOptsCfg = rccOpts;
var cmdLine = string.Empty;
var cbt = HelperFunctions.GetCustomBuildTool(vfc);
-
cbt.AdditionalDependencies = filesInQrcFile;
-
cbt.Description = "Rcc'ing " + ProjectMacros.FileName + "...";
-
cbt.Outputs = qrcCppFile.Replace(nameOnly, ProjectMacros.Name);
cmdLine += "\"" + Resources.rcc4Command + "\""
@@ -1539,6 +1261,8 @@
public void UpdateRccStep(VCFile qrcFile, RccOptions rccOpts)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (GetFormatVersion(vcPro) >= Resources.qtMinFormatVersion_Settings) {
qrcFile.ItemType = QtRcc.ItemTypeName;
return;
@@ -1548,8 +1272,6 @@
IsQtMsBuildEnabled() ? CustomTool.MSBuildTarget : CustomTool.CustomBuildStep;
var vcpro = (VCProject)qrcFile.project;
- var dteObject = ((Project)vcpro.Object).DTE;
-
var qtPro = Create(vcpro);
var parser = new QrcParser(qrcFile.FullPath);
var filesInQrcFile = ProjectMacros.Path;
@@ -1606,7 +1328,7 @@
}
}
- static public void ExcludeFromAllBuilds(VCFile file)
+ public static void ExcludeFromAllBuilds(VCFile file)
{
if (file == null)
return;
@@ -1672,8 +1394,7 @@
List<VCFile> GetCppMocFiles(VCFile cppFile)
{
List<VCFile> mocFiles = new List<VCFile>();
- var vcProj = cppFile.project as VCProject;
- if (vcProj != null) {
+ if (cppFile.project is VCProject vcProj) {
mocFiles.AddRange(from VCFile vcFile
in (IVCCollection)vcProj.Files
where vcFile.ItemType == "CustomBuild"
@@ -1697,27 +1418,29 @@
bool HasCppMocFiles(VCFile cppFile)
{
- if (!IsQtMsBuildEnabled()) {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (!IsQtMsBuildEnabled())
return File.Exists(Path.ChangeExtension(cppFile.FullPath, ".cbt"));
- } else {
- var vcProj = cppFile.project as VCProject;
- if (vcProj != null) {
- foreach (VCFile vcFile in (IVCCollection)vcProj.Files) {
- if (vcFile.ItemType == "CustomBuild") {
- if (IsCppMocFileCustomBuild(vcProj, vcFile, cppFile))
- return true;
- } else if (vcFile.ItemType == QtMoc.ItemTypeName) {
- if (IsCppMocFileQtMsBuild(vcProj, vcFile, cppFile))
- return true;
- }
+
+ if (cppFile.project is VCProject vcProj) {
+ foreach (VCFile vcFile in (IVCCollection)vcProj.Files) {
+ if (vcFile.ItemType == "CustomBuild") {
+ if (IsCppMocFileCustomBuild(vcProj, vcFile, cppFile))
+ return true;
+ } else if (vcFile.ItemType == QtMoc.ItemTypeName) {
+ if (IsCppMocFileQtMsBuild(vcProj, vcFile, cppFile))
+ return true;
}
}
- return false;
}
+ return false;
}
public void RemoveMocStep(VCFile file)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (file.ItemType == QtMoc.ItemTypeName) {
RemoveMocStepQtMsBuild(file);
} else if (HelperFunctions.IsHeaderFile(file.Name)) {
@@ -1756,6 +1479,7 @@
/// <param name="file">file</param>
public void RemoveMocStepCustomBuild(VCFile file)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
try {
if (!HasMocStep(file))
return;
@@ -1890,14 +1614,11 @@
public VCFile GetFileFromProject(string fileName)
{
fileName = HelperFunctions.NormalizeRelativeFilePath(fileName);
-
- var nf = fileName;
if (!HelperFunctions.IsAbsoluteFilePath(fileName))
- nf = HelperFunctions.NormalizeFilePath(vcPro.ProjectDirectory + "\\" + fileName);
- nf = nf.ToLower();
+ fileName = HelperFunctions.NormalizeFilePath(vcPro.ProjectDirectory + "\\" + fileName);
foreach (VCFile f in (IVCCollection)vcPro.Files) {
- if (f.FullPath.ToLower() == nf)
+ if (f.FullPath.Equals(fileName, StringComparison.OrdinalIgnoreCase))
return f;
}
return null;
@@ -1913,7 +1634,7 @@
{
var fi = new FileInfo(HelperFunctions.NormalizeRelativeFilePath(fileName));
foreach (VCFile f in (IVCCollection)vcPro.Files) {
- if (string.Equals(f.Name, fi.Name, StringComparison.OrdinalIgnoreCase))
+ if (f.Name.Equals(fi.Name, StringComparison.OrdinalIgnoreCase))
yield return f;
}
}
@@ -1924,34 +1645,6 @@
foreach (VCFilter subfilter in (IVCCollection)filter.Filters)
tmpList.AddRange(GetAllFilesFromFilter(subfilter));
return tmpList;
- }
-
- /// <summary>
- /// Adds a file to a filter. If the filter doesn't exist yet, it
- /// will be created. (Doesn't check for duplicates)
- /// </summary>
- /// <param name="filter">fake filter</param>
- /// <param name="fileName">relative file name</param>
- /// <returns>A VCFile object of the added file.</returns>
- public VCFile AddFileInFilter(FakeFilter filter, string fileName)
- {
- return AddFileInFilter(filter, fileName, false);
- }
-
- public void RemoveItem(ProjectItem item)
- {
- foreach (ProjectItem tmpFilter in Project.ProjectItems) {
- if (tmpFilter.Name == item.Name) {
- tmpFilter.Remove();
- return;
- }
- foreach (ProjectItem tmpItem in tmpFilter.ProjectItems) {
- if (tmpItem.Name == item.Name) {
- tmpItem.Remove();
- return;
- }
- }
- }
}
/// <summary>
@@ -1972,7 +1665,8 @@
return AddFileInSubfilter(filter, subfilterName, fileName, false);
}
- public VCFile AddFileInSubfilter(FakeFilter filter, string subfilterName, string fileName, bool checkForDuplicates)
+ public VCFile AddFileInSubfilter(FakeFilter filter, string subfilterName, string fileName,
+ bool checkForDuplicates)
{
try {
var vfilt = FindFilterFromGuid(filter.UniqueIdentifier);
@@ -1981,7 +1675,7 @@
// check if user already created this filter... then add guid
vfilt = FindFilterFromName(filter.Name);
if (vfilt == null)
- throw new QtVSException(SR.GetString("QtProject_CannotAddFilter", filter.Name));
+ throw new QtVSException($"Project cannot add filter {filter.Name}");
} else {
vfilt = (VCFilter)vcPro.AddFilter(filter.Name);
}
@@ -2014,14 +1708,7 @@
}
if (!subfilterFound) {
if (!vfilt.CanAddFilter(subfilterName))
- throw new QtVSException(SR.GetString("QtProject_CannotAddFilter", filter.Name));
-
-#if !(VS2017 || VS2019 || VS2022)
- // TODO: Enable once the freeze gets fixed in VS.
- vfilt = (VCFilter)vfilt.AddFilter(subfilterName);
- vfilt.Filter = "cpp;moc";
- vfilt.SourceControlFiles = false;
-#endif
+ throw new QtVSException($"Project cannot add filter {filter.Name}");
}
}
@@ -2034,10 +1721,13 @@
if (vfilt.CanAddFile(fileName))
return (VCFile)(vfilt.AddFile(fileName));
- throw new QtVSException(SR.GetString("QtProject_CannotAddFile", fileName));
- } catch {
- throw new QtVSException(SR.GetString("QtProject_CannotAddFile", fileName));
+ throw new QtVSException($"Cannot add file {fileName} to filter.");
+ } catch (QtVSException) {
+ throw;
+ } catch (Exception e){
+ throw new QtVSException($"Cannot add file {fileName} to filter.", e);
}
+
}
/// <summary>
@@ -2165,94 +1855,38 @@
}
}
- public void AddDirectories()
+ public static bool IsQtPlugin(Core.QtProject qtPro)
{
- try {
- // resource directory
- var fi = new FileInfo(envPro.FullName);
- var dfi = new DirectoryInfo(fi.DirectoryName + "\\" + Resources.resourceDir);
- dfi.Create();
- } catch {
- throw new QtVSException(SR.GetString("QtProject_CannotCreateResourceDir"));
- }
- AddFilterToProject(Filters.ResourceFiles());
- }
+ ThreadHelper.ThrowIfNotOnUIThread();
- public void Finish()
- {
- try {
- var solutionExplorer = dte.Windows.Item(Constants.vsWindowKindSolutionExplorer);
- if (solutionExplorer != null) {
- var hierarchy = (UIHierarchy)solutionExplorer.Object;
- var projects = hierarchy.UIHierarchyItems.Item(1).UIHierarchyItems;
+ if (qtPro.FormatVersion < Resources.qtMinFormatVersion_Settings)
+ return false;
- foreach (UIHierarchyItem itm in projects) {
- if (itm.Name == envPro.Name) {
- foreach (UIHierarchyItem i in itm.UIHierarchyItems) {
- if (i.Name == Filters.GeneratedFiles().Name)
- i.UIHierarchyItems.Expanded = false;
- }
- break;
- }
- }
- }
- } catch { }
-
- ProjectTracker?.AddProject(envPro);
- }
-
- public bool IsDesignerPluginProject()
- {
- var b = false;
- if (Project.Globals.get_VariablePersists("IsDesignerPlugin")) {
- var s = (string)Project.Globals["IsDesignerPlugin"];
- try {
- b = bool.Parse(s);
- } catch { }
- }
- return b;
- }
-
- /// <summary>
- /// Adds a file to a specified filter in a project.
- /// </summary>
- /// <param name="destName">name of the file in the project (relative to the project directory)</param>
- /// <param name="filter">filter</param>
- /// <returns>VCFile</returns>
- public VCFile AddFileToProject(string destName, FakeFilter filter)
- {
- VCFile file = null;
- if (filter != null)
- file = AddFileInFilter(filter, destName);
- else
- file = (VCFile)vcPro.AddFile(destName);
-
- if (file == null)
- return null;
-
- if (HelperFunctions.IsHeaderFile(file.Name)) {
- foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
- var compiler = CompilerToolWrapper.Create(config);
- if (compiler == null)
- continue;
-
- var paths = compiler.GetAdditionalIncludeDirectoriesList();
- var fi = new FileInfo(file.FullPath);
- var relativePath = HelperFunctions.GetRelativePath(ProjectDir, fi.Directory.ToString());
- var fixedRelativePath = FixFilePathForComparison(relativePath);
- if (!paths.Any(p => FixFilePathForComparison(p) == fixedRelativePath))
- compiler.AddAdditionalIncludeDirectories(relativePath);
+ foreach (VCConfiguration config in qtPro.VCProject.Configurations as IVCCollection) {
+ if ((config.Rules.Item("QtRule10_Settings") as IVCRulePropertyStorage)
+ .GetEvaluatedPropertyValue("QtPlugin") == "true") {
+ return true;
}
}
- return file;
+ return false;
+ }
+
+ public static void MarkAsQtPlugin(Core.QtProject qtPro)
+ {
+ foreach (VCConfiguration config in qtPro.VCProject.Configurations as IVCCollection) {
+ (config.Rules.Item("QtRule10_Settings") as IVCRulePropertyStorage)
+ .SetPropertyValue("QtPlugin", "true");
+ }
}
/// <summary>
/// adjusts the whitespaces, tabs in the given file according to VS settings
/// </summary>
/// <param name="file"></param>
- public void AdjustWhitespace(string file)
+ public static void AdjustWhitespace(DTE dte, string file)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (!File.Exists(file))
return;
@@ -2299,89 +1933,6 @@
return whitespaces;
}
- /// <summary>
- /// Copy a file to the projects folder. Does not add the file to the project.
- /// </summary>
- /// <param name="srcFile">full name of the file to add</param>
- /// <param name="destFolder">the name of the project folder</param>
- /// <param name="destName">name of the file in the project (relative to the project directory)</param>
- /// <returns>full name of the destination file</returns>
- public static string CopyFileToFolder(string srcFile, string destFolder, string destName)
- {
- var fullDestName = destFolder + "\\" + destName;
- var fi = new FileInfo(fullDestName);
-
- var replace = true;
- if (File.Exists(fullDestName)) {
- if (DialogResult.No == MessageBox.Show(SR.GetString("QtProject_FileExistsInProjectFolder", destName)
- , SR.GetString("Resources_QtVsTools"), MessageBoxButtons.YesNo, MessageBoxIcon.Question)) {
- replace = false;
- }
- }
-
- if (replace) {
- if (!fi.Directory.Exists)
- fi.Directory.Create();
- File.Copy(srcFile, fullDestName, true);
- var attribs = File.GetAttributes(fullDestName);
- File.SetAttributes(fullDestName, attribs & (~FileAttributes.ReadOnly));
- }
- return fi.FullName;
- }
-
- public static void ReplaceTokenInFile(string file, string token, string replacement)
- {
- var text = string.Empty;
- try {
- var reader = new StreamReader(file);
- text = reader.ReadToEnd();
- reader.Close();
- } catch (Exception e) {
- Messages.DisplayErrorMessage(
- SR.GetString("QtProject_CannotReplaceTokenRead", token, replacement, e.ToString()));
- return;
- }
-
- try {
- if (token.ToUpper() == "%PRE_DEF%" && !Char.IsLetter(replacement[0]))
- replacement = "_" + replacement;
-
- text = text.Replace(token, replacement);
- var writer = new StreamWriter(file);
- writer.Write(text);
- writer.Close();
- } catch (Exception e) {
- Messages.DisplayErrorMessage(
- SR.GetString("QtProject_CannotReplaceTokenWrite", token, replacement, e.ToString()));
- }
- }
-
- public void RepairGeneratedFilesStructure()
- {
- DeleteGeneratedFiles();
-
- var files = new ConcurrentBag<VCFile>();
- Task.WaitAll(
- Task.Run(() =>
- Parallel.ForEach(((IVCCollection)vcPro.Files).Cast<VCFile>(), file =>
- {
- var name = file.Name;
- if (!HelperFunctions.IsHeaderFile(name) && !HelperFunctions.IsSourceFile(name))
- return;
- if (HelperFunctions.HasQObjectDeclaration(file))
- files.Add(file);
- })
- )
- );
-
- qtMsBuild.BeginSetItemProperties();
- foreach (var file in files) {
- RemoveMocStep(file);
- AddMocStep(file);
- }
- qtMsBuild.EndSetItemProperties();
- }
-
public void TranslateFilterNames()
{
var filters = vcPro.Filters as IVCCollection;
@@ -2402,37 +1953,10 @@
}
}
- public static string CreateQrcFile(string projectDir, string className, string destName)
- {
- var fullDestName = projectDir + "\\" + destName;
-
- if (!File.Exists(fullDestName)) {
- FileStream s = null;
- try {
- s = File.Open(fullDestName, FileMode.CreateNew);
- if (s.CanWrite) {
- using (var sw = new StreamWriter(s)) {
- s = null;
- sw.WriteLine("<RCC>");
- sw.WriteLine(" <qresource prefix=\"" + className + "\">");
- sw.WriteLine(" </qresource>");
- sw.WriteLine("</RCC>");
- }
- }
- } finally {
- if (s != null)
- s.Dispose();
- }
- var attribs = File.GetAttributes(fullDestName);
- File.SetAttributes(fullDestName, attribs & (~FileAttributes.ReadOnly));
- }
-
- var fi = new FileInfo(fullDestName);
- return fi.FullName;
- }
-
public void AddActiveQtBuildStep(string version, string defFile = null)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (FormatVersion < Resources.qtMinFormatVersion_ClProperties)
return;
@@ -2463,6 +1987,8 @@
private void UpdateCompilerIncludePaths(string oldDir, string newDir)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var fixedOldDir = FixFilePathForComparison(oldDir);
var dirs = new[] {
FixFilePathForComparison(QtVSIPSettings.GetUicDirectory(envPro)),
@@ -2516,6 +2042,8 @@
public void UpdateUicSteps(string oldUicDir, bool update_inc_path)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
Messages.Print("\r\n=== Update uic steps ===");
var vcFilter = FindFilterFromGuid(Filters.GeneratedFiles().UniqueIdentifier);
if (vcFilter != null) {
@@ -2538,7 +2066,7 @@
qtMsBuild.BeginSetItemProperties();
foreach (var file in files) {
- if (HelperFunctions.IsUicFile(file.Name) && !IsUic3File(file)) {
+ if (HelperFunctions.IsUicFile(file.Name)) {
AddUic4BuildStep(file);
Messages.Print("Update uic step for " + file.Name + ".");
++updatedFiles;
@@ -2549,42 +2077,6 @@
UpdateCompilerIncludePaths(oldUicDir, QtVSIPSettings.GetUicDirectory(envPro));
Messages.Print("\r\n=== " + updatedFiles + " uic steps updated. ===\r\n");
- }
-
- private static bool IsUic3File(VCFile file)
- {
- foreach (VCFileConfiguration config in (IVCCollection)file.FileConfigurations) {
- var tool = HelperFunctions.GetCustomBuildTool(config);
- if (tool == null)
- return false;
- if (tool.CommandLine.IndexOf("uic3.exe", StringComparison.OrdinalIgnoreCase) > -1)
- return true;
- }
- return false;
- }
-
- public bool UsePrecompiledHeaders(VCConfiguration config)
- {
- var compiler = CompilerToolWrapper.Create(config);
- return UsePrecompiledHeaders(compiler);
- }
-
- private bool UsePrecompiledHeaders(CompilerToolWrapper compiler)
- {
- try {
- compiler.SetUsePrecompiledHeader(pchOption.pchUseUsingSpecific);
- var pcHeaderThrough = GetPrecompiledHeaderThrough();
- if (string.IsNullOrEmpty(pcHeaderThrough))
- pcHeaderThrough = "stdafx.h";
- compiler.SetPrecompiledHeaderThrough(pcHeaderThrough);
- var pcHeaderFile = GetPrecompiledHeaderFile();
- if (string.IsNullOrEmpty(pcHeaderFile))
- pcHeaderFile = ".\\$(ConfigurationName)/" + Project.Name + ".pch";
- compiler.SetPrecompiledHeaderFile(pcHeaderFile);
- return true;
- } catch {
- return false;
- }
}
public bool UsesPrecompiledHeaders()
@@ -2637,32 +2129,6 @@
return null;
}
- public string GetPrecompiledHeaderFile()
- {
- foreach (VCConfiguration config in vcPro.Configurations as IVCCollection) {
- var file = GetPrecompiledHeaderFile(config);
- if (!string.IsNullOrEmpty(file))
- return file;
- }
- return null;
- }
-
- public static string GetPrecompiledHeaderFile(VCConfiguration config)
- {
- var compiler = CompilerToolWrapper.Create(config);
- return GetPrecompiledHeaderFile(compiler);
- }
-
- private static string GetPrecompiledHeaderFile(CompilerToolWrapper compiler)
- {
- try {
- var file = compiler.GetPrecompiledHeaderFile();
- if (!string.IsNullOrEmpty(file))
- return file;
- } catch { }
- return null;
- }
-
public static void SetPCHOption(VCFile vcFile, pchOption option)
{
foreach (VCFileConfiguration config in vcFile.FileConfigurations as IVCCollection) {
@@ -2692,6 +2158,8 @@
/// <returns></returns>
private VCFile GetGeneratedMocFile(string fileName, VCFileConfiguration fileConfig)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (QtVSIPSettings.HasDifferentMocFilePerConfig(envPro)
|| QtVSIPSettings.HasDifferentMocFilePerPlatform(envPro)) {
var projectConfig = (VCConfiguration)fileConfig.ProjectConfiguration;
@@ -2763,6 +2231,8 @@
public void RefreshMocSteps()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
// Ignore when using shared compiler properties
if (GetFormatVersion(vcPro) >= Resources.qtMinFormatVersion_ClProperties)
return;
@@ -2790,6 +2260,7 @@
public void RefreshMocStep(VCFile vcfile)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
RefreshMocStep(vcfile, true);
}
@@ -2803,6 +2274,8 @@
/// <param name="vcfile"></param>
private void RefreshMocStep(VCFile vcfile, bool singleFile)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var isHeaderFile = HelperFunctions.IsHeaderFile(vcfile.FullPath);
if (!isHeaderFile && !HelperFunctions.IsSourceFile(vcfile.FullPath))
return;
@@ -2942,6 +2415,8 @@
public void OnExcludedFromBuildChanged(VCFile vcFile, VCFileConfiguration vcFileCfg)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
// Update the ExcludedFromBuild flags of the mocced file
// according to the ExcludedFromBuild flag of the mocable source file.
var moccedFileName = GetMocFileName(vcFile.Name);
@@ -3011,6 +2486,8 @@
public void UpdateMocSteps(string oldMocDir)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
Messages.Print("\r\n=== Update moc steps ===");
var orgFiles = new List<VCFile>();
var abandonedMocFiles = new List<string>();
@@ -3053,8 +2530,8 @@
try {
RemoveMocStep(file);
AddMocStep(file);
- } catch (QtVSException e) {
- Messages.Print(e.Message);
+ } catch (QtVSException exception) {
+ exception.Log();
continue;
}
Messages.Print("Moc step updated successfully for " + file.Name + ".");
@@ -3073,6 +2550,8 @@
private void Clean()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var solutionConfigs = envPro.DTE.Solution.SolutionBuild.SolutionConfigurations;
var backup = new List<KeyValuePair<SolutionContext, bool>>();
foreach (SolutionConfiguration config in solutionConfigs) {
@@ -3125,47 +2604,6 @@
}
}
- public bool isWinRT()
- {
- try {
- var vcProject = Project.Object as VCProject;
- var vcConfigs = vcProject.Configurations as IVCCollection;
- var vcConfig = vcConfigs.Item(1) as VCConfiguration;
- var appType = vcConfig.GetEvaluatedPropertyValue("ApplicationType");
- if (appType == "Windows Store")
- return true;
- } catch { }
- return false;
- }
-
- public bool PromptChangeQtVersion(string oldVersion, string newVersion)
- {
- var versionManager = QtVersionManager.The();
- var viOld = versionManager.GetVersionInfo(oldVersion);
- var viNew = versionManager.GetVersionInfo(newVersion);
-
- if (viOld == null || viNew == null)
- return true;
-
- var oldIsWinRt = viOld.isWinRT();
- var newIsWinRt = viNew.isWinRT();
-
- if (newIsWinRt == oldIsWinRt || newIsWinRt == isWinRT())
- return true;
-
- var promptCaption = string.Format("Change Qt Version ({0})", Project.Name);
- var promptText = string.Format(
- "Changing Qt version from {0} to {1}.\r\n" +
- "Project might not build. Are you sure?",
- newIsWinRt ? "Win32" : "WinRT",
- newIsWinRt ? "WinRT" : "Win32"
- );
-
- return (MessageBox.Show(
- promptText, promptCaption, MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
- == DialogResult.Yes);
- }
-
/// <summary>
/// Changes the Qt version of this project.
/// </summary>
@@ -3175,6 +2613,8 @@
/// <returns>true, if the operation performed successfully</returns>
public bool ChangeQtVersion(string oldVersion, string newVersion, ref bool newProjectCreated)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
newProjectCreated = false;
var versionManager = QtVersionManager.The();
var viNew = versionManager.GetVersionInfo(newVersion);
@@ -3243,6 +2683,8 @@
public bool SelectSolutionPlatform(string platformName)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
foreach (SolutionConfiguration solutionCfg in dte.Solution.SolutionBuild.SolutionConfigurations) {
var contexts = solutionCfg.SolutionContexts;
for (var i = 1; i <= contexts.Count; ++i) {
@@ -3268,6 +2710,8 @@
public void CreatePlatform(string oldPlatform, string newPlatform,
VersionInformation viOld, VersionInformation viNew, ref bool newProjectCreated)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
try {
var cfgMgr = envPro.ConfigurationManager;
cfgMgr.AddPlatform(newPlatform, oldPlatform, true);
@@ -3329,9 +2773,7 @@
if (genVCFilter == null)
return;
- var error = false;
- error = DeleteFilesFromFilter(genVCFilter);
- if (error)
+ if (DeleteFilesFromFilter(genVCFilter))
Messages.Print(SR.GetString("DeleteGeneratedFilesError"));
}
@@ -3389,7 +2831,7 @@
resFile.Remove();
}
- static private void AddPlatformToVCProj(string projectFileName, string oldPlatformName, string newPlatformName)
+ private static void AddPlatformToVCProj(string projectFileName, string oldPlatformName, string newPlatformName)
{
var tempFileName = Path.GetTempFileName();
var fi = new FileInfo(projectFileName);
@@ -3404,7 +2846,7 @@
fi.Delete();
}
- static private void AddPlatformToVCProj(XmlDocument doc, string oldPlatformName, string newPlatformName)
+ private static void AddPlatformToVCProj(XmlDocument doc, string oldPlatformName, string newPlatformName)
{
var vsProj = doc.DocumentElement.SelectSingleNode("/VisualStudioProject");
var platforms = vsProj.SelectSingleNode("Platforms");
@@ -3438,7 +2880,7 @@
}
}
- static private void SetTargetMachine(VCLinkerTool linker, VersionInformation versionInfo)
+ private static void SetTargetMachine(VCLinkerTool linker, VersionInformation versionInfo)
{
var qMakeLFlagsWindows = versionInfo.GetQMakeConfEntry("QMAKE_LFLAGS_WINDOWS");
var rex = new Regex("/MACHINE:(\\S+)");
@@ -3476,6 +2918,8 @@
public void CollapseFilter(string filterName)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var solutionExplorer = (UIHierarchy)dte.Windows.Item(Constants.vsext_wk_SProjectWindow).Object;
if (solutionExplorer.UIHierarchyItems.Count == 0)
return;
@@ -3489,6 +2933,8 @@
private UIHierarchyItem FindProjectHierarchyItem(UIHierarchy hierarchy)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (hierarchy.UIHierarchyItems.Count == 0)
return null;
@@ -3504,6 +2950,8 @@
private UIHierarchyItem FindProjectHierarchyItem(UIHierarchyItem root)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
UIHierarchyItem projectItem = null;
try {
if (root.Name == envPro.Name)
@@ -3524,6 +2972,7 @@
/// </summary>
public string GetQtVersion()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
return QtVersionManager.The().GetProjectQtVersion(envPro);
}
@@ -3532,6 +2981,7 @@
/// </summary>
public void SetQtEnvironment()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
SetQtEnvironment(QtVersionManager.The().GetProjectQtVersion(envPro));
}
@@ -3540,6 +2990,7 @@
/// </summary>
public void SetQtEnvironment(string qtVersion)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
SetQtEnvironment(qtVersion, string.Empty);
}
@@ -3548,6 +2999,8 @@
/// </summary>
public void SetQtEnvironment(string qtVersion, string solutionConfig, bool build = false)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (string.IsNullOrEmpty(qtVersion))
return;
@@ -3558,6 +3011,7 @@
if (qtVersion != "$(QTDIR)")
qtDir = QtVersionManager.The().GetInstallPath(qtVersion);
HelperFunctions.SetEnvironmentVariableEx("QTDIR", qtDir);
+
try {
var propertyAccess = (IVCBuildPropertyStorage)vcPro;
var vcprj = envPro.Object as VCProject;
@@ -3590,8 +3044,7 @@
debuggerEnv = propertyAccess.GetPropertyValue(
"LocalDebuggerEnvironment", cur_solution, "UserFile");
if (!string.IsNullOrEmpty(debuggerEnv)) {
- var debugSettings = conf.DebugSettings as VCDebugSettings;
- if (debugSettings != null) {
+ if (conf.DebugSettings is VCDebugSettings debugSettings) {
//Get original value without expanded properties
debuggerEnv = debugSettings.Environment;
}
@@ -3624,9 +3077,8 @@
var projProps = vcProj as IVCBuildPropertyStorage;
try {
return projProps.GetPropertyValue(pszPropName, Config.Name, "UserFile");
- } catch (Exception e) {
- System.Diagnostics.Debug.WriteLine(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
return string.Empty;
}
}
@@ -3637,9 +3089,8 @@
var projProps = vcProj as IVCBuildPropertyStorage;
try {
projProps.SetPropertyValue(pszPropName, Config.Name, "UserFile", pszPropValue);
- } catch (Exception e) {
- System.Diagnostics.Debug.WriteLine(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
}
}
@@ -3649,9 +3100,8 @@
var projProps = vcProj as IVCBuildPropertyStorage;
try {
projProps.RemoveProperty(pszPropName, Config.Name, "UserFile");
- } catch (Exception e) {
- System.Diagnostics.Debug.WriteLine(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
}
}
}
@@ -3970,10 +3420,10 @@
{
if (propertyStorage == null)
return null;
- if (propertyStorage is VCFileConfiguration)
- return GetParentProject(propertyStorage as VCFileConfiguration);
- else if (propertyStorage is VCConfiguration)
- return GetParentProject(propertyStorage as VCConfiguration);
+ if (propertyStorage is VCFileConfiguration configuration)
+ return GetParentProject(configuration);
+ else if (propertyStorage is VCConfiguration storage)
+ return GetParentProject(storage);
return null;
}
@@ -4026,8 +3476,7 @@
public class VCMacroExpander : IVSMacroExpander
{
- object config;
-
+ readonly object config;
public VCMacroExpander(object config)
{
this.config = config;
@@ -4042,14 +3491,15 @@
public class QtCustomBuildTool
{
- QtMsBuildContainer qtMsBuild;
- VCFileConfiguration vcConfig;
- VCFile vcFile;
- VCCustomBuildTool tool;
- VCMacroExpander macros;
+ readonly QtMsBuildContainer qtMsBuild;
+ readonly VCFileConfiguration vcConfig;
+ readonly VCFile vcFile;
+ readonly VCCustomBuildTool tool;
+ readonly VCMacroExpander macros;
enum FileItemType { Other = 0, CustomBuild, QtMoc, QtRcc, QtRepc, QtUic };
- FileItemType itemType = FileItemType.Other;
+ readonly FileItemType itemType = FileItemType.Other;
+
public QtCustomBuildTool(VCFileConfiguration vcConfig, QtMsBuildContainer container = null)
{
if (container != null)
diff --git a/QtVsTools.Core/QtVSIPSettings.cs b/QtVsTools.Core/QtVSIPSettings.cs
index bbd3a45..7eb4146 100644
--- a/QtVsTools.Core/QtVSIPSettings.cs
+++ b/QtVsTools.Core/QtVSIPSettings.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,11 +26,9 @@
**
****************************************************************************/
+using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.VCProjectEngine;
-using Microsoft.Win32;
-using QtVsTools.Core.QtMsBuild;
-using System;
-using System.Collections;
+using QtVsTools.Common;
namespace QtVsTools.Core
{
@@ -46,41 +44,26 @@
{
public static IQtVsToolsOptions Options { get; set; }
- static Hashtable mocDirCache = new Hashtable();
- static Hashtable uicDirCache = new Hashtable();
- static Hashtable rccDirCache = new Hashtable();
-
public static bool GetDisableAutoMocStepsUpdate()
{
- return GetBoolValue(Resources.disableAutoMocStepsUpdateKeyword, false);
- }
-
- public static void SaveDisableAutoMocStepsUpdate(bool b)
- {
- SetBoolValue(Resources.disableAutoMocStepsUpdateKeyword, b);
+ return QtVSIPSettingsShared.GetBoolValue(Resources.disableAutoMocStepsUpdateKeyword, false);
}
public static string GetUicDirectory(EnvDTE.Project project)
{
- return GetDirectory(project, Resources.uicDirKeyword);
- }
-
- public static void SaveUicDirectory(EnvDTE.Project project, string directory)
- {
- if (directory == null)
- SaveDirectory(project, Resources.uicDirKeyword, GetDirectory(project, Resources.uicDirKeyword));
- else
- SaveDirectory(project, Resources.uicDirKeyword, directory);
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return QtVSIPSettingsShared.GetDirectory(project, Resources.uicDirKeyword);
}
public static string GetMocDirectory()
{
- return GetDirectory(Resources.mocDirKeyword);
+ return QtVSIPSettingsShared.GetDirectory(Resources.mocDirKeyword);
}
public static string GetMocDirectory(EnvDTE.Project project)
{
- return GetDirectory(project, Resources.mocDirKeyword);
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return QtVSIPSettingsShared.GetDirectory(project, Resources.mocDirKeyword);
}
public static string GetMocDirectory(
@@ -88,6 +71,8 @@
string configName,
string platformName, VCFile vCFile)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
string filePath = null;
if (vCFile != null)
filePath = vCFile.FullPath;
@@ -100,7 +85,9 @@
string platformName,
string filePath = null)
{
- var dir = GetDirectory(project, Resources.mocDirKeyword);
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ var dir = QtVSIPSettingsShared.GetDirectory(project, Resources.mocDirKeyword);
if (!string.IsNullOrEmpty(configName)
&& !string.IsNullOrEmpty(platformName))
HelperFunctions.ExpandString(ref dir, project, configName, platformName, filePath);
@@ -109,458 +96,56 @@
public static bool HasDifferentMocFilePerConfig(EnvDTE.Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var mocDir = GetMocDirectory(project);
return mocDir.Contains("$(ConfigurationName)");
}
public static bool HasDifferentMocFilePerPlatform(EnvDTE.Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var mocDir = GetMocDirectory(project);
return mocDir.Contains("$(PlatformName)");
}
- public static string GetMocOptions()
- {
- return GetOption(Resources.mocOptionsKeyword);
- }
-
public static string GetMocOptions(EnvDTE.Project project)
{
- return GetOption(project, Resources.mocOptionsKeyword);
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return QtVSIPSettingsShared.GetOption(project, Resources.mocOptionsKeyword);
}
public static bool GetLUpdateOnBuild(EnvDTE.Project project)
{
- if (GetProjectQtSetting(project, "QtRunLUpdateOnBuild") == "true")
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (QtVSIPSettingsShared.GetProjectQtSetting(project, "QtRunLUpdateOnBuild") == "true")
return true;
- return GetBoolValue(project, Resources.lupdateKeyword);
- }
-
- public static string GetLUpdateOptions()
- {
- return GetOption(Resources.lupdateOptionsKeyword);
- }
-
- static string GetProjectQtSetting(EnvDTE.Project project, string propertyName)
- {
- var vcProject = project.Object as VCProject;
- if (vcProject == null)
- return null;
-
- var vcConfigs = vcProject.Configurations as IVCCollection;
- if (vcConfigs == null)
- return null;
-
- var activeConfig = project.ConfigurationManager.ActiveConfiguration;
- if (activeConfig == null)
- return null;
-
- var activeConfigId = string.Format("{0}|{1}",
- activeConfig.ConfigurationName, activeConfig.PlatformName);
-
- var props = vcProject as IVCBuildPropertyStorage;
- if (props == null)
- return null;
-
- try {
- return props.GetPropertyValue(propertyName, activeConfigId, "ProjectFile");
- } catch {
- return null;
- }
- }
-
- public static string GetLUpdateOptions(EnvDTE.Project project)
- {
- string qtLUpdateOptions = GetProjectQtSetting(project, "QtLUpdateOptions");
- if (!string.IsNullOrEmpty(qtLUpdateOptions))
- return qtLUpdateOptions;
- return GetOption(project, Resources.lupdateOptionsKeyword);
- }
-
- public static string GetLReleaseOptions()
- {
- return GetOption(Resources.lreleaseOptionsKeyword);
- }
-
- public static string GetLReleaseOptions(EnvDTE.Project project)
- {
- string qtLReleaseOptions = GetProjectQtSetting(project, "QtLReleaseOptions");
- if (!string.IsNullOrEmpty(qtLReleaseOptions))
- return qtLReleaseOptions;
- return GetOption(project, Resources.lreleaseOptionsKeyword);
- }
-
- public static bool GetAskBeforeCheckoutFile()
- {
- return GetBoolValue(Resources.askBeforeCheckoutFileKeyword, true);
- }
-
- public static void SaveAskBeforeCheckoutFile(bool value)
- {
- SetBoolValue(Resources.askBeforeCheckoutFileKeyword, value);
- }
-
- public static bool GetDisableCheckoutFiles()
- {
- return GetBoolValue(Resources.disableCheckoutFilesKeyword, false);
- }
-
- public static void SaveDisableCheckoutFiles(bool value)
- {
- SetBoolValue(Resources.disableCheckoutFilesKeyword, value);
- }
-
- public static void SaveMocDirectory(EnvDTE.Project project, string directory)
- {
- if (directory == null)
- SaveDirectory(project, Resources.mocDirKeyword, GetDirectory(project, Resources.mocDirKeyword));
- else
- SaveDirectory(project, Resources.mocDirKeyword, directory);
- }
-
- public static void SaveMocOptions(EnvDTE.Project project, string options)
- {
- if (options == null)
- options = GetMocOptions();
- SaveOption(project, Resources.mocOptionsKeyword, options);
- }
-
- public static void SaveMocOptions(string options)
- {
- SaveOption(Resources.mocOptionsKeyword, options);
- }
-
- public static void SaveLUpdateOnBuild(EnvDTE.Project project)
- {
- SetBoolValue(project, Resources.lupdateKeyword, GetLUpdateOnBuild());
- }
-
- public static void SaveLUpdateOnBuild(EnvDTE.Project project, bool value)
- {
- SetBoolValue(project, Resources.lupdateKeyword, value);
- }
-
- public static void SaveLUpdateOptions(EnvDTE.Project project, string options)
- {
- if (options == null)
- options = GetLUpdateOptions();
-
- SaveOption(project, Resources.lupdateOptionsKeyword, options);
- }
-
- public static void SaveLUpdateOptions(string options)
- {
- SaveOption(Resources.lupdateOptionsKeyword, options);
- }
-
- public static void SaveLReleaseOptions(EnvDTE.Project project, string options)
- {
- if (options == null)
- options = GetLReleaseOptions();
- SaveOption(project, Resources.lreleaseOptionsKeyword, options);
- }
-
- public static void SaveLReleaseOptions(string options)
- {
- SaveOption(Resources.lreleaseOptionsKeyword, options);
+ return QtVSIPSettingsShared.GetBoolValue(project, Resources.lupdateKeyword);
}
public static string GetRccDirectory(EnvDTE.Project project)
{
- return GetDirectory(project, Resources.rccDirKeyword);
- }
-
- public static void SaveRccDirectory(string dir)
- {
- SaveDirectory(Resources.rccDirKeyword, dir);
- }
-
- public static void SaveRccDirectory(EnvDTE.Project project, string directory)
- {
- if (directory == null)
- SaveDirectory(project, Resources.rccDirKeyword, GetDirectory(project, Resources.rccDirKeyword));
- else
- SaveDirectory(project, Resources.rccDirKeyword, directory);
- }
-
- private static string GetDirectory(string type)
- {
- try {
- var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\" + Resources.registryPackagePath);
- if (key != null) {
- var path = (string)key.GetValue(type, null);
- if (path != null)
- return HelperFunctions.NormalizeRelativeFilePath(path);
- }
- } catch { }
- if (type == Resources.mocDirKeyword)
- return Resources.generatedFilesDir + "\\$(ConfigurationName)";
- return Resources.generatedFilesDir;
- }
-
- private static string GetOption(string type)
- {
- try {
- var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\" + Resources.registryPackagePath);
- if (key != null) {
- var opt = (string)key.GetValue(type, null);
- if (opt != null)
- return opt;
- }
- } catch { }
- return null;
- }
-
- public static bool GetLUpdateOnBuild()
- {
- return GetBoolValue(Resources.lupdateKeyword, false);
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return QtVSIPSettingsShared.GetDirectory(project, Resources.rccDirKeyword);
}
public static string GetRccDirectory()
{
- return GetDirectory(Resources.rccDirKeyword);
+ return QtVSIPSettingsShared.GetDirectory(Resources.rccDirKeyword);
}
public static string GetUicDirectory()
{
- return GetDirectory(Resources.uicDirKeyword);
- }
-
- private static string GetDirectory(EnvDTE.Project project, string type)
- {
- // check for directory in following order:
- // - stored in project
- // - stored in cache
- // - retrieve from moc/uic steps
- // - globally defined default directory
- // - fallback on hardcoded directory
- if (project != null) {
- if (project.Globals.get_VariablePersists(type))
- return HelperFunctions.NormalizeRelativeFilePath((string)project.Globals[type]);
-
- try {
- if (type == Resources.mocDirKeyword && mocDirCache.Contains(project.FullName))
- return (string)mocDirCache[project.FullName];
- if (type == Resources.uicDirKeyword && uicDirCache.Contains(project.FullName))
- return (string)uicDirCache[project.FullName];
- if (type == Resources.rccDirKeyword && rccDirCache.Contains(project.FullName))
- return (string)rccDirCache[project.FullName];
-
- QtCustomBuildTool tool = null;
- string configName = null;
- string platformName = null;
- var vcpro = (VCProject)project.Object;
- foreach (VCFile vcfile in (IVCCollection)vcpro.Files) {
- var name = vcfile.Name;
- if ((type == Resources.mocDirKeyword && HelperFunctions.IsHeaderFile(name))
- || (type == Resources.mocDirKeyword && HelperFunctions.IsMocFile(name))
- || (type == Resources.uicDirKeyword && HelperFunctions.IsUicFile(name))
- || (type == Resources.rccDirKeyword && HelperFunctions.IsQrcFile(name))) {
- foreach (VCFileConfiguration config in (IVCCollection)vcfile.FileConfigurations) {
- tool = new QtCustomBuildTool(config);
- configName = config.Name.Remove(config.Name.IndexOf('|'));
- var vcConfig = config.ProjectConfiguration as VCConfiguration;
- var platform = vcConfig.Platform as VCPlatform;
- platformName = platform.Name;
- if (tool != null && (tool.CommandLine.IndexOf("moc.exe", StringComparison.OrdinalIgnoreCase) != -1
- || (tool.CommandLine.IndexOf("uic.exe", StringComparison.OrdinalIgnoreCase) != -1)
- || (tool.CommandLine.IndexOf("rcc.exe", StringComparison.OrdinalIgnoreCase) != -1)))
- break;
- tool = null;
- }
-
- if (tool != null)
- break;
- }
- }
-
- if (tool != null) {
- string dir = null;
- var lastindex = tool.Outputs.LastIndexOf('\\');
- if (tool.Outputs.LastIndexOf('/') > lastindex)
- lastindex = tool.Outputs.LastIndexOf('/');
-
- if (lastindex == -1)
- dir = ".";
- else
- dir = tool.Outputs.Substring(0, lastindex);
- dir = dir.Replace("\"", "");
-
- if (type == Resources.mocDirKeyword) {
- int index;
- if ((index = dir.IndexOf(configName, StringComparison.OrdinalIgnoreCase)) != -1)
- dir = dir.Replace(dir.Substring(index, configName.Length), "$(ConfigurationName)");
- if ((index = dir.IndexOf(platformName, StringComparison.OrdinalIgnoreCase)) != -1)
- dir = dir.Replace(dir.Substring(index, platformName.Length), "$(PlatformName)");
-
- mocDirCache.Add(project.FullName, HelperFunctions.NormalizeRelativeFilePath(dir));
- } else if (type == Resources.uicDirKeyword)
- uicDirCache.Add(project.FullName, HelperFunctions.NormalizeRelativeFilePath(dir));
- else if (type == Resources.rccDirKeyword)
- rccDirCache.Add(project.FullName, HelperFunctions.NormalizeRelativeFilePath(dir));
-
- cleanUpCache(project);
-
- return HelperFunctions.NormalizeRelativeFilePath(dir);
- }
- } catch { }
- }
-
- return GetDirectory(type);
- }
-
- private static string GetOption(EnvDTE.Project project, string type)
- {
- // check for directory in following order:
- // - stored in project
- // - globally defined default option
- // - empty options
- if (project != null && project.Globals.get_VariablePersists(type))
- return (string)project.Globals[type];
- return GetOption(type);
- }
-
- private static bool GetBoolValue(EnvDTE.Project project, string type)
- {
- // check for directory in following order:
- // - stored in project
- // - globally defined default option
- // - empty options
- if (project != null && project.Globals.get_VariablePersists(type))
- return Convert.ToInt32(project.Globals[type] as string) > 0;
- return GetBoolValue(type, false);
- }
-
- private static void SaveDirectory(EnvDTE.Project project, string type, string dir)
- {
- dir = HelperFunctions.NormalizeRelativeFilePath(dir);
- project.Globals[type] = dir;
- if (!project.Globals.get_VariablePersists(type))
- project.Globals.set_VariablePersists(type, true);
-
- cleanUpCache(project);
- }
-
- private static void SaveOption(EnvDTE.Project project, string type, string option)
- {
- project.Globals[type] = option;
- if (!project.Globals.get_VariablePersists(type))
- project.Globals.set_VariablePersists(type, true);
- }
-
- private static void SetBoolValue(EnvDTE.Project project, string type, bool value)
- {
- project.Globals[type] = Convert.ToInt32(value).ToString();
- if (!project.Globals.get_VariablePersists(type))
- project.Globals.set_VariablePersists(type, true);
- }
-
- public static void SaveUicDirectory(string dir)
- {
- SaveDirectory(Resources.uicDirKeyword, dir);
- }
-
- public static void SaveMocDirectory(string dir)
- {
- SaveDirectory(Resources.mocDirKeyword, dir);
- }
-
- public static void SaveLUpdateOnBuild(bool val)
- {
- SetBoolValue(Resources.lupdateKeyword, val);
- }
-
- public static void cleanUpCache(EnvDTE.Project project)
- {
- try {
- var mocEnumerator = mocDirCache.GetEnumerator();
- while (mocEnumerator.MoveNext()) {
- if (!HelperFunctions.IsProjectInSolution(project.DTE, (string)mocEnumerator.Key)) {
- mocDirCache.Remove(mocEnumerator.Key);
- mocEnumerator = mocDirCache.GetEnumerator();
- }
- }
-
- var uicEnumerator = uicDirCache.GetEnumerator();
- while (uicEnumerator.MoveNext()) {
- if (!HelperFunctions.IsProjectInSolution(project.DTE, (string)uicEnumerator.Key)) {
- uicDirCache.Remove(uicEnumerator.Key);
- uicEnumerator = uicDirCache.GetEnumerator();
- }
- }
-
- var rccEnumerator = rccDirCache.GetEnumerator();
- while (rccEnumerator.MoveNext()) {
- if (!HelperFunctions.IsProjectInSolution(project.DTE, (string)rccEnumerator.Key)) {
- rccDirCache.Remove(rccEnumerator.Key);
- rccEnumerator = rccDirCache.GetEnumerator();
- }
- }
- } catch { }
- }
-
- private static void SaveDirectory(string type, string dir)
- {
- dir = HelperFunctions.NormalizeRelativeFilePath(dir);
- var key = Registry.CurrentUser.CreateSubKey("SOFTWARE\\" + Resources.registryPackagePath);
- if (key == null)
- return;
- key.SetValue(type, dir);
- }
-
- private static void SaveOption(string type, string option)
- {
- var key = Registry.CurrentUser.CreateSubKey("SOFTWARE\\" + Resources.registryPackagePath);
- if (key == null)
- return;
- if (option == null)
- option = "";
- key.SetValue(type, option);
+ return QtVSIPSettingsShared.GetDirectory(Resources.uicDirKeyword);
}
public static bool AutoUpdateUicSteps()
{
- if (ValueExists("AutoUpdateUicSteps"))
- return GetBoolValue("AutoUpdateUicSteps", true);
- return GetBoolValue("AutoUpdateBuildSteps", true);
- }
-
- private static bool GetBoolValue(string key, bool defaultValue)
- {
- var regKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\" + Resources.registryPackagePath);
- if (regKey == null)
- return defaultValue;
- return ((int)regKey.GetValue(key, defaultValue ? 1 : 0)) > 0;
- }
-
- private static bool ValueExists(string key)
- {
- var regKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\" + Resources.registryPackagePath);
- if (regKey != null) {
- foreach (var s in regKey.GetValueNames()) {
- if (s == key)
- return true;
- }
- }
- return false;
- }
-
- private static void SetBoolValue(string key, bool val)
- {
- var regKey = Registry.CurrentUser.CreateSubKey("SOFTWARE\\" + Resources.registryPackagePath);
- if (regKey == null)
- return;
- regKey.SetValue(key, val ? 1 : 0);
- }
-
- public static bool GetQmlDebug(EnvDTE.Project project)
- {
- return QtProject.Create(project).QmlDebug;
- }
-
- public static void SaveQmlDebug(EnvDTE.Project project, bool enabled)
- {
- QtProject.Create(project).QmlDebug = enabled;
+ if (QtVSIPSettingsShared.ValueExists("AutoUpdateUicSteps"))
+ return QtVSIPSettingsShared.GetBoolValue("AutoUpdateUicSteps", true);
+ return QtVSIPSettingsShared.GetBoolValue("AutoUpdateBuildSteps", true);
}
}
}
diff --git a/QtVsTools.Core/QtVersionManager.cs b/QtVsTools.Core/QtVersionManager.cs
index 000a198..15a3ae2 100644
--- a/QtVsTools.Core/QtVersionManager.cs
+++ b/QtVsTools.Core/QtVersionManager.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,16 +26,14 @@
**
****************************************************************************/
-using Microsoft.VisualStudio.VCProjectEngine;
-using Microsoft.Win32;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
using System.Threading;
-using QtVsTools.VisualStudio;
-using EnvDTE;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
+using Microsoft.Win32;
namespace QtVsTools.Core
{
@@ -45,37 +43,20 @@
public class QtVersionManager
{
private static QtVersionManager instance;
- private string regVersionPath;
- private string strVersionKey;
+ private readonly string regVersionPath;
+ private readonly string strVersionKey;
private Hashtable versionCache;
protected QtVersionManager()
{
strVersionKey = "Versions";
regVersionPath = Resources.registryVersionPath;
- RefreshVersionNames();
}
- void RefreshVersionNames()
- {
- var rootKeyPath = "SOFTWARE\\" + Resources.registryRootPath;
- try {
- using (var rootKey = Registry.CurrentUser.OpenSubKey(rootKeyPath, true))
- using (var versionsKey = rootKey.OpenSubKey(strVersionKey, true)) {
- versionsKey.SetValue("VersionNames", string.Join(";", GetVersions()));
- }
+ private static readonly EventWaitHandle packageInit = new EventWaitHandle(false, EventResetMode.ManualReset);
+ private static EventWaitHandle packageInitDone = null;
- } catch (Exception e) {
- Messages.Print(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
- }
- }
-
- static EventWaitHandle
- packageInit = new EventWaitHandle(false, EventResetMode.ManualReset),
- packageInitDone = null;
-
- static public QtVersionManager The(EventWaitHandle initDone = null)
+ public static QtVersionManager The(EventWaitHandle initDone = null)
{
if (initDone == null) {
packageInit.WaitOne();
@@ -92,10 +73,10 @@
public VersionInformation GetVersionInfo(string name)
{
- if (name == "$(DefaultQtVersion)")
- name = GetDefaultVersion();
if (name == null)
return null;
+ if (name == "$(DefaultQtVersion)")
+ name = GetDefaultVersion();
if (versionCache == null)
versionCache = new Hashtable();
@@ -111,13 +92,8 @@
public VersionInformation GetVersionInfo(EnvDTE.Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
return GetVersionInfo(GetProjectQtVersion(project));
- }
-
- public void ClearVersionCache()
- {
- if (versionCache != null)
- versionCache.Clear();
}
public string[] GetVersions()
@@ -130,13 +106,12 @@
if (qtDir == null)
return null;
- qtDir = qtDir.ToLower();
var versions = GetVersions();
foreach (var version in versions) {
var installPath = GetInstallPath(version);
if (installPath == null)
continue;
- if (installPath.ToLower() == qtDir)
+ if (installPath.Equals(qtDir, StringComparison.OrdinalIgnoreCase))
return version;
}
@@ -157,84 +132,61 @@
/// <summary>
/// Check if all Qt versions are valid and readable.
/// </summary>
- /// Also sets the default Qt version to the newest version, if needed.
/// <param name="errorMessage"></param>
- /// <returns>true, if we found an invalid version</returns>
- public bool HasInvalidVersions(out string errorMessage)
+ /// <returns>true, if there are one or more invalid Qt version</returns>
+ public bool HasInvalidVersions(out string errorMessage, out bool defaultVersionInvalid)
{
- var validVersions = new Dictionary<string, QtConfig>();
- var invalidVersions = new List<string>();
+ var defaultVersion = GetDefaultVersionString();
+ defaultVersionInvalid = string.IsNullOrEmpty(defaultVersion);
- foreach (var v in GetVersions()) {
- if (v == "$(DefaultQtVersion)")
- continue;
-
- var vPath = GetInstallPath(v);
- if (string.IsNullOrEmpty(vPath)) {
- invalidVersions.Add(v);
- continue;
- }
-
- if (vPath.StartsWith("SSH:") || vPath.StartsWith("WSL:"))
- continue;
-
- var qmakePath = Path.Combine(vPath, "bin", "qmake.exe");
- if (!File.Exists(qmakePath))
- qmakePath = Path.Combine(vPath, "qmake.exe");
- if (!File.Exists(qmakePath)) {
- invalidVersions.Add(v);
- continue;
- }
-
- validVersions[v] = new QtConfig(vPath);
- }
-
- if (invalidVersions.Count > 0) {
- errorMessage = "These Qt version are inaccessible:\n";
- foreach (var invalidVersion in invalidVersions)
- errorMessage += invalidVersion + " in " + GetInstallPath(invalidVersion) + "\n";
- errorMessage += "Make sure that you have read access to all files in your Qt directories.";
-
- // Is the default Qt version invalid?
- var isDefaultQtVersionInvalid = false;
- var defaultQtVersionName = GetDefaultVersion();
- if (string.IsNullOrEmpty(defaultQtVersionName)) {
- isDefaultQtVersionInvalid = true;
- } else {
- foreach (var name in invalidVersions) {
- if (name == defaultQtVersionName) {
- isDefaultQtVersionInvalid = true;
- break;
- }
- }
- }
-
- // find the newest valid Qt version that can be used as default version
- if (isDefaultQtVersionInvalid && validVersions.Count > 0) {
- QtConfig defaultQtVersionConfig = null;
- foreach (var vNameConfig in validVersions) {
- var vName = vNameConfig.Key;
- var v = vNameConfig.Value;
- if (defaultQtVersionConfig == null) {
- defaultQtVersionConfig = v;
- defaultQtVersionName = vName;
- continue;
- }
- if (defaultQtVersionConfig.VersionMajor < v.VersionMajor ||
- (defaultQtVersionConfig.VersionMajor == v.VersionMajor && (defaultQtVersionConfig.VersionMinor < v.VersionMinor ||
- (defaultQtVersionConfig.VersionMinor == v.VersionMinor && defaultQtVersionConfig.VersionPatch < v.VersionPatch)))) {
- defaultQtVersionConfig = v;
- defaultQtVersionName = vName;
- }
- }
- if (defaultQtVersionConfig != null)
- SaveDefaultVersion(defaultQtVersionName);
- }
-
- return true;
- }
errorMessage = null;
- return false;
+ foreach (var version in GetVersions()) {
+ if (version == "$(DefaultQtVersion)")
+ continue;
+
+ var path = GetInstallPath(version);
+ if (path != null && (path.StartsWith("SSH:") || path.StartsWith("WSL:")))
+ continue;
+
+ if (string.IsNullOrEmpty(path) || !QMake.Exists(path)) {
+ errorMessage += version + " in " + path + "\n";
+ defaultVersionInvalid |= version == defaultVersion;
+ }
+
+ if (!string.IsNullOrEmpty(errorMessage)) {
+ errorMessage = "These Qt version are inaccessible:\n"
+ + errorMessage
+ + "Make sure that you have read access to all files in your Qt directories.";
+ }
+ }
+ return errorMessage != null;
+ }
+
+ public void SetLatestQtVersionAsDefault()
+ {
+ var validVersions = new Dictionary<string, Version>();
+ foreach (var version in GetVersions()) {
+ if (version == "$(DefaultQtVersion)")
+ continue;
+
+ var path = GetInstallPath(version);
+ if (!string.IsNullOrEmpty(path) && QMake.Exists(path))
+ validVersions[version] = new Version(new QtConfig(path).VersionString);
+ }
+
+ if (validVersions.Count <= 0)
+ return;
+
+ var defaultName = "";
+ Version defaultVersion = null;
+ foreach (var tmp in validVersions) {
+ var version = tmp.Value;
+ if (defaultVersion == null || defaultVersion < version) {
+ defaultName = tmp.Key;
+ defaultVersion = version;
+ }
+ }
+ SaveDefaultVersion(defaultName);
}
public string GetInstallPath(string version)
@@ -252,16 +204,14 @@
return Environment.GetEnvironmentVariable("QTDIR");
var key = root.OpenSubKey("SOFTWARE\\" + Resources.registryRootPath, false);
- if (key == null)
- return null;
- var versionKey = key.OpenSubKey(strVersionKey + "\\" + version, false);
- if (versionKey == null)
- return null;
- return (string)versionKey.GetValue("InstallDir");
+ var versionKey = key?.OpenSubKey(strVersionKey + "\\" + version, false);
+ return versionKey?.GetValue("InstallDir") as string;
}
public string GetInstallPath(EnvDTE.Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var version = GetProjectQtVersion(project);
if (version == "$(DefaultQtVersion)")
version = GetDefaultVersion();
@@ -309,7 +259,6 @@
versionKey.SetValue("InstallDir", dir);
}
}
- RefreshVersionNames();
return true;
}
@@ -320,10 +269,9 @@
return;
key.DeleteSubKey(versionName);
key.Close();
- RefreshVersionNames();
}
- private bool IsVersionAvailable(string version)
+ internal bool IsVersionAvailable(string version)
{
var versionAvailable = false;
var versions = GetVersions();
@@ -338,13 +286,17 @@
public bool SaveProjectQtVersion(EnvDTE.Project project, string version)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
return SaveProjectQtVersion(project, version, project.ConfigurationManager.ActiveConfiguration.PlatformName);
}
public bool SaveProjectQtVersion(EnvDTE.Project project, string version, string platform)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (!IsVersionAvailable(version) && version != "$(DefaultQtVersion)")
return false;
+
if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_Settings) {
var vcPro = project.Object as VCProject;
if (vcPro == null)
@@ -365,6 +317,8 @@
public string GetProjectQtVersion(EnvDTE.Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
EnvDTE.Configuration config = null;
try {
config = project.ConfigurationManager.ActiveConfiguration;
@@ -382,13 +336,15 @@
}
if (version == null)
- version = GetSolutionQtVersion(project.DTE.Solution);
+ version = Legacy.QtVersionManager.GetSolutionQtVersion(project.DTE.Solution);
return version;
}
public string GetProjectQtVersion(EnvDTE.Project project, EnvDTE.Configuration config)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_Settings)
return QtProject.GetPropertyValue(project, config, "QtInstall");
@@ -402,6 +358,8 @@
public string GetProjectQtVersion(EnvDTE.Project project, string platform)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_Settings)
return GetProjectQtVersion(project);
@@ -426,29 +384,6 @@
version = Environment.GetEnvironmentVariable(env);
}
}
- }
-
- public bool SaveSolutionQtVersion(EnvDTE.Solution solution, string version)
- {
- if (!IsVersionAvailable(version) && version != "$(DefaultQtVersion)")
- return false;
- solution.Globals["Qt5Version"] = version;
- if (!solution.Globals.get_VariablePersists("Qt5Version"))
- solution.Globals.set_VariablePersists("Qt5Version", true);
- return true;
- }
-
- public string GetSolutionQtVersion(EnvDTE.Solution solution)
- {
- if (solution == null)
- return null;
-
- if (solution.Globals.get_VariableExists("Qt5Version")) {
- var version = (string)solution.Globals["Qt5Version"];
- return VerifyIfQtVersionExists(version) ? version : null;
- }
-
- return null;
}
public string GetDefaultVersion()
@@ -489,6 +424,25 @@
}
}
return VerifyIfQtVersionExists(defaultVersion) ? defaultVersion : null;
+ }
+
+ public string GetDefaultVersionString()
+ {
+ string defaultVersion = null;
+ try {
+ var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\" + regVersionPath, false);
+ if (key != null)
+ defaultVersion = key.GetValue("DefaultQtVersion") as string;
+ } catch {
+ Messages.Print("Cannot read the default Qt version from registry.");
+ }
+
+ if (defaultVersion == null) {
+ var qtDir = Environment.GetEnvironmentVariable("QTDIR");
+ if (string.IsNullOrEmpty(qtDir))
+ return defaultVersion;
+ }
+ return defaultVersion;
}
public bool SaveDefaultVersion(string version)
@@ -540,7 +494,7 @@
}
}
- private bool VerifyIfQtVersionExists(string version)
+ internal bool VerifyIfQtVersionExists(string version)
{
if (version == "$(DefaultQtVersion)")
version = GetDefaultVersion();
diff --git a/QtVsTools.Core/QtVsTools.Core.csproj b/QtVsTools.Core/QtVsTools.Core.csproj
index c436e03..19e3727 100644
--- a/QtVsTools.Core/QtVsTools.Core.csproj
+++ b/QtVsTools.Core/QtVsTools.Core.csproj
@@ -69,36 +69,45 @@
// -->
<ItemGroup>
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ <Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Windows.Forms" />
+ <Reference Include="WindowsBase" />
</ItemGroup>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
- // Version specific references
+ // General package references
// -->
<Import Project="$(SolutionDir)\references.props" />
<ItemGroup>
- <PackageReference Include="Microsoft.VisualStudio.SDK"
- Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
- <PackageReference Include="Microsoft.VSSDK.BuildTools"
- Version="$(Version_Microsoft_VSSDK_BuildTools)" />
- <PackageReference Include="Microsoft.Build"
- Version="$(Version_Microsoft_Build)" />
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ <PackageReference Include="$(Name_Microsoft_Build)" Version="$(Version_Microsoft_Build)" />
</ItemGroup>
- <ItemGroup Condition="'$(VisualStudioVersion)'=='17.0'">
- <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
- Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
- </ItemGroup>
- <ItemGroup Condition="'$(VisualStudioVersion)'=='16.0'">
- <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
- Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
- </ItemGroup>
- <ItemGroup Condition="'$(VisualStudioVersion)'=='15.0'">
- <Reference Include="Microsoft.VisualStudio.VCProjectEngine" />
- </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)" Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ <Reference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)" />
+ </ItemGroup>
+ </When>
+ </Choose>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
// Solution project references
@@ -117,6 +126,8 @@
<Compile Include="BuildConfig.cs" />
<Compile Include="CommandLineParser.cs" />
<Compile Include="Common\EnumExt.cs" />
+ <Compile Include="Common\LazyFactory.cs" />
+ <Compile Include="Common\QtVSIPSettingsShared.cs" />
<Compile Include="CompilerToolWrapper.cs" />
<Compile Include="CxxStreamReader.cs" />
<Compile Include="ExportProjectDialog.cs">
@@ -130,12 +141,16 @@
<Compile Include="ImageButton.cs">
<SubType>Component</SubType>
</Compile>
+ <Compile Include="Legacy\QtProject.cs" />
+ <Compile Include="Legacy\QtVersionManager.cs" />
+ <Compile Include="Legacy\QtVSIPSettings.cs" />
<Compile Include="LinkerToolWrapper.cs" />
<Compile Include="MainWinWrapper.cs" />
<Compile Include="Messages.cs" />
<Compile Include="MocCmdChecker.cs" />
<Compile Include="MsBuildProject.cs" />
<Compile Include="Observable.cs" />
+ <Compile Include="OutputWindowPane.cs" />
<Compile Include="ProFileContent.cs" />
<Compile Include="ProFileOption.cs" />
<Compile Include="ProjectExporter.cs" />
@@ -170,10 +185,12 @@
<Compile Include="RccOptions.cs" />
<Compile Include="Resources.cs" />
<Compile Include="SR.cs" />
- <Compile Include="TemplateType.cs" />
<Compile Include="VersionInformation.cs" />
+ <Compile Include="VisualStudio\InfoBarMessage.cs" />
<Compile Include="VisualStudio\IProjectTracker.cs" />
+ <Compile Include="VisualStudio\VsSearch.cs" />
<Compile Include="VisualStudio\VsServiceProvider.cs" />
+ <Compile Include="VisualStudio\VsShell.cs" />
<Compile Include="WaitDialog.cs" />
<EmbeddedResource Include="ExportProjectDialog.resx">
<DependentUpon>ExportProjectDialog.cs</DependentUpon>
@@ -188,4 +205,4 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
-</Project>
+</Project>
\ No newline at end of file
diff --git a/QtVsTools.Core/RccOptions.cs b/QtVsTools.Core/RccOptions.cs
index 44e8b2e..3d3dd48 100644
--- a/QtVsTools.Core/RccOptions.cs
+++ b/QtVsTools.Core/RccOptions.cs
@@ -26,8 +26,9 @@
**
****************************************************************************/
-using Microsoft.VisualStudio.VCProjectEngine;
using System;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
namespace QtVsTools.Core
{
@@ -57,6 +58,8 @@
{
get
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (project.Globals.get_VariablePersists("RccCompressFiles" + id)
&& (string)project.Globals["RccCompressFiles" + id] == "true")
return true;
@@ -64,6 +67,8 @@
}
set
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (value)
project.Globals["RccCompressFiles" + id] = "true";
else
@@ -77,12 +82,16 @@
{
get
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (project.Globals.get_VariablePersists("RccCompressLevel" + id))
return Convert.ToInt32((string)project.Globals["RccCompressLevel" + id], 10);
return 0;
}
set
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
project.Globals["RccCompressLevel" + id] = value.ToString();
if (!project.Globals.get_VariablePersists("RccCompressLevel" + id))
project.Globals.set_VariablePersists("RccCompressLevel" + id, true);
@@ -93,12 +102,16 @@
{
get
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (project.Globals.get_VariablePersists("RccCompressThreshold" + id))
return Convert.ToInt32((string)project.Globals["RccCompressThreshold" + id], 10);
return 0;
}
set
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
project.Globals["RccCompressThreshold" + id] = value.ToString();
if (!project.Globals.get_VariablePersists("RccCompressThreshold" + id))
project.Globals.set_VariablePersists("RccCompressThreshold" + id, true);
diff --git a/QtVsTools.Core/Resources.cs b/QtVsTools.Core/Resources.cs
index c8db0c9..79e97a0 100644
--- a/QtVsTools.Core/Resources.cs
+++ b/QtVsTools.Core/Resources.cs
@@ -100,18 +100,11 @@
public const int qtMinFormatVersion_PropertyEval = 303;
// Project properties labels
- public const string projLabelGlobals = "Globals";
public const string projLabelQtSettings = "QtSettings";
public const string uic4Command = "$(QTDIR)\\bin\\uic.exe";
public const string moc4Command = "$(QTDIR)\\bin\\moc.exe";
public const string rcc4Command = "$(QTDIR)\\bin\\rcc.exe";
- public const string lupdateCommand = "\\bin\\lupdate.exe";
- public const string lreleaseCommand = "\\bin\\lrelease.exe";
-
- // All defined paths have to be relative to the project directory!!!
-
- public const string resourceDir = "Resources";
// If those directories do not equal to the project directory
// they have to be added to the include directories for
diff --git a/QtVsTools.Core/Resources.resx b/QtVsTools.Core/Resources.resx
index 7861f15..ad354aa 100644
--- a/QtVsTools.Core/Resources.resx
+++ b/QtVsTools.Core/Resources.resx
@@ -123,9 +123,6 @@
<data name="OpenSolution" xml:space="preserve">
<value>Open Solution</value>
</data>
- <data name="ProjectExists" xml:space="preserve">
- <value>Project file already exists.</value>
- </data>
<data name="ExportProject_EditProjectFileManually" xml:space="preserve">
<value>qmake has generated a .vcproj file, but it needs to be converted.
To do this you must open the .vcproj file manually.
@@ -140,17 +137,13 @@
<value>Export to .pri File</value>
</data>
<data name="ExportProject_NoProjectsToExport" xml:space="preserve">
- <value>Cannot find any Qt 4 projects to export.</value>
+ <value>Cannot find any Qt projects to export.</value>
</data>
<data name="ExportProject_PriFileContainsSpaces" xml:space="preserve">
<value>The generated .pri file contains paths with spaces. You will not be able to import from this file.
1. Manually edit the generated .pri file.
2. Move your project to a location without spaces in the path.
3. Place the .pri file in another directory.</value>
- </data>
- <data name="ExportProject_ProjectExistsRegenerateOrReuse" xml:space="preserve">
- <value>{0} already exists.
-Select 'Yes' to regenerate the file, and 'No' to use the existing one.</value>
</data>
<data name="ExportProject_ProjectOrSolutionCorrupt" xml:space="preserve">
<value>{0}
@@ -216,12 +209,6 @@
<data name="QtProject_CannotRemoveMocStep" xml:space="preserve">
<value>Cannot remove a moc step from file {0}</value>
</data>
- <data name="QtProject_CannotAddFilter" xml:space="preserve">
- <value>Project cannot add filter {0}</value>
- </data>
- <data name="QtProject_CannotAddFile" xml:space="preserve">
- <value>Cannot add file {0} to filter.</value>
- </data>
<data name="QtProject_CannotRemoveFile" xml:space="preserve">
<value>Cannot remove file {0} from filter.</value>
</data>
@@ -238,25 +225,9 @@
<data name="QtProject_ProjectCannotAddResourceFilter" xml:space="preserve">
<value>Cannot add a resource filter.</value>
</data>
- <data name="QtProject_CannotCreateResourceDir" xml:space="preserve">
- <value>Cannot create a resource directory.</value>
- </data>
<data name="QtProject_CannotAdjustWhitespaces" xml:space="preserve">
<value>Cannot adjust whitespace or tabs in file (write).
({0})</value>
- </data>
- <data name="QtProject_CannotReplaceTokenRead" xml:space="preserve">
- <value>Cannot replace token ({0} -> {1}) in file (read).
-({3})</value>
- </data>
- <data name="QtProject_CannotReplaceTokenWrite" xml:space="preserve">
- <value>Cannot replace token ({0} -> {1}) in file (write).
-({3})</value>
- </data>
- <data name="QtProject_FileExistsInProjectFolder" xml:space="preserve">
- <value>The file {0} exists in your project folder. Qt VS Tools will overwrite the existing file.
-
-Select 'Yes' to overwrite, select 'No' to keep the existing file and automatically add it to the project.</value>
</data>
<data name="QtVersionManager_CannotLoadQtVersion" xml:space="preserve">
<value>Cannot load the default Qt version.</value>
@@ -276,9 +247,6 @@
<data name="Resources_ResourceFiles" xml:space="preserve">
<value>Resource Files</value>
</data>
- <data name="Resources_TranslationFiles" xml:space="preserve">
- <value>Translation Files</value>
- </data>
<data name="Resources_GeneratedFiles" xml:space="preserve">
<value>Generated Files</value>
</data>
@@ -287,12 +255,6 @@
</data>
<data name="QtProject_CannotAccessUserFile" xml:space="preserve">
<value>Could not add QTDIR to {0}'s .user file.</value>
- </data>
- <data name="ImportProject_CannotConvertProject" xml:space="preserve">
- <value>Could not convert project file {0} to Qt/MSBuild.</value>
- </data>
- <data name="Resources_OtherFiles" xml:space="preserve">
- <value>Other Files</value>
</data>
<data name="WaitDialogRefreshMoc" xml:space="preserve">
<value>Updating moc steps...</value>
diff --git a/QtVsTools.Core/SR.cs b/QtVsTools.Core/SR.cs
index ef66800..d5ed78b 100644
--- a/QtVsTools.Core/SR.cs
+++ b/QtVsTools.Core/SR.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,10 +26,7 @@
**
****************************************************************************/
-using System;
-using System.Globalization;
using System.Resources;
-using System.Threading;
namespace QtVsTools.Core
{
@@ -37,7 +34,7 @@
{
static SR loader;
readonly ResourceManager resources;
- static readonly Object obj = new Object();
+ static readonly object obj = new object();
internal SR()
{
@@ -52,20 +49,7 @@
loader = new SR();
}
}
-
return loader;
- }
-
- private static CultureInfo Culture
- {
- get { return null/*use ResourceManager default, CultureInfo.CurrentUICulture*/; }
- //get { return new CultureInfo("de-DE"); }
- }
-
- public static string LanguageName
- {
- get { return Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName; }
- //get { return Culture.TwoLetterISOLanguageName; }
}
public static string GetString(string name, params object[] args)
@@ -73,19 +57,16 @@
var sys = GetLoader();
if (sys == null)
return null;
- var res = sys.resources.GetString(name, Culture);
- if (args != null && args.Length > 0)
+ var res = sys.resources.GetString(name, null);
+ if (args != null && args.Length > 0 && !string.IsNullOrEmpty(res))
return string.Format(res, args);
return res;
}
public static string GetString(string name)
{
- var sys = GetLoader();
- if (sys == null)
- return null;
- return sys.resources.GetString(name, Culture);
+ return GetString(name, null);
}
}
}
diff --git a/QtVsTools.Core/VersionInformation.cs b/QtVsTools.Core/VersionInformation.cs
index fd8cc1a..12d6c81 100644
--- a/QtVsTools.Core/VersionInformation.cs
+++ b/QtVsTools.Core/VersionInformation.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -34,6 +34,7 @@
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
+using Microsoft.VisualStudio.Shell;
namespace QtVsTools.Core
{
@@ -42,11 +43,10 @@
{
//fields
public string name;
- public string qtDir;
+ public readonly string qtDir;
public uint qtMajor; // X in version x.y.z
public uint qtMinor; // Y in version x.y.z
public uint qtPatch; // Z in version x.y.z
- public bool qt5Version = true;
private QtConfig qtConfig;
private QMakeConf qmakeConf;
private string vsPlatformName;
@@ -79,18 +79,18 @@
_cache.Clear();
}
- Dictionary<string, bool> _IsModuleAvailable;
+ readonly Dictionary<string, bool> _IsModuleAvailable;
public bool IsModuleAvailable(string module)
{
return _IsModuleAvailable?[module] ?? false;
}
- public string VC_MinimumVisualStudioVersion { get; private set; }
- public string VC_ApplicationTypeRevision { get; private set; }
- public string VC_WindowsTargetPlatformMinVersion { get; private set; }
- public string VC_WindowsTargetPlatformVersion { get; private set; }
- public string VC_Link_TargetMachine { get; private set; }
- public string VC_PlatformToolset { get; private set; }
+ public string VC_MinimumVisualStudioVersion { get; }
+ public string VC_ApplicationTypeRevision { get; }
+ public string VC_WindowsTargetPlatformMinVersion { get; }
+ public string VC_WindowsTargetPlatformVersion { get; }
+ public string VC_Link_TargetMachine { get; }
+ private string VC_PlatformToolset { get; }
private VersionInformation(string qtDirIn)
{
@@ -128,7 +128,6 @@
qtMinor = (version >> 8) & 0xFF;
qtPatch = version & 0xFF;
}
- qt5Version = (qtMajor == 5);
try {
QtInstallDocs = qmakeQuery["QT_INSTALL_DOCS"];
@@ -143,7 +142,7 @@
var tempProData = new StringBuilder();
tempProData.AppendLine("SOURCES = main.cpp");
- var modules = QtModules.Instance.GetAvailableModules()
+ var modules = QtModules.Instance.GetAvailableModules(qtMajor)
.Where((QtModule mi) => mi.Selectable);
foreach (QtModule mi in modules) {
@@ -194,7 +193,7 @@
public string QtInstallDocs
{
- get; private set;
+ get;
}
public string QMakeSpecDirectory
diff --git a/QtVsTools.Core/VisualStudio/InfoBarMessage.cs b/QtVsTools.Core/VisualStudio/InfoBarMessage.cs
new file mode 100644
index 0000000..b5572b0
--- /dev/null
+++ b/QtVsTools.Core/VisualStudio/InfoBarMessage.cs
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using Microsoft.VisualStudio.Imaging.Interop;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+
+namespace QtVsTools.VisualStudio
+{
+ using Common;
+
+ public abstract class InfoBarMessage
+ {
+ protected abstract ImageMoniker Icon { get; }
+ protected abstract TextSpan[] Text { get; }
+ protected abstract Hyperlink[] Hyperlinks { get; }
+
+ protected class TextSpan
+ {
+ public string Text { get; set; }
+ public bool Bold { get; set; }
+ public bool Italic { get; set; }
+ public bool Underline { get; set; }
+ public static implicit operator TextSpan(string text) => new TextSpan { Text = text };
+ }
+
+ protected class TextSpacer : TextSpan
+ {
+ public TextSpacer(int spaces)
+ {
+ Text = new string(' ', spaces);
+ }
+ }
+
+ protected class Hyperlink
+ {
+ public string Text { get; set; }
+ public bool CloseInfoBar { get; set; }
+ public Action OnClicked { get; set; }
+ }
+
+ private MessageUI UI { get; set; }
+
+ public InfoBarMessage()
+ {
+ UI = new MessageUI { Message = this };
+ }
+
+ public virtual void Show()
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ UI.Show();
+ }
+
+ public virtual void Close()
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ UI.Close();
+ }
+
+ public bool IsOpen => UI.IsOpen;
+
+ protected virtual void OnClosed()
+ { }
+
+ private class MessageUI : IVsInfoBarUIEvents
+ {
+ static LazyFactory StaticLazy { get; } = new LazyFactory();
+ static IVsInfoBarUIFactory Factory => StaticLazy.Get(() =>
+ Factory, () => VsServiceProvider
+ .GetService<SVsInfoBarUIFactory, IVsInfoBarUIFactory>());
+
+ private IVsInfoBarUIElement UIElement { get; set; }
+ private uint eventNotificationCookie;
+
+ public bool IsOpen => UIElement != null;
+
+ public InfoBarMessage Message { get; set; }
+
+ public void Show()
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ if (Factory == null)
+ return;
+ if (UIElement != null) // Message already shown
+ return;
+ var textSpans = Enumerable.Empty<InfoBarTextSpan>();
+ if (Message.Text != null) {
+ textSpans = Message.Text
+ .Select(x => new InfoBarTextSpan(x.Text, x.Bold, x.Italic, x.Underline));
+ }
+ var hyperlinks = Enumerable.Empty<InfoBarHyperlink>();
+ if (Message.Hyperlinks != null) {
+ hyperlinks = Message.Hyperlinks
+ .Select(x => new InfoBarHyperlink(x.Text, x));
+ }
+ var model = new InfoBarModel(textSpans, hyperlinks, Message.Icon, true);
+ UIElement = Factory.CreateInfoBar(model);
+ if (UIElement != null) {
+ UIElement.Advise(this, out eventNotificationCookie);
+ VsShell.InfoBarHost?.AddInfoBar(UIElement);
+ }
+ }
+
+ public void Close()
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ UIElement?.Close();
+ }
+
+ void IVsInfoBarUIEvents.OnActionItemClicked(
+ IVsInfoBarUIElement infoBarUIElement,
+ IVsInfoBarActionItem actionItem)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ Debug.Assert(infoBarUIElement == UIElement);
+ var hyperlink = actionItem.ActionContext as Hyperlink;
+ if (hyperlink == null)
+ return;
+ if (hyperlink.CloseInfoBar)
+ Close();
+ hyperlink.OnClicked();
+ }
+
+ void IVsInfoBarUIEvents.OnClosed(IVsInfoBarUIElement infoBarUIElement)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ Debug.Assert(infoBarUIElement == UIElement);
+ if (UIElement != null) {
+ UIElement.Unadvise(eventNotificationCookie);
+ UIElement = null;
+ eventNotificationCookie = 0;
+ Message.OnClosed();
+ }
+ }
+ }
+ }
+}
diff --git a/QtVsTools.Core/VisualStudio/VsSearch.cs b/QtVsTools.Core/VisualStudio/VsSearch.cs
new file mode 100644
index 0000000..1a79603
--- /dev/null
+++ b/QtVsTools.Core/VisualStudio/VsSearch.cs
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Controls;
+using System.Windows.Data;
+using Microsoft.Internal.VisualStudio.PlatformUI;
+using Microsoft.VisualStudio;
+using Microsoft.VisualStudio.PlatformUI;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+
+namespace QtVsTools.VisualStudio
+{
+ public class SearchTask : VsSearchTask
+ {
+ private readonly Action _clearCallback = null;
+ private readonly Func<IEnumerable<string>, uint> _searchCallBack = null;
+
+ public SearchTask(uint cookie, IVsSearchQuery query, IVsSearchCallback callback,
+ Action clearCallback, Func<IEnumerable<string>, uint> searchCallBack)
+ : base(cookie, query, callback)
+ {
+ _clearCallback = clearCallback;
+ _searchCallBack = searchCallBack;
+ }
+
+ protected override void OnStartSearch()
+ {
+ ErrorCode = VSConstants.S_OK;
+ try {
+ _ = ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ if (TaskStatus != VSConstants.VsSearchTaskStatus.Stopped) {
+ SearchResults = _searchCallBack(
+ SearchUtilities.ExtractSearchTokens(SearchQuery).Select(token =>
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return token.ParsedTokenText;
+ })
+ );
+ } else if (TaskStatus == VSConstants.VsSearchTaskStatus.Stopped) {
+ _clearCallback();
+ }
+ });
+ } catch {
+ ErrorCode = VSConstants.E_FAIL;
+ }
+ base.OnStartSearch();
+ }
+
+ protected override void OnStopSearch()
+ {
+ SearchResults = 0;
+ }
+ }
+
+ public abstract class VsWindowSearch : IVsWindowSearch
+ {
+ public abstract IVsSearchTask CreateSearch(uint cookie, IVsSearchQuery query,
+ IVsSearchCallback callback);
+
+ public virtual void ClearSearch()
+ {}
+
+ public virtual void ProvideSearchSettings(IVsUIDataSource settings)
+ {
+ Utilities.SetValue(settings, SearchSettingsDataSource.PropertyNames.ControlMaxWidth,
+ (uint)10000);
+ Utilities.SetValue(settings, SearchSettingsDataSource.PropertyNames.SearchStartType,
+ (uint)VSSEARCHSTARTTYPE.SST_INSTANT);
+ }
+
+ public virtual bool OnNavigationKeyDown(uint dwNavigationKey, uint dwModifiers) => false;
+
+ public virtual bool SearchEnabled => true;
+
+ public virtual Guid Category => Guid.Empty;
+
+ public virtual IVsEnumWindowSearchFilters SearchFiltersEnum => null;
+
+ public virtual IVsEnumWindowSearchOptions SearchOptionsEnum => null;
+ }
+
+ public class ListBoxSearch : VsWindowSearch
+ {
+ private readonly ListBox _listBox = null;
+ private Action<string> _setSearchText = null;
+
+ public ListBoxSearch(ListBox listBox, Action<string> action)
+ {
+ _listBox = listBox;
+ _setSearchText = action;
+ }
+
+ public override IVsSearchTask CreateSearch(uint cookie, IVsSearchQuery query,
+ IVsSearchCallback callback)
+ {
+ return new SearchTask(cookie, query, callback, ClearSearch,
+ searchCallBack: (IEnumerable<string> tokens) =>
+ {
+ _setSearchText(string.Join(" ", tokens));
+ var view = CollectionViewSource.GetDefaultView(_listBox.ItemsSource);
+
+ view.Refresh();
+ if (_listBox.Items.Count == 1 || _listBox.SelectedItem == null)
+ _listBox.SelectedIndex = 0;
+ return (uint)view.Cast<object>().Count();
+ });
+ }
+
+ public override void ClearSearch()
+ {
+ _setSearchText(string.Empty);
+ CollectionViewSource.GetDefaultView(_listBox.ItemsSource).Refresh();
+ }
+ }
+}
diff --git a/QtVsTools.Core/VisualStudio/VsServiceProvider.cs b/QtVsTools.Core/VisualStudio/VsServiceProvider.cs
index ed53ed5..d9060ed 100644
--- a/QtVsTools.Core/VisualStudio/VsServiceProvider.cs
+++ b/QtVsTools.Core/VisualStudio/VsServiceProvider.cs
@@ -26,7 +26,6 @@
**
****************************************************************************/
-using Microsoft.VisualStudio.Shell;
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
@@ -45,7 +44,7 @@
{
public static IVsServiceProvider Instance { get; set; }
- static ConcurrentDictionary<ServiceType, object> services
+ static readonly ConcurrentDictionary<ServiceType, object> services
= new ConcurrentDictionary<ServiceType, object>();
public static I GetService<I>()
@@ -61,8 +60,7 @@
if (Instance == null)
return null;
- object serviceObj;
- if (services.TryGetValue(new ServiceType(typeof(T), typeof(I)), out serviceObj))
+ if (services.TryGetValue(new ServiceType(typeof(T), typeof(I)), out object serviceObj))
return serviceObj as I;
var serviceInterface = Instance.GetService<T, I>();
@@ -83,8 +81,7 @@
if (Instance == null)
return null;
- object serviceObj;
- if (services.TryGetValue(new ServiceType(typeof(T), typeof(I)), out serviceObj))
+ if (services.TryGetValue(new ServiceType(typeof(T), typeof(I)), out object serviceObj))
return serviceObj as I;
var serviceInterface = await Instance.GetServiceAsync<T, I>();
diff --git a/QtVsTools.Core/VisualStudio/VsShell.cs b/QtVsTools.Core/VisualStudio/VsShell.cs
new file mode 100644
index 0000000..1bccafc
--- /dev/null
+++ b/QtVsTools.Core/VisualStudio/VsShell.cs
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using Microsoft.VisualStudio;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+
+namespace QtVsTools.VisualStudio
+{
+ public static class VsShell
+ {
+ public static string InstallRootDir
+ {
+ get
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ Initialize();
+ return _InstallRootDir;
+ }
+ }
+
+ private static IVsShell vsShell;
+ private static string _InstallRootDir;
+
+ private static void Initialize()
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (vsShell != null)
+ return;
+ vsShell = VsServiceProvider.GetService<IVsShell>();
+
+ int res = vsShell.GetProperty((int)__VSSPROPID2.VSSPROPID_InstallRootDir, out object o);
+ if (res == VSConstants.S_OK && o is string property)
+ _InstallRootDir = property;
+ }
+
+ public static EnvDTE.Project GetProject(IVsHierarchy context)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ int res = context.GetProperty(
+ (uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID.VSHPROPID_ExtObject, out object value);
+ if (res == VSConstants.S_OK && value is EnvDTE.Project project)
+ return project;
+ return null;
+ }
+
+ public static EnvDTE.ProjectItem GetProjectItem(IVsHierarchy context, uint itemid)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ int res = context.GetProperty(
+ itemid, (int)__VSHPROPID.VSHPROPID_ExtObject, out object value);
+ if (res == VSConstants.S_OK && value is EnvDTE.ProjectItem item)
+ return item;
+ return null;
+ }
+
+ public static EnvDTE.Document GetDocument(IVsHierarchy context, uint itemid)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return GetProjectItem(context, itemid)?.Document;
+ }
+
+ private static IVsInfoBarHost _InfoBarHost = null;
+ public static IVsInfoBarHost InfoBarHost
+ {
+ get
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ if (_InfoBarHost != null)
+ return _InfoBarHost;
+ Initialize();
+ object host = null;
+ vsShell?.GetProperty((int)__VSSPROPID7.VSSPROPID_MainWindowInfoBarHost, out host);
+ return _InfoBarHost = host as IVsInfoBarHost;
+ }
+ }
+ }
+}
diff --git a/QtVsTools.Core/WaitDialog.cs b/QtVsTools.Core/WaitDialog.cs
index cff8851..60a6adc 100644
--- a/QtVsTools.Core/WaitDialog.cs
+++ b/QtVsTools.Core/WaitDialog.cs
@@ -27,25 +27,21 @@
****************************************************************************/
using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Windows.Forms;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.VisualStudio.VCProjectEngine;
-using QtVsTools.VisualStudio;
namespace QtVsTools.Core
{
+ using VisualStudio;
+
public class WaitDialog : IDisposable
{
static IVsThreadedWaitDialogFactory factory = null;
- public IVsThreadedWaitDialog2 VsWaitDialog { get; private set; }
+ private IVsThreadedWaitDialog2 VsWaitDialog { get; set; }
- public bool Running { get; private set; }
+ private bool Running { get; set; }
bool? vsDialogCanceled = null;
@@ -53,14 +49,15 @@
{
get
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (vsDialogCanceled.HasValue)
return vsDialogCanceled.Value;
if (VsWaitDialog == null)
return false;
- bool canceled = false;
- int res = VsWaitDialog.HasCanceled(out canceled);
+ int res = VsWaitDialog.HasCanceled(out bool canceled);
if (res != VSConstants.S_OK)
return false;
@@ -76,6 +73,8 @@
static WaitDialog Create(IVsThreadedWaitDialogFactory dialogFactory)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (factory == null) {
factory = dialogFactory ?? VsServiceProvider
.GetService<SVsThreadedWaitDialogFactory, IVsThreadedWaitDialogFactory>();
@@ -83,8 +82,7 @@
return null;
}
- IVsThreadedWaitDialog2 vsWaitDialog = null;
- factory.CreateInstance(out vsWaitDialog);
+ factory.CreateInstance(out IVsThreadedWaitDialog2 vsWaitDialog);
if (vsWaitDialog == null)
return null;
@@ -105,6 +103,8 @@
bool showMarqueeProgress = true,
IVsThreadedWaitDialogFactory dialogFactory = null)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var dialog = Create(dialogFactory);
if (dialog == null)
return null;
@@ -129,6 +129,8 @@
bool isCancelable = false,
IVsThreadedWaitDialogFactory dialogFactory = null)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var dialog = Create(dialogFactory);
if (dialog == null)
return null;
@@ -151,12 +153,13 @@
string statusBarText = null,
bool disableCancel = false)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (!Running)
return;
- bool canceled = false;
int res = VsWaitDialog.UpdateProgress(message, progressText,
- statusBarText, currentStep, totalSteps, disableCancel, out canceled);
+ statusBarText, currentStep, totalSteps, disableCancel, out bool canceled);
if (res != VSConstants.S_OK)
return;
@@ -167,18 +170,22 @@
public void Stop()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (!Running)
return;
Running = false;
- int canceled = 0;
- VsWaitDialog.EndWaitDialog(out canceled);
+ VsWaitDialog.EndWaitDialog(out int canceled);
Canceled = (canceled != 0);
}
void IDisposable.Dispose()
{
- Stop();
+ ThreadHelper.JoinableTaskFactory.Run(async () => {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ Stop();
+ });
}
}
}
diff --git a/QtVsTools.Package/Common/Concurrent.cs b/QtVsTools.Package/Common/Concurrent.cs
index d1426f4..c963968 100644
--- a/QtVsTools.Package/Common/Concurrent.cs
+++ b/QtVsTools.Package/Common/Concurrent.cs
@@ -40,12 +40,9 @@
public abstract class Concurrent<TSubClass>
where TSubClass : Concurrent<TSubClass>
{
- private static readonly object _StaticCriticalSection = new object();
- protected static object StaticCriticalSection => _StaticCriticalSection;
+ protected static object StaticCriticalSection { get; } = new object();
- private object _CriticalSection = null;
- protected object CriticalSection =>
- StaticThreadSafeInit(() => _CriticalSection, () => _CriticalSection = new object());
+ protected object CriticalSection { get; } = new object();
protected T ThreadSafeInit<T>(Func<T> getValue, Action init)
where T : class
diff --git a/QtVsTools.Package/Common/ConcurrentStopwatch.cs b/QtVsTools.Package/Common/ConcurrentStopwatch.cs
index 82547e0..35f78b3 100644
--- a/QtVsTools.Package/Common/ConcurrentStopwatch.cs
+++ b/QtVsTools.Package/Common/ConcurrentStopwatch.cs
@@ -33,7 +33,7 @@
{
public class ConcurrentStopwatch : Concurrent<ConcurrentStopwatch>
{
- Stopwatch Stopwatch { get; set; }
+ Stopwatch Stopwatch { get; }
public ConcurrentStopwatch()
{
diff --git a/QtVsTools.Package/Common/Json/DeferredObject.cs b/QtVsTools.Package/Common/Json/DeferredObject.cs
index 9ecc47b..d8c2a06 100644
--- a/QtVsTools.Package/Common/Json/DeferredObject.cs
+++ b/QtVsTools.Package/Common/Json/DeferredObject.cs
@@ -26,8 +26,6 @@
**
****************************************************************************/
-using System;
-using System.Collections.Generic;
using System.Runtime.Serialization;
namespace QtVsTools.Json
diff --git a/QtVsTools.Package/Common/Json/Serializable.cs b/QtVsTools.Package/Common/Json/Serializable.cs
index 2d2b990..32e02b4 100644
--- a/QtVsTools.Package/Common/Json/Serializable.cs
+++ b/QtVsTools.Package/Common/Json/Serializable.cs
@@ -48,7 +48,7 @@
{
#region //////////////////// Prototype ////////////////////////////////////////////////////
- protected Serializer Serializer { get; set; }
+ private Serializer Serializer { get; set; }
protected Serializable()
{ }
@@ -192,9 +192,11 @@
var container = toDo.Dequeue();
foreach (var defObj in container.PendingObjects) {
defObj.Deserialize();
- var subContainer = defObj.Object as IDeferredObjectContainer;
- if (subContainer != null && subContainer.PendingObjects.Any())
+ if (defObj.Object is IDeferredObjectContainer subContainer
+ && subContainer.PendingObjects.Any()) {
toDo.Enqueue(subContainer);
+
+ }
}
}
return obj;
diff --git a/QtVsTools.Package/Common/Json/SerializableEnum.cs b/QtVsTools.Package/Common/Json/SerializableEnum.cs
index 6493668..832c42c 100644
--- a/QtVsTools.Package/Common/Json/SerializableEnum.cs
+++ b/QtVsTools.Package/Common/Json/SerializableEnum.cs
@@ -27,7 +27,6 @@
****************************************************************************/
using System;
-using System.ComponentModel;
using System.Linq;
using System.Reflection;
@@ -106,7 +105,7 @@
class EnumStringAttribute : Attribute
{
- public string ValueString { get; private set; }
+ public string ValueString { get; }
public EnumStringAttribute(string enumValueString)
{
diff --git a/QtVsTools.Package/Common/Json/Serializer.cs b/QtVsTools.Package/Common/Json/Serializer.cs
index d263207..8121eed 100644
--- a/QtVsTools.Package/Common/Json/Serializer.cs
+++ b/QtVsTools.Package/Common/Json/Serializer.cs
@@ -36,6 +36,7 @@
using System.Runtime.Serialization.Json;
using System.Text;
using System.Xml;
+using QtVsTools.Core;
/// <summary>
/// The classes in this namespace provide support to the serialization and deserialization of
@@ -127,11 +128,10 @@
serializer.WriteObject(writer, obj);
writer.Close();
return new JsonData() { Stream = stream };
- } catch (Exception e) {
+ } catch (Exception exception) {
+ exception.Log();
if (stream != null && stream.CanRead && stream.Length > 0)
stream.Dispose();
- System.Diagnostics.Debug.WriteLine(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
return null;
}
}
@@ -151,16 +151,14 @@
using (reader = XmlReader.Create(data.XmlStream)) {
var obj = serializer.ReadObject(reader, false);
- var container = obj as IDeferredObjectContainer;
- if (container != null)
+ if (obj is IDeferredObjectContainer container)
deferredObjects.ForEach(x => container.Add(x));
return obj;
}
- } catch (Exception e) {
- System.Diagnostics.Debug.WriteLine(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
return null;
} finally {
@@ -206,9 +204,8 @@
data.XmlStream = new MemoryStream(xmlData);
}
return true;
- } catch (Exception e) {
- System.Diagnostics.Debug.WriteLine(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
return false;
}
}
@@ -245,9 +242,9 @@
#region //////////////////// Data Contract Surrogate //////////////////////////////////////
- static Exclusive<Serializer> sharedInstance = new Exclusive<Serializer>();
+ static readonly Exclusive<Serializer> sharedInstance = new Exclusive<Serializer>();
private XmlReader reader = null;
- private List<IDeferredObject> deferredObjects = new List<IDeferredObject>();
+ private readonly List<IDeferredObject> deferredObjects = new List<IDeferredObject>();
public static IJsonData GetCurrentJsonData()
{
@@ -260,9 +257,8 @@
root.Append("</root>");
var xmlData = Encoding.UTF8.GetBytes(root.ToString());
return new JsonData { XmlStream = new MemoryStream(xmlData) };
- } catch (Exception e) {
- System.Diagnostics.Debug.WriteLine(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
return null;
}
}
diff --git a/QtVsTools.Package/Common/NativeAPI.cs b/QtVsTools.Package/Common/NativeAPI.cs
index 155db09..4cf3ba9 100644
--- a/QtVsTools.Package/Common/NativeAPI.cs
+++ b/QtVsTools.Package/Common/NativeAPI.cs
@@ -127,12 +127,12 @@
szTypeName = "";
}
public IntPtr hIcon;
- public int iIcon;
- public uint dwAttributes;
+ private readonly int iIcon;
+ private readonly uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
- public string szDisplayName;
+ private readonly string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_TYPE)]
- public string szTypeName;
+ private readonly string szTypeName;
};
[Flags]
diff --git a/QtVsTools.Package/Common/PriorityQueue.cs b/QtVsTools.Package/Common/PriorityQueue.cs
index cdc57e7..af8fffd 100644
--- a/QtVsTools.Package/Common/PriorityQueue.cs
+++ b/QtVsTools.Package/Common/PriorityQueue.cs
@@ -51,8 +51,8 @@
public abstract class BasePriorityQueue<T, TPriority> : Concurrent, IEnumerable<T>
where TPriority : IComparable<TPriority>
{
- SortedDictionary<TPriority, T> ItemsByPriority { get; set; }
- Dictionary<object, TPriority> ItemPriority { get; set; }
+ SortedDictionary<TPriority, T> ItemsByPriority { get; }
+ Dictionary<object, TPriority> ItemPriority { get; }
T Head { get; set; }
public int Count { get; private set; }
public bool IsEmpty => (Count == 0);
@@ -61,7 +61,7 @@
IEnumerator<T> IEnumerable<T>.GetEnumerator() => Items.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => Items.GetEnumerator();
- Func<T, object> GetItemKey { get; set; }
+ Func<T, object> GetItemKey { get; }
public BasePriorityQueue() : this(x => x)
{ }
@@ -102,11 +102,10 @@
if (item == null)
throw new InvalidOperationException("Item cannot be null.");
lock (CriticalSection) {
- T oldItem;
- if (ItemsByPriority.TryGetValue(priority, out oldItem) && !item.Equals(oldItem))
+ if (ItemsByPriority.TryGetValue(priority, out T oldItem) && !item.Equals(oldItem))
throw new InvalidOperationException("An item with the same priority exists.");
- TPriority oldPriority;
- if (ItemPriority.TryGetValue(GetItemKey(item), out oldPriority)) {
+
+ if (ItemPriority.TryGetValue(GetItemKey(item), out TPriority oldPriority)) {
ItemsByPriority.Remove(oldPriority);
--Count;
}
@@ -128,8 +127,7 @@
public T Peek()
{
lock (CriticalSection) {
- T result;
- if (!TryPeek(out result))
+ if (!TryPeek(out T result))
throw new InvalidOperationException("Queue is empty.");
return result;
}
@@ -167,8 +165,7 @@
public T Dequeue()
{
lock (CriticalSection) {
- T result;
- if (!TryDequeue(out result))
+ if (!TryDequeue(out T result))
throw new InvalidOperationException("Queue is empty.");
return result;
}
diff --git a/QtVsTools.Package/Common/Prototyped.cs b/QtVsTools.Package/Common/Prototyped.cs
index cba7019..94bd14b 100644
--- a/QtVsTools.Package/Common/Prototyped.cs
+++ b/QtVsTools.Package/Common/Prototyped.cs
@@ -134,7 +134,7 @@
static readonly object classCriticalSection = new object();
- static Dictionary<Type, List<Type>> types = GetTypeHierarchy(typeof(TBase));
+ static readonly Dictionary<Type, List<Type>> types = GetTypeHierarchy(typeof(TBase));
static Dictionary<Type, List<Type>> GetTypeHierarchy(Type baseType)
{
@@ -174,7 +174,7 @@
return subTypes;
}
- static Dictionary<Type, SubClass> classes = types
+ static readonly Dictionary<Type, SubClass> classes = types
.ToDictionary(x => x.Key, x => Create(x.Key, x.Value));
static SubClass Create(Type type, IEnumerable<Type> subTypes)
@@ -194,8 +194,7 @@
lock (classCriticalSection) {
- SubClass subClass = null;
- if (!classes.TryGetValue(type, out subClass)) {
+ if (!classes.TryGetValue(type, out SubClass subClass)) {
var newTypes = GetTypeHierarchy(type)
.Where(x => !classes.ContainsKey(x.Key));
@@ -213,7 +212,7 @@
}
}
- public static SubClass baseClass = Get(typeof(TBase));
+ public static readonly SubClass baseClass = Get(typeof(TBase));
}
#endregion //////////////////// SubClass //////////////////////////////////////////////////
diff --git a/QtVsTools.Package/Common/Timestamp.cs b/QtVsTools.Package/Common/Timestamp.cs
index deaf18a..cf3155e 100644
--- a/QtVsTools.Package/Common/Timestamp.cs
+++ b/QtVsTools.Package/Common/Timestamp.cs
@@ -30,8 +30,12 @@
namespace QtVsTools
{
+ using Common;
+
public class Timestamp : Concurrent<Timestamp>
{
+ static LazyFactory StaticLazy { get; } = new LazyFactory();
+
long LastTimestamp { get; set; }
long GetStrictMonotonicTimestamp()
{
@@ -43,9 +47,8 @@
}
}
- static Timestamp _Instance;
- static Timestamp Instance =>
- StaticThreadSafeInit(() => _Instance, () => _Instance = new Timestamp());
+ static Timestamp Instance => StaticLazy.Get(() =>
+ Instance, () => new Timestamp());
public static long Next()
{
diff --git a/QtVsTools.Package/Editors/Editor.QtDesigner.cs b/QtVsTools.Package/Editors/Editor.QtDesigner.cs
index 518bd6c..73148b0 100644
--- a/QtVsTools.Package/Editors/Editor.QtDesigner.cs
+++ b/QtVsTools.Package/Editors/Editor.QtDesigner.cs
@@ -31,12 +31,15 @@
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
-using Microsoft.VisualStudio.Shell.Interop;
-using QtVsTools.QtMsBuild;
-using QtVsTools.VisualStudio;
+using Microsoft.VisualStudio.Shell;
+
+using Task = System.Threading.Tasks.Task;
namespace QtVsTools.Editors
{
+ using QtMsBuild;
+ using VisualStudio;
+
[Guid(GuidString)]
public class QtDesigner : Editor
{
@@ -58,27 +61,31 @@
protected override void OnStart(Process process)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
base.OnStart(process);
var document = VsShell.GetDocument(Context, ItemId);
if (document == null)
return;
+
var project = document.ProjectItem?.ContainingProject;
- if (project == null || !QtProjectTracker.IsTracked(project))
+ if (project == null || !QtProjectTracker.IsTracked(project.FullName))
return;
+ string projectPath = project.FullName;
string filePath = document.FullName;
string[] itemId = new[] { document.ProjectItem?.Name };
var lastWriteTime = File.GetLastWriteTime(filePath);
- Task.Run(() =>
+ _ = Task.Run(async () =>
{
while (!process.WaitForExit(1000)) {
var latestWriteTime = File.GetLastWriteTime(filePath);
if (lastWriteTime != latestWriteTime) {
lastWriteTime = latestWriteTime;
- QtProjectIntellisense.Refresh(project, selectedFiles: itemId);
+ await QtProjectIntellisense.RefreshAsync(project, projectPath);
}
}
if (lastWriteTime != File.GetLastWriteTime(filePath)) {
- QtProjectIntellisense.Refresh(project, selectedFiles: itemId);
+ await QtProjectIntellisense.RefreshAsync(project, projectPath);
}
});
}
diff --git a/QtVsTools.Package/Editors/Editor.QtResourceEditor.cs b/QtVsTools.Package/Editors/Editor.QtResourceEditor.cs
index 6c159cd..0c38ad7 100644
--- a/QtVsTools.Package/Editors/Editor.QtResourceEditor.cs
+++ b/QtVsTools.Package/Editors/Editor.QtResourceEditor.cs
@@ -29,7 +29,7 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
-using Microsoft.VisualStudio.Shell.Interop;
+using Microsoft.VisualStudio.Shell;
namespace QtVsTools.Editors
{
@@ -44,18 +44,13 @@
public override string ExecutableName => "QrcEditor.exe";
- protected override string GetToolsPath()
- {
- return QtVsToolsPackage.Instance?.PkgInstallPath;
- }
+ protected override string GetToolsPath() =>
+ QtVsToolsPackage.Instance?.PkgInstallPath;
public override Func<string, bool> WindowFilter =>
caption => caption.StartsWith(Title);
- protected override string GetTitle(Process editorProcess)
- {
- return Title;
- }
+ protected override string GetTitle(Process editorProcess) => Title;
protected override bool Detached => QtVsToolsPackage.Instance.Options.ResourceEditorDetached;
}
diff --git a/QtVsTools.Package/Editors/Editor.cs b/QtVsTools.Package/Editors/Editor.cs
index 754f4ba..58db95a 100644
--- a/QtVsTools.Package/Editors/Editor.cs
+++ b/QtVsTools.Package/Editors/Editor.cs
@@ -40,11 +40,12 @@
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.VCProjectEngine;
-using QtVsTools.Core;
-using QtVsTools.VisualStudio;
namespace QtVsTools.Editors
{
+ using Core;
+ using VisualStudio;
+
using static Core.HelperFunctions;
public abstract class Editor : IVsEditorFactory
@@ -61,6 +62,7 @@
protected virtual string GetToolsPath()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
return GetQtToolsPath() ?? GetDefaultQtToolsPath();
}
@@ -69,33 +71,37 @@
string GetQtToolsPath()
{
- var project = VsShell.GetProject(Context);
- if (project == null)
- return null;
+ return ThreadHelper.JoinableTaskFactory.Run(async () =>
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ var project = VsShell.GetProject(Context);
+ if (project == null)
+ return null;
- var vcProject = project.Object as VCProject;
- if (vcProject == null)
- return null;
+ var vcProject = project.Object as VCProject;
+ if (vcProject == null)
+ return null;
- var vcConfigs = vcProject.Configurations as IVCCollection;
- if (vcConfigs == null)
- return null;
+ var vcConfigs = vcProject.Configurations as IVCCollection;
+ if (vcConfigs == null)
+ return null;
- var activeConfig = project.ConfigurationManager?.ActiveConfiguration;
- if (activeConfig == null)
- return null;
+ var activeConfig = project.ConfigurationManager?.ActiveConfiguration;
+ if (activeConfig == null)
+ return null;
- var activeConfigId = string.Format("{0}|{1}",
- activeConfig.ConfigurationName, activeConfig.PlatformName);
- var vcConfig = vcConfigs.Item(activeConfigId) as VCConfiguration;
- if (vcConfig == null)
- return null;
+ var activeConfigId = string.Format("{0}|{1}",
+ activeConfig.ConfigurationName, activeConfig.PlatformName);
+ var vcConfig = vcConfigs.Item(activeConfigId) as VCConfiguration;
+ if (vcConfig == null)
+ return null;
- var qtToolsPath = vcConfig.GetEvaluatedPropertyValue("QtToolsPath");
- if (string.IsNullOrEmpty(qtToolsPath))
- return null;
+ var qtToolsPath = vcConfig.GetEvaluatedPropertyValue("QtToolsPath");
+ if (string.IsNullOrEmpty(qtToolsPath))
+ return null;
- return qtToolsPath;
+ return qtToolsPath;
+ });
}
string GetDefaultQtToolsPath()
@@ -126,6 +132,8 @@
out Guid pguidCmdUI,
out int pgrfCDW)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
// Initialize to null
ppunkDocView = IntPtr.Zero;
ppunkDocData = IntPtr.Zero;
@@ -202,11 +210,15 @@
{
if (string.IsNullOrEmpty(qtToolsPath))
qtToolsPath = GetDefaultQtToolsPath();
+ var st = GetStartInfo(filePath, qtToolsPath, hideWindow);
try {
- return Process.Start(GetStartInfo(filePath, qtToolsPath, hideWindow));
- } catch (Exception e) {
- Messages.Print(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ return Process.Start(st);
+ } catch (Exception exception) {
+ exception.Log();
+ if (!File.Exists(st.Arguments))
+ Messages.Print("The system cannot find the file: " + st.Arguments);
+ if (!File.Exists(st.FileName))
+ Messages.Print("The system cannot find the file: " + st.FileName);
return null;
}
}
@@ -223,20 +235,20 @@
private class EditorPane : WindowPane, IVsPersistDocData
{
- public Editor Editor { get; private set; }
- public string QtToolsPath { get; private set; }
+ private Editor Editor { get; }
+ private string QtToolsPath { get; }
- public TableLayoutPanel EditorContainer { get; private set; }
- public Label EditorTitle { get; private set; }
- public LinkLabel EditorDetachButton { get; private set; }
- public Panel EditorControl { get; private set; }
+ private TableLayoutPanel EditorContainer { get; set; }
+ private Label EditorTitle { get; }
+ private LinkLabel EditorDetachButton { get; }
+ private Panel EditorControl { get; }
public override IWin32Window Window => EditorContainer;
- public Process EditorProcess { get; private set; }
- public IntPtr EditorWindow { get; private set; }
- public int EditorWindowStyle { get; private set; }
- public int EditorWindowStyleExt { get; private set; }
- public IntPtr EditorIcon { get; private set; }
+ private Process EditorProcess { get; set; }
+ private IntPtr EditorWindow { get; set; }
+ private int EditorWindowStyle { get; set; }
+ private int EditorWindowStyleExt { get; set; }
+ private IntPtr EditorIcon { get; set; }
public EditorPane(Editor editor, string qtToolsPath)
{
@@ -306,11 +318,11 @@
int IVsPersistDocData.LoadDocData(string pszMkDocument)
{
- var solution = GetService(typeof(SVsSolution)) as IVsSolution;
EditorProcess = Editor.Start(pszMkDocument, QtToolsPath,
hideWindow: !Editor.Detached);
if (EditorProcess == null)
return VSConstants.E_FAIL;
+
if (Editor.Detached) {
Editor.OnStart(EditorProcess);
CloseParentFrame();
@@ -395,8 +407,12 @@
{
EditorProcess = null;
EditorWindow = IntPtr.Zero;
- var parentFrame = GetService(typeof(SVsWindowFrame)) as IVsWindowFrame;
- parentFrame?.CloseFrame((uint)__FRAMECLOSE.FRAMECLOSE_NoSave);
+ ThreadHelper.JoinableTaskFactory.Run(async () =>
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ var parentFrame = GetService(typeof(SVsWindowFrame)) as IVsWindowFrame;
+ parentFrame?.CloseFrame((uint)__FRAMECLOSE.FRAMECLOSE_NoSave);
+ });
}
private void EditorProcess_Exited(object sender, EventArgs e)
@@ -452,7 +468,7 @@
EditorWindow = IntPtr.Zero;
// Close editor window
- System.Threading.Tasks.Task.Run(() =>
+ _ = System.Threading.Tasks.Task.Run(() =>
{
NativeAPI.SendMessage(editorWindow, NativeAPI.WM_CLOSE, 0, 0);
if (!editorProcess.WaitForExit(500)) {
diff --git a/QtVsTools.Package/Icons/Monikers.imagemanifest b/QtVsTools.Package/Icons/Monikers.imagemanifest
new file mode 100644
index 0000000..27e1e2b
--- /dev/null
+++ b/QtVsTools.Package/Icons/Monikers.imagemanifest
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ImageManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://schemas.microsoft.com/VisualStudio/ImageManifestSchema/2014">
+ <Symbols>
+ <String Name="Resources" Value="/QtVsTools;Component/Icons" />
+ <Guid Name="QtMonikersGuid" Value="{0d2e443f-6dbb-4001-99dc-9cd7d5c924e7}" />
+ <ID Name="prf" Value="0" />
+ <ID Name="pri" Value="1" />
+ <ID Name="pro" Value="2" />
+ <ID Name="qml" Value="3" />
+ <ID Name="qrc" Value="4" />
+ <ID Name="ts" Value="5" />
+ <ID Name="ui" Value="6" />
+ </Symbols>
+ <Images>
+ <Image Guid="$(QtMonikersGuid)" ID="$(prf)">
+ <Source Uri="$(Resources)/prf32.png">
+ <Size Value="32" />
+ </Source>
+ </Image>
+ <Image Guid="$(QtMonikersGuid)" ID="$(pri)">
+ <Source Uri="$(Resources)/pri32.png">
+ <Size Value="32" />
+ </Source>
+ </Image>
+ <Image Guid="$(QtMonikersGuid)" ID="$(pro)">
+ <Source Uri="$(Resources)/pro32.png">
+ <Size Value="32" />
+ </Source>
+ </Image>
+ <Image Guid="$(QtMonikersGuid)" ID="$(qml)">
+ <Source Uri="$(Resources)/qml32.png">
+ <Size Value="32" />
+ </Source>
+ </Image>
+ <Image Guid="$(QtMonikersGuid)" ID="$(qrc)">
+ <Source Uri="$(Resources)/qrc32.png">
+ <Size Value="32" />
+ </Source>
+ </Image>
+ <Image Guid="$(QtMonikersGuid)" ID="$(ts)">
+ <Source Uri="$(Resources)/ts32.png">
+ <Size Value="32" />
+ </Source>
+ </Image>
+ <Image Guid="$(QtMonikersGuid)" ID="$(ui)">
+ <Source Uri="$(Resources)/ui32.png">
+ <Size Value="32" />
+ </Source>
+ </Image>
+ </Images>
+ <ImageLists />
+</ImageManifest>
diff --git a/QtVsTools.Package/Icons/prf32.png b/QtVsTools.Package/Icons/prf32.png
new file mode 100644
index 0000000..359c5c8
--- /dev/null
+++ b/QtVsTools.Package/Icons/prf32.png
Binary files differ
diff --git a/QtVsTools.Package/Icons/pri32.png b/QtVsTools.Package/Icons/pri32.png
new file mode 100644
index 0000000..f82fea4
--- /dev/null
+++ b/QtVsTools.Package/Icons/pri32.png
Binary files differ
diff --git a/QtVsTools.Package/Icons/pro32.png b/QtVsTools.Package/Icons/pro32.png
new file mode 100644
index 0000000..13d8a84
--- /dev/null
+++ b/QtVsTools.Package/Icons/pro32.png
Binary files differ
diff --git a/QtVsTools.Package/Icons/qml32.png b/QtVsTools.Package/Icons/qml32.png
new file mode 100644
index 0000000..85ad155
--- /dev/null
+++ b/QtVsTools.Package/Icons/qml32.png
Binary files differ
diff --git a/QtVsTools.Package/Icons/qrc32.png b/QtVsTools.Package/Icons/qrc32.png
new file mode 100644
index 0000000..b4b70d8
--- /dev/null
+++ b/QtVsTools.Package/Icons/qrc32.png
Binary files differ
diff --git a/QtVsTools.Package/Icons/ts32.png b/QtVsTools.Package/Icons/ts32.png
new file mode 100644
index 0000000..9731b08
--- /dev/null
+++ b/QtVsTools.Package/Icons/ts32.png
Binary files differ
diff --git a/QtVsTools.Package/Icons/ui32.png b/QtVsTools.Package/Icons/ui32.png
new file mode 100644
index 0000000..5a40101
--- /dev/null
+++ b/QtVsTools.Package/Icons/ui32.png
Binary files differ
diff --git a/QtVsTools.Package/Legacy/ChangeFor.cs b/QtVsTools.Package/Legacy/ChangeFor.cs
new file mode 100644
index 0000000..8eb45fd
--- /dev/null
+++ b/QtVsTools.Package/Legacy/ChangeFor.cs
@@ -0,0 +1,32 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+namespace QtVsTools.Legacy
+{
+ internal enum ChangeFor { Solution, Project }
+}
diff --git a/QtVsTools.Package/Legacy/FormChangeQtVersion.Designer.cs b/QtVsTools.Package/Legacy/FormChangeQtVersion.Designer.cs
new file mode 100644
index 0000000..52fdac0
--- /dev/null
+++ b/QtVsTools.Package/Legacy/FormChangeQtVersion.Designer.cs
@@ -0,0 +1,87 @@
+namespace QtVsTools.Legacy
+{
+ partial class FormChangeQtVersion
+ {
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ btnOK = new System.Windows.Forms.Button();
+ btnCancel = new System.Windows.Forms.Button();
+ lbQtVersions = new System.Windows.Forms.ListBox();
+ lQtVersions = new System.Windows.Forms.Label();
+ SuspendLayout();
+ //
+ // btnOK
+ //
+ btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
+ btnOK.Location = new System.Drawing.Point(124, 231);
+ btnOK.Name = "btnOK";
+ btnOK.Size = new System.Drawing.Size(75, 23);
+ btnOK.TabIndex = 1;
+ btnOK.Text = "&OK";
+ btnOK.UseVisualStyleBackColor = true;
+ //
+ // btnCancel
+ //
+ btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ btnCancel.Location = new System.Drawing.Point(205, 231);
+ btnCancel.Name = "btnCancel";
+ btnCancel.Size = new System.Drawing.Size(75, 23);
+ btnCancel.TabIndex = 2;
+ btnCancel.Text = "&Cancel";
+ btnCancel.UseVisualStyleBackColor = true;
+ //
+ // lbQtVersions
+ //
+ lbQtVersions.FormattingEnabled = true;
+ lbQtVersions.Location = new System.Drawing.Point(13, 39);
+ lbQtVersions.Name = "lbQtVersions";
+ lbQtVersions.Size = new System.Drawing.Size(267, 173);
+ lbQtVersions.TabIndex = 0;
+ //
+ // lQtVersions
+ //
+ lQtVersions.AutoSize = true;
+ lQtVersions.Location = new System.Drawing.Point(13, 20);
+ lQtVersions.Name = "lQtVersions";
+ lQtVersions.Size = new System.Drawing.Size(103, 13);
+ lQtVersions.TabIndex = 3;
+ lQtVersions.Text = "Installed Qt Versions";
+ //
+ // FormChangeQtVersion
+ //
+ AcceptButton = btnOK;
+ AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ CancelButton = btnCancel;
+ ClientSize = new System.Drawing.Size(292, 266);
+ Controls.Add(lQtVersions);
+ Controls.Add(lbQtVersions);
+ Controls.Add(btnCancel);
+ Controls.Add(btnOK);
+ FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+ KeyPreview = true;
+ MaximizeBox = false;
+ MinimizeBox = false;
+ Name = "FormChangeQtVersion";
+ ShowInTaskbar = false;
+ Text = "FormChangeQtVersion";
+ ResumeLayout(false);
+ PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.Button btnCancel;
+ private System.Windows.Forms.ListBox lbQtVersions;
+ private System.Windows.Forms.Label lQtVersions;
+ }
+}
diff --git a/QtVsTools.Package/Legacy/FormChangeQtVersion.cs b/QtVsTools.Package/Legacy/FormChangeQtVersion.cs
new file mode 100644
index 0000000..a001086
--- /dev/null
+++ b/QtVsTools.Package/Legacy/FormChangeQtVersion.cs
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Windows.Forms;
+using Microsoft.VisualStudio.Shell;
+
+namespace QtVsTools.Legacy
+{
+ using Core;
+ using Legacy = Core.Legacy;
+
+ public partial class FormChangeQtVersion : Form
+ {
+ public FormChangeQtVersion()
+ {
+ InitializeComponent();
+ btnOK.Text = "&OK";
+ btnCancel.Text = "&Cancel";
+ lQtVersions.Text = "Installed Qt Versions";
+ lbQtVersions.DoubleClick += OnQtVersions_DoubleClick;
+ KeyPress += FormChangeQtVersion_KeyPress;
+ Shown += FormChangeQtVersion_Shown;
+ }
+
+ private void FormChangeQtVersion_Shown(object sender, EventArgs e)
+ {
+ Text = "Set Solution's Qt Version";
+ }
+
+ void OnQtVersions_DoubleClick(object sender, EventArgs e)
+ {
+ DialogResult = DialogResult.OK;
+ Close();
+ }
+
+ void FormChangeQtVersion_KeyPress(object sender, KeyPressEventArgs e)
+ {
+ if (e.KeyChar == 27) {
+ DialogResult = DialogResult.Cancel;
+ Close();
+ }
+ }
+
+ internal void UpdateContent(ChangeFor change)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ lbQtVersions.Items.Clear();
+ var vm = QtVersionManager.The();
+ foreach (var versionName in vm.GetVersions())
+ lbQtVersions.Items.Add(versionName);
+
+ lbQtVersions.Items.Add("$(DefaultQtVersion)");
+ if (change == ChangeFor.Solution) {
+ var qtVer = Legacy.QtVersionManager
+ .GetSolutionQtVersion(QtVsToolsPackage.Instance.Dte.Solution);
+ if (qtVer == null)
+ qtVer = vm.GetDefaultVersion();
+ if (qtVer != null)
+ lbQtVersions.SelectedItem = qtVer;
+ Text = "Set Solution's Qt Version";
+ } else {
+ var pro = Core.HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
+ var qtVer = vm.GetProjectQtVersion(pro);
+ if (qtVer == null)
+ qtVer = vm.GetDefaultVersion();
+ if (qtVer != null)
+ lbQtVersions.SelectedItem = qtVer;
+ Text = "Set Project's Qt Version";
+ }
+ }
+
+ public string GetSelectedQtVersion()
+ {
+ var idx = lbQtVersions.SelectedIndex;
+ if (idx < 0)
+ return null;
+ return lbQtVersions.Items[idx].ToString();
+ }
+ }
+}
diff --git a/QtVsTools.Package/Legacy/FormChangeQtVersion.resx b/QtVsTools.Package/Legacy/FormChangeQtVersion.resx
new file mode 100644
index 0000000..e0a4c98
--- /dev/null
+++ b/QtVsTools.Package/Legacy/FormChangeQtVersion.resx
@@ -0,0 +1,120 @@
+<?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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file
diff --git a/QtVsTools.Package/Legacy/FormProjectQtSettings.Designer.cs b/QtVsTools.Package/Legacy/FormProjectQtSettings.Designer.cs
new file mode 100644
index 0000000..76265ea
--- /dev/null
+++ b/QtVsTools.Package/Legacy/FormProjectQtSettings.Designer.cs
@@ -0,0 +1,159 @@
+using System.Windows.Forms;
+
+namespace QtVsTools.Legacy
+{
+ partial class FormProjectQtSettings
+ {
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.OptionsPropertyGrid = new System.Windows.Forms.PropertyGrid();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.okButton = new System.Windows.Forms.Button();
+ this.cancelButton = new System.Windows.Forms.Button();
+ this.tabControl1 = new System.Windows.Forms.TabControl();
+ this.tabPage1 = new System.Windows.Forms.TabPage();
+ this.tabPage2 = new System.Windows.Forms.TabPage();
+ this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
+ this.panel1.SuspendLayout();
+ this.tabControl1.SuspendLayout();
+ this.tabPage1.SuspendLayout();
+ this.tabPage2.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // OptionsPropertyGrid
+ //
+ this.OptionsPropertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.OptionsPropertyGrid.HelpVisible = false;
+ this.OptionsPropertyGrid.Location = new System.Drawing.Point(6, 6);
+ this.OptionsPropertyGrid.Margin = new System.Windows.Forms.Padding(6);
+ this.OptionsPropertyGrid.Name = "OptionsPropertyGrid";
+ this.OptionsPropertyGrid.PropertySort = System.Windows.Forms.PropertySort.Alphabetical;
+ this.OptionsPropertyGrid.Size = new System.Drawing.Size(898, 603);
+ this.OptionsPropertyGrid.TabIndex = 8;
+ this.OptionsPropertyGrid.ToolbarVisible = false;
+ //
+ // panel1
+ //
+ this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.panel1.Controls.Add(this.okButton);
+ this.panel1.Controls.Add(this.cancelButton);
+ this.panel1.Location = new System.Drawing.Point(620, 700);
+ this.panel1.Margin = new System.Windows.Forms.Padding(6);
+ this.panel1.Name = "panel1";
+ this.panel1.Size = new System.Drawing.Size(336, 73);
+ this.panel1.TabIndex = 9;
+ //
+ // okButton
+ //
+ this.okButton.Location = new System.Drawing.Point(16, 15);
+ this.okButton.Margin = new System.Windows.Forms.Padding(6);
+ this.okButton.Name = "okButton";
+ this.okButton.Size = new System.Drawing.Size(150, 44);
+ this.okButton.TabIndex = 0;
+ this.okButton.Click += new System.EventHandler(this.OkButton_Click);
+ this.okButton.Text = "&OK";
+ //
+ // cancelButton
+ //
+ this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.cancelButton.Location = new System.Drawing.Point(176, 15);
+ this.cancelButton.Margin = new System.Windows.Forms.Padding(6);
+ this.cancelButton.Name = "cancelButton";
+ this.cancelButton.Size = new System.Drawing.Size(150, 44);
+ this.cancelButton.TabIndex = 1;
+ this.cancelButton.Text = "Cancel";
+ //
+ // tabControl1
+ //
+ this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.tabControl1.Controls.Add(this.tabPage1);
+ this.tabControl1.Controls.Add(this.tabPage2);
+ this.tabControl1.Location = new System.Drawing.Point(24, 23);
+ this.tabControl1.Margin = new System.Windows.Forms.Padding(6);
+ this.tabControl1.Name = "tabControl1";
+ this.tabControl1.SelectedIndex = 0;
+ this.tabControl1.Size = new System.Drawing.Size(926, 662);
+ this.tabControl1.TabIndex = 10;
+ //
+ // tabPage1
+ //
+ this.tabPage1.BackColor = System.Drawing.SystemColors.Control;
+ this.tabPage1.Controls.Add(this.OptionsPropertyGrid);
+ this.tabPage1.Location = new System.Drawing.Point(8, 39);
+ this.tabPage1.Margin = new System.Windows.Forms.Padding(6);
+ this.tabPage1.Name = "tabPage1";
+ this.tabPage1.Padding = new System.Windows.Forms.Padding(6);
+ this.tabPage1.Size = new System.Drawing.Size(910, 615);
+ this.tabPage1.TabIndex = 0;
+ this.tabPage1.Text = "Properties";
+ //
+ // tabPage2
+ //
+ this.tabPage2.BackColor = System.Drawing.SystemColors.Control;
+ this.tabPage2.Controls.Add(this.flowLayoutPanel1);
+ this.tabPage2.Location = new System.Drawing.Point(8, 39);
+ this.tabPage2.Margin = new System.Windows.Forms.Padding(6);
+ this.tabPage2.Name = "tabPage2";
+ this.tabPage2.Padding = new System.Windows.Forms.Padding(6);
+ this.tabPage2.Size = new System.Drawing.Size(910, 615);
+ this.tabPage2.TabIndex = 1;
+ this.tabPage2.Text = "Qt Modules";
+ //
+ // flowLayoutPanel1
+ //
+ this.flowLayoutPanel1.AutoScroll = true;
+ this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
+ this.flowLayoutPanel1.Location = new System.Drawing.Point(6, 6);
+ this.flowLayoutPanel1.Name = "flowLayoutPanel1";
+ this.flowLayoutPanel1.Size = new System.Drawing.Size(898, 603);
+ this.flowLayoutPanel1.TabIndex = 66;
+ //
+ // FormProjectQtSettings
+ //
+ this.AcceptButton = this.okButton;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.cancelButton;
+ this.ClientSize = new System.Drawing.Size(962, 801);
+ this.Controls.Add(this.tabControl1);
+ this.Controls.Add(this.panel1);
+ this.KeyPreview = true;
+ this.Margin = new System.Windows.Forms.Padding(6);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.MinimumSize = new System.Drawing.Size(988, 750);
+ this.Name = "FormProjectQtSettings";
+ this.ShowIcon = false;
+ this.ShowInTaskbar = false;
+ this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
+ this.Text = "Qt Project Settings";
+ this.panel1.ResumeLayout(false);
+ this.tabControl1.ResumeLayout(false);
+ this.tabPage1.ResumeLayout(false);
+ this.tabPage2.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private PropertyGrid OptionsPropertyGrid;
+ private Panel panel1;
+ private Button okButton;
+ private Button cancelButton;
+ private TabControl tabControl1;
+ private TabPage tabPage1;
+ private TabPage tabPage2;
+ private FlowLayoutPanel flowLayoutPanel1;
+ }
+}
diff --git a/QtVsTools.Package/Legacy/FormProjectQtSettings.cs b/QtVsTools.Package/Legacy/FormProjectQtSettings.cs
new file mode 100644
index 0000000..93a7be0
--- /dev/null
+++ b/QtVsTools.Package/Legacy/FormProjectQtSettings.cs
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Windows.Forms;
+using System.IO;
+using EnvDTE;
+
+namespace QtVsTools.Legacy
+{
+ using Core;
+ using Legacy = Core.Legacy;
+
+ public partial class FormProjectQtSettings : Form
+ {
+ private readonly Project project;
+ private readonly ProjectQtSettings qtSettings;
+ private readonly List<ModuleItem> moduleMap = new List<ModuleItem>();
+
+ private struct ModuleItem
+ {
+ public readonly CheckBox checkbox;
+ public readonly int moduleId;
+ public bool initialValue;
+
+ public ModuleItem(CheckBox cb, int mid, bool init)
+ {
+ checkbox = cb;
+ moduleId = mid;
+ initialValue = init;
+ }
+ }
+
+ public FormProjectQtSettings(Project pro)
+ {
+ InitializeComponent();
+
+ project = pro;
+ qtSettings = new ProjectQtSettings(project);
+ qtSettings.PropertyChanged += OnPropertyChanged;
+ OptionsPropertyGrid.SelectedObject = qtSettings;
+
+ InitModules(QtVersionManager.The().GetProjectQtVersion(project));
+ }
+
+ protected override bool ProcessDialogKey(Keys keyData)
+ {
+ if (ModifierKeys == Keys.None && keyData == Keys.Escape) {
+ Close();
+ return true;
+ }
+ return base.ProcessDialogKey(keyData);
+ }
+
+ private void OkButton_Click(object sender, EventArgs e)
+ {
+ // Disable the buttons since some operations are quite expensive (e.g. changing
+ // the Qt version) and take some to finish. Keeping the buttons enabled allows to hit
+ // the buttons several times resulting in successive executions of these operations.
+ okButton.Enabled = false;
+ cancelButton.Enabled = false;
+
+ qtSettings.SaveSettings();
+ SaveModules();
+ okButton.DialogResult = DialogResult.OK;
+ Close();
+ }
+
+ private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName != "Version")
+ throw new ArgumentException();
+ InitModules(qtSettings.Version);
+ }
+
+ private void InitModules(string qtVersion)
+ {
+ moduleMap.Clear();
+ flowLayoutPanel1.Controls.Clear();
+
+ var vm = QtVersionManager.The();
+ var versionInfo = vm.GetVersionInfo(qtVersion);
+ if (string.IsNullOrEmpty(qtVersion) || versionInfo == null) {
+ flowLayoutPanel1.Controls.Add(new Label
+ {
+ Text = Environment.NewLine
+ + "Please set a valid Qt version first.",
+ AutoSize = true
+ });
+ return;
+ }
+
+ var installPath = vm.GetInstallPath(qtVersion) ?? string.Empty;
+ var modules = QtModules.Instance.GetAvailableModules(versionInfo.qtMajor)
+ .Where(x => x.Selectable)
+ .OrderBy(x => x.Name);
+ foreach (var module in modules) {
+ var checkBox = new CheckBox
+ {
+ Margin = new Padding(6),
+ Location = new System.Drawing.Point(150, 150),
+ Name = module.LibraryPrefix,
+ UseVisualStyleBackColor = true,
+ AutoSize = true,
+ Text = module.Name,
+ Checked = Legacy.QtProject.HasModule(project, module.Id, qtVersion)
+ };
+ flowLayoutPanel1.Controls.Add(checkBox);
+ moduleMap.Add(new ModuleItem(checkBox, module.Id, checkBox.Checked));
+
+ var info = QtModules.Instance.Module(module.Id, versionInfo.qtMajor);
+ var libraryPrefix = info?.LibraryPrefix;
+ if (libraryPrefix.StartsWith("Qt", StringComparison.Ordinal))
+ libraryPrefix = "Qt" + versionInfo.qtMajor + libraryPrefix.Substring(2);
+ checkBox.Enabled = new FileInfo(
+ Path.Combine(installPath, "lib", $"{libraryPrefix}{versionInfo.LibInfix()}.lib")
+ ).Exists; // Disable the check-box if the module is not installed.
+ if (!checkBox.Enabled)
+ checkBox.Checked = false; // Uncheck if the module is not installed.
+ }
+ }
+
+ private void SaveModules()
+ {
+ for (var i = 0; i < moduleMap.Count; ++i) {
+ var item = moduleMap[i];
+ var isModuleChecked = item.checkbox.Checked;
+ if (isModuleChecked != item.initialValue) {
+ if (isModuleChecked)
+ Legacy.QtProject.AddModule(project, item.moduleId);
+ else
+ Legacy.QtProject.RemoveModule(project, item.moduleId);
+ }
+ }
+ }
+
+ }
+}
diff --git a/QtVsTools.Package/Legacy/FormProjectQtSettings.resx b/QtVsTools.Package/Legacy/FormProjectQtSettings.resx
new file mode 100644
index 0000000..c7e0d4b
--- /dev/null
+++ b/QtVsTools.Package/Legacy/FormProjectQtSettings.resx
@@ -0,0 +1,120 @@
+<?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>
+</root>
\ No newline at end of file
diff --git a/QtVsTools.Package/Legacy/ProjectQtSettings.cs b/QtVsTools.Package/Legacy/ProjectQtSettings.cs
new file mode 100644
index 0000000..1cc4d53
--- /dev/null
+++ b/QtVsTools.Package/Legacy/ProjectQtSettings.cs
@@ -0,0 +1,336 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using System.Text.RegularExpressions;
+
+namespace QtVsTools.Legacy
+{
+ using Core;
+ using Legacy = Core.Legacy;
+
+ public class ProjectQtSettings : INotifyPropertyChanged
+ {
+ public event PropertyChangedEventHandler PropertyChanged;
+ protected void OnPropertyChanged(string propertyName)
+ {
+ var eventHandler = PropertyChanged;
+ if (eventHandler != null)
+ eventHandler.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+ public ProjectQtSettings(EnvDTE.Project proj)
+ {
+ versionManager = QtVersionManager.The();
+ project = proj;
+ newMocDir = oldMocDir = Legacy.QtVSIPSettings.GetMocDirectory(project);
+ newMocOptions = oldMocOptions = Legacy.QtVSIPSettings.GetMocOptions(project);
+ newRccDir = oldRccDir = Legacy.QtVSIPSettings.GetRccDirectory(project);
+ newUicDir = oldUicDir = Legacy.QtVSIPSettings.GetUicDirectory(project);
+ newLUpdateOnBuild = oldLUpdateOnBuild = Legacy.QtVSIPSettings.GetLUpdateOnBuild(project);
+ newLUpdateOptions = oldLUpdateOptions = Legacy.QtVSIPSettings.GetLUpdateOptions(project);
+ newLReleaseOptions = oldLReleaseOptions = Legacy.QtVSIPSettings.GetLReleaseOptions(project);
+ newQtVersion = oldQtVersion = versionManager.GetProjectQtVersion(project);
+ QmlDebug = oldQmlDebug = Legacy.QtVSIPSettings.GetQmlDebug(project);
+ }
+
+ private readonly QtVersionManager versionManager;
+ private EnvDTE.Project project;
+
+ private readonly string oldMocDir;
+ private readonly string oldMocOptions;
+ private readonly string oldRccDir;
+ private readonly string oldUicDir;
+ private readonly string oldQtVersion;
+ private readonly bool oldLUpdateOnBuild;
+ private readonly string oldLUpdateOptions;
+ private readonly string oldLReleaseOptions;
+ private readonly bool oldQmlDebug;
+
+ private string newMocDir;
+ private string newMocOptions;
+ private string newRccDir;
+ private string newUicDir;
+ private string newQtVersion;
+ private bool newLUpdateOnBuild;
+ private string newLUpdateOptions;
+ private string newLReleaseOptions;
+
+ public void SaveSettings()
+ {
+ var updateMoc = false;
+ var qtPro = QtProject.Create(project);
+
+ if (oldMocDir != newMocDir) {
+ Legacy.QtVSIPSettings.SaveMocDirectory(project, newMocDir);
+ updateMoc = true;
+ }
+ if (oldMocOptions != newMocOptions) {
+ Legacy.QtVSIPSettings.SaveMocOptions(project, newMocOptions);
+ updateMoc = true;
+ }
+ if (updateMoc)
+ qtPro.UpdateMocSteps(oldMocDir);
+
+ if (oldUicDir != newUicDir) {
+ Legacy.QtVSIPSettings.SaveUicDirectory(project, newUicDir);
+ qtPro.UpdateUicSteps(oldUicDir, true);
+ }
+
+ if (oldRccDir != newRccDir) {
+ Legacy.QtVSIPSettings.SaveRccDirectory(project, newRccDir);
+ qtPro.RefreshRccSteps(oldRccDir);
+ }
+
+ if (oldLUpdateOnBuild != newLUpdateOnBuild)
+ Legacy.QtVSIPSettings.SaveLUpdateOnBuild(project, newLUpdateOnBuild);
+
+ if (oldLUpdateOptions != newLUpdateOptions)
+ Legacy.QtVSIPSettings.SaveLUpdateOptions(project, newLUpdateOptions);
+
+ if (oldLReleaseOptions != newLReleaseOptions)
+ Legacy.QtVSIPSettings.SaveLReleaseOptions(project, newLReleaseOptions);
+
+ if (oldQmlDebug != QmlDebug)
+ Legacy.QtVSIPSettings.SaveQmlDebug(project, QmlDebug);
+
+ if (oldQtVersion != newQtVersion) {
+ if (Legacy.QtProject.PromptChangeQtVersion(project, oldQtVersion, newQtVersion)) {
+ var newProjectCreated = false;
+ var versionChanged = qtPro.ChangeQtVersion(
+ oldQtVersion, newQtVersion, ref newProjectCreated);
+ if (versionChanged && newProjectCreated)
+ project = qtPro.Project;
+ }
+ }
+ }
+
+ public string MocDirectory
+ {
+ get
+ {
+ return newMocDir;
+ }
+ set
+ {
+ var tmp = HelperFunctions.NormalizeRelativeFilePath(value);
+ if (tmp.Equals(oldMocDir, StringComparison.OrdinalIgnoreCase))
+ return;
+
+ string badMacros = IncompatibleMacros(tmp);
+ if (!string.IsNullOrEmpty(badMacros))
+ Messages.DisplayErrorMessage(SR.GetString("IncompatibleMacros", badMacros));
+ else
+ newMocDir = tmp;
+ }
+ }
+
+ public string MocOptions
+ {
+ get
+ {
+ return newMocOptions;
+ }
+
+ set
+ {
+ newMocOptions = value;
+ }
+ }
+
+ public string UicDirectory
+ {
+ get
+ {
+ return newUicDir;
+ }
+ set
+ {
+ var tmp = HelperFunctions.NormalizeRelativeFilePath(value);
+ if (tmp.Equals(oldUicDir, StringComparison.OrdinalIgnoreCase))
+ return;
+
+ string badMacros = IncompatibleMacros(tmp);
+ if (!string.IsNullOrEmpty(badMacros))
+ Messages.DisplayErrorMessage(SR.GetString("IncompatibleMacros", badMacros));
+ else
+ newUicDir = tmp;
+ }
+ }
+
+ public string RccDirectory
+ {
+ get
+ {
+ return newRccDir;
+ }
+ set
+ {
+ var tmp = HelperFunctions.NormalizeRelativeFilePath(value);
+ if (tmp.Equals(oldRccDir, StringComparison.OrdinalIgnoreCase))
+ return;
+
+ string badMacros = IncompatibleMacros(tmp);
+ if (!string.IsNullOrEmpty(badMacros))
+ Messages.DisplayErrorMessage(SR.GetString("IncompatibleMacros", badMacros));
+ else
+ newRccDir = tmp;
+ }
+ }
+
+ public bool lupdateOnBuild
+ {
+ get
+ {
+ return newLUpdateOnBuild;
+ }
+
+ set
+ {
+ newLUpdateOnBuild = value;
+ }
+ }
+
+ public string LUpdateOptions
+ {
+ get
+ {
+ return newLUpdateOptions;
+ }
+
+ set
+ {
+ newLUpdateOptions = value;
+ }
+ }
+
+ public string LReleaseOptions
+ {
+ get
+ {
+ return newLReleaseOptions;
+ }
+
+ set
+ {
+ newLReleaseOptions = value;
+ }
+ }
+
+ [DisplayName("QML Debug")]
+ [TypeConverter(typeof(QmlDebugConverter))]
+ private bool QmlDebug { get; }
+
+ private static string IncompatibleMacros(string stringToExpand)
+ {
+ string incompatibleMacros = "";
+ foreach (Match metaNameMatch in Regex.Matches(stringToExpand, @"\%\(([^\)]+)\)")) {
+ string metaName = metaNameMatch.Groups[1].Value;
+ if (!incompatibleMacros.Contains(string.Format("%({0})", metaName))) {
+ switch (metaName) {
+ case "RecursiveDir":
+ case "ModifiedTime":
+ case "CreatedTime":
+ case "AccessedTime":
+ if (!string.IsNullOrEmpty(incompatibleMacros))
+ incompatibleMacros += ", ";
+ incompatibleMacros += string.Format("%({0})", metaName);
+ break;
+ }
+ }
+ }
+ return incompatibleMacros;
+ }
+
+ internal class QmlDebugConverter : BooleanConverter
+ {
+ public override object ConvertTo(
+ ITypeDescriptorContext context,
+ CultureInfo culture,
+ object value,
+ Type destinationType)
+ {
+ return (bool)value ? "Enabled" : "Disabled";
+ }
+
+ public override object ConvertFrom(
+ ITypeDescriptorContext context,
+ CultureInfo culture,
+ object value)
+ {
+ return (string)value == "Enabled";
+ }
+ }
+
+ [TypeConverter(typeof(VersionConverter))]
+ public string Version
+ {
+ get
+ {
+ return newQtVersion;
+ }
+ set
+ {
+ if (newQtVersion != value) {
+ newQtVersion = value;
+ OnPropertyChanged("Version");
+ }
+ }
+ }
+
+ internal class VersionConverter : StringConverter
+ {
+ private readonly QtVersionManager versionManager;
+
+ public VersionConverter()
+ {
+ versionManager = QtVersionManager.The();
+ }
+
+ public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
+ {
+ return true;
+ }
+
+ public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
+ {
+ var versions = versionManager.GetVersions();
+ Array.Resize(ref versions, versions.Length + 1);
+ versions[versions.Length - 1] = "$(DefaultQtVersion)";
+ return new StandardValuesCollection(versions);
+ }
+
+ public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
+ {
+ return true;
+ }
+ }
+ }
+}
diff --git a/QtVsTools.Package/Legacy/QtMenu.cs b/QtVsTools.Package/Legacy/QtMenu.cs
new file mode 100644
index 0000000..bc38e6e
--- /dev/null
+++ b/QtVsTools.Package/Legacy/QtMenu.cs
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Windows.Forms;
+using EnvDTE;
+using EnvDTE80;
+using Microsoft.VisualStudio.Shell;
+
+namespace QtVsTools.Legacy
+{
+ using Core;
+ using Legacy = Core.Legacy;
+
+ internal static class QtMenu
+ {
+ internal static void ShowFormProjectQtSettings(Project project)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ using (var form = new FormProjectQtSettings(project)) {
+ form.StartPosition = FormStartPosition.CenterParent;
+ form.ShowDialog(new MainWinWrapper(QtVsToolsPackage.Instance.Dte));
+ }
+ }
+
+ internal static void ShowFormChangeProjectQtVersion()
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
+ if (!HelperFunctions.IsQtProject(pro))
+ return;
+
+ using (var formChangeQtVersion = new FormChangeQtVersion()) {
+ formChangeQtVersion.UpdateContent(ChangeFor.Project);
+ var ww = new MainWinWrapper(QtVsToolsPackage.Instance.Dte);
+ if (formChangeQtVersion.ShowDialog(ww) == DialogResult.OK) {
+ var qtVersion = formChangeQtVersion.GetSelectedQtVersion();
+ HelperFunctions.SetDebuggingEnvironment(pro, "PATH=" + QtVersionManager
+ .The().GetInstallPath(qtVersion) + @"\bin;$(PATH)", true);
+ }
+ }
+ }
+
+ internal static void ShowFormChangeSolutionQtVersion()
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ string newQtVersion = null;
+ using (var formChangeQtVersion = new FormChangeQtVersion()) {
+ formChangeQtVersion.UpdateContent(ChangeFor.Solution);
+ if (formChangeQtVersion.ShowDialog() != DialogResult.OK)
+ return;
+ newQtVersion = formChangeQtVersion.GetSelectedQtVersion();
+ }
+ if (newQtVersion == null)
+ return;
+
+ string platform = null;
+ var dte = QtVsToolsPackage.Instance.Dte;
+ try {
+ platform = (dte.Solution.SolutionBuild.ActiveConfiguration as SolutionConfiguration2)
+ .PlatformName;
+ } catch { }
+ if (string.IsNullOrEmpty(platform))
+ return;
+
+ var vm = QtVersionManager.The();
+ foreach (var project in HelperFunctions.ProjectsInSolution(dte)) {
+ if (HelperFunctions.IsVsToolsProject(project)) {
+ var OldQtVersion = vm.GetProjectQtVersion(project, platform);
+ if (OldQtVersion == null)
+ OldQtVersion = vm.GetDefaultVersion();
+
+ var created = false;
+ var qtProject = QtProject.Create(project);
+ if (Legacy.QtProject.PromptChangeQtVersion(project, OldQtVersion, newQtVersion))
+ qtProject.ChangeQtVersion(OldQtVersion, newQtVersion, ref created);
+ }
+ }
+ Legacy.QtVersionManager.SaveSolutionQtVersion(dte.Solution, newQtVersion);
+ }
+ }
+}
diff --git a/QtVsTools.Package/Legacy/QtOptionsPage.cs b/QtVsTools.Package/Legacy/QtOptionsPage.cs
new file mode 100644
index 0000000..c0783c6
--- /dev/null
+++ b/QtVsTools.Package/Legacy/QtOptionsPage.cs
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.ComponentModel;
+using Microsoft.Win32;
+using Microsoft.VisualStudio.Shell;
+
+namespace QtVsTools.Legacy
+{
+ using Core;
+
+ public class QtOptionsPage : DialogPage
+ {
+ [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
+ [DisplayName("Source control: Ask before checking out files")]
+ public bool CheckoutPrompt { get; set; }
+
+ [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
+ [DisplayName("Source control: Enable file check-out")]
+ public bool Checkout { get; set; }
+
+ [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
+ [DisplayName("Linguist: Default lrelease options")]
+ public string DefaultLReleaseOptions { get; set; }
+
+ [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
+ [DisplayName("Linguist: Default lupdate options")]
+ public string DefaultLUpdateOptions { get; set; }
+
+ [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
+ [DisplayName("Linguist: Run lupdate during build")]
+ public bool EnableLUpdateOnBuild { get; set; }
+
+ [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
+ [DisplayName("Meta-Object Compiler: Default moc generated files directory")]
+ public string DefaultMocDir { get; set; }
+
+ [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
+ [DisplayName("Meta-Object Compiler: Default additional moc options ")]
+ public string AdditionalMocOptions { get; set; }
+
+ [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
+ [DisplayName("Meta-Object Compiler: Enable automatic moc")]
+ public bool AutoMoc { get; set; }
+
+ [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
+ [DisplayName("Resource Compiler: Default rcc generated files directory")]
+ public string DefaultRccDir { get; set; }
+
+ [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
+ [DisplayName("User Interface Compiler: Default uic generated files directory")]
+ public string DefaultUicDir { get; set; }
+
+ [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
+ [DisplayName("Build: Run pre-build setup")]
+ public bool PreBuildSetup { get; set; }
+
+ const string VALUENAME_LegacyPreBuild = "LegacyPreBuild";
+
+ public override void ResetSettings()
+ {
+ CheckoutPrompt = true;
+ Checkout = true;
+ DefaultLReleaseOptions = "";
+ DefaultLUpdateOptions = "";
+ EnableLUpdateOnBuild = false;
+ DefaultMocDir = "";
+ AdditionalMocOptions = "";
+ AutoMoc = true;
+ DefaultRccDir = "";
+ DefaultUicDir = "";
+ PreBuildSetup = false;
+ }
+
+ public override void LoadSettingsFromStorage()
+ {
+ ResetSettings();
+ try {
+ using (var key = Registry.CurrentUser
+ .OpenSubKey(@"SOFTWARE\" + Resources.registryPackagePath, writable: false)) {
+ if (key == null)
+ return;
+ if (key.GetValue(Resources.askBeforeCheckoutFileKeyword) is int checkoutPrompt)
+ CheckoutPrompt = (checkoutPrompt != 0);
+ if (key.GetValue(Resources.disableCheckoutFilesKeyword) is int disableCheckout)
+ Checkout = (disableCheckout == 0);
+ if (key.GetValue(Resources.lreleaseOptionsKeyword) is string lreleaseOptions)
+ DefaultLReleaseOptions = lreleaseOptions;
+ if (key.GetValue(Resources.lupdateOptionsKeyword) is string lupdateOptions)
+ DefaultLUpdateOptions = lupdateOptions;
+ if (key.GetValue(Resources.lupdateKeyword) is int lupdateOnBuild)
+ EnableLUpdateOnBuild = (lupdateOnBuild != 0);
+ if (key.GetValue(Resources.mocDirKeyword) is string mocDir)
+ DefaultMocDir = mocDir;
+ if (key.GetValue(Resources.mocOptionsKeyword) is string mocOptions)
+ AdditionalMocOptions = mocOptions;
+ if (key.GetValue(Resources.disableAutoMocStepsUpdateKeyword) is int autoMocOff)
+ AutoMoc = (autoMocOff == 0);
+ if (key.GetValue(Resources.rccDirKeyword) is string rccDir)
+ DefaultRccDir = rccDir;
+ if (key.GetValue(Resources.uicDirKeyword) is string uicDir)
+ DefaultUicDir = uicDir;
+ if (key.GetValue(VALUENAME_LegacyPreBuild) is int preBuild)
+ PreBuildSetup = (preBuild != 0);
+ }
+ } catch (Exception exception) {
+ exception.Log();
+ }
+ }
+
+ public override void SaveSettingsToStorage()
+ {
+ try {
+ using (var key = Registry.CurrentUser
+ .CreateSubKey(@"SOFTWARE\" + Resources.registryPackagePath)) {
+ if (key == null)
+ return;
+ key.SetValue(Resources.askBeforeCheckoutFileKeyword, CheckoutPrompt ? 1 : 0);
+ key.SetValue(Resources.disableCheckoutFilesKeyword, Checkout ? 0 : 1);
+ key.SetValue(Resources.lreleaseOptionsKeyword, DefaultLReleaseOptions);
+ key.SetValue(Resources.lupdateOptionsKeyword, DefaultLUpdateOptions);
+ key.SetValue(Resources.lupdateKeyword, EnableLUpdateOnBuild ? 1 : 0);
+ key.SetValue(Resources.mocDirKeyword, DefaultMocDir);
+ key.SetValue(Resources.mocOptionsKeyword, AdditionalMocOptions);
+ key.SetValue(Resources.disableAutoMocStepsUpdateKeyword, AutoMoc ? 0 : 1);
+ key.SetValue(Resources.rccDirKeyword, DefaultRccDir);
+ key.SetValue(Resources.uicDirKeyword, DefaultUicDir);
+ key.SetValue(VALUENAME_LegacyPreBuild, PreBuildSetup ? 1 : 0);
+ }
+ } catch (Exception exception) {
+ exception.Log();
+ }
+ }
+ }
+}
diff --git a/QtVsTools.Package/Legacy/Translation.cs b/QtVsTools.Package/Legacy/Translation.cs
new file mode 100644
index 0000000..645d0ee
--- /dev/null
+++ b/QtVsTools.Package/Legacy/Translation.cs
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using Microsoft.VisualStudio.VCProjectEngine;
+
+namespace QtVsTools.Legacy
+{
+ using Core;
+ using Legacy = Core.Legacy;
+
+ using static Core.HelperFunctions;
+ using BuildAction = QtVsTools.Translation.BuildAction;
+
+ internal static class Translation
+ {
+ internal static void Run(BuildAction buildAction, QtProject qtProject,
+ IEnumerable<string> tsFiles)
+ {
+ var qtInstallPath = QtVersionManager.The().GetInstallPath(qtProject.GetQtVersion());
+ if (string.IsNullOrEmpty(qtInstallPath)) {
+ Messages.Print("translation: Error accessing Qt installation");
+ return;
+ }
+
+ if (tsFiles == null) {
+ tsFiles = (qtProject.VCProject
+ .GetFilesEndingWith(".ts") as IVCCollection)
+ .Cast<VCFile>()
+ .Select(vcFile => vcFile.RelativePath);
+ }
+
+ if (tsFiles != null) {
+ var project = qtProject.Project;
+ var tempFile = Path.GetTempFileName();
+
+ File.WriteAllLines(tempFile, GetProjectFiles(project, FilesToList.FL_HFiles)
+ .Union(GetProjectFiles(project, FilesToList.FL_CppFiles))
+ .Union(GetProjectFiles(project, FilesToList.FL_UiFiles))
+ .Union(GetProjectFiles(project, FilesToList.FL_QmlFiles)));
+
+ var procInfo = new ProcessStartInfo
+ {
+ WorkingDirectory = qtProject.ProjectDir,
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ RedirectStandardError = true,
+ RedirectStandardOutput = true,
+ Arguments = ""
+ };
+ procInfo.FileName = Path.Combine(qtInstallPath, "bin",
+ buildAction == BuildAction.Update ? "lupdate.exe" : "lrelease.exe");
+
+ foreach (var file in tsFiles.Where(file => file != null))
+ Run(buildAction, file, tempFile, procInfo);
+ } else {
+ Messages.Print("translation: No translation files found");
+ }
+ }
+
+ private static void Run(BuildAction buildAction, string tsFile, string tempFile,
+ ProcessStartInfo procInfo)
+ {
+ switch (buildAction) {
+ case BuildAction.Update:
+ Messages.Print("\r\n--- (lupdate) file: " + tsFile);
+ var options = Legacy.QtVSIPSettings.GetLUpdateOptions();
+ if (!string.IsNullOrEmpty(options))
+ procInfo.Arguments += options + " ";
+ procInfo.Arguments += string.Format("\"@{0}\" -ts \"{1}\"", tempFile, tsFile);
+ break;
+ case BuildAction.Release:
+ Messages.Print("\r\n--- (lrelease) file: " + tsFile);
+ options = Legacy.QtVSIPSettings.GetLReleaseOptions();
+ if (!string.IsNullOrEmpty(options))
+ procInfo.Arguments += options + " ";
+ procInfo.Arguments += string.Format("\"{0}\"", tsFile);
+ break;
+ }
+
+ using (var proc = Process.Start(procInfo)) {
+ proc.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
+ {
+ if (!string.IsNullOrEmpty(e.Data))
+ Messages.Print(e.Data);
+ };
+ proc.ErrorDataReceived += (object sender, DataReceivedEventArgs e) =>
+ {
+ if (!string.IsNullOrEmpty(e.Data))
+ Messages.Print(e.Data);
+ };
+ proc.BeginOutputReadLine();
+ proc.BeginErrorReadLine();
+ proc.WaitForExit();
+ switch (proc.ExitCode) {
+ case 0:
+ Messages.Print("translation: ok");
+ break;
+ default:
+ Messages.Print(string.Format("translation: ERROR {0}", proc.ExitCode));
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/QtVsTools.Package/Marketplace/Overview.html_TT b/QtVsTools.Package/Marketplace/Overview.html_TT
index 7f83418..875bea6 100644
--- a/QtVsTools.Package/Marketplace/Overview.html_TT
+++ b/QtVsTools.Package/Marketplace/Overview.html_TT
@@ -94,7 +94,7 @@
<p><h3><span>The main features of Qt VS Tools are:</span></h3></p>
<ul>
<li>
- Wizards for creating new Qt projects and classes.
+ Wizards for creating new Qt and Qt Quick projects and files.
</li>
<li>
Automated build setup for the <a href="http://doc.qt.io/qt-5/moc.html">
@@ -122,6 +122,9 @@
<li>
Debugging extensions for Qt data types.
</li>
+ <li>
+ QML debug engine for debugging Qt Quick applications.
+ </li>
</ul>
<p><h3>How to set up F1 help</h3></p>
<ol class="1" type="1">
@@ -140,13 +143,41 @@
Select <strong>Assign</strong>, and then select <strong>OK</strong>.
</li>
</ol>
-<p><h3>How to report bugs and contribute code?</h3></p>
+<p><h3>How to contribute via GitHub?</h3></p>
<ul>
<li>
- <a title="Bug reports" href="https://bugreports.qt.io/browse/QTVSADDINBUG">Bug reports</a>
+ <a title="Source code on GitHub"
+ href="https://github.com/qt-labs/vstools">Source code on GitHub</a>
</li>
<li>
- <a title="Source code" href="https://code.qt.io/cgit/qt-labs/vstools.git">Source code</a>
+ <a title="Pull requests on GitHub"
+ href="https://github.com/qt-labs/vstools/pulls">Pull requests on GitHub</a>
+ </li>
+</ul>
+<p><h3>How to contribute via Qt Labs?</h3></p>
+<ul>
+ <li>
+ <a title="Source code on Qt Labs"
+ href="https://code.qt.io/cgit/qt-labs/vstools.git">Source code on Qt Labs</a>
+ </li>
+ <li>
+ <a title="Qt VS Tools Code Review"
+ href="https://codereview.qt-project.org/q/project:qt-labs/vstools">Qt VS Tools Code Review</a>
+ </li>
+</ul>
+For more information on how to contribute to the Qt Visual Tools via Qt Labs, please look at the
+ <a title="Qt contribution Guidelines"
+ href="https://wiki.qt.io/Qt_Contribution_Guidelines">
+ Qt contribution Guidelines</a> first.
+<p><h3>How to report bugs?</h3></p>
+<ul>
+ <li>
+ <a title="Qt Bug Tracker"
+ href="https://bugreports.qt.io/browse/QTVSADDINBUG">Qt Bug Tracker</a>
+ </li>
+ <li>
+ <a title="GitHub Issue Tracker"
+ href="https://github.com/qt-labs/vstools/issues">GitHub Issue Tracker</a>
</li>
</ul>
<p>
diff --git a/QtVsTools.Package/Options/QtOptionsPage.cs b/QtVsTools.Package/Options/QtOptionsPage.cs
index 5035285..7da27ae 100644
--- a/QtVsTools.Package/Options/QtOptionsPage.cs
+++ b/QtVsTools.Package/Options/QtOptionsPage.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -30,20 +30,20 @@
using System.ComponentModel;
using System.Globalization;
using System.Linq;
-using Microsoft.Win32;
+using System.Linq.Expressions;
+using System.Reflection;
+using Microsoft.Build.Framework;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.Build.Framework;
+using Microsoft.Win32;
using EnvDTE;
-using QtVsTools.Core;
-using QtVsTools.Common;
-using QtVsTools.VisualStudio;
-using System.Reflection;
-using System.Linq.Expressions;
namespace QtVsTools.Options
{
- using static EnumExt;
+ using Core;
+ using VisualStudio;
+
+ using static Common.EnumExt;
public class QtOptionsPage : DialogPage, IQtVsToolsOptions
{
@@ -85,6 +85,16 @@
[String("BkgBuild_RunQtTools")] RunQtTools,
[String("BkgBuild_DebugInfo")] DebugInfo,
[String("BkgBuild_LoggerVerbosity")] LoggerVerbosity,
+ }
+
+ public enum Notifications
+ {
+ [String("Notifications_Installed")] Installed,
+ }
+
+ public enum Natvis
+ {
+ [String("LinkNatvis")] Link,
}
public enum Timeout : uint { Disabled = 0 }
@@ -144,8 +154,8 @@
object value,
Type destinationType)
{
- if (value.GetType() == typeof(bool) && destinationType == typeof(string))
- return ((bool)value) ? "Enable" : "Disable";
+ if (value is bool b && destinationType == typeof(string))
+ return b ? "Enable" : "Disable";
return base.ConvertTo(context, culture, value, destinationType);
}
}
@@ -170,7 +180,7 @@
[DisplayName("Keyboard shortcut")]
[Description("To change keyboard mapping, go to: Tools > Options > Keyboard")]
[ReadOnly(true)]
- public string QtHelpKeyBinding { get; set; }
+ private string QtHelpKeyBinding { get; set; }
[Category("Help")]
[DisplayName("Preferred source")]
@@ -222,8 +232,25 @@
[Description("Configure verbosity level of background build log.")]
public LoggerVerbosity BuildLoggerVerbosity { get; set; }
+ [Category("Notifications")]
+ [DisplayName("New version installed")]
+ [Description("Show notification when a new version was recently installed.")]
+ [TypeConverter(typeof(EnableDisableConverter))]
+ public bool NotifyInstalled { get; set; }
+
+ [Category("Natvis")]
+ [DisplayName("Embed .natvis file into PDB")]
+ [Description("Embeds the debugger visualizations (.natvis file) into the PDB file"
+ + "generated by LINK. While setting this option, the embedded Natvis file will"
+ + "take precedence over user-specific Natvis files(for example the files"
+ + "located in %USERPROFILE%\\Documents\\Visual Studio 2022\\Visualizers).")]
+ [TypeConverter(typeof(EnableDisableConverter))]
+ public bool LinkNatvis { get; set; }
+
public override void ResetSettings()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
QtMsBuildPath = "";
QmlDebuggerEnabled = true;
QmlDebuggerTimeout = (Timeout)60000;
@@ -234,6 +261,8 @@
BuildRunQtTools = ProjectTracking = true;
BuildDebugInformation = false;
BuildLoggerVerbosity = LoggerVerbosity.Quiet;
+ NotifyInstalled = true;
+ LinkNatvis = true;
////////
// Get Qt Help keyboard shortcut
@@ -252,6 +281,8 @@
public override void LoadSettingsFromStorage()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
ResetSettings();
try {
QtMsBuildPath = Environment.GetEnvironmentVariable("QTMSBUILD");
@@ -271,10 +302,11 @@
Load(() => BuildRunQtTools, key, BkgBuild.RunQtTools);
Load(() => BuildDebugInformation, key, BkgBuild.DebugInfo);
Load(() => BuildLoggerVerbosity, key, BkgBuild.LoggerVerbosity);
+ Load(() => NotifyInstalled, key, Notifications.Installed);
+ Load(() => LinkNatvis, key, Natvis.Link);
}
} catch (Exception exception) {
- Messages.Print(
- exception.Message + "\r\n\r\nStacktrace:\r\n" + exception.StackTrace);
+ exception.Log();
}
}
@@ -296,7 +328,7 @@
Save(QmlDebuggerEnabled, key, QmlDebug.Enable);
Save(QmlDebuggerTimeout, key, QmlDebug.Timeout);
Save(HelpPreference, key, Help.Preference);
- Save(TryQtHelpOnF1Pressed, key, Help.Preference);
+ Save(TryQtHelpOnF1Pressed, key, Help.TryOnF1Pressed);
Save(DesignerDetached, key, Designer.Detached);
Save(LinguistDetached, key, Linguist.Detached);
Save(ResourceEditorDetached, key, ResEditor.Detached);
@@ -304,10 +336,11 @@
Save(BuildRunQtTools, key, BkgBuild.RunQtTools);
Save(BuildDebugInformation, key, BkgBuild.DebugInfo);
Save(BuildLoggerVerbosity, key, BkgBuild.LoggerVerbosity);
+ Save(NotifyInstalled, key, Notifications.Installed);
+ Save(LinkNatvis, key, Natvis.Link);
}
} catch (Exception exception) {
- Messages.Print(
- exception.Message + "\r\n\r\nStacktrace:\r\n" + exception.StackTrace);
+ exception.Log();
}
}
diff --git a/QtVsTools.Package/Options/QtVersionsPage.cs b/QtVsTools.Package/Options/QtVersionsPage.cs
index f28e8ee..cffc4b7 100644
--- a/QtVsTools.Package/Options/QtVersionsPage.cs
+++ b/QtVsTools.Package/Options/QtVersionsPage.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -28,29 +28,37 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Windows;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
-using QtVsTools.Core;
namespace QtVsTools.Options
{
+ using Common;
+ using Core;
+ using static QtVsTools.Options.QtVersionsTable;
+
public class QtVersionsPage : UIElementDialogPage
{
+ static LazyFactory Lazy { get; } = new LazyFactory();
+
QtVersionManager VersionManager => QtVersionManager.The();
- QtVersionsTable _VersionsTable;
- QtVersionsTable VersionsTable => _VersionsTable
- ?? (_VersionsTable = new QtVersionsTable());
+ QtVersionsTable VersionsTable => Lazy.Get(() =>
+ VersionsTable, () => new QtVersionsTable());
protected override UIElement Child => VersionsTable;
public override void LoadSettingsFromStorage()
{
- var versions = new List<QtVersionsTable.Row>();
+ var versions = new List<Row>();
foreach (var versionName in VersionManager.GetVersions()) {
var versionPath = VersionManager.GetInstallPath(versionName);
+ if (string.IsNullOrEmpty(versionPath))
+ continue;
+
BuildHost host = BuildHost.Windows;
string compiler = "msvc";
if (versionPath.StartsWith("SSH:") || versionPath.StartsWith("WSL:")) {
@@ -65,13 +73,15 @@
compiler = linuxPaths[2];
}
var defaultVersion = VersionManager.GetDefaultVersion();
- versions.Add(new QtVersionsTable.Row()
+ versions.Add(new Row()
{
IsDefault = (versionName == defaultVersion),
VersionName = versionName,
+ InitialVersionName = versionName,
Path = versionPath,
Host = host,
Compiler = compiler,
+ State = State.Unknown
});
}
VersionsTable.UpdateVersions(versions);
@@ -79,23 +89,40 @@
public override void SaveSettingsToStorage()
{
- foreach (var versionName in VersionManager.GetVersions()) {
+ void RemoveVersion(string versionName)
+ {
try {
VersionManager.RemoveVersion(versionName);
} catch (Exception exception) {
- Messages.Print(
- exception.Message + "\r\n\r\nStacktrace:\r\n" + exception.StackTrace);
+ exception.Log();
}
}
- foreach (var version in VersionsTable.Versions) {
+
+ var versions = VersionsTable.Versions;
+ foreach (var version in versions) {
+ if (version.State.HasFlag(State.Removed))
+ RemoveVersion(version.VersionName);
+
+ if (!version.State.HasFlag(State.Modified))
+ continue;
+
try {
if (version.Host == BuildHost.Windows) {
- var versionInfo = VersionInformation.Get(version.Path);
- var generator = versionInfo.GetQMakeConfEntry("MAKEFILE_GENERATOR");
- if (generator != "MSVC.NET" && generator != "MSBUILD")
- throw new Exception(SR.GetString(
- "AddQtVersionDialog_IncorrectMakefileGenerator", generator));
- VersionManager.SaveVersion(version.VersionName, version.Path);
+ if (version.State.HasFlag((State)Column.Path)) {
+ var versionPath = version.Path;
+ var ignoreCase = StringComparison.CurrentCultureIgnoreCase;
+ if (Path.GetFileName(versionPath).Equals("qmake.exe", ignoreCase))
+ versionPath = Path.GetDirectoryName(versionPath);
+ if (Path.GetFileName(versionPath).Equals("bin", ignoreCase))
+ versionPath = Path.GetDirectoryName(versionPath);
+ var versionInfo = VersionInformation.Get(versionPath);
+ var generator = versionInfo.GetQMakeConfEntry("MAKEFILE_GENERATOR");
+ if (generator != "MSVC.NET" && generator != "MSBUILD")
+ throw new Exception(string.Format(
+ "This Qt version uses an unsupported makefile generator (used: "
+ + "{0}, supported: MSVC.NET, MSBUILD)", generator));
+ VersionManager.SaveVersion(version.VersionName, versionPath);
+ }
} else {
string name = version.VersionName;
string access =
@@ -107,21 +134,34 @@
path = string.Format("{0}:{1}:{2}", access, path, compiler);
VersionManager.SaveVersion(name, path, checkPath: false);
}
+
+ if (version.State.HasFlag((State)Column.VersionName)) {
+ try {
+ VersionManager.SaveVersion(version.VersionName, version.Path);
+ if (!string.IsNullOrEmpty(version.InitialVersionName))
+ VersionManager.RemoveVersion(version.InitialVersionName);
+ } catch (Exception exception) {
+ exception.Log();
+ }
+ }
} catch (Exception exception) {
- Messages.Print(
- exception.Message + "\r\n\r\nStacktrace:\r\n" + exception.StackTrace);
+ exception.Log();
+ version.State = State.Removed;
+ RemoveVersion(version.VersionName);
}
}
+
try {
- var defaultVersion = VersionsTable.Versions
- .Where(version => version.IsDefault)
- .FirstOrDefault();
- if (defaultVersion != null)
- VersionManager.SaveDefaultVersion(defaultVersion.VersionName);
+ var defaultVersion =
+ versions.FirstOrDefault(v => v.IsDefault && v.State != State.Removed)
+ ?? versions.FirstOrDefault(v => v.State != State.Removed);
+ VersionManager.SaveDefaultVersion(defaultVersion?.VersionName ?? "");
} catch (Exception exception) {
- Messages.Print(
- exception.Message + "\r\n\r\nStacktrace:\r\n" + exception.StackTrace);
+ exception.Log();
}
+
+ if (Notifications.NoQtVersion.IsOpen && VersionManager.GetVersions()?.Any() == true)
+ Notifications.NoQtVersion.Close();
}
protected override void OnApply(PageApplyEventArgs e)
diff --git a/QtVsTools.Package/Options/QtVersionsTable.cs b/QtVsTools.Package/Options/QtVersionsTable.cs
index dc6f9c5..cb09fff 100644
--- a/QtVsTools.Package/Options/QtVersionsTable.cs
+++ b/QtVsTools.Package/Options/QtVersionsTable.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -37,11 +37,12 @@
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
-using QtVsTools.Common;
namespace QtVsTools.Options
{
- using static EnumExt;
+ using Common;
+ using QtVsTools.Core;
+ using static Common.EnumExt;
public enum BuildHost
{
@@ -52,9 +53,28 @@
public partial class QtVersionsTable : UserControl
{
+ LazyFactory Lazy { get; } = new LazyFactory();
+
public QtVersionsTable()
{
InitializeComponent();
+ }
+
+ [Flags] public enum Column
+ {
+ IsDefault = 0x10,
+ VersionName = 0x20,
+ Host = 0x40,
+ Path = 0x80,
+ Compiler = 0x100
+ }
+
+ [Flags] public enum State
+ {
+ Unknown = 0x00,
+ Existing = 0x01,
+ Removed = 0x02,
+ Modified = 0x04
}
public class Field
@@ -62,57 +82,66 @@
public string Value { get; set; }
public Control Control { get; set; }
public DataGridCell Cell { get; set; }
- public string ValidationError { get; set; }
+ private string error;
+ public string ValidationError {
+ set {
+ UpdateUi = value != error;
+ error = value;
+ }
+ get { return error; }
+ }
public bool IsValid => string.IsNullOrEmpty(ValidationError);
public ToolTip ToolTip
=> IsValid ? null : new ToolTip() { Content = ValidationError };
public int SelectionStart { get; set; }
+ public bool UpdateUi { get; private set; } = false;
}
public class Row
{
- public enum FieldNames { IsDefault, VersionName, Host, Path, Compiler }
+ static LazyFactory StaticLazy { get; } = new LazyFactory();
+ LazyFactory Lazy { get; } = new LazyFactory();
- public Dictionary<FieldNames, Field> _Fields;
- public Dictionary<FieldNames, Field> Fields => _Fields
- ?? (_Fields = GetValues<FieldNames>()
- .Select(field => new KeyValuePair<FieldNames, Field>(field, null))
+ public Dictionary<Column, Field> Fields => Lazy.Get(() =>
+ Fields, () => GetValues<Column>()
+ .Select(field => new KeyValuePair<Column, Field>(field, null))
.ToDictionary(keyValue => keyValue.Key, keyValue => keyValue.Value));
- public Field FieldDefault => Fields[FieldNames.IsDefault]
- ?? (Fields[FieldNames.IsDefault] = new Field());
+ public Field FieldDefault => Fields[Column.IsDefault]
+ ?? (Fields[Column.IsDefault] = new Field());
public bool IsDefault
{
get => (FieldDefault.Value == true.ToString());
set => FieldDefault.Value = value.ToString();
}
- public Field FieldVersionName => Fields[FieldNames.VersionName]
- ?? (Fields[FieldNames.VersionName] = new Field());
+ public Field FieldVersionName => Fields[Column.VersionName]
+ ?? (Fields[Column.VersionName] = new Field());
public string VersionName
{
get => FieldVersionName.Value;
set => FieldVersionName.Value = value;
}
+ public string InitialVersionName { get; set; }
- public Field FieldHost => Fields[FieldNames.Host]
- ?? (Fields[FieldNames.Host] = new Field());
+ public Field FieldHost => Fields[Column.Host]
+ ?? (Fields[Column.Host] = new Field());
public BuildHost Host
{
get => FieldHost.Value.Cast(defaultValue: BuildHost.Windows);
set => FieldHost.Value = value.Cast<string>();
}
- public Field FieldPath => Fields[FieldNames.Path]
- ?? (Fields[FieldNames.Path] = new Field());
+ public Field FieldPath => Fields[Column.Path]
+ ?? (Fields[Column.Path] = new Field());
public string Path
{
get => FieldPath.Value;
set => FieldPath.Value = value;
}
- public Field FieldCompiler => Fields[FieldNames.Compiler]
- ?? (Fields[FieldNames.Compiler] = new Field());
+ public Field FieldCompiler => Fields[Column.Compiler]
+ ?? (Fields[Column.Compiler] = new Field());
public string Compiler
{
get => FieldCompiler.Value;
@@ -124,7 +153,7 @@
public bool DefaultEnabled => !IsDefault && !LastRow;
public bool NameEnabled => !LastRow;
public bool CompilerEnabled => (Host != BuildHost.Windows);
- public Visibility RowVisibility
+ public Visibility RowContentVisibility
=> LastRow ? Visibility.Hidden : Visibility.Visible;
public Visibility ButtonAddVisibility
=> LastRow ? Visibility.Visible : Visibility.Hidden;
@@ -135,17 +164,16 @@
public FontWeight FontWeight
=> IsDefault ? FontWeights.Bold : FontWeights.Normal;
- public static ImageSource _ExplorerIcon;
- public static ImageSource ExplorerIcon => _ExplorerIcon
- ?? (_ExplorerIcon = GetExplorerIcon());
- }
+ public static ImageSource ExplorerIcon => StaticLazy.Get(() =>
+ ExplorerIcon, () => GetExplorerIcon());
- public bool IsValid { get; private set; }
+ public State State { get; set; } = State.Unknown;
+ public bool RowVisible => State != State.Removed;
+ }
Field FocusedField { get; set; }
- List<Row> _Rows;
- List<Row> Rows => _Rows ?? (_Rows = new List<Row>());
+ List<Row> Rows => Lazy.Get(() => Rows, () => new List<Row>());
public IEnumerable<Row> Versions => Rows.TakeWhile(item => !item.LastRow);
public void UpdateVersions(IEnumerable<Row> versions)
@@ -154,15 +182,16 @@
Rows.AddRange(versions);
Rows.Add(new Row { LastRow = true });
DataGrid.ItemsSource = Rows;
- IsValid = true;
FocusedField = null;
Validate(true);
+ Rows.ForEach(item => item.State = State.Existing);
}
public IEnumerable<string> GetErrorMessages()
{
Validate(true);
return Versions
+ .Where(v => v.State != State.Removed)
.SelectMany(v => v.Fields.Values.Select(f => f.ValidationError))
.Where(s => !string.IsNullOrEmpty(s))
.Distinct();
@@ -170,95 +199,73 @@
void Validate(bool mustRefresh)
{
- /////////////////////////
- // Automatic cell values
- foreach (var version in Versions) {
- if (version.Host != BuildHost.Windows && version.Compiler == "msvc") {
- version.Compiler = "g++";
- version.FieldCompiler.SelectionStart = version.Compiler.Length;
- mustRefresh = true;
- } else if (version.Host == BuildHost.Windows && version.Compiler != "msvc") {
- version.Compiler = "msvc";
- version.FieldCompiler.SelectionStart = version.Compiler.Length;
- mustRefresh = true;
- }
- }
-
////////////////////////
// Validate cell values
- string previousValidation;
- bool wasValid = IsValid;
- IsValid = true;
foreach (var version in Versions) {
+ if (!version.State.HasFlag(State.Modified))
+ continue;
//////////////////////
// Default validation
- previousValidation = version.FieldDefault.ValidationError;
- version.FieldDefault.ValidationError = null;
- if (version.IsDefault && version.Host != BuildHost.Windows) {
- version.FieldDefault.ValidationError = "Default version: host must be Windows";
- IsValid = false;
+ if (version.State.HasFlag((State)Column.IsDefault)) {
+ version.FieldDefault.ValidationError = null;
+ if (version.IsDefault && version.Host != BuildHost.Windows)
+ version.FieldDefault.ValidationError = "Default version: Host must be Windows";
+ mustRefresh |= version.FieldDefault.UpdateUi;
}
- if (previousValidation != version.FieldDefault.ValidationError)
- mustRefresh = true;
///////////////////
// Name validation
- previousValidation = version.FieldVersionName.ValidationError;
- version.FieldVersionName.ValidationError = null;
- if (string.IsNullOrEmpty(version.VersionName)) {
- version.FieldVersionName.ValidationError = "Name cannot be empty";
- IsValid = false;
- } else if (Versions
- .Where(otherVersion => otherVersion != version
- && otherVersion.VersionName == version.VersionName)
- .Any()) {
- version.FieldVersionName.ValidationError = "Duplicate version names";
- IsValid = false;
+ if (version.State.HasFlag((State)Column.VersionName)) {
+ version.FieldVersionName.ValidationError = null;
+ if (string.IsNullOrEmpty(version.VersionName)) {
+ version.FieldVersionName.ValidationError = "Name cannot be empty";
+ } else if (Versions.Where(otherVersion => otherVersion != version
+ && otherVersion.VersionName == version.VersionName).Any()) {
+ version.FieldVersionName.ValidationError = "Duplicate version names";
+ }
+ mustRefresh |= version.FieldVersionName.UpdateUi;
}
- if (previousValidation != version.FieldVersionName.ValidationError)
- mustRefresh = true;
///////////////////
// Host validation
- previousValidation = version.FieldHost.ValidationError;
- version.FieldHost.ValidationError = null;
- if (version.IsDefault && version.Host != BuildHost.Windows) {
- version.FieldHost.ValidationError = "Default version: host must be Windows";
- IsValid = false;
+ if (version.State.HasFlag((State)Column.Host)) {
+ version.FieldHost.ValidationError = null;
+ if (version.IsDefault && version.Host != BuildHost.Windows)
+ version.FieldHost.ValidationError = "Default version: Host must be Windows";
+ mustRefresh |= version.FieldHost.UpdateUi;
}
- if (previousValidation != version.FieldHost.ValidationError)
- mustRefresh = true;
///////////////////
// Path validation
- previousValidation = version.FieldPath.ValidationError;
- version.FieldPath.ValidationError = null;
- if (string.IsNullOrEmpty(version.Path)) {
- version.FieldPath.ValidationError = "Path cannot be empty";
- IsValid = false;
- } else if (version.Host == BuildHost.Windows && !Directory.Exists(version.Path)) {
- version.FieldPath.ValidationError = "Path does not exist";
- IsValid = false;
+ if (version.State.HasFlag((State)Column.Path)) {
+ version.FieldPath.ValidationError = null;
+ if (string.IsNullOrEmpty(version.Path)) {
+ version.FieldPath.ValidationError = "Path cannot be empty";
+ } else if (version.Host == BuildHost.Windows) {
+ string path = NormalizePath(version.Path);
+ if (path == null) {
+ version.FieldPath.ValidationError = "Invalid path format";
+ } else {
+ if (!QMake.Exists(path))
+ version.FieldPath.ValidationError = "Cannot find qmake.exe";
+ }
+ }
+ mustRefresh |= version.FieldPath.UpdateUi;
}
- if (previousValidation != version.FieldPath.ValidationError)
- mustRefresh = true;
///////////////////////
// Compiler validation
- previousValidation = version.FieldCompiler.ValidationError;
- version.FieldCompiler.ValidationError = null;
- if (string.IsNullOrEmpty(version.Compiler)) {
- version.FieldCompiler.ValidationError = "Compiler cannot be empty";
- IsValid = false;
+ if (version.State.HasFlag((State)Column.Compiler)) {
+ version.FieldCompiler.ValidationError = null;
+ if (string.IsNullOrEmpty(version.Compiler))
+ version.FieldCompiler.ValidationError = "Compiler cannot be empty";
+ mustRefresh |= version.FieldCompiler.UpdateUi;
}
- if (previousValidation != version.FieldCompiler.ValidationError)
- mustRefresh = true;
}
//////////////////////////////////////
// Refresh versions table if required
- mustRefresh |= (wasValid != IsValid);
if (mustRefresh) {
// Reset bindings
foreach (var version in Versions) {
@@ -304,22 +311,20 @@
if (sender is Control control && GetBinding(control) is Row version) {
if (version.LastRow)
return;
-
- Row.FieldNames field;
- if (string.IsNullOrEmpty(control.Name) || !control.Name.TryCast(out field))
+ if (string.IsNullOrEmpty(control.Name) || !control.Name.TryCast(out Column column))
return;
- var fieldBinding = version.Fields[field];
- fieldBinding.Control = control;
- fieldBinding.Cell = FindContainingCell(control);
- if (fieldBinding.Cell != null) {
- fieldBinding.Cell.Background =
- fieldBinding.IsValid ? Brushes.Transparent : InvalidCellBackground;
+ var field = version.Fields[column];
+ field.Control = control;
+ field.Cell = FindContainingCell(control);
+ if (field.Cell != null) {
+ field.Cell.Background =
+ field.IsValid ? Brushes.Transparent : InvalidCellBackground;
}
- if (fieldBinding == FocusedField)
+ if (field == FocusedField)
control.Focus();
- if (control is TextBox textBox && fieldBinding.SelectionStart >= 0)
- textBox.Select(fieldBinding.SelectionStart, 0);
+ if (control is TextBox textBox && field.SelectionStart >= 0)
+ textBox.Select(field.SelectionStart, 0);
}
}
@@ -339,24 +344,24 @@
void Control_GotFocus(object sender, RoutedEventArgs e)
{
if (sender is Control control && GetBinding(control) is Row version) {
- Row.FieldNames field;
- if (string.IsNullOrEmpty(control.Name) || !control.Name.TryCast(out field))
+ if (string.IsNullOrEmpty(control.Name) || !control.Name.TryCast(out Column column))
return;
- var fieldBinding = version.Fields[field];
- if (fieldBinding.Control != control)
+
+ var field = version.Fields[column];
+ if (field.Control != control)
return;
- FocusedField = fieldBinding;
+ FocusedField = field;
}
}
void Control_LostFocus(object sender, RoutedEventArgs e)
{
if (sender is Control control && GetBinding(control) is Row version) {
- Row.FieldNames field;
- if (string.IsNullOrEmpty(control.Name) || !control.Name.TryCast(out field))
+ if (string.IsNullOrEmpty(control.Name) || !control.Name.TryCast(out Column column))
return;
- var fieldBinding = version.Fields[field];
- if (fieldBinding != FocusedField || fieldBinding.Control != control)
+
+ var field = version.Fields[column];
+ if (field != FocusedField || field.Control != control)
return;
FocusedField = null;
}
@@ -365,29 +370,32 @@
void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
{
if (sender is TextBox textBox && GetBinding(textBox) is Row version) {
- Row.FieldNames field;
- if (string.IsNullOrEmpty(textBox.Name) || !textBox.Name.TryCast(out field))
+ if (string.IsNullOrEmpty(textBox.Name) || !textBox.Name.TryCast(out Column column))
return;
- var fieldBinding = version.Fields[field];
- if (fieldBinding.Control != textBox)
+
+ var field = version.Fields[column];
+ if (field.Control != textBox)
return;
- fieldBinding.SelectionStart = textBox.SelectionStart;
+ field.SelectionStart = textBox.SelectionStart;
}
}
void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (sender is TextBox textBox && GetBinding(textBox) is Row version) {
- Row.FieldNames field;
- if (string.IsNullOrEmpty(textBox.Name) || !textBox.Name.TryCast(out field))
+ if (string.IsNullOrEmpty(textBox.Name) || !textBox.Name.TryCast(out Column column))
return;
- var fieldBinding = version.Fields[field];
- if (fieldBinding == null
- || fieldBinding.Control != textBox
- || fieldBinding.Value == textBox.Text)
+
+ var field = version.Fields[column];
+ if (field == null
+ || field.Control != textBox
+ || field.Value == textBox.Text)
return;
- fieldBinding.SelectionStart = textBox.SelectionStart;
- fieldBinding.Value = textBox.Text;
+
+ field.SelectionStart = textBox.SelectionStart;
+ field.Value = textBox.Text;
+ version.State |= State.Modified | (State)column;
+
Validate(false);
}
}
@@ -397,28 +405,49 @@
if (sender is ComboBox comboBox && GetBinding(comboBox) is Row version) {
if (!comboBox.IsEnabled || comboBox.SelectedIndex < 0)
return;
+ if (string.IsNullOrEmpty(comboBox.Name) || !comboBox.Name.TryCast(out Column column))
+ return;
+
string comboBoxValue = comboBox.Items[comboBox.SelectedIndex] as string;
- string controlName = comboBox.Name;
- Row.FieldNames field;
- if (string.IsNullOrEmpty(controlName) || !controlName.TryCast(out field))
+ var field = version.Fields[column];
+ if (field == null
+ || field.Control != comboBox
+ || field.Value == comboBoxValue)
return;
- var fieldBinding = version.Fields[field];
- if (fieldBinding == null
- || fieldBinding.Control != comboBox
- || fieldBinding.Value == comboBoxValue)
- return;
- fieldBinding.Value = comboBoxValue;
- Validate(false);
+
+ field.Value = comboBoxValue;
+ version.State |= State.Modified | (State)Column.Host;
+
+ bool mustRefresh = false;
+ if (version.Host != BuildHost.Windows && version.Compiler == "msvc") {
+ version.Compiler = "g++";
+ version.FieldCompiler.SelectionStart = version.Compiler.Length;
+ version.State |= (State)Column.Compiler;
+ mustRefresh = true;
+ } else if (version.Host == BuildHost.Windows && version.Compiler != "msvc") {
+ version.Compiler = "msvc";
+ version.FieldCompiler.SelectionStart = version.Compiler.Length;
+ version.State |= (State)Column.Compiler;
+ mustRefresh = true;
+ }
+
+ Validate(mustRefresh);
}
+ }
+
+ static void SetDefaultState(ref Row version, bool value)
+ {
+ version.IsDefault = value;
+ version.State |= State.Modified | (State)Column.IsDefault;
}
void Default_Click(object sender, RoutedEventArgs e)
{
if (sender is CheckBox checkBox && GetBinding(checkBox) is Row version) {
- var defaultVersion = Rows.Where(row => row.IsDefault).FirstOrDefault();
+ var defaultVersion = Rows.FirstOrDefault(row => row.IsDefault);
if (defaultVersion != null)
- defaultVersion.IsDefault = false;
- version.IsDefault = true;
+ SetDefaultState(ref defaultVersion, false);
+ SetDefaultState(ref version, true);
Validate(true);
}
}
@@ -427,12 +456,16 @@
{
var version = new Row()
{
- IsDefault = !Versions.Any(),
+ IsDefault = !Versions.Any(x => x.State != State.Removed),
Host = BuildHost.Windows,
Path = "",
Compiler = "msvc",
- LastRow = false
+ LastRow = false,
+ State = State.Modified | (State)Column.VersionName | (State)Column.Host
+ | (State)Column.Path | (State)Column.Compiler
};
+ if (version.IsDefault)
+ version.State |= (State)Column.IsDefault;
Rows.Insert(Rows.Count - 1, version);
FocusedField = version.FieldVersionName;
Validate(true);
@@ -441,10 +474,26 @@
void Remove_Click(object sender, RoutedEventArgs e)
{
if (sender is Button button && GetBinding(button) is Row version) {
- Rows.Remove(version);
- if (version.IsDefault && Versions.Any())
- Versions.First().IsDefault = true;
+ version.State = State.Removed;
+ if (version.IsDefault) {
+ var first = Versions.FirstOrDefault(x => x.State != State.Removed);
+ if (first != null)
+ SetDefaultState(ref first, true);
+ }
Validate(true);
+ }
+ }
+
+ static string NormalizePath(string path)
+ {
+ if (string.IsNullOrEmpty(path))
+ return path;
+ try {
+ return Path.GetFullPath(new Uri(path).LocalPath)
+ .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
+ .ToUpperInvariant();
+ } catch (UriFormatException) {
+ return null;
}
}
@@ -462,6 +511,7 @@
if (openFileDialog.ShowDialog() == true) {
var qmakePath = openFileDialog.FileName;
var qmakeDir = Path.GetDirectoryName(qmakePath);
+ var previousPath = NormalizePath(version.Path);
if (Path.GetFileName(qmakeDir)
.Equals("bin", StringComparison.InvariantCultureIgnoreCase)) {
qmakeDir = Path.GetDirectoryName(qmakeDir);
@@ -469,12 +519,18 @@
} else {
version.Path = qmakePath;
}
+
+ if (previousPath != NormalizePath(version.Path))
+ version.State |= State.Modified | (State)Column.Path;
+
if (string.IsNullOrEmpty(version.VersionName)) {
version.VersionName = string.Format("{0}_{1}",
Path.GetFileName(Path.GetDirectoryName(qmakeDir)),
Path.GetFileName(qmakeDir))
.Replace(" ", "_");
+ version.State |= State.Modified | (State)Column.VersionName;
}
+
Validate(true);
}
}
@@ -503,9 +559,9 @@
static object GetBinding(FrameworkElement control)
{
if (control == null
- || control.BindingGroup == null
- || control.BindingGroup.Items == null
- || control.BindingGroup.Items.Count == 0) {
+ || control.BindingGroup == null
+ || control.BindingGroup.Items == null
+ || control.BindingGroup.Items.Count == 0) {
return null;
}
return control.BindingGroup.Items[0];
@@ -515,7 +571,7 @@
{
while (control != null) {
if (control is ContentPresenter contentPresenter
- && contentPresenter.Parent is DataGridCell cell) {
+ && contentPresenter.Parent is DataGridCell cell) {
return cell;
}
control = VisualTreeHelper.GetParent(control);
diff --git a/QtVsTools.Package/Options/QtVersionsTable.xaml b/QtVsTools.Package/Options/QtVersionsTable.xaml
index 1b147ff..9f85dc3 100644
--- a/QtVsTools.Package/Options/QtVersionsTable.xaml
+++ b/QtVsTools.Package/Options/QtVersionsTable.xaml
@@ -1,7 +1,7 @@
<!--
/****************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -32,7 +32,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:local="clr-namespace:QtVsTools.Options"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800">
@@ -58,7 +57,13 @@
Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
Color="Transparent" />
+ <BooleanToVisibilityConverter x:Key="b2v" />
</DataGrid.Resources>
+ <DataGrid.RowStyle>
+ <Style TargetType="{x:Type DataGridRow}">
+ <Setter Property="Visibility" Value="{Binding RowVisible, Converter={StaticResource b2v}}"/>
+ </Style>
+ </DataGrid.RowStyle>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness"
@@ -76,8 +81,7 @@
<CheckBox x:Name="IsDefault"
IsChecked="{Binding IsDefault}"
Focusable="{Binding DefaultEnabled}"
- IsHitTestVisible="{Binding DefaultEnabled}"
- Visibility="{Binding RowVisibility}"
+ Visibility="{Binding RowContentVisibility}"
BorderThickness="1"
Background="Transparent"
VerticalAlignment="Center"
@@ -94,7 +98,7 @@
<!--//// Name ////-->
<Grid>
<Button Cursor="Hand"
- Visibility="{Binding RowVisibility}"
+ Visibility="{Binding RowContentVisibility}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Click="Remove_Click">
@@ -153,7 +157,7 @@
</Button>
<TextBox x:Name="VersionName"
Text="{Binding VersionName}"
- Visibility="{Binding RowVisibility}"
+ Visibility="{Binding RowContentVisibility}"
IsEnabled="{Binding NameEnabled}"
FontWeight="{Binding FontWeight}"
Margin="20,4,2,4"
@@ -166,7 +170,7 @@
LostFocus="Control_LostFocus"
TextChanged="TextBox_TextChanged"
SelectionChanged="TextBox_SelectionChanged"
- ToolTip="{Binding FieldName.ToolTip}">
+ ToolTip="{Binding FieldVersionName.ToolTip}">
<TextBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="LimeGreen" />
@@ -181,7 +185,7 @@
<DataTemplate>
<!--//// Host ////-->
<ComboBox x:Name="Host"
- Visibility="{Binding RowVisibility}"
+ Visibility="{Binding RowContentVisibility}"
IsEditable="True"
IsReadOnly="True"
BorderThickness="0"
@@ -233,7 +237,7 @@
</Button>
<TextBox x:Name="Path"
Text="{Binding Path}"
- Visibility="{Binding RowVisibility}"
+ Visibility="{Binding RowContentVisibility}"
BorderThickness="0"
Background="Transparent"
Margin="{Binding PathMargin}"
@@ -260,7 +264,7 @@
<!--//// Compiler ////-->
<TextBox x:Name="Compiler"
Text="{Binding Compiler}"
- Visibility="{Binding RowVisibility}"
+ Visibility="{Binding RowContentVisibility}"
IsEnabled="{Binding CompilerEnabled}"
BorderThickness="0"
Background="Transparent"
diff --git a/QtVsTools.Package/Package/DteEventsHandler.cs b/QtVsTools.Package/Package/DteEventsHandler.cs
index c7304c0..df8bfc4 100644
--- a/QtVsTools.Package/Package/DteEventsHandler.cs
+++ b/QtVsTools.Package/Package/DteEventsHandler.cs
@@ -26,44 +26,45 @@
**
****************************************************************************/
-using EnvDTE;
-using EnvDTE80;
-using Microsoft.VisualStudio;
-using Microsoft.VisualStudio.Shell;
-using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.VisualStudio.VCProjectEngine;
-using QtVsTools.Core;
-using QtVsTools.Core.QtMsBuild;
-using QtVsTools.QtMsBuild;
using System;
-using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
+using Microsoft.VisualStudio;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
+using EnvDTE;
+using EnvDTE80;
namespace QtVsTools
{
+ using Core;
+ using QtMsBuild;
+
class DteEventsHandler
{
- private DTE dte;
- private SolutionEvents solutionEvents;
- private BuildEvents buildEvents;
- private DocumentEvents documentEvents;
- private ProjectItemsEvents projectItemsEvents;
+ private readonly DTE dte;
+ private readonly SolutionEvents solutionEvents;
+ private readonly BuildEvents buildEvents;
+ private readonly DocumentEvents documentEvents;
+ private readonly ProjectItemsEvents projectItemsEvents;
private vsBuildAction currentBuildAction = vsBuildAction.vsBuildActionBuild;
private VCProjectEngineEvents vcProjectEngineEvents;
- private CommandEvents debugStartEvents;
- private CommandEvents debugStartWithoutDebuggingEvents;
- private CommandEvents f1HelpEvents;
- private int dispId_VCFileConfiguration_ExcludedFromBuild;
- private int dispId_VCCLCompilerTool_UsePrecompiledHeader;
- private int dispId_VCCLCompilerTool_PrecompiledHeaderThrough;
- private int dispId_VCCLCompilerTool_PreprocessorDefinitions;
- private int dispId_VCCLCompilerTool_AdditionalIncludeDirectories;
+ private readonly CommandEvents debugStartEvents;
+ private readonly CommandEvents debugStartWithoutDebuggingEvents;
+ private readonly CommandEvents f1HelpEvents;
+ private WindowEvents windowEvents;
+ private readonly int dispId_VCFileConfiguration_ExcludedFromBuild;
+ private readonly int dispId_VCCLCompilerTool_UsePrecompiledHeader;
+ private readonly int dispId_VCCLCompilerTool_PrecompiledHeaderThrough;
+ private readonly int dispId_VCCLCompilerTool_PreprocessorDefinitions;
+ private readonly int dispId_VCCLCompilerTool_AdditionalIncludeDirectories;
public DteEventsHandler(DTE _dte)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
dte = _dte;
var events = dte.Events as Events2;
@@ -85,6 +86,9 @@
solutionEvents.Opened += SolutionEvents_Opened;
solutionEvents.AfterClosing += SolutionEvents_AfterClosing;
+ windowEvents = events.WindowEvents;
+ windowEvents.WindowActivated += WindowEvents_WindowActivated;
+
var debugCommandsGUID = "{5EFC7975-14BC-11CF-9B2B-00AA00573819}";
debugStartEvents = events.get_CommandEvents(debugCommandsGUID, 295);
debugStartEvents.BeforeExecute += debugStartEvents_BeforeExecute;
@@ -105,15 +109,33 @@
InitializeVCProjects();
}
+ private void WindowEvents_WindowActivated(Window gotFocus, Window lostFocus)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ if (dte.MainWindow?.Visible == true) {
+ windowEvents.WindowActivated -= WindowEvents_WindowActivated;
+ windowEvents = null;
+ QtVsToolsPackage.Instance.VsMainWindowActivated();
+ }
+ }
+
private void F1HelpEvents_BeforeExecute(
string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
{
- if (QtVsToolsPackage.Instance.Options.TryQtHelpOnF1Pressed && QtHelp.QueryEditorContextHelp())
+ ThreadHelper.ThrowIfNotOnUIThread();
+ if (QtVsToolsPackage.Instance.Options.TryQtHelpOnF1Pressed) {
+ if (!QtHelp.ShowEditorContextHelp()) {
+ Messages.Print("No help match was found. You can still try to search online at "
+ + "https://doc.qt.io" + ".", false, true);
+ }
CancelDefault = true;
+ }
}
void debugStartEvents_BeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var debugger = dte.Debugger;
if (debugger != null && debugger.CurrentMode != dbgDebugMode.dbgDesignMode)
return;
@@ -147,6 +169,8 @@
public void Disconnect()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (buildEvents != null) {
buildEvents.OnBuildBegin -= buildEvents_OnBuildBegin;
buildEvents.OnBuildProjConfigBegin -= OnBuildProjConfigBegin;
@@ -174,12 +198,19 @@
if (debugStartWithoutDebuggingEvents != null)
debugStartWithoutDebuggingEvents.BeforeExecute -= debugStartWithoutDebuggingEvents_BeforeExecute;
- if (vcProjectEngineEvents != null)
+ if (vcProjectEngineEvents != null) {
vcProjectEngineEvents.ItemPropertyChange -= OnVCProjectEngineItemPropertyChange;
+ vcProjectEngineEvents.ItemPropertyChange2 -= OnVCProjectEngineItemPropertyChange2;
+ }
+
+ if (windowEvents != null)
+ windowEvents.WindowActivated -= WindowEvents_WindowActivated;
}
public void OnBuildProjConfigBegin(string projectName, string projectConfig, string platform, string solutionConfig)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (!QtVsToolsPackage.Instance.LegacyOptions.PreBuildSetup)
return;
@@ -195,7 +226,7 @@
break;
}
}
- if (project == null || !HelperFunctions.IsQtProject(project))
+ if (project == null || !HelperFunctions.IsVsToolsProject(project))
return;
if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_Settings)
@@ -229,9 +260,11 @@
public void DocumentSaved(Document document)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var qtPro = QtProject.Create(document.ProjectItem.ContainingProject);
- if (!HelperFunctions.IsQtProject(qtPro.VCProject))
+ if (!HelperFunctions.IsVsToolsProject(qtPro.VCProject))
return;
var file = (VCFile)((IVCCollection)qtPro.VCProject.Files).Item(document.FullName);
@@ -323,10 +356,13 @@
public void ProjectItemsEvents_ItemAdded(ProjectItem projectItem)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var project = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
var qtPro = QtProject.Create(project);
- if (!HelperFunctions.IsQtProject(project))
+ if (!HelperFunctions.IsVsToolsProject(project))
return;
+
var vcFile = GetVCFileFromProject(projectItem.Name, qtPro.VCProject);
if (vcFile == null)
return;
@@ -373,12 +409,15 @@
HelperFunctions.EnsureCustomBuildToolAvailable(projectItem);
qtPro.UpdateRccStep(vcFile, null);
} else if (HelperFunctions.IsTranslationFile(vcFile.Name)) {
+ Translation.RunlUpdate(vcFile);
}
} catch { }
}
void ProjectItemsEvents_ItemRemoved(ProjectItem ProjectItem)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
if (pro == null)
return;
@@ -389,6 +428,8 @@
void ProjectItemsEvents_ItemRenamed(ProjectItem ProjectItem, string OldName)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (OldName == null)
return;
var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
@@ -397,12 +438,15 @@
var qtPro = QtProject.Create(pro);
qtPro.RemoveGeneratedFiles(OldName);
+
ProjectItemsEvents_ItemAdded(ProjectItem);
}
void SolutionEvents_ProjectAdded(Project project)
{
- if (HelperFunctions.IsQMakeProject(project)) {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (HelperFunctions.IsQtProject(project)) {
InitializeVCProject(project);
QtProjectTracker.Add(project);
var vcpro = project.Object as VCProject;
@@ -446,9 +490,11 @@
public void SolutionEvents_Opened()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
QtProjectTracker.SolutionPath = QtVsToolsPackage.Instance.Dte.Solution.FullName;
foreach (var p in HelperFunctions.ProjectsInSolution(QtVsToolsPackage.Instance.Dte)) {
- if (HelperFunctions.IsQtProject(p)) {
+ if (HelperFunctions.IsVsToolsProject(p)) {
InitializeVCProject(p);
QtProjectTracker.Add(p);
}
@@ -464,14 +510,18 @@
void InitializeVCProjects()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
foreach (var project in HelperFunctions.ProjectsInSolution(dte)) {
- if (project != null && HelperFunctions.IsQtProject(project))
+ if (project != null && HelperFunctions.IsVsToolsProject(project))
InitializeVCProject(project);
}
}
void InitializeVCProject(Project p)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (vcProjectEngineEvents != null)
return;
@@ -480,12 +530,12 @@
return;
// Retrieves the VCProjectEngine from the given project and registers the handlers for VCProjectEngineEvents.
- var prjEngine = vcPrj.VCProjectEngine as VCProjectEngine;
- if (prjEngine != null) {
+ if (vcPrj.VCProjectEngine is VCProjectEngine prjEngine) {
vcProjectEngineEvents = prjEngine.Events as VCProjectEngineEvents;
if (vcProjectEngineEvents != null) {
try {
vcProjectEngineEvents.ItemPropertyChange += OnVCProjectEngineItemPropertyChange;
+ vcProjectEngineEvents.ItemPropertyChange2 += OnVCProjectEngineItemPropertyChange2;
} catch {
Messages.DisplayErrorMessage("VCProjectEngine events could not be registered.");
}
@@ -495,7 +545,6 @@
private void OnVCProjectEngineItemPropertyChange(object item, object tool, int dispid)
{
- //System.Diagnostics.Debug.WriteLine("OnVCProjectEngineItemPropertyChange " + dispid.ToString());
var vcFileCfg = item as VCFileConfiguration;
if (vcFileCfg == null) {
// A global or project specific property has changed.
@@ -506,7 +555,7 @@
var vcPrj = vcCfg.project as VCProject;
if (vcPrj == null)
return;
- if (!HelperFunctions.IsQtProject(vcPrj))
+ if (!HelperFunctions.IsVsToolsProject(vcPrj))
return;
// Ignore property events when using shared compiler properties
if (QtProject.GetFormatVersion(vcPrj) >= Resources.qtMinFormatVersion_ClProperties)
@@ -538,7 +587,7 @@
var vcPrj = vcFile.project as VCProject;
if (vcPrj == null)
return;
- if (!HelperFunctions.IsQtProject(vcPrj))
+ if (!HelperFunctions.IsVsToolsProject(vcPrj))
return;
// Ignore property events when using shared compiler properties
if (QtProject.GetFormatVersion(vcPrj) >= Resources.qtMinFormatVersion_ClProperties)
@@ -557,10 +606,27 @@
}
}
+ private void OnVCProjectEngineItemPropertyChange2(
+ object item,
+ string propertySheet,
+ string itemType,
+ string propertyName)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ if (!propertyName.StartsWith("Qt") || propertyName == "QtLastBackgroundBuild")
+ return;
+ if (item is VCConfiguration vcConfig
+ && vcConfig.project is VCProject vcProject
+ && vcProject.Object is Project project) {
+ QtProjectIntellisense.Refresh(
+ QtProjectTracker.Get(project, project.FullName).Project, vcConfig.Name);
+ }
+ }
+
private static VCFile GetVCFileFromProject(string absFileName, VCProject project)
{
foreach (VCFile f in (IVCCollection)project.Files) {
- if (f.Name.ToLower() == absFileName.ToLower())
+ if (f.Name.Equals(absFileName, StringComparison.OrdinalIgnoreCase))
return f;
}
return null;
@@ -574,8 +640,7 @@
var pi = type.GetProperty(propertyName);
if (pi != null) {
foreach (Attribute attribute in pi.GetCustomAttributes(true)) {
- var dispIdAttribute = attribute as DispIdAttribute;
- if (dispIdAttribute != null)
+ if (attribute is DispIdAttribute dispIdAttribute)
return dispIdAttribute.Value;
}
}
diff --git a/QtVsTools.Package/Package/ExtLoader.cs b/QtVsTools.Package/Package/ExtLoader.cs
index 83885ac..76fc8bf 100644
--- a/QtVsTools.Package/Package/ExtLoader.cs
+++ b/QtVsTools.Package/Package/ExtLoader.cs
@@ -26,22 +26,27 @@
**
****************************************************************************/
-using Microsoft.VisualStudio.VCProjectEngine;
-using QtVsTools.Core;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
namespace QtVsTools
{
+ using Core;
+
public static class ExtLoader
{
public static void ImportProFile()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var vm = QtVersionManager.The();
var qtVersion = vm.GetDefaultVersion();
var qtDir = vm.GetInstallPath(qtVersion);
+
if (qtDir == null) {
Messages.DisplayErrorMessage(SR.GetString("CannotFindQMake"));
return;
@@ -59,11 +64,13 @@
public static void ImportPriFile(EnvDTE.Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (project == null)
return;
VCProject vcproj;
- if (!HelperFunctions.IsQtProject(project))
+ if (!HelperFunctions.IsVsToolsProject(project))
return;
vcproj = project.Object as VCProject;
@@ -87,10 +94,12 @@
public static void ImportPriFile(EnvDTE.Project project, string fileName)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (project == null)
return;
- if (!HelperFunctions.IsQtProject(project))
+ if (!HelperFunctions.IsVsToolsProject(project))
return;
var vcproj = project.Object as VCProject;
@@ -134,6 +143,8 @@
private static List<string> ResolveFilesFromQMake(string[] files, EnvDTE.Project project, string path)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var lst = new List<string>();
foreach (var file in files) {
var s = ResolveEnvironmentVariables(file, project);
diff --git a/QtVsTools.Package/Package/Notifications.cs b/QtVsTools.Package/Package/Notifications.cs
new file mode 100644
index 0000000..de0a639
--- /dev/null
+++ b/QtVsTools.Package/Package/Notifications.cs
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using Microsoft.VisualStudio.Imaging;
+using Microsoft.VisualStudio.Shell;
+
+namespace QtVsTools
+{
+ using Common;
+ using Microsoft.VisualStudio.Imaging.Interop;
+ using VisualStudio;
+
+ public static class Notifications
+ {
+ static LazyFactory StaticLazy { get; } = new LazyFactory();
+
+ public static NoQtVersion NoQtVersion
+ => StaticLazy.Get(() => NoQtVersion, () => new NoQtVersion());
+
+ public static NotifyInstall NotifyInstall
+ => StaticLazy.Get(() => NotifyInstall, () => new NotifyInstall());
+ }
+
+ public class NoQtVersion : InfoBarMessage
+ {
+ protected override ImageMoniker Icon => KnownMonikers.StatusWarning;
+
+ protected override TextSpan[] Text => new TextSpan[]
+ {
+ new TextSpan { Bold = true, Text = "Qt Visual Studio Tools" },
+ new TextSpacer(2),
+ "\u2014", // Em dash
+ new TextSpacer(2),
+ "You must select a Qt version to use for development."
+ };
+
+ protected override Hyperlink[] Hyperlinks => new Hyperlink[]
+ {
+ new Hyperlink
+ {
+ Text = "Select Qt version...",
+ CloseInfoBar = false,
+ OnClicked = () =>
+ QtVsToolsPackage.Instance.ShowOptionPage(typeof(Options.QtVersionsPage))
+ }
+ };
+ }
+
+ public class NotifyInstall : InfoBarMessage
+ {
+ protected override ImageMoniker Icon => KnownMonikers.StatusInformation;
+
+ protected override TextSpan[] Text => new TextSpan[]
+ {
+ new TextSpan { Bold = true, Text = "Qt Visual Studio Tools" },
+ new TextSpacer(2),
+ "\u2014", // Em dash
+ new TextSpacer(2),
+ $"Version {Version.USER_VERSION} was recently installed."
+ };
+
+ protected override Hyperlink[] Hyperlinks => new Hyperlink[]
+ {
+ new Hyperlink
+ {
+ Text = "Release Notes",
+ CloseInfoBar = false,
+ OnClicked= () =>
+ {
+ VsShellUtilities.OpenSystemBrowser(
+ "https://code.qt.io/cgit/qt-labs/vstools.git/tree/Changelog");
+ }
+ },
+ new Hyperlink
+ {
+ Text = "Don't show again",
+ CloseInfoBar = true,
+ OnClicked = () =>
+ {
+ QtVsToolsPackage.Instance.Options.NotifyInstalled = false;
+ QtVsToolsPackage.Instance.Options.SaveSettingsToStorage();
+ }
+ }
+ };
+ }
+}
diff --git a/QtVsTools.Package/Package/QMakeWrapper.cs b/QtVsTools.Package/Package/QMakeWrapper.cs
index 11b0614..61f7bcb 100644
--- a/QtVsTools.Package/Package/QMakeWrapper.cs
+++ b/QtVsTools.Package/Package/QMakeWrapper.cs
@@ -37,7 +37,7 @@
public string QtDir { get; set; }
public bool IsFlat { get; private set; }
- public bool IsValid { get; private set; }
+ private bool IsValid { get; set; }
public string[] SourceFiles { get; private set; }
public string[] HeaderFiles { get; private set; }
diff --git a/QtVsTools.Package/Package/QtHelp.cs b/QtVsTools.Package/Package/QtHelp.cs
index e36cb83..12e7b19 100644
--- a/QtVsTools.Package/Package/QtHelp.cs
+++ b/QtVsTools.Package/Package/QtHelp.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,13 +26,6 @@
**
****************************************************************************/
-using EnvDTE;
-using Microsoft.VisualStudio.Settings;
-using Microsoft.VisualStudio.Shell;
-using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.VisualStudio.Shell.Settings;
-using QtVsTools.Core;
-using QtVsTools.VisualStudio;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
@@ -40,37 +33,36 @@
using System.Data.SQLite;
using System.IO;
using System.Linq;
-using System.Threading.Tasks;
-using Task = System.Threading.Tasks.Task;
+using EnvDTE;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
namespace QtVsTools
{
+ using Core;
+ using VisualStudio;
+
public class QtHelp
{
public enum SourcePreference { Online, Offline }
- public static QtHelp Instance
+ private static QtHelp Instance
{
get;
- private set;
+ set;
}
- public static void Initialize(Package package)
+ public static void Initialize()
{
- Instance = new QtHelp(package);
+ Instance = new QtHelp();
}
const int F1QtHelpId = 0x0502;
- readonly Package package;
- public static readonly Guid MainMenuGuid = new Guid("58f83fff-d39d-4c66-810b-2702e1f04e73");
+ private static readonly Guid MainMenuGuid = new Guid("58f83fff-d39d-4c66-810b-2702e1f04e73");
- QtHelp(Package pkg)
+ private QtHelp()
{
- if (pkg == null)
- throw new ArgumentNullException("package");
- package = pkg;
-
var commandService = VsServiceProvider
.GetService<IMenuCommandService, OleMenuCommandService>();
if (commandService == null)
@@ -79,12 +71,6 @@
var menuCommandID = new CommandID(MainMenuGuid, F1QtHelpId);
commandService.AddCommand(new MenuCommand(F1QtHelpEventHandler, menuCommandID));
}
-
- IServiceProvider ServiceProvider
- {
- get { return package; }
- }
-
static bool IsSuperfluousCharacter(string text)
{
switch (text) {
@@ -131,11 +117,17 @@
void F1QtHelpEventHandler(object sender, EventArgs args)
{
- QueryEditorContextHelp(true);
+ ThreadHelper.ThrowIfNotOnUIThread();
+ if (!ShowEditorContextHelp()) {
+ Messages.Print("No help match was found. You can still try to search online at "
+ + "https://doc.qt.io" + ".", false, true);
+ }
}
- public static bool QueryEditorContextHelp(bool defaultTryOnline = false)
+ public static bool ShowEditorContextHelp()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
try {
var dte = VsServiceProvider.GetService<SDTE, DTE>();
var objTextDocument = dte?.ActiveDocument?.Object() as TextDocument;
@@ -173,7 +165,7 @@
var project = HelperFunctions.GetSelectedQtProject(dte);
if (project == null) {
project = HelperFunctions.GetSelectedProject(dte);
- if (project != null && HelperFunctions.IsQMakeProject(project)) {
+ if (project != null && HelperFunctions.IsQtProject(project)) {
var qmakeQtDir = HelperFunctions.GetQtDirFromQMakeProject(project);
qtVersion = QtVersionManager.The().GetQtVersionFromInstallDir(qmakeQtDir);
}
@@ -188,7 +180,7 @@
var qchFiles = Directory.GetFiles(docPath, "*?.qch");
if (qchFiles.Length == 0)
- return false;
+ return TryShowGenericSearchResultsOnline(keyword, info.qtMajor);
var offline = QtVsToolsPackage.Instance.Options.HelpPreference == SourcePreference.Offline;
@@ -207,8 +199,9 @@
using (var connection = new SQLiteConnection(builder.ToString())) {
connection.Open();
using (var command = new SQLiteCommand(linksForKeyword, connection)) {
- using (var reader =
- Task.Run(async () => await command.ExecuteReaderAsync()).Result) {
+ var reader = QtVsToolsPackage.Instance.JoinableTaskFactory
+ .Run(async () => await command.ExecuteReaderAsync());
+ using (reader) {
while (reader.Read()) {
var title = GetString(reader, 0);
if (string.IsNullOrWhiteSpace(title))
@@ -233,15 +226,7 @@
var uri = string.Empty;
switch (links.Values.Count) {
case 0:
- if (!offline && defaultTryOnline) {
- uri = new UriBuilder($"https://doc.qt.io/qt-{info.qtMajor}/search-results.html")
- {
- Query = "q=" + keyword
- }.ToString();
- } else {
- return false;
- }
- break;
+ return TryShowGenericSearchResultsOnline(keyword, info.qtMajor);
case 1:
uri = links.First().Value;
break;
@@ -254,34 +239,40 @@
};
if (!dialog.ShowModal().GetValueOrDefault())
return false;
- uri = dialog.Link
- .Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
+ uri = dialog.Link;
break;
}
- if (string.IsNullOrEmpty(uri)) { // offline mode without a single search hit
- VsShellUtilities.ShowMessageBox(Instance.ServiceProvider,
- "Your search - " + keyword + " - did not match any documents.",
+ uri = HelperFunctions.FromNativeSeparators(uri);
+ var helpUri = new Uri(uri);
+ if (helpUri.IsFile && !File.Exists(helpUri.LocalPath)) {
+ VsShellUtilities.ShowMessageBox(QtVsToolsPackage.Instance,
+ "Your search - " + keyword + " - did match a document, but it could "
+ + "not be found on disk. To use the online help, select: "
+ + "Tools | Options | Qt | Preferred source | Online",
string.Empty, OLEMSGICON.OLEMSGICON_INFO, OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
} else {
- var helpUri = new Uri(uri.Replace('\\', '/'));
- if (helpUri.IsFile && !File.Exists(helpUri.LocalPath)) {
- VsShellUtilities.ShowMessageBox(Instance.ServiceProvider,
- "Your search - " + keyword + " - did match a document, but it could "
- + "not be found on disk. To use the online help, select: "
- + "Help | Set Qt Help Preference | Use Online Documentation",
- string.Empty, OLEMSGICON.OLEMSGICON_INFO, OLEMSGBUTTON.OLEMSGBUTTON_OK,
- OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
- } else {
- VsShellUtilities.OpenSystemBrowser(HelperFunctions.ChangePathFormat(uri));
- }
+ VsShellUtilities.OpenSystemBrowser(uri);
}
- } catch (Exception e) {
- Messages.Print(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
}
return true;
}
+
+ private static bool TryShowGenericSearchResultsOnline(string keyword, uint version)
+ {
+ if (QtVsToolsPackage.Instance.Options.HelpPreference != SourcePreference.Online)
+ return false;
+
+ VsShellUtilities.OpenSystemBrowser(HelperFunctions.FromNativeSeparators(
+ new UriBuilder($"https://doc.qt.io/qt-{version}/search-results.html")
+ {
+ Query = "q=" + keyword
+ }.ToString())
+ );
+ return true;
+ }
}
}
diff --git a/QtVsTools.Package/Package/QtHelpLinkChooser.xaml b/QtVsTools.Package/Package/QtHelpLinkChooser.xaml
index d901292..adfa3d6 100644
--- a/QtVsTools.Package/Package/QtHelpLinkChooser.xaml
+++ b/QtVsTools.Package/Package/QtHelpLinkChooser.xaml
@@ -1,7 +1,7 @@
<!--
*****************************************************************************
**
- ** Copyright (C) 2016 The Qt Company Ltd.
+ ** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -28,33 +28,31 @@
*****************************************************************************
-->
-<local:VsToolsDialogWindow x:Class="QtVsTools.QtHelpLinkChooser"
- 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:local="clr-namespace:QtVsTools"
- Width="400"
- Height="250"
- MinWidth="400"
- MinHeight="250"
- mc:Ignorable="d"
- Title="Choose Topic"
- ShowInTaskbar="False"
- HasHelpButton="False"
- HasMinimizeButton="False"
- ResizeMode="CanResizeWithGrip"
- WindowStartupLocation="CenterOwner">
- <local:VsToolsDialogWindow.Resources>
- <BooleanToVisibilityConverter x:Key="b2v" />
+<vsui:DialogWindow x:Class="QtVsTools.QtHelpLinkChooser"
+ 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:vsui="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0"
+ Width="400"
+ Height="250"
+ MinWidth="400"
+ MinHeight="250"
+ mc:Ignorable="d"
+ Title="Choose Topic"
+ ShowInTaskbar="False"
+ HasHelpButton="False"
+ HasMinimizeButton="False"
+ ResizeMode="CanResizeWithGrip"
+ WindowStartupLocation="CenterOwner">
+ <vsui:DialogWindow.Resources>
<Style x:Key="ListBoxDoubleClickStyle"
TargetType="ListBoxItem">
<EventSetter Event="MouseDoubleClick"
Handler="OnListBoxItem_DoubleClick" />
</Style>
- </local:VsToolsDialogWindow.Resources>
- <Grid Margin="10"
- FocusManager.FocusedElement="{Binding ElementName=searchBox}">
+ </vsui:DialogWindow.Resources>
+ <Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
@@ -68,18 +66,8 @@
Text="{Binding Path=Keyword}" />
<Run Text=":" />
</TextBlock>
- <Grid Grid.Row="1"
- MinHeight="22"
- Background="White">
- <TextBlock Text=" Filter..."
- Foreground="LightSteelBlue"
- VerticalAlignment="Center"
- Visibility="{Binding ElementName=searchBox,
- Path=Text.IsEmpty, Converter={StaticResource b2v}}" />
- <TextBox Name="searchBox"
- Background="Transparent"
- TextChanged="OnSearchBox_TextChanged"
- VerticalContentAlignment="Center" />
+ <Grid Grid.Row="1">
+ <Grid Name="searchControlHost" />
</Grid>
<ListBox Grid.Row="2"
Margin="0,10,0,0"
@@ -104,4 +92,4 @@
Margin="0,10,0,0" />
</StackPanel>
</Grid>
-</local:VsToolsDialogWindow>
+</vsui:DialogWindow>
diff --git a/QtVsTools.Package/Package/QtHelpLinkChooser.xaml.cs b/QtVsTools.Package/Package/QtHelpLinkChooser.xaml.cs
index 290f966..8d71431 100644
--- a/QtVsTools.Package/Package/QtHelpLinkChooser.xaml.cs
+++ b/QtVsTools.Package/Package/QtHelpLinkChooser.xaml.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -32,10 +32,14 @@
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
+using Microsoft.VisualStudio.PlatformUI;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+using QtVsTools.VisualStudio;
namespace QtVsTools
{
- partial class QtHelpLinkChooser : VsToolsDialogWindow
+ partial class QtHelpLinkChooser : DialogWindow
{
public QtHelpLinkChooser()
{
@@ -46,28 +50,32 @@
}
public string Link { get; set; }
+ public string SearchText { get; set; }
+
public string Keyword { private get; set; }
public Dictionary<string, string> Links { private get; set; }
private void OnLoaded(object sender, RoutedEventArgs e)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var view = CollectionViewSource.GetDefaultView(linkListBox.ItemsSource);
view.Filter = obj =>
{
- if (string.IsNullOrEmpty(searchBox.Text))
+ if (string.IsNullOrEmpty(SearchText))
return true;
var item = (KeyValuePair<string, string>)obj;
- return item.Key.IndexOf(searchBox.Text, StringComparison.OrdinalIgnoreCase) >= 0;
+ return item.Key.IndexOf(SearchText, StringComparison.OrdinalIgnoreCase) >= 0;
};
linkListBox.SelectedIndex = 0;
- }
- private void OnSearchBox_TextChanged(object sender, TextChangedEventArgs e)
- {
- CollectionViewSource.GetDefaultView(linkListBox.ItemsSource).Refresh();
- if (linkListBox.Items.Count == 1 || linkListBox.SelectedItem == null)
- linkListBox.SelectedIndex = 0;
+ var factory = VsServiceProvider
+ .GetService<SVsWindowSearchHostFactory, IVsWindowSearchHostFactory>();
+ var host = factory.CreateWindowSearchHost(searchControlHost);
+
+ host.SetupSearch(new ListBoxSearch(linkListBox, value => SearchText = value));
+ host.Activate(); // set focus
}
private void OnListBoxItem_DoubleClick(object sender, MouseButtonEventArgs e)
diff --git a/QtVsTools.Package/Package/QtItemContextMenu.cs b/QtVsTools.Package/Package/QtItemContextMenu.cs
index 19bc389..ce4f888 100644
--- a/QtVsTools.Package/Package/QtItemContextMenu.cs
+++ b/QtVsTools.Package/Package/QtItemContextMenu.cs
@@ -26,15 +26,16 @@
**
****************************************************************************/
-using EnvDTE;
-using Microsoft.VisualStudio.Shell;
-using QtVsTools.Core;
-using QtVsTools.VisualStudio;
using System;
using System.ComponentModel.Design;
+using Microsoft.VisualStudio.Shell;
+using EnvDTE;
namespace QtVsTools
{
+ using Core;
+ using VisualStudio;
+
/// <summary>
/// Command handler
/// </summary>
@@ -43,30 +44,24 @@
/// <summary>
/// Command menu group (command set GUID).
/// </summary>
- public static readonly Guid ItemContextMenuGuid = new Guid("9f67a0bd-ee0a-47e3-b656-5efb12e3c770");
+ private static readonly Guid ItemContextMenuGuid = new Guid("9f67a0bd-ee0a-47e3-b656-5efb12e3c770");
/// <summary>
/// Gets the instance of the command.
/// </summary>
- public static QtItemContextMenu Instance
+ private static QtItemContextMenu Instance
{
get;
- private set;
+ set;
}
/// <summary>
/// Initializes the singleton instance of the command.
/// </summary>
- /// <param name="package">Owner package, not null.</param>
- public static void Initialize(Package package)
+ public static void Initialize()
{
- Instance = new QtItemContextMenu(package);
+ Instance = new QtItemContextMenu();
}
-
- /// <summary>
- /// VS Package that provides this command, not null.
- /// </summary>
- private readonly Package m_package;
/// <summary>
/// Command ID.
@@ -78,14 +73,8 @@
/// Initializes a new instance of the <see cref="QtMainMenu"/> class.
/// Adds our command handlers for menu (commands must exist in the command table file)
/// </summary>
- /// <param name="package">Owner package, not null.</param>
- private QtItemContextMenu(Package package)
+ private QtItemContextMenu()
{
- if (package == null)
- throw new ArgumentNullException("package");
-
- m_package = package;
-
var commandService = VsServiceProvider
.GetService<IMenuCommandService, OleMenuCommandService>();
if (commandService == null)
@@ -104,6 +93,8 @@
private void execHandler(object sender, EventArgs e)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var command = sender as OleMenuCommand;
if (command == null)
return;
@@ -120,6 +111,8 @@
private void beforeQueryStatus(object sender, EventArgs e)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var command = sender as OleMenuCommand;
if (command == null)
return;
@@ -128,7 +121,7 @@
command.Visible = false;
var prj = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
- if (!HelperFunctions.IsQtProject(prj) || QtVsToolsPackage.Instance.Dte.SelectedItems.Count <= 0)
+ if (!HelperFunctions.IsVsToolsProject(prj) || QtVsToolsPackage.Instance.Dte.SelectedItems.Count <= 0)
return;
foreach (SelectedItem si in QtVsToolsPackage.Instance.Dte.SelectedItems) {
@@ -136,7 +129,7 @@
return; // Don't display commands if one of the selected files is not a .ts file.
}
- command.Enabled = true;
+ command.Enabled = Translation.ToolsAvailable(prj);
command.Visible = true;
}
}
diff --git a/QtVsTools.Package/Package/QtMainMenu.cs b/QtVsTools.Package/Package/QtMainMenu.cs
index 2c8e90d..7298333 100644
--- a/QtVsTools.Package/Package/QtMainMenu.cs
+++ b/QtVsTools.Package/Package/QtMainMenu.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,16 +26,17 @@
**
****************************************************************************/
-using EnvDTE;
-using Microsoft.VisualStudio.Shell;
-using QtVsTools.Core;
-using QtVsTools.VisualStudio;
using System;
using System.ComponentModel.Design;
using System.Windows.Forms;
+using Microsoft.VisualStudio.Shell;
+using EnvDTE;
namespace QtVsTools
{
+ using Core;
+ using VisualStudio;
+
/// <summary>
/// Command handler
/// </summary>
@@ -44,24 +45,23 @@
/// <summary>
/// Command menu group (command set GUID).
/// </summary>
- public static readonly Guid MainMenuGuid = new Guid("58f83fff-d39d-4c66-810b-2702e1f04e73");
+ private static readonly Guid MainMenuGuid = new Guid("58f83fff-d39d-4c66-810b-2702e1f04e73");
/// <summary>
/// Gets the instance of the command.
/// </summary>
- public static QtMainMenu Instance
+ private static QtMainMenu Instance
{
get;
- private set;
+ set;
}
/// <summary>
/// Initializes the singleton instance of the command.
/// </summary>
- /// <param name="package">Owner package, not null.</param>
- public static void Initialize(Package package)
+ public static void Initialize()
{
- Instance = new QtMainMenu(package);
+ Instance = new QtMainMenu();
}
/// <summary>
@@ -71,16 +71,14 @@
{
QtVersionId = 0x0500,
ViewQtHelpId = 0x0501,
+ ViewGettingStartedId = 0x0503,
LaunchDesignerId = 0x0100,
LaunchLinguistId = 0x0101,
OpenProFileId = 0x0102,
ImportPriFileId = 0x0103,
ExportPriFileId = 0x0104,
ExportProFileId = 0x0105,
- CreateNewTsFileId = 0x0107,
ConvertToQtMsBuild = 0x0130,
- ConvertToQtId = 0x0124,
- ConvertToQmakeId = 0x0108,
QtProjectSettingsId = 0x0109,
ChangeProjectQtVersionId = 0x0126,
QtOptionsId = 0x0110,
@@ -88,22 +86,12 @@
}
/// <summary>
- /// VS Package that provides this command, not null.
- /// </summary>
- private readonly Package m_package;
-
- /// <summary>
/// Initializes a new instance of the <see cref="QtMainMenu"/> class.
/// Adds our command handlers for menu (commands must exist in the command table file)
/// </summary>
/// <param name="package">Owner package, not null.</param>
- private QtMainMenu(Package package)
+ private QtMainMenu()
{
- if (package == null)
- throw new ArgumentNullException("package");
-
- m_package = package;
-
var commandService = VsServiceProvider
.GetService<IMenuCommandService, OleMenuCommandService>();
if (commandService == null)
@@ -119,6 +107,8 @@
private void execHandler(object sender, EventArgs e)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var command = sender as OleMenuCommand;
if (command == null)
return;
@@ -126,6 +116,9 @@
switch ((CommandId)command.CommandID.ID) {
case CommandId.ViewQtHelpId:
VsShellUtilities.OpenSystemBrowser("https://www.qt.io/developers");
+ break;
+ case CommandId.ViewGettingStartedId:
+ VsShellUtilities.OpenSystemBrowser("https://doc.qt.io/qtvstools/qtvstools-getting-started.html");
break;
case CommandId.LaunchDesignerId:
QtVsToolsPackage.Instance.QtDesigner.Start(hideWindow: false);
@@ -145,23 +138,8 @@
case CommandId.ExportProFileId:
ExtLoader.ExportProFile();
break;
- case CommandId.CreateNewTsFileId:
- Translation.CreateNewTranslationFile(HelperFunctions.GetSelectedQtProject(QtVsToolsPackage
- .Instance.Dte));
- break;
- case CommandId.ConvertToQtId:
- case CommandId.ConvertToQmakeId: {
- var caption = SR.GetString("ConvertTitle");
- var text = SR.GetString("ConvertConfirmation");
- if (MessageBox.Show(text, caption, MessageBoxButtons.YesNo) == DialogResult.Yes) {
- HelperFunctions.ToggleProjectKind(HelperFunctions.GetSelectedProject(QtVsToolsPackage
- .Instance.Dte));
- }
- }
- break;
- case CommandId.ConvertToQtMsBuild: {
- QtMsBuildConverter.SolutionToQtMsBuild();
- }
+ case CommandId.ConvertToQtMsBuild:
+ QtMsBuildConverter.SolutionToQtMsBuild();
break;
case CommandId.QtProjectSettingsId: {
var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
@@ -169,31 +147,14 @@
if (projectVersion >= Resources.qtMinFormatVersion_Settings) {
QtVsToolsPackage.Instance.Dte.ExecuteCommand("Project.Properties");
} else if (pro != null) {
- using (var formProjectQtSettings = new FormProjectQtSettings()) {
- formProjectQtSettings.SetProject(pro);
- formProjectQtSettings.StartPosition = FormStartPosition.CenterParent;
- var ww = new MainWinWrapper(QtVsToolsPackage.Instance.Dte);
- formProjectQtSettings.ShowDialog(ww);
- }
+ Legacy.QtMenu.ShowFormProjectQtSettings(pro);
} else {
MessageBox.Show(SR.GetString("NoProjectOpened"));
}
}
break;
- case CommandId.ChangeProjectQtVersionId: {
- var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
- if (HelperFunctions.IsQMakeProject(pro)) {
- using (var formChangeQtVersion = new FormChangeQtVersion()) {
- formChangeQtVersion.UpdateContent(ChangeFor.Project);
- var ww = new MainWinWrapper(QtVsToolsPackage.Instance.Dte);
- if (formChangeQtVersion.ShowDialog(ww) == DialogResult.OK) {
- var qtVersion = formChangeQtVersion.GetSelectedQtVersion();
- HelperFunctions.SetDebuggingEnvironment(pro, "PATH=" + QtVersionManager
- .The().GetInstallPath(qtVersion) + @"\bin;$(PATH)", true);
- }
- }
- }
- }
+ case CommandId.ChangeProjectQtVersionId:
+ Legacy.QtMenu.ShowFormChangeProjectQtVersion();
break;
case CommandId.QtOptionsId:
QtVsToolsPackage.Instance.ShowOptionPage(typeof(Options.QtOptionsPage));
@@ -206,12 +167,17 @@
private void beforeQueryStatus(object sender, EventArgs e)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var command = sender as OleMenuCommand;
if (command == null)
return;
+ var project = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
+
switch ((CommandId)command.CommandID.ID) {
case CommandId.ViewQtHelpId:
+ case CommandId.ViewGettingStartedId:
command.Visible = command.Enabled = true;
break;
case CommandId.QtVersionId:
@@ -230,39 +196,26 @@
case CommandId.ImportPriFileId:
case CommandId.ExportPriFileId:
case CommandId.ExportProFileId:
- case CommandId.CreateNewTsFileId: {
- command.Visible = true;
- command.Enabled = HelperFunctions.IsQtProject(HelperFunctions
- .GetSelectedProject(QtVsToolsPackage.Instance.Dte));
- }
+ command.Visible = true;
+ command.Enabled = HelperFunctions.IsVsToolsProject(project);
break;
- // TODO: Fix these functionality and re-enable the menu items
- case CommandId.ConvertToQtId:
- case CommandId.ConvertToQmakeId: {
- command.Visible = false;
- }
- break;
- //case CommandId.ConvertToQmakeId:
case CommandId.QtProjectSettingsId: {
var status = vsCommandStatus.vsCommandStatusSupported;
- var project = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
if (project != null) {
- if (HelperFunctions.IsQtProject(project))
+ if (HelperFunctions.IsVsToolsProject(project))
status |= vsCommandStatus.vsCommandStatusEnabled;
- else if (HelperFunctions.IsQMakeProject(project))
+ else if (HelperFunctions.IsQtProject(project))
status |= vsCommandStatus.vsCommandStatusInvisible;
}
command.Enabled = ((status & vsCommandStatus.vsCommandStatusEnabled) != 0);
command.Visible = ((status & vsCommandStatus.vsCommandStatusInvisible) == 0);
}
break;
- //case CommandId.ConvertToQtId:
case CommandId.ChangeProjectQtVersionId: {
var status = vsCommandStatus.vsCommandStatusSupported;
- var project = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
- if ((project == null) || HelperFunctions.IsQtProject(project))
+ if ((project == null) || HelperFunctions.IsVsToolsProject(project))
status |= vsCommandStatus.vsCommandStatusInvisible;
- else if (HelperFunctions.IsQMakeProject(project))
+ else if (HelperFunctions.IsQtProject(project))
status |= vsCommandStatus.vsCommandStatusEnabled;
else
status |= vsCommandStatus.vsCommandStatusInvisible;
diff --git a/QtVsTools.Package/Package/QtMsBuildConverter.cs b/QtVsTools.Package/Package/QtMsBuildConverter.cs
index eac783f..79d484d 100644
--- a/QtVsTools.Package/Package/QtMsBuildConverter.cs
+++ b/QtVsTools.Package/Package/QtMsBuildConverter.cs
@@ -32,17 +32,21 @@
using System.Linq;
using System.Windows.Forms;
using Microsoft.VisualStudio;
+using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.VCProjectEngine;
-using QtVsTools.Core;
-using QtVsTools.VisualStudio;
namespace QtVsTools
{
+ using Core;
+ using VisualStudio;
+
static class QtMsBuildConverter
{
public static bool SolutionToQtMsBuild()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var solution = QtVsToolsPackage.Instance.Dte.Solution;
if (solution == null)
return ErrorMessage(string.Format(SR.GetString("ErrorConvertingProject"), ""));
@@ -53,8 +57,8 @@
return WarningMessage(SR.GetString("NoProjectsToConvert"));
foreach (EnvDTE.Project project in allProjects) {
- if ((HelperFunctions.IsQtProject(project)
- || HelperFunctions.IsQMakeProject(project))
+ if ((HelperFunctions.IsVsToolsProject(project)
+ || HelperFunctions.IsQtProject(project))
&& !QtProject.IsQtMsBuildEnabled(project)) {
projects.Add(project);
}
@@ -68,7 +72,14 @@
MessageBoxButtons.YesNo) != DialogResult.Yes)
return WarningMessage(SR.GetString("CancelConvertingProject"));
- if (projects.Where(project => project.IsDirty).Any()) {
+ bool hasDirtyProjects = projects
+ .Where(project =>
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return project.IsDirty;
+ })
+ .Any();
+ if (hasDirtyProjects) {
if (MessageBox.Show(
SR.GetString("ConvertSaveConfirmation"),
SR.GetString("ConvertTitle"),
@@ -76,7 +87,13 @@
return WarningMessage(SR.GetString("CancelConvertingProject"));
}
- var projectPaths = projects.Select(x => x.FullName).ToList();
+ var projectPaths = projects
+ .Select(x =>
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return x.FullName;
+ })
+ .ToList();
string solutionPath = solution.FileName;
solution.Close(true);
@@ -142,6 +159,8 @@
public static bool ProjectToQtMsBuild(EnvDTE.Project project, bool askConfirmation = true)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (project == null)
return ErrorMessage(string.Format(SR.GetString("ErrorConvertingProject"), ""));
var pathToProject = project.FullName;
@@ -178,7 +197,7 @@
try {
if (solution.UnloadProject(
ref projectGuid,
- (uint)_VSProjectUnloadStatus.UNLOADSTATUS_LoadPendingIfNeeded)
+ (uint)_VSProjectUnloadStatus.UNLOADSTATUS_UnloadedByUser)
!= VSConstants.S_OK)
return ErrorMessage(
string.Format(SR.GetString("ErrorConvertingProject"), projectName));
diff --git a/QtVsTools.Package/Package/QtProjectContextMenu.cs b/QtVsTools.Package/Package/QtProjectContextMenu.cs
index 2706ef5..3b08b13 100644
--- a/QtVsTools.Package/Package/QtProjectContextMenu.cs
+++ b/QtVsTools.Package/Package/QtProjectContextMenu.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,20 +26,17 @@
**
****************************************************************************/
-using EnvDTE;
-using Microsoft.VisualStudio;
-using Microsoft.VisualStudio.Shell;
-using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.VisualStudio.VCProjectEngine;
-using QtVsTools.Core;
-using QtVsTools.VisualStudio;
using System;
using System.ComponentModel.Design;
using System.Windows.Forms;
+using Microsoft.VisualStudio.Shell;
+using EnvDTE;
namespace QtVsTools
{
+ using Core;
using QtMsBuild;
+ using VisualStudio;
/// <summary>
/// Command handler
@@ -49,24 +46,23 @@
/// <summary>
/// Command menu group (command set GUID).
/// </summary>
- public static readonly Guid ProjectContextMenuGuid = new Guid("5732faa9-6074-4e07-b035-2816e809f50e");
+ private static readonly Guid ProjectContextMenuGuid = new Guid("5732faa9-6074-4e07-b035-2816e809f50e");
/// <summary>
/// Gets the instance of the command.
/// </summary>
- public static QtProjectContextMenu Instance
+ private static QtProjectContextMenu Instance
{
get;
- private set;
+ set;
}
/// <summary>
/// Initializes the singleton instance of the command.
/// </summary>
- /// <param name="package">Owner package, not null.</param>
- public static void Initialize(Package package)
+ public static void Initialize()
{
- Instance = new QtProjectContextMenu(package);
+ Instance = new QtProjectContextMenu();
}
/// <summary>
@@ -77,35 +73,20 @@
ImportPriFileProjectId = 0x0114,
ExportPriFileProjectId = 0x0115,
ExportProFileProjectId = 0x0116,
- CreateNewTsFileProjectId = 0x0117,
lUpdateOnProjectId = 0x0118,
lReleaseOnProjectId = 0x0119,
ProjectConvertToQtMsBuild = 0x0130,
ProjectRefreshIntelliSense = 0x0131,
- ConvertToQtProjectId = 0x0120,
- ConvertToQmakeProjectId = 0x0121,
QtProjectSettingsProjectId = 0x0122,
- ChangeProjectQtVersionProjectId = 0x0123,
- ProjectAddNewQtClassProjectId = 0x200
+ ChangeProjectQtVersionProjectId = 0x0123
}
-
- /// <summary>
- /// VS Package that provides this command, not null.
- /// </summary>
- private readonly Package m_package;
/// <summary>
/// Initializes a new instance of the <see cref="QtMainMenu"/> class.
/// Adds our command handlers for menu (commands must exist in the command table file)
/// </summary>
- /// <param name="package">Owner package, not null.</param>
- private QtProjectContextMenu(Package package)
+ private QtProjectContextMenu()
{
- if (package == null)
- throw new ArgumentNullException("package");
-
- m_package = package;
-
var commandService = VsServiceProvider
.GetService<IMenuCommandService, OleMenuCommandService>();
if (commandService == null)
@@ -121,6 +102,8 @@
private void execHandler(object sender, EventArgs e)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var command = sender as OleMenuCommand;
if (command == null)
return;
@@ -135,25 +118,11 @@
case CommandId.ExportProFileProjectId:
ExtLoader.ExportProFile();
break;
- case CommandId.CreateNewTsFileProjectId:
- Translation.CreateNewTranslationFile(HelperFunctions.GetSelectedQtProject(QtVsToolsPackage
- .Instance.Dte));
- break;
case CommandId.lUpdateOnProjectId:
Translation.RunlUpdate(HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte));
break;
case CommandId.lReleaseOnProjectId:
Translation.RunlRelease(HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte));
- break;
- case CommandId.ConvertToQtProjectId:
- case CommandId.ConvertToQmakeProjectId: {
- var caption = SR.GetString("ConvertTitle");
- var text = SR.GetString("ConvertConfirmation");
- if (MessageBox.Show(text, caption, MessageBoxButtons.YesNo) == DialogResult.Yes) {
- HelperFunctions.ToggleProjectKind(HelperFunctions.GetSelectedProject(QtVsToolsPackage
- .Instance.Dte));
- }
- }
break;
case CommandId.QtProjectSettingsProjectId: {
var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
@@ -161,31 +130,14 @@
if (projectVersion >= Resources.qtMinFormatVersion_Settings) {
QtVsToolsPackage.Instance.Dte.ExecuteCommand("Project.Properties");
} else if (pro != null) {
- using (var formProjectQtSettings = new FormProjectQtSettings()) {
- formProjectQtSettings.SetProject(pro);
- formProjectQtSettings.StartPosition = FormStartPosition.CenterParent;
- var ww = new MainWinWrapper(QtVsToolsPackage.Instance.Dte);
- formProjectQtSettings.ShowDialog(ww);
- }
+ Legacy.QtMenu.ShowFormProjectQtSettings(pro);
} else {
MessageBox.Show(SR.GetString("NoProjectOpened"));
}
}
break;
- case CommandId.ChangeProjectQtVersionProjectId: {
- var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
- if (HelperFunctions.IsQMakeProject(pro)) {
- using (var formChangeQtVersion = new FormChangeQtVersion()) {
- formChangeQtVersion.UpdateContent(ChangeFor.Project);
- var ww = new MainWinWrapper(QtVsToolsPackage.Instance.Dte);
- if (formChangeQtVersion.ShowDialog(ww) == DialogResult.OK) {
- var qtVersion = formChangeQtVersion.GetSelectedQtVersion();
- HelperFunctions.SetDebuggingEnvironment(pro, "PATH=" + QtVersionManager
- .The().GetInstallPath(qtVersion) + @"\bin;$(PATH)", true);
- }
- }
- }
- }
+ case CommandId.ChangeProjectQtVersionProjectId:
+ Legacy.QtMenu.ShowFormChangeProjectQtVersion();
break;
case CommandId.ProjectConvertToQtMsBuild: {
QtMsBuildConverter.ProjectToQtMsBuild(
@@ -194,29 +146,8 @@
break;
case CommandId.ProjectRefreshIntelliSense: {
var selectedProject = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
- var tracker = QtProjectTracker.Get(selectedProject);
+ var tracker = QtProjectTracker.Get(selectedProject, selectedProject.FullName);
QtProjectIntellisense.Refresh(tracker.Project);
- }
- break;
- case CommandId.ProjectAddNewQtClassProjectId: {
- try {
- var project = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
- if (!HelperFunctions.IsQtProject(project))
- return;
-
- var vcProject = project.Object as VCProject;
- if (vcProject == null)
- return;
-
- var loop = true;
- do {
- var classWizard = new Wizards.ClassWizard.AddClassWizard();
- loop = classWizard.Run(QtVsToolsPackage.Instance.Dte, vcProject.Name,
- vcProject.ProjectDirectory) == Wizards.WizardResult.Exception;
- } while (loop);
- } catch {
- // Deliberately ignore any kind of exception but close the dialog.
- }
}
break;
}
@@ -229,8 +160,8 @@
return;
var project = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
- var isQtProject = HelperFunctions.IsQtProject(project);
- var isQMakeProject = HelperFunctions.IsQMakeProject(project);
+ var isQtProject = HelperFunctions.IsVsToolsProject(project);
+ var isQMakeProject = HelperFunctions.IsQtProject(project);
var isQtMsBuildEnabled = QtProject.IsQtMsBuildEnabled(project);
if (!isQtProject && !isQMakeProject) {
@@ -239,25 +170,19 @@
}
switch ((CommandId)command.CommandID.ID) {
- // TODO: Fix these functionality and re-enable the menu items
- case CommandId.ConvertToQtProjectId:
- case CommandId.ConvertToQmakeProjectId: {
- command.Visible = false;
- }
- break;
case CommandId.ImportPriFileProjectId:
case CommandId.ExportPriFileProjectId:
case CommandId.ExportProFileProjectId:
- case CommandId.CreateNewTsFileProjectId:
+ command.Visible = true;
+ command.Enabled = HelperFunctions.IsVsToolsProject(HelperFunctions
+ .GetSelectedProject(QtVsToolsPackage.Instance.Dte));
+ break;
case CommandId.lUpdateOnProjectId:
case CommandId.lReleaseOnProjectId:
command.Visible = true;
- command.Enabled = HelperFunctions.IsQtProject(HelperFunctions
- .GetSelectedProject(QtVsToolsPackage.Instance.Dte));
+ command.Enabled = Translation.ToolsAvailable(project);
break;
- //case CommandId.ConvertToQmakeProjectId:
- case CommandId.QtProjectSettingsProjectId:
- case CommandId.ProjectAddNewQtClassProjectId: {
+ case CommandId.QtProjectSettingsProjectId: {
var status = vsCommandStatus.vsCommandStatusSupported;
if (project != null) {
if (isQtProject)
@@ -269,7 +194,6 @@
command.Visible = ((status & vsCommandStatus.vsCommandStatusInvisible) == 0);
}
break;
- //case CommandId.ConvertToQtProjectId:
case CommandId.ChangeProjectQtVersionProjectId: {
var status = vsCommandStatus.vsCommandStatusSupported;
if ((project == null) || isQtProject)
diff --git a/QtVsTools.Package/Package/QtSolutionContextMenu.cs b/QtVsTools.Package/Package/QtSolutionContextMenu.cs
index d680fe7..67f2a8c 100644
--- a/QtVsTools.Package/Package/QtSolutionContextMenu.cs
+++ b/QtVsTools.Package/Package/QtSolutionContextMenu.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,17 +26,15 @@
**
****************************************************************************/
-using EnvDTE80;
-using Microsoft.VisualStudio.Shell;
-using QtVsTools.Core;
-using QtVsTools.VisualStudio;
using System;
using System.ComponentModel.Design;
-using System.Windows.Forms;
+using Microsoft.VisualStudio.Shell;
namespace QtVsTools
{
+ using Core;
using QtMsBuild;
+ using VisualStudio;
/// <summary>
/// Command handler
@@ -46,30 +44,24 @@
/// <summary>
/// Command menu group (command set GUID).
/// </summary>
- public static readonly Guid SolutionContextMenuGuid = new Guid("6dcda34f-4d22-4d6a-a176-5507069c5a3e");
+ private static readonly Guid SolutionContextMenuGuid = new Guid("6dcda34f-4d22-4d6a-a176-5507069c5a3e");
/// <summary>
/// Gets the instance of the command.
/// </summary>
- public static QtSolutionContextMenu Instance
+ private static QtSolutionContextMenu Instance
{
get;
- private set;
+ set;
}
/// <summary>
/// Initializes the singleton instance of the command.
/// </summary>
- /// <param name="package">Owner package, not null.</param>
- public static void Initialize(Package package)
+ public static void Initialize()
{
- Instance = new QtSolutionContextMenu(package);
+ Instance = new QtSolutionContextMenu();
}
-
- /// <summary>
- /// VS Package that provides this command, not null.
- /// </summary>
- private readonly Package m_package;
/// <summary>
/// Command ID.
@@ -87,14 +79,8 @@
/// Initializes a new instance of the <see cref="QtMainMenu"/> class.
/// Adds our command handlers for menu (commands must exist in the command table file)
/// </summary>
- /// <param name="package">Owner package, not null.</param>
- private QtSolutionContextMenu(Package package)
+ private QtSolutionContextMenu()
{
- if (package == null)
- throw new ArgumentNullException("package");
-
- m_package = package;
-
var commandService = VsServiceProvider
.GetService<IMenuCommandService, OleMenuCommandService>();
if (commandService == null)
@@ -113,66 +99,51 @@
var command = sender as OleMenuCommand;
if (command == null)
return;
- command.Enabled = command.Visible = true;
+
+ switch (command.CommandID.ID) {
+ case (int)CommandId.ChangeSolutionQtVersionId:
+ var projects = HelperFunctions.ProjectsInSolution(QtVsToolsPackage.Instance.Dte);
+ foreach (var project in projects) {
+ if (!HelperFunctions.IsVsToolsProject(project)
+ && HelperFunctions.IsQtProject(project)) {
+ command.Enabled = command.Visible = true;
+ return;
+ }
+ }
+ command.Enabled = command.Visible = false;
+ break;
+ default:
+ command.Enabled = command.Visible = true;
+ break;
+ }
}
private void execHandler(object sender, EventArgs e)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var command = sender as OleMenuCommand;
if (command == null)
return;
var dte = QtVsToolsPackage.Instance.Dte;
- switch (command.CommandID.ID) {
- case (int)CommandId.lUpdateOnSolutionId:
+ switch ((CommandId)command.CommandID.ID) {
+ case CommandId.lUpdateOnSolutionId:
Translation.RunlUpdate(QtVsToolsPackage.Instance.Dte.Solution);
break;
- case (int)CommandId.lReleaseOnSolutionId:
+ case CommandId.lReleaseOnSolutionId:
Translation.RunlRelease(QtVsToolsPackage.Instance.Dte.Solution);
break;
- case (int)CommandId.ChangeSolutionQtVersionId:
- string newQtVersion = null;
- using (var formChangeQtVersion = new FormChangeQtVersion()) {
- formChangeQtVersion.UpdateContent(ChangeFor.Solution);
- if (formChangeQtVersion.ShowDialog() != DialogResult.OK)
- return;
- newQtVersion = formChangeQtVersion.GetSelectedQtVersion();
- }
- if (newQtVersion == null)
- return;
-
- string currentPlatform = null;
- try {
- var config2 = QtVsToolsPackage.Instance.Dte.Solution.SolutionBuild
- .ActiveConfiguration as SolutionConfiguration2;
- currentPlatform = config2.PlatformName;
- } catch { }
- if (string.IsNullOrEmpty(currentPlatform))
- return;
-
- foreach (var project in HelperFunctions.ProjectsInSolution(dte)) {
- if (HelperFunctions.IsQtProject(project)) {
- var OldQtVersion = QtVersionManager.The().GetProjectQtVersion(project,
- currentPlatform);
- if (OldQtVersion == null)
- OldQtVersion = QtVersionManager.The().GetDefaultVersion();
-
- var created = false;
- var qtProject = QtProject.Create(project);
- if (qtProject.PromptChangeQtVersion(OldQtVersion, newQtVersion))
- qtProject.ChangeQtVersion(OldQtVersion, newQtVersion, ref created);
- }
- }
- QtVersionManager.The().SaveSolutionQtVersion(dte.Solution, newQtVersion);
+ case CommandId.ChangeSolutionQtVersionId:
+ Legacy.QtMenu.ShowFormChangeSolutionQtVersion();
break;
- case (int)CommandId.SolutionConvertToQtMsBuild: {
- QtMsBuildConverter.SolutionToQtMsBuild();
- }
+ case CommandId.SolutionConvertToQtMsBuild:
+ QtMsBuildConverter.SolutionToQtMsBuild();
break;
- case (int)CommandId.SolutionEnableProjectTracking: {
+ case CommandId.SolutionEnableProjectTracking: {
foreach (var project in HelperFunctions.ProjectsInSolution(dte)) {
- if (HelperFunctions.IsQtProject(project))
- QtProjectTracker.Get(project);
+ if (HelperFunctions.IsVsToolsProject(project))
+ QtProjectTracker.Get(project, project.FullName);
}
}
break;
diff --git a/QtVsTools.Package/Package/SR.cs b/QtVsTools.Package/Package/SR.cs
index 8dd6c57..6bf9f44 100644
--- a/QtVsTools.Package/Package/SR.cs
+++ b/QtVsTools.Package/Package/SR.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,8 +26,6 @@
**
****************************************************************************/
-using System;
-using System.Globalization;
using System.Resources;
namespace QtVsTools
@@ -36,66 +34,39 @@
{
static SR loader;
readonly ResourceManager resources;
- static readonly Object obj = new Object();
+ static readonly object obj = new object();
- internal const string OK = "OK";
- internal const string Cancel = "Cancel";
-
- internal static CultureInfo appCultureInfo;
- internal static CultureInfo defaultCultureInfo;
-
- internal SR(int localeId)
+ internal SR()
{
- defaultCultureInfo = CultureInfo.GetCultureInfo("en");
- appCultureInfo = CultureInfo.GetCultureInfo(localeId);
- if (appCultureInfo.Name.StartsWith("en", StringComparison.Ordinal))
- appCultureInfo = null;
resources = new ResourceManager("QtVsTools.Package.Resources", GetType().Assembly);
}
- private static SR GetLoader(int localeId)
+ private static SR GetLoader()
{
if (loader == null) {
lock (obj) {
if (loader == null)
- loader = new SR(localeId);
+ loader = new SR();
}
}
return loader;
}
- private static CultureInfo Culture
- {
- get { return appCultureInfo; }
- }
-
public static string GetString(string name, params object[] args)
{
- var res = GetString(name);
- if (!string.IsNullOrEmpty(res) && args != null && args.Length > 0)
+ var sys = GetLoader();
+ if (sys == null)
+ return null;
+
+ var res = sys.resources.GetString(name, null);
+ if (args != null && args.Length > 0 && !string.IsNullOrEmpty(res))
return string.Format(res, args);
return res;
}
public static string GetString(string name)
{
- return GetString(name, QtVsToolsPackage.Instance);
- }
-
- public static string GetString(string name, QtVsToolsPackage vsixInstance)
- {
- var sys = GetLoader(vsixInstance.Dte.LocaleID);
- if (sys == null)
- return null;
-
- string result;
- try {
- result = sys.resources.GetString(name, Culture);
- } catch (Exception) {
- result = sys.resources.GetString(name, defaultCultureInfo);
- }
-
- return result;
+ return GetString(name, null);
}
}
}
diff --git a/QtVsTools.Package/Package/Translation.cs b/QtVsTools.Package/Package/Translation.cs
index 3c7e9f2..d47e525 100644
--- a/QtVsTools.Package/Package/Translation.cs
+++ b/QtVsTools.Package/Package/Translation.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -26,24 +26,16 @@
**
****************************************************************************/
-using Microsoft.VisualStudio;
-using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.VisualStudio.VCProjectEngine;
-using QtVsTools.Core;
-using QtVsTools.VisualStudio;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Windows.Forms;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
namespace QtVsTools
{
- using static Core.HelperFunctions;
+ using Core;
using QtMsBuild;
/// <summary>
@@ -51,16 +43,10 @@
/// </summary>
public static class Translation
{
- public static void RunlRelease(VCFile vcFile)
- {
- var vcProj = vcFile.project as VCProject;
- var project = vcProj?.Object as EnvDTE.Project;
- RunTranslationTarget(BuildAction.Release,
- project, new[] { vcFile.RelativePath });
- }
-
public static void RunlRelease(VCFile[] vcFiles)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var vcProj = vcFiles.FirstOrDefault()?.project as VCProject;
var project = vcProj?.Object as EnvDTE.Project;
RunTranslationTarget(BuildAction.Release,
@@ -69,11 +55,14 @@
public static void RunlRelease(EnvDTE.Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
RunTranslationTarget(BuildAction.Release, project);
}
public static void RunlRelease(EnvDTE.Solution solution)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (solution == null)
return;
@@ -83,6 +72,8 @@
public static void RunlUpdate(VCFile vcFile)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var vcProj = vcFile.project as VCProject;
var project = vcProj?.Object as EnvDTE.Project;
RunTranslationTarget(BuildAction.Update,
@@ -91,6 +82,8 @@
public static void RunlUpdate(VCFile[] vcFiles)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var vcProj = vcFiles.FirstOrDefault()?.project as VCProject;
var project = vcProj?.Object as EnvDTE.Project;
RunTranslationTarget(BuildAction.Update,
@@ -99,16 +92,19 @@
public static void RunlUpdate(EnvDTE.Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
RunTranslationTarget(BuildAction.Update, project);
}
- enum BuildAction { Update, Release }
+ internal enum BuildAction { Update, Release }
static void RunTranslationTarget(
BuildAction buildAction,
EnvDTE.Project project,
IEnumerable<string> selectedFiles = null)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
using (WaitDialog.Start(
"Qt Visual Studio Tools", "Running translation tool...")) {
@@ -122,10 +118,9 @@
if (qtPro.FormatVersion < Resources.qtMinFormatVersion_Settings) {
Messages.Print("translation: Legacy project format");
try {
- Legacy_RunTranslation(buildAction, qtPro, selectedFiles);
- } catch (Exception e) {
- Messages.Print(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ Legacy.Translation.Run(buildAction, qtPro, selectedFiles);
+ } catch (Exception exception) {
+ exception.Log();
}
return;
}
@@ -152,12 +147,15 @@
if (selectedFiles != null)
properties["SelectedFiles"] = string.Join(";", selectedFiles);
- QtProjectBuild.StartBuild(project, activeConfigId, properties, new[] { target });
+ QtProjectBuild.StartBuild(
+ project, project.FullName, activeConfigId, properties, new[] { target });
}
}
public static void RunlUpdate(EnvDTE.Solution solution)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (solution == null)
return;
@@ -165,118 +163,23 @@
RunlUpdate(project);
}
- static void Legacy_RunTranslation(
- BuildAction buildAction,
- QtProject qtProject,
- IEnumerable<string> tsFiles)
- {
- if (tsFiles == null) {
- tsFiles = (qtProject.VCProject
- .GetFilesEndingWith(".ts") as IVCCollection)
- .Cast<VCFile>()
- .Select(vcFile => vcFile.RelativePath);
- if (tsFiles == null) {
- Messages.Print("translation: no translation files found");
- return;
- }
- }
- string tempFile = null;
- foreach (var file in tsFiles.Where(file => file != null))
- Legacy_RunTranslation(buildAction, qtProject, file, ref tempFile);
- }
-
- static void Legacy_RunTranslation(
- BuildAction buildAction,
- QtProject qtProject,
- string tsFile,
- ref string tempFile)
- {
- var qtVersion = qtProject.GetQtVersion();
- var qtInstallPath = QtVersionManager.The().GetInstallPath(qtVersion);
- if (string.IsNullOrEmpty(qtInstallPath)) {
- Messages.Print("translation: Error accessing Qt installation");
- return;
- }
-
- var procInfo = new ProcessStartInfo
- {
- WorkingDirectory = qtProject.ProjectDir,
- CreateNoWindow = true,
- UseShellExecute = false,
- RedirectStandardError = true,
- RedirectStandardOutput = true,
- Arguments = ""
- };
- switch (buildAction) {
- case BuildAction.Update:
- Messages.Print("\r\n--- (lupdate) file: " + tsFile);
- procInfo.FileName = Path.Combine(qtInstallPath, "bin", "lupdate.exe");
- var options = QtVSIPSettings.GetLUpdateOptions();
- if (!string.IsNullOrEmpty(options))
- procInfo.Arguments += options + " ";
- if (tempFile == null) {
- var inputFiles = GetProjectFiles(qtProject.Project, FilesToList.FL_HFiles)
- .Union(GetProjectFiles(qtProject.Project, FilesToList.FL_CppFiles))
- .Union(GetProjectFiles(qtProject.Project, FilesToList.FL_UiFiles))
- .Union(GetProjectFiles(qtProject.Project, FilesToList.FL_QmlFiles));
- tempFile = Path.GetTempFileName();
- File.WriteAllLines(tempFile, inputFiles);
- }
- procInfo.Arguments += string.Format("\"@{0}\" -ts \"{1}\"", tempFile, tsFile);
- break;
- case BuildAction.Release:
- Messages.Print("\r\n--- (lrelease) file: " + tsFile);
- procInfo.FileName = Path.Combine(qtInstallPath, "bin", "lrelease.exe");
- options = QtVSIPSettings.GetLReleaseOptions();
- if (!string.IsNullOrEmpty(options))
- procInfo.Arguments += options + " ";
- procInfo.Arguments += string.Format("\"{0}\"", tsFile);
- break;
- }
- using (var proc = Process.Start(procInfo)) {
- proc.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
- {
- if (!string.IsNullOrEmpty(e.Data))
- Messages.Print(e.Data);
- };
- proc.ErrorDataReceived += (object sender, DataReceivedEventArgs e) =>
- {
- if (!string.IsNullOrEmpty(e.Data))
- Messages.Print(e.Data);
- };
- proc.BeginOutputReadLine();
- proc.BeginErrorReadLine();
- proc.WaitForExit();
- switch (proc.ExitCode) {
- case 0:
- Messages.Print("translation: ok");
- break;
- default:
- Messages.Print(string.Format("translation: ERROR {0}", proc.ExitCode));
- break;
- }
- }
- }
-
- public static void CreateNewTranslationFile(EnvDTE.Project project)
+ public static bool ToolsAvailable(EnvDTE.Project project)
{
if (project == null)
- return;
+ return false;
+ if (QtProject.GetPropertyValue(project, "ApplicationType") == "Linux")
+ return true;
- using (var transDlg = new AddTranslationDialog(project)) {
- if (transDlg.ShowDialog() == DialogResult.OK) {
- try {
- var qtPro = QtProject.Create(project);
- var file = qtPro.AddFileInFilter(Filters.TranslationFiles(),
- transDlg.TranslationFile, true);
- RunlUpdate(file);
- } catch (QtVSException e) {
- Messages.DisplayErrorMessage(e.Message);
- } catch (System.Exception ex) {
- Messages.DisplayErrorMessage(ex.Message);
- }
- }
+ var qtToolsPath = QtProject.GetPropertyValue(project, "QtToolsPath");
+ if (string.IsNullOrEmpty(qtToolsPath)) {
+ var qtVersion = QtVersionManager.The().GetProjectQtVersion(project);
+ var qtInstallPath = QtVersionManager.The().GetInstallPath(qtVersion);
+ if (string.IsNullOrEmpty(qtInstallPath))
+ return false;
+ qtToolsPath = Path.Combine(qtInstallPath, "bin");
}
+ return File.Exists(Path.Combine(qtToolsPath, "lupdate.exe"))
+ && File.Exists(Path.Combine(qtToolsPath, "lrelease.exe"));
}
}
}
diff --git a/QtVsTools.Package/QML/Classification/QmlAsyncClassifier.cs b/QtVsTools.Package/QML/Classification/QmlAsyncClassifier.cs
index d8698b4..b69d9b6 100644
--- a/QtVsTools.Package/QML/Classification/QmlAsyncClassifier.cs
+++ b/QtVsTools.Package/QML/Classification/QmlAsyncClassifier.cs
@@ -33,7 +33,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using Microsoft.VisualStudio.Text;
@@ -52,7 +51,7 @@
/// </summary>
class SharedTagList : Concurrent
{
- SortedList<int, TrackingTag> data = new SortedList<int, TrackingTag>();
+ readonly SortedList<int, TrackingTag> data = new SortedList<int, TrackingTag>();
object owner;
public bool Ready { get; private set; }
@@ -97,7 +96,7 @@
class TrackingTagComparer : Comparer<TrackingTag>
{
- ITextSnapshot snapshot;
+ readonly ITextSnapshot snapshot;
public TrackingTagComparer(ITextSnapshot snapshot)
{
this.snapshot = snapshot;
@@ -232,17 +231,16 @@
/// <returns>Instance of T corresponding to the given TrackingTag</returns>
protected abstract T GetClassification(TrackingTag tag);
- protected ITextView TextView { get; private set; }
- protected ITextBuffer Buffer { get; private set; }
+ private ITextView TextView { get; }
+ private ITextBuffer Buffer { get; }
readonly object criticalSection = new object();
-
- string classificationType;
+ readonly string classificationType;
ParserKey currentParserKey;
TagListKey currentTagListKey;
SharedTagList currentTagList;
- Dispatcher dispatcher;
- DispatcherTimer timer;
+ readonly Dispatcher dispatcher;
+ readonly DispatcherTimer timer;
bool flag = false;
protected QmlAsyncClassifier(
@@ -267,7 +265,7 @@
currentTagList = null;
this.classificationType = classificationType;
- AsyncParse(buffer.CurrentSnapshot);
+ Parse(buffer.CurrentSnapshot);
}
private void TextView_Closed(object sender, EventArgs e)
@@ -286,16 +284,16 @@
private void Buffer_Changed(object sender, TextContentChangedEventArgs e)
{
timer.Stop();
- AsyncParse(e.After);
+ Parse(e.After);
}
private void Timer_Tick(object sender, EventArgs e)
{
timer.Stop();
- AsyncParse(Buffer.CurrentSnapshot);
+ Parse(Buffer.CurrentSnapshot);
}
- private async void AsyncParse(ITextSnapshot snapshot)
+ private void Parse(ITextSnapshot snapshot)
{
lock (criticalSection) {
if (flag)
@@ -311,7 +309,7 @@
ParserKey oldParserKey = null;
TagListKey oldTagListKey = null;
- await Task.Run(() =>
+ _ = Task.Run(() =>
{
var parser = ParserStore.Instance.Get(this, newParserKey);
@@ -344,7 +342,7 @@
flag = false;
}
- await Task.Run(() =>
+ _ = Task.Run(() =>
{
if (oldParserKey != null)
ParserStore.Instance.Release(this, oldParserKey);
@@ -511,7 +509,7 @@
public TValue Value { get; set; }
public HashSet<object> ClientObjects { get; set; }
}
- Dictionary<TKey, ValueRef> data = new Dictionary<TKey, ValueRef>();
+ readonly Dictionary<TKey, ValueRef> data = new Dictionary<TKey, ValueRef>();
static readonly object staticCriticalSection = new object();
readonly object criticalSection = new object();
@@ -524,8 +522,7 @@
public TValue Get(object client, TKey key)
{
lock (criticalSection) {
- ValueRef valueRef;
- if (!data.TryGetValue(key, out valueRef)) {
+ if (!data.TryGetValue(key, out ValueRef valueRef)) {
valueRef = new ValueRef
{
Value = GetDefaultValue(key),
@@ -543,8 +540,7 @@
{
IDisposable disposable = null;
lock (criticalSection) {
- ValueRef valueRef;
- if (data.TryGetValue(key, out valueRef)) {
+ if (data.TryGetValue(key, out ValueRef valueRef)) {
valueRef.ClientObjects.Remove(client);
if (valueRef.ClientObjects.Count == 0) {
data.Remove(key);
@@ -573,8 +569,8 @@
class TagListKey
{
- public string Classification { get; private set; }
- public ITextSnapshot Snapshot { get; private set; }
+ private string Classification { get; }
+ private ITextSnapshot Snapshot { get; }
public TagListKey(string classification, ITextSnapshot snapshot)
{
Classification = classification;
@@ -614,7 +610,7 @@
class ParserKey
{
- public ITextSnapshot Snapshot { get; private set; }
+ public ITextSnapshot Snapshot { get; }
public ParserKey(ITextSnapshot snapshot)
{
Snapshot = snapshot;
diff --git a/QtVsTools.Package/QML/Classification/QmlErrorClassifier.cs b/QtVsTools.Package/QML/Classification/QmlErrorClassifier.cs
index 85c216d..1878c56 100644
--- a/QtVsTools.Package/QML/Classification/QmlErrorClassifier.cs
+++ b/QtVsTools.Package/QML/Classification/QmlErrorClassifier.cs
@@ -28,11 +28,7 @@
/// Highlighting of syntax errors
-using System;
-using System.Collections.Generic;
using System.ComponentModel.Composition;
-using System.Threading.Tasks;
-using System.Windows.Threading;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
diff --git a/QtVsTools.Package/QML/Classification/QmlExpressionEvalClassifier.cs b/QtVsTools.Package/QML/Classification/QmlExpressionEvalClassifier.cs
index dd0528e..9cb30eb 100644
--- a/QtVsTools.Package/QML/Classification/QmlExpressionEvalClassifier.cs
+++ b/QtVsTools.Package/QML/Classification/QmlExpressionEvalClassifier.cs
@@ -41,11 +41,12 @@
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.TextManager.Interop;
using Microsoft.VisualStudio.Utilities;
-using QtVsTools.Qml.Syntax;
-using QtVsTools.VisualStudio;
namespace QtVsTools.Qml.Classification
{
+ using QtVsTools.VisualStudio;
+ using Syntax;
+
[Export(typeof(IViewTaggerProvider))]
[ContentType("qml")]
[TagType(typeof(ClassificationTag))]
@@ -169,6 +170,8 @@
int IVsTextViewFilter.GetDataTipText(TextSpan[] pSpan, out string pbstrText)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
pbstrText = "";
var dbgMode = new DBGMODE[1];
if (debugger.GetMode(dbgMode) != VSConstants.S_OK
@@ -215,6 +218,7 @@
OLECMD[] prgCmds,
IntPtr pCmdText)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
return nextTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
}
@@ -225,12 +229,13 @@
IntPtr pvaIn,
IntPtr pvaOut)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
return nextTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
}
class ExprTrackingTag : TrackingTag
{
- public IOrderedEnumerable<AstNode> Exprs { get; private set; }
+ public IOrderedEnumerable<AstNode> Exprs { get; }
public ExprTrackingTag(
ITextSnapshot snapshot,
@@ -245,7 +250,7 @@
class ExprTag : ClassificationTag
{
- public IOrderedEnumerable<AstNode> Exprs { get; private set; }
+ public IOrderedEnumerable<AstNode> Exprs { get; }
public ExprTag(IOrderedEnumerable<AstNode> exprs, IClassificationType type)
: base(type)
diff --git a/QtVsTools.Package/QML/Classification/QmlSyntaxClassifier.cs b/QtVsTools.Package/QML/Classification/QmlSyntaxClassifier.cs
index 4675637..4035a67 100644
--- a/QtVsTools.Package/QML/Classification/QmlSyntaxClassifier.cs
+++ b/QtVsTools.Package/QML/Classification/QmlSyntaxClassifier.cs
@@ -29,11 +29,7 @@
/// This file implements the actual highlighting of the text according to the
/// classification of the syntax elements recognized by the QML parser.
-using System;
-using System.Collections.Generic;
using System.ComponentModel.Composition;
-using System.Threading.Tasks;
-using System.Windows.Threading;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
diff --git a/QtVsTools.Package/QML/Classification/QmlTag.cs b/QtVsTools.Package/QML/Classification/QmlTag.cs
index 5d92dcd..8cd0ba1 100644
--- a/QtVsTools.Package/QML/Classification/QmlTag.cs
+++ b/QtVsTools.Package/QML/Classification/QmlTag.cs
@@ -47,10 +47,10 @@
/// </summary>
public class TrackingTag : ITag
{
- public ITextSnapshot Snapshot { get; private set; }
- public int Start { get; private set; }
- public int Length { get; private set; }
- public ITrackingSpan Span { get; private set; }
+ public ITextSnapshot Snapshot { get; }
+ public int Start { get; }
+ private int Length { get; }
+ public ITrackingSpan Span { get; }
public TrackingTag(ITextSnapshot snapshot, int start, int length)
{
Snapshot = snapshot;
@@ -76,9 +76,9 @@
public const string TypeName = "typename.qml";
public const string Binding = "binding.qml";
- public SyntaxElement SyntaxElement { get; private set; }
- public SourceLocation SourceLocation { get; private set; }
- public IClassificationType ClassificationType { get; private set; }
+ private SyntaxElement SyntaxElement { get; }
+ private SourceLocation SourceLocation { get; }
+ public IClassificationType ClassificationType { get; }
private QmlSyntaxTag(ITextSnapshot snapshot, SourceLocation location)
: base(snapshot, location.Offset, location.Length)
@@ -118,7 +118,7 @@
return new QmlSyntaxTag(snapshot, parentNode, classificationType, fullNameLocation);
}
- public static readonly HashSet<string> QmlBasicTypes = new HashSet<string> {
+ private static readonly HashSet<string> QmlBasicTypes = new HashSet<string> {
"bool", "double", "enumeration", "int",
"list", "real", "string", "url", "var",
"date", "point", "rect", "size", "alias"
@@ -223,7 +223,7 @@
public class QmlDiagnosticsTag : TrackingTag
{
- public DiagnosticMessage DiagnosticMessage { get; private set; }
+ private DiagnosticMessage DiagnosticMessage { get; }
public QmlDiagnosticsTag(ITextSnapshot snapshot, DiagnosticMessage diagnosticMessage)
: base(snapshot, diagnosticMessage.Location.Offset, diagnosticMessage.Location.Length)
{
diff --git a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Breakpoint.cs b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Breakpoint.cs
index fad795d..13838bc 100644
--- a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Breakpoint.cs
+++ b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Breakpoint.cs
@@ -44,12 +44,12 @@
static readonly string[] ValidExtensions = new string[] { ".qml", ".js" };
public QmlEngine Engine { get; private set; }
- public IDebugBreakpointRequest2 Request { get; private set; }
- public enum_BP_LOCATION_TYPE LocationType { get; private set; }
- public BP_REQUEST_INFO RequestInfo { get; private set; }
+ private IDebugBreakpointRequest2 Request { get; set; }
+ private enum_BP_LOCATION_TYPE LocationType { get; set; }
+ private BP_REQUEST_INFO RequestInfo { get; set; }
public string FileName { get; private set; }
public TEXT_POSITION BeginPosition { get; private set; }
- public TEXT_POSITION EndPosition { get; private set; }
+ private TEXT_POSITION EndPosition { get; set; }
public bool Enabled { get; private set; }
HashSet<Breakpoint> breakpoints;
@@ -85,8 +85,7 @@
if (docPosition == null)
return false;
- string fileName;
- if (docPosition.GetFileName(out fileName) != VSConstants.S_OK)
+ if (docPosition.GetFileName(out string fileName) != VSConstants.S_OK)
return false;
if (!ValidExtensions.Where(x => string.Equals(x, Path.GetExtension(fileName))).Any())
@@ -186,12 +185,12 @@
IDebugBreakpointResolution2 // "This interface represents the information that describes a
// bound breakpoint."
{
- public QmlDebugger Debugger { get; private set; }
- public QmlEngine Engine { get; private set; }
+ private QmlDebugger Debugger { get; set; }
+ private QmlEngine Engine { get; set; }
public Program Program { get; private set; }
public PendingBreakpoint Parent { get; private set; }
- public CodeContext CodeContext { get; private set; }
- public bool Enabled { get; set; }
+ private CodeContext CodeContext { get; set; }
+ private bool Enabled { get; set; }
bool supressNotify;
diff --git a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Engine.cs b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Engine.cs
index 8da6eb9..5dc4bdb 100644
--- a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Engine.cs
+++ b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Engine.cs
@@ -78,13 +78,13 @@
FileSystem = FileSystem.Create();
}
- Dictionary<Guid, Program> programs = new Dictionary<Guid, Program>();
+ readonly Dictionary<Guid, Program> programs = new Dictionary<Guid, Program>();
public IEnumerable<Program> Programs
{
get { return ThreadSafe(() => programs.Values.ToList()); }
}
- HashSet<PendingBreakpoint> pendingBreakpoints = new HashSet<PendingBreakpoint>();
+ readonly HashSet<PendingBreakpoint> pendingBreakpoints = new HashSet<PendingBreakpoint>();
public IEnumerable<PendingBreakpoint> PendingBreakpoints
{
get { return ThreadSafe(() => pendingBreakpoints.ToList()); }
@@ -106,8 +106,7 @@
if (string.IsNullOrEmpty(pszOptions))
return VSConstants.E_FAIL;
- uint procId;
- if (!uint.TryParse(pszOptions, out procId))
+ if (!uint.TryParse(pszOptions, out uint procId))
return VSConstants.E_FAIL;
var env = bstrEnv.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
@@ -120,13 +119,12 @@
FileSystem.RegisterRccFile(rccFile);
}
- IDebugProcess2 nativeProc;
var nativeProcId = new AD_PROCESS_ID
{
ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM,
dwProcessId = procId
};
- if (pPort.GetProcess(nativeProcId, out nativeProc) != VSConstants.S_OK)
+ if (pPort.GetProcess(nativeProcId, out IDebugProcess2 nativeProc) != VSConstants.S_OK)
return VSConstants.E_FAIL;
var program = Program.Create(this, nativeProc, pszExe, pszArgs);
@@ -144,20 +142,11 @@
if (program == null)
return VSConstants.E_FAIL;
- IDebugPort2 port;
- if (process.GetPort(out port) != VSConstants.S_OK)
+ if (process.GetPort(out IDebugPort2 port) != VSConstants.S_OK)
return VSConstants.E_FAIL;
- string portName;
- port.GetPortName(out portName);
-
- Guid guidPort;
- port.GetPortId(out guidPort);
-
IDebugDefaultPort2 defaultPort = (IDebugDefaultPort2)port;
-
- IDebugPortNotify2 portNotify;
- if (defaultPort.GetPortNotify(out portNotify) != VSConstants.S_OK)
+ if (defaultPort.GetPortNotify(out IDebugPortNotify2 portNotify) != VSConstants.S_OK)
return VSConstants.E_FAIL;
if (portNotify.AddProgramNode(program) != VSConstants.S_OK)
@@ -181,8 +170,7 @@
DebugEvent.Send(new EngineCreateEvent(this));
- Guid pguidProgramId;
- if (rgpPrograms[0].GetProgramId(out pguidProgramId) != VSConstants.S_OK)
+ if (rgpPrograms[0].GetProgramId(out Guid pguidProgramId) != VSConstants.S_OK)
return VSConstants.E_FAIL;
program.ProgramId = pguidProgramId;
@@ -199,15 +187,10 @@
int IDebugEngineLaunch2.CanTerminateProcess(IDebugProcess2 pProcess)
{
- Guid procId;
- if (pProcess.GetProcessId(out procId) != VSConstants.S_OK)
+ if (pProcess.GetProcessId(out Guid procId) != VSConstants.S_OK)
return VSConstants.E_FAIL;
- Program program;
- if (!programs.TryGetValue(procId, out program))
- return VSConstants.S_FALSE;
-
- return VSConstants.S_OK;
+ return programs.TryGetValue(procId, out _) ? VSConstants.S_OK : VSConstants.S_FALSE;
}
public bool ProgramIsRunning(Program program)
@@ -217,12 +200,10 @@
int IDebugEngineLaunch2.TerminateProcess(IDebugProcess2 pProcess)
{
- Guid procId;
- if (pProcess.GetProcessId(out procId) != VSConstants.S_OK)
+ if (pProcess.GetProcessId(out Guid procId) != VSConstants.S_OK)
return VSConstants.E_FAIL;
- Program program;
- if (!programs.TryGetValue(procId, out program))
+ if (!programs.TryGetValue(procId, out Program program))
return VSConstants.S_FALSE;
programs.Remove(procId);
@@ -235,8 +216,7 @@
int IDebugEngine2.ContinueFromSynchronousEvent(IDebugEvent2 pEvent)
{
- var evtProgramDestroy = pEvent as ProgramDestroyEvent;
- if (evtProgramDestroy != null)
+ if (pEvent is ProgramDestroyEvent evtProgramDestroy)
evtProgramDestroy.Program.Dispose();
return VSConstants.S_OK;
@@ -271,7 +251,7 @@
#region //////////////////// Concurrent ///////////////////////////////////////////////////
- LocalConcurrent concurrent = new LocalConcurrent();
+ readonly LocalConcurrent concurrent = new LocalConcurrent();
class LocalConcurrent : Concurrent
{
public void LocalThreadSafe(Action action)
diff --git a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Events.cs b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Events.cs
index 9c75bc5..6ea40cf 100644
--- a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Events.cs
+++ b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Events.cs
@@ -38,8 +38,8 @@
// such as stopping at a breakpoint, and non-critical information, such as a
// debugging message."
{
- public Guid InterfaceId { get; protected set; }
- public uint Attributes { get; protected set; }
+ private Guid InterfaceId { get; }
+ private uint Attributes { get; }
protected const uint ASYNCHRONOUS = (uint)enum_EVENTATTRIBUTES.EVENT_ASYNCHRONOUS;
protected const uint STOPPING = (uint)enum_EVENTATTRIBUTES.EVENT_ASYNC_STOP;
@@ -48,10 +48,10 @@
(uint)enum_EVENTATTRIBUTES.EVENT_STOPPING
| (uint)enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS;
- protected QmlEngine Engine { get; set; }
- protected IDebugProgram2 Program { get; set; }
- protected IDebugThread2 Thread { get; set; }
- protected IDebugEventCallback2 Callback { get; set; }
+ protected QmlEngine Engine { get; }
+ private IDebugProgram2 Program { get; }
+ private IDebugThread2 Thread { get; }
+ private IDebugEventCallback2 Callback { get; }
protected DebugEvent(
QmlEngine engine,
@@ -114,8 +114,8 @@
class ProgramDestroyEvent : DebugEvent, IDebugProgramDestroyEvent2
{
- uint exitCode;
- public new Program Program { get; private set; }
+ readonly uint exitCode;
+ public Program Program { get; }
public ProgramDestroyEvent(Program program, uint exitCode)
: base(program.Engine, typeof(IDebugProgramDestroyEvent2).GUID,
@@ -142,7 +142,7 @@
class ThreadDestroyEvent : DebugEvent, IDebugThreadDestroyEvent2
{
- uint exitCode;
+ readonly uint exitCode;
public ThreadDestroyEvent(Program program, uint exitCode)
: base(program.Engine, typeof(IDebugThreadDestroyEvent2).GUID,
@@ -176,7 +176,7 @@
class BreakpointBoundEvent : DebugEvent, IDebugBreakpointBoundEvent2
{
- public Breakpoint Breakpoint { get; private set; }
+ private Breakpoint Breakpoint { get; }
public BreakpointBoundEvent(Breakpoint breakpoint)
: base(breakpoint.Program.Engine, typeof(IDebugBreakpointBoundEvent2).GUID,
ASYNCHRONOUS, breakpoint.Program, breakpoint.Program)
@@ -201,7 +201,7 @@
class BreakpointEvent : DebugEvent, IDebugBreakpointEvent2
{
- IEnumDebugBoundBreakpoints2 boundBreakpoints;
+ readonly IEnumDebugBoundBreakpoints2 boundBreakpoints;
public BreakpointEvent(Program program,
IEnumDebugBoundBreakpoints2 boundBreakpoints)
@@ -228,8 +228,8 @@
class ExpressionEvaluationCompleteEvent : DebugEvent, IDebugExpressionEvaluationCompleteEvent2
{
- public Expression Expression { get; private set; }
- public Property Property { get; private set; }
+ private Expression Expression { get; }
+ private Property Property { get; }
public ExpressionEvaluationCompleteEvent(
IDebugEventCallback2 callback,
@@ -257,7 +257,7 @@
class OutputStringEvent : DebugEvent, IDebugOutputStringEvent2
{
- string outputString;
+ readonly string outputString;
public OutputStringEvent(QmlEngine engine, string outputString)
: base(engine, typeof(IDebugOutputStringEvent2).GUID, ASYNCHRONOUS)
diff --git a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Expression.cs b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Expression.cs
index 57f2e8b..f705c84 100644
--- a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Expression.cs
+++ b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Expression.cs
@@ -26,7 +26,6 @@
**
****************************************************************************/
-using System;
using System.Threading.Tasks;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Debugger.Interop;
@@ -40,13 +39,13 @@
IDebugExpression2 // "This interface represents a parsed expression ready for binding
// and evaluating."
{
- public string ExpressionString { get; private set; }
+ private string ExpressionString { get; set; }
- public StackFrame StackFrame { get; private set; }
+ private StackFrame StackFrame { get; set; }
public QmlEngine Engine { get; private set; }
public Program Program { get; private set; }
- public QmlDebugger Debugger { get; private set; }
- public CodeContext CodeContext { get; private set; }
+ private QmlDebugger Debugger { get; set; }
+ private CodeContext CodeContext { get; set; }
public static Expression Create(StackFrame frame, string expr)
{
@@ -86,7 +85,7 @@
enum_EVALFLAGS dwFlags,
IDebugEventCallback2 pExprCallback)
{
- Task.Run(() =>
+ _ = Task.Run(() =>
{
var value = Debugger.Evaluate(StackFrame.FrameNumber, ExpressionString);
if (value != null)
diff --git a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7InfoHelpers.cs b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7InfoHelpers.cs
index 312aa39..dfd2af2 100644
--- a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7InfoHelpers.cs
+++ b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7InfoHelpers.cs
@@ -26,12 +26,9 @@
**
****************************************************************************/
-using Microsoft.VisualStudio.Debugger.Interop;
using System;
using System.Collections;
using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
namespace QtVsTools.Qml.Debug.AD7
{
@@ -76,9 +73,9 @@
public class Mapping<TStruct, TFieldMask> : Mapping,
IEnumerable<MapField<TStruct, TFieldMask>>
{
- List<MapField<TStruct, TFieldMask>> fieldMaps;
+ readonly List<MapField<TStruct, TFieldMask>> fieldMaps;
- protected static Action<Ref<TStruct>, TFieldMask> UpdateMask { get; set; }
+ private static Action<Ref<TStruct>, TFieldMask> UpdateMask { get; set; }
public Mapping(Action<Ref<TStruct>, TFieldMask> updateMask)
{
@@ -188,8 +185,7 @@
TFieldMask fieldMask,
out TStruct infoStruct)
{
- var mappingToStruct = mapping as Mapping<TStruct, TFieldMask>;
- if (mappingToStruct != null)
+ if (mapping is Mapping<TStruct, TFieldMask> mappingToStruct)
mappingToStruct.Map(this as TDerived, fieldMask, out infoStruct);
else
infoStruct = default(TStruct);
diff --git a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Program.cs b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Program.cs
index 6a7cee4..0111f31 100644
--- a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Program.cs
+++ b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Program.cs
@@ -29,18 +29,16 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading;
using System.Windows.Threading;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Debugger.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
-using QtVsTools.VisualStudio;
namespace QtVsTools.Qml.Debug.AD7
{
+ using VisualStudio;
+
sealed partial class Program : Disposable, IDebuggerEventSink,
IDebugProgramNode2, // "This interface represents a program that can be debugged."
@@ -64,21 +62,21 @@
public QmlEngine Engine { get; private set; }
- public List<StackFrame> CurrentFrames { get; private set; }
+ private List<StackFrame> CurrentFrames { get; set; }
- public const string Name = "QML Debugger";
- public Guid ProcessId { get; private set; }
+ private const string Name = "QML Debugger";
+ public Guid ProcessId { get; set; }
public Guid ProgramId { get; set; }
- public IDebugProcess2 NativeProc { get; private set; }
- public uint NativeProcId { get; private set; }
- public string ExecPath { get; private set; }
- public string ExecArgs { get; private set; }
- public IVsDebugger VsDebugger { get; private set; }
- Dispatcher vsDebuggerThreadDispatcher;
+ private IDebugProcess2 NativeProc { get; set; }
+ private uint NativeProcId { get; set; }
+ private string ExecPath { get; set; }
+ private string ExecArgs { get; set; }
+ private IVsDebugger VsDebugger { get; set; }
+ private Dispatcher vsDebuggerThreadDispatcher;
- private readonly static object criticalSectionGlobal = new object();
- static bool originalBreakAllProcesses = BreakAllProcesses;
- static int runningPrograms = 0;
+ private static readonly object criticalSectionGlobal = new object();
+ private static bool originalBreakAllProcesses = BreakAllProcesses;
+ private static int runningPrograms = 0;
public static Program Create(
QmlEngine engine,
@@ -114,8 +112,13 @@
return false;
VsDebugger = VsServiceProvider.GetService<IVsDebugger>();
- if (VsDebugger != null)
- VsDebugger.AdviseDebugEventCallback(this as IDebugEventCallback2);
+ if (VsDebugger != null) {
+ ThreadHelper.JoinableTaskFactory.Run(async () =>
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ VsDebugger.AdviseDebugEventCallback(this);
+ });
+ }
vsDebuggerThreadDispatcher = Dispatcher.CurrentDispatcher;
ProcessId = Guid.NewGuid();
@@ -141,8 +144,13 @@
protected override void DisposeManaged()
{
Debugger.Dispose();
- if (VsDebugger != null)
- VsDebugger.UnadviseDebugEventCallback(this as IDebugEventCallback2);
+ if (VsDebugger != null) {
+ ThreadHelper.JoinableTaskFactory.Run(async () =>
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ VsDebugger.UnadviseDebugEventCallback(this as IDebugEventCallback2);
+ });
+ }
lock (criticalSectionGlobal) {
runningPrograms--;
@@ -161,9 +169,12 @@
{
var debugMode = new DBGMODE[1];
int res = VSConstants.S_FALSE;
- vsDebuggerThreadDispatcher
- .BeginInvoke(new Action(() => res = VsDebugger.GetMode(debugMode)), new object[0])
- .Wait();
+
+ QtVsToolsPackage.Instance.JoinableTaskFactory.Run(async () =>
+ {
+ await QtVsToolsPackage.Instance.JoinableTaskFactory.SwitchToMainThreadAsync();
+ res = VsDebugger.GetMode(debugMode);
+ });
if (res != VSConstants.S_OK)
return false;
@@ -295,17 +306,24 @@
{
get
{
- return ((bool)QtVsToolsPackage.Instance.Dte
- .Properties["Debugging", "General"]
- .Item("BreakAllProcesses")
- .Value);
+ return ThreadHelper.JoinableTaskFactory.Run(async () => {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ return ((bool)QtVsToolsPackage.Instance.Dte
+ .Properties["Debugging", "General"]
+ .Item("BreakAllProcesses")
+ .Value);
+ });
}
set
{
- QtVsToolsPackage.Instance.Dte
- .Properties["Debugging", "General"]
- .Item("BreakAllProcesses")
- .let_Value(value ? "True" : "False");
+ ThreadHelper.JoinableTaskFactory.Run(async () =>
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ QtVsToolsPackage.Instance.Dte
+ .Properties["Debugging", "General"]
+ .Item("BreakAllProcesses")
+ .let_Value(value ? "True" : "False");
+ });
}
}
diff --git a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Property.cs b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Property.cs
index c1e7c1f..eba56a8 100644
--- a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Property.cs
+++ b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7Property.cs
@@ -29,7 +29,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Debugger.Interop;
@@ -43,23 +42,23 @@
// property, or some other property. The property is usually the result of
// an expression evaluation."
{
- public QmlDebugger Debugger { get; private set; }
+ private QmlDebugger Debugger { get; set; }
- public QmlEngine Engine { get; private set; }
- public Program Program { get; private set; }
- public StackFrame StackFrame { get; private set; }
- public CodeContext CodeContext { get; private set; }
+ private QmlEngine Engine { get; set; }
+ private Program Program { get; set; }
+ private StackFrame StackFrame { get; set; }
+ private CodeContext CodeContext { get; set; }
- public Property Parent { get; private set; }
- public SortedDictionary<string, Property> Children { get; private set; }
+ private Property Parent { get; set; }
+ private SortedDictionary<string, Property> Children { get; set; }
- public int FrameNumber { get; private set; }
- public int ScopeNumber { get; private set; }
- public JsValue JsValue { get; private set; }
- public string Name { get; private set; }
- public string FullName { get; private set; }
- public string Type { get; private set; }
- public string Value { get; private set; }
+ private int FrameNumber { get; set; }
+ private int ScopeNumber { get; set; }
+ private JsValue JsValue { get; set; }
+ private string Name { get; set; }
+ private string FullName { get; set; }
+ private string Type { get; set; }
+ private string Value { get; set; }
public static Property Create(
StackFrame frame,
@@ -120,11 +119,9 @@
static string GetChildKey(string childName)
{
- int childIndex;
- if (int.TryParse(childName, out childIndex))
+ if (int.TryParse(childName, out int childIndex))
return string.Format("{0:D9}", childIndex);
- else
- return childName;
+ return childName;
}
int IDebugProperty2.SetValueAsString(string pszValue, uint dwRadix, uint dwTimeout)
@@ -242,8 +239,7 @@
public DEBUG_PROPERTY_INFO GetInfo(enum_DEBUGPROP_INFO_FLAGS dwFields)
{
- DEBUG_PROPERTY_INFO info;
- Info.Map(MappingToDEBUG_PROPERTY_INFO, dwFields, out info);
+ Info.Map(MappingToDEBUG_PROPERTY_INFO, dwFields, out DEBUG_PROPERTY_INFO info);
return info;
}
@@ -275,19 +271,19 @@
public static readonly Guid Registers
= new Guid("223ae797-bd09-4f28-8241-2763bdc5f713");
- public static readonly Guid Locals
+ private static readonly Guid Locals
= new Guid("b200f725-e725-4c53-b36a-1ec27aef12ef");
- public static readonly Guid AllLocals
+ private static readonly Guid AllLocals
= new Guid("196db21f-5f22-45a9-b5a3-32cddb30db06");
public static readonly Guid Args
= new Guid("804bccea-0475-4ae7-8a46-1862688ab863");
- public static readonly Guid LocalsPlusArgs
+ private static readonly Guid LocalsPlusArgs
= new Guid("e74721bb-10c0-40f5-807f-920d37f95419");
- public static readonly Guid AllLocalsPlusArgs
+ private static readonly Guid AllLocalsPlusArgs
= new Guid("939729a8-4cb0-4647-9831-7ff465240d5f");
public static bool LocalsSelected(ref Guid guidFilter)
diff --git a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7StackFrame.cs b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7StackFrame.cs
index 8578f60..cc80a67 100644
--- a/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7StackFrame.cs
+++ b/QtVsTools.Package/QML/Debugging/AD7/QmlDebugAD7StackFrame.cs
@@ -32,6 +32,7 @@
using System.Threading.Tasks;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Debugger.Interop;
+using Microsoft.VisualStudio.Threading;
namespace QtVsTools.Qml.Debug.AD7
{
@@ -52,14 +53,14 @@
public Program Program { get; private set; }
public CodeContext Context { get; private set; }
- public Dictionary<int, Dictionary<string, Property>> Properties { get; private set; }
+ private Dictionary<int, Dictionary<string, Property>> Properties { get; set; }
- public string Name { get; private set; }
- public int FrameNumber { get; private set; }
- public IEnumerable<int> Scopes { get; private set; }
- public Task InitThread { get; private set; }
+ private string Name { get; set; }
+ public int FrameNumber { get; set; }
+ private IEnumerable<int> Scopes { get; set; }
+ private JoinableTask InitThread { get; set; }
- static public StackFrame Create(
+ public static StackFrame Create(
string name,
int number,
IEnumerable<int> scopes,
@@ -85,7 +86,11 @@
Name = string.Format("{0}@{1}:{2}", name, context.FilePath, context.FileLine + 1);
FrameNumber = number;
Scopes = scopes;
- InitThread = Task.Run(() => InitializeProperties());
+ InitThread = QtVsToolsPackage.Instance.JoinableTaskFactory.RunAsync(async () =>
+ {
+ InitializeProperties();
+ await Task.Yield();
+ });
return true;
}
@@ -134,7 +139,7 @@
if (guidFilter != Guid.Empty && !Property.Filter.LocalsSelected(ref guidFilter))
return VSConstants.S_OK;
- InitThread.Wait();
+ InitThread.Join();
pcelt = 0;
ppEnum = PropertyEnum.Create(Properties
.SelectMany(x => x.Value
@@ -152,9 +157,8 @@
uint dwTimeout,
out IEnumDebugPropertyInfo2 ppEnum)
{
- uint pcelt;
return ((IDebugStackFrame2)this)
- .EnumProperties(dwFields, dwRadix, guidFilter, dwTimeout, out pcelt, out ppEnum);
+ .EnumProperties(dwFields, dwRadix, guidFilter, dwTimeout, out _, out ppEnum);
}
#region //////////////////// Info /////////////////////////////////////////////////////////
diff --git a/QtVsTools.Package/QML/Debugging/QmlDebugLauncher.cs b/QtVsTools.Package/QML/Debugging/QmlDebugLauncher.cs
index 025ee42..02fd242 100644
--- a/QtVsTools.Package/QML/Debugging/QmlDebugLauncher.cs
+++ b/QtVsTools.Package/QML/Debugging/QmlDebugLauncher.cs
@@ -35,39 +35,50 @@
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.VCProjectEngine;
-using QtVsTools.Core;
-using QtVsTools.Core.QtMsBuild;
-using QtVsTools.SyntaxAnalysis;
-using static QtVsTools.SyntaxAnalysis.RegExpr;
namespace QtVsTools.Qml.Debug
{
using AD7;
+ using Common;
+ using Core;
+ using Core.QtMsBuild;
+ using SyntaxAnalysis;
using VisualStudio;
+
+ using static SyntaxAnalysis.RegExpr;
class Launcher : Disposable, IDebugEventCallback2
{
- public static Launcher Instance { get; private set; }
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ private static Launcher Instance { get; set; }
IVsDebugger debugger;
IVsDebugger4 debugger4;
- HashSet<Guid> _ExcludedProcesses;
- HashSet<Guid> ExcludedProcesses => _ExcludedProcesses
- ?? (_ExcludedProcesses = new HashSet<Guid>());
+ HashSet<Guid> ExcludedProcesses => Lazy.Get(() =>
+ ExcludedProcesses, () => new HashSet<Guid>());
public static void Initialize()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
Instance = new Launcher();
Instance.debugger = VsServiceProvider.GetService<IVsDebugger>();
Instance.debugger4 = VsServiceProvider.GetService<IVsDebugger, IVsDebugger4>();
+
if (Instance.debugger != null && Instance.debugger4 != null)
Instance.debugger.AdviseDebugEventCallback(Instance);
}
protected override void DisposeManaged()
{
- if (debugger != null)
- debugger.UnadviseDebugEventCallback(this);
+ if (debugger != null) {
+ ThreadHelper.JoinableTaskFactory.Run(async () =>
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ debugger.UnadviseDebugEventCallback(this);
+ });
+ }
}
int IDebugEventCallback2.Event(
@@ -79,6 +90,8 @@
ref Guid riidEvent,
uint dwAttrib)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
if (!QtVsToolsPackage.Instance.Options.QmlDebuggerEnabled)
return VSConstants.S_OK;
@@ -90,8 +103,7 @@
if (pProcess == null && pProgram.GetProcess(out pProcess) != VSConstants.S_OK)
return VSConstants.S_OK;
- Guid procGuid;
- if (pProcess.GetProcessId(out procGuid) != VSConstants.S_OK)
+ if (pProcess.GetProcessId(out Guid procGuid) != VSConstants.S_OK)
return VSConstants.S_OK;
// Run only once per process
@@ -119,14 +131,10 @@
else
return VSConstants.S_OK;
- string execPath;
- uint procId;
- if (!GetProcessInfo(pProcess, native, out execPath, out procId))
+ if (!GetProcessInfo(pProcess, native, out string execPath, out uint procId))
return VSConstants.S_OK;
- string execCmd;
- IEnumerable<string> rccItems;
- if (!GetProjectInfo(execPath, native, out execCmd, out rccItems))
+ if (!GetProjectInfo(execPath, native, out string execCmd, out IEnumerable<string> rccItems))
return VSConstants.S_OK;
LaunchDebug(execPath, execCmd, procId, rccItems);
@@ -135,9 +143,7 @@
Guid GetEngineId(IDebugProgram2 pProgram)
{
- string engineName;
- Guid engineGuid;
- if (pProgram.GetEngineInfo(out engineName, out engineGuid) != VSConstants.S_OK)
+ if (pProgram.GetEngineInfo(out _, out Guid engineGuid) != VSConstants.S_OK)
return Guid.Empty;
return engineGuid;
}
@@ -152,7 +158,7 @@
}
}
- static RegExpr wslPathRegex = new Token("WSLPATH", SkipWs_Disable, StartOfFile
+ static readonly RegExpr wslPathRegex = new Token("WSLPATH", SkipWs_Disable, StartOfFile
& "/mnt/" & new Token("DRIVE", CharWord) & "/" & new Token("PATH", AnyChar.Repeat()))
{
new Rule<WslPath>
@@ -161,15 +167,14 @@
Update("PATH", (WslPath wslPath, string path) => wslPath.Path = path),
}
};
- static RegExpr.Parser wslPathParser = wslPathRegex.Render();
+ static readonly RegExpr.Parser wslPathParser = wslPathRegex.Render();
bool GetProcessInfo(IDebugProcess2 pProcess, bool native, out string execPath, out uint procId)
{
execPath = "";
procId = 0;
- string fileName;
- if (pProcess.GetName(enum_GETNAME_TYPE.GN_FILENAME, out fileName) != VSConstants.S_OK)
+ if (pProcess.GetName(enum_GETNAME_TYPE.GN_FILENAME, out string fileName) != VSConstants.S_OK)
return false;
var pProcessId = new AD_PROCESS_ID[1];
@@ -193,6 +198,8 @@
bool GetProjectInfo(string execPath, bool native, out string execCmd, out IEnumerable<string> rccItems)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
execCmd = "";
rccItems = null;
@@ -290,6 +297,8 @@
uint procId,
IEnumerable<string> rccItems)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var targets = new[] { new VsDebugTargetInfo4
{
dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_CreateProcess,
@@ -305,8 +314,8 @@
try {
debugger4.LaunchDebugTargets4((uint)targets.Length, targets, processInfo);
- } catch (System.Exception e) {
- OutputWriteLine(e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
}
}
}
diff --git a/QtVsTools.Package/QML/Debugging/QmlDebugger.cs b/QtVsTools.Package/QML/Debugging/QmlDebugger.cs
index 892a17d..b877956 100644
--- a/QtVsTools.Package/QML/Debugging/QmlDebugger.cs
+++ b/QtVsTools.Package/QML/Debugging/QmlDebugger.cs
@@ -26,18 +26,19 @@
**
****************************************************************************/
-using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using System.Threading.Tasks;
-using QtVsTools.SyntaxAnalysis;
-using static QtVsTools.SyntaxAnalysis.RegExpr;
-using RegExprParser = QtVsTools.SyntaxAnalysis.RegExpr.Parser;
namespace QtVsTools.Qml.Debug
{
+ using Common;
+ using SyntaxAnalysis;
using V4;
+
+ using RegExprParser = SyntaxAnalysis.RegExpr.Parser;
+
+ using static SyntaxAnalysis.RegExpr;
struct FrameInfo
{
@@ -69,6 +70,8 @@
class QmlDebugger : Disposable, IMessageEventSink
{
+ static LazyFactory StaticLazy { get; } = new LazyFactory();
+
IDebuggerEventSink sink;
ProtocolDriver driver;
string connectionHostName;
@@ -80,11 +83,11 @@
List<Request> outbox;
Dictionary<int, IBreakpoint> breakpoints;
- public bool Started { get; private set; }
+ private bool Started { get; set; }
- public bool Running { get; private set; }
+ private bool Running { get; set; }
- public string Version { get; private set; }
+ private string Version { get; set; }
public uint? ThreadId { get { return driver.ThreadId; } }
@@ -160,7 +163,7 @@
if (!Started) {
Running = Started = true;
LeaveCriticalSection();
- Task.Run(() => ConnectToDebugger());
+ _ = Task.Run(() => ConnectToDebugger());
} else if (!Running) {
Running = true;
@@ -201,7 +204,7 @@
setBreakpoint.Arguments.Line = (int)breakpoint.Line;
setBreakpoint.Tag = breakpoint;
if (driver.ConnectionState == DebugClientState.Connected)
- setBreakpoint.SendAsync();
+ setBreakpoint.SendRequest();
else
ThreadSafe(() => outbox.Add(setBreakpoint));
}
@@ -231,7 +234,7 @@
var reqClearBreak = Message.Create<ClearBreakpointRequest>(driver);
reqClearBreak.Arguments.Breakpoint = breakpointNum[breakpoint];
- reqClearBreak.SendAsync();
+ reqClearBreak.SendRequest();
}
void RefreshFrames()
@@ -286,8 +289,7 @@
} else {
foreach (int breakpointId in evtBreak.Body.Breakpoints) {
- IBreakpoint breakpoint;
- if (!breakpoints.TryGetValue(breakpointId, out breakpoint))
+ if (!breakpoints.TryGetValue(breakpointId, out IBreakpoint breakpoint))
continue;
breakpoint.NotifyBreak();
}
@@ -406,20 +408,20 @@
{
if (oldState != DebugClientState.Unavailable
&& newState == DebugClientState.Disconnected) {
- Task.Run(() => sink.NotifyClientDisconnected());
+ _ = Task.Run(() => sink.NotifyClientDisconnected());
}
}
void IMessageEventSink.NotifyRequestResponded(Request msgRequest)
{
if (msgRequest is SetBreakpointRequest)
- Task.Run(() => SetBreakpointResponded(msgRequest as SetBreakpointRequest));
+ _ = Task.Run(() => SetBreakpointResponded(msgRequest as SetBreakpointRequest));
}
void IMessageEventSink.NotifyEvent(Event msgEvent)
{
if (msgEvent is BreakEvent)
- Task.Run(() => BreakNotified(msgEvent as BreakEvent));
+ _ = Task.Run(() => BreakNotified(msgEvent as BreakEvent));
}
void IMessageEventSink.NotifyMessage(Message msg)
@@ -430,13 +432,7 @@
public static bool CheckCommandLine(string execPath, string args)
{
- ushort portFrom;
- ushort portTo;
- string hostName;
- string fileName;
- bool block;
- return ParseCommandLine(
- execPath, args, out portFrom, out portTo, out hostName, out fileName, out block);
+ return ParseCommandLine(execPath, args, out _, out _, out _, out _, out _);
}
/// <summary>
@@ -456,8 +452,8 @@
/// <summary>
/// Regex-based parser for QML debug connection parameters
/// </summary>
- static RegExprParser ConnectParamsParser => _ConnectParamsParser ?? (
- _ConnectParamsParser = new Token(TokenId.ConnectParams, RxConnectParams)
+ static RegExprParser ConnectParamsParser => StaticLazy.Get(() =>
+ ConnectParamsParser, () => new Token(TokenId.ConnectParams, RxConnectParams)
{
new Rule<ConnectParams>
{
@@ -469,7 +465,6 @@
}
}
.Render());
- static RegExprParser _ConnectParamsParser;
/// <summary>
/// Regular expression for parsing connection parameters string in the form:
diff --git a/QtVsTools.Package/QML/Debugging/QmlFileSystem.cs b/QtVsTools.Package/QML/Debugging/QmlFileSystem.cs
index 4b33faf..20af63b 100644
--- a/QtVsTools.Package/QML/Debugging/QmlFileSystem.cs
+++ b/QtVsTools.Package/QML/Debugging/QmlFileSystem.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -36,6 +36,8 @@
namespace QtVsTools.Qml.Debug
{
+ using QtVsTools.Core;
+
struct QmlFile
{
public string QrcPath;
@@ -92,9 +94,8 @@
using (var reader = XmlReader.Create(new StringReader(xmlText), settings)) {
rccXml = XDocument.Load(reader);
}
- } catch (Exception e) {
- System.Diagnostics.Debug.WriteLine(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
return;
}
@@ -156,8 +157,7 @@
qrcPath = string.Format("qrc:///{0}", qrcPath);
- QmlFile file;
- if (!files.TryGetValue(qrcPath, out file))
+ if (!files.TryGetValue(qrcPath, out QmlFile file))
return default(QmlFile);
return file;
@@ -190,8 +190,7 @@
return default(QmlFile);
}
- QmlFile file;
- if (files.TryGetValue(fullPath, out file))
+ if (files.TryGetValue(fullPath, out QmlFile file))
return file;
return new QmlFile
diff --git a/QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Continue.cs b/QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Continue.cs
index 905adff..febf0d7 100644
--- a/QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Continue.cs
+++ b/QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Continue.cs
@@ -26,10 +26,7 @@
**
****************************************************************************/
-using System.Collections.Generic;
-using System.ComponentModel;
using System.Runtime.Serialization;
-using System.Threading;
namespace QtVsTools.Qml.Debug.V4
{
diff --git a/QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4JsObject.cs b/QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4JsObject.cs
index a5a9272..eb5b243 100644
--- a/QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4JsObject.cs
+++ b/QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4JsObject.cs
@@ -26,7 +26,6 @@
**
****************************************************************************/
-using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
diff --git a/QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Message.cs b/QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Message.cs
index ad1a5b9..f1c3739 100644
--- a/QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Message.cs
+++ b/QtVsTools.Package/QML/Debugging/V4/Messages/QmlDebugV4Message.cs
@@ -143,14 +143,14 @@
set { Atomic(() => tag == null, () => tag = value); }
}
- public virtual ProtocolDriver.PendingRequest SendAsync()
+ public virtual ProtocolDriver.PendingRequest SendRequest()
{
return Driver.SendRequest(this);
}
public new Response Send()
{
- return SendAsync().WaitForResponse();
+ return SendRequest().WaitForResponse();
}
public static new Response Send<T>(ProtocolDriver driver, Action<T> initMsg = null)
@@ -173,7 +173,7 @@
public new virtual TResponse Send()
{
- var pendingRequest = SendAsync();
+ var pendingRequest = SendRequest();
if (!pendingRequest.RequestSent)
return null;
diff --git a/QtVsTools.Package/QML/Debugging/V4/QmlDebugV4Client.cs b/QtVsTools.Package/QML/Debugging/V4/QmlDebugV4Client.cs
index abbf6de..19f88f2 100644
--- a/QtVsTools.Package/QML/Debugging/V4/QmlDebugV4Client.cs
+++ b/QtVsTools.Package/QML/Debugging/V4/QmlDebugV4Client.cs
@@ -26,14 +26,9 @@
**
****************************************************************************/
-using QtVsTools.Options;
using System;
-using System.Collections.Concurrent;
-using System.IO;
using System.Net.Sockets;
using System.Runtime.InteropServices;
-using System.Runtime.Serialization;
-using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -62,7 +57,7 @@
IConnectionEventSink sink;
IntPtr client;
Task clientThread;
- EventWaitHandle clientCreated = new EventWaitHandle(false, EventResetMode.ManualReset);
+ readonly EventWaitHandle clientCreated = new EventWaitHandle(false, EventResetMode.ManualReset);
EventWaitHandle clientConnected;
public uint? ThreadId { get; private set; }
@@ -82,7 +77,7 @@
if (state != value) {
var oldState = state;
state = value;
- Task.Run(() => sink.NotifyStateTransition(this, oldState, value));
+ _ = Task.Run(() => sink.NotifyStateTransition(this, oldState, value));
}
}
}
@@ -100,14 +95,17 @@
{
this.sink = sink;
- Task.WaitAny(new[]
+ QtVsToolsPackage.Instance.JoinableTaskFactory.Run(async () =>
{
- // Try to start client thread
- // Unblock if thread was abruptly terminated (e.g. DLL not found)
- clientThread = Task.Run(() => ClientThread()),
+ await Task.WhenAny(new[]
+ {
+ // Try to start client thread
+ // Unblock if thread was abruptly terminated (e.g. DLL not found)
+ clientThread = Task.Run(() => ClientThread()),
- // Unblock if client was created (i.e. client thread is running)
- Task.Run(() => clientCreated.WaitOne())
+ // Unblock if client was created (i.e. client thread is running)
+ Task.Run(() => clientCreated.WaitOne())
+ });
});
if (State == DebugClientState.Unavailable) {
@@ -135,7 +133,9 @@
{
if (State != DebugClientState.Unavailable) {
NativeMethods.DebugClientShutdown(client);
- clientThread.Wait();
+
+ QtVsToolsPackage.Instance.JoinableTaskFactory.Run(
+ async () => await Task.WhenAll(new[] { clientThread }));
}
}
@@ -180,7 +180,7 @@
var hostNameData = Encoding.UTF8.GetBytes(hostName);
uint timeout = (uint)QtVsToolsPackage.Instance.Options.QmlDebuggerTimeout;
- Task.Run(() =>
+ _ = Task.Run(() =>
{
var connectTimer = new System.Diagnostics.Stopwatch();
connectTimer.Start();
@@ -246,7 +246,7 @@
uint timeout = (uint)QtVsToolsPackage.Instance.Options.QmlDebuggerTimeout;
if (timeout != 0) {
- Task.Run(() =>
+ _ = Task.Run(() =>
{
var connectTimer = new System.Diagnostics.Stopwatch();
connectTimer.Start();
diff --git a/QtVsTools.Package/QML/Debugging/V4/QmlDebugV4Protocol.cs b/QtVsTools.Package/QML/Debugging/V4/QmlDebugV4Protocol.cs
index 07315df..a6bc303 100644
--- a/QtVsTools.Package/QML/Debugging/V4/QmlDebugV4Protocol.cs
+++ b/QtVsTools.Package/QML/Debugging/V4/QmlDebugV4Protocol.cs
@@ -53,10 +53,10 @@
IMessageEventSink sink;
DebugClient client;
int nextRequestSeq = 0;
- Dictionary<int, PendingRequest> pendingRequests = new Dictionary<int, PendingRequest>();
+ readonly Dictionary<int, PendingRequest> pendingRequests = new Dictionary<int, PendingRequest>();
Task eventHandlingThread;
- EventWaitHandle eventReceived = new EventWaitHandle(false, EventResetMode.AutoReset);
- ConcurrentQueue<Event> eventQueue = new ConcurrentQueue<Event>();
+ readonly EventWaitHandle eventReceived = new EventWaitHandle(false, EventResetMode.AutoReset);
+ readonly ConcurrentQueue<Event> eventQueue = new ConcurrentQueue<Event>();
public uint? ThreadId { get { return client.ThreadId; } }
@@ -92,7 +92,8 @@
protected override void DisposeFinally()
{
eventReceived.Set();
- eventHandlingThread.Wait();
+ QtVsToolsPackage.Instance.JoinableTaskFactory.Run(
+ async () => await Task.WhenAll(new[] { eventHandlingThread }));
eventReceived.Dispose();
}
@@ -100,8 +101,7 @@
{
while (!Disposing) {
eventReceived.WaitOne();
- Event evt;
- while (!Disposing && eventQueue.TryDequeue(out evt))
+ while (!Disposing && eventQueue.TryDequeue(out Event evt))
sink.NotifyEvent(evt);
}
}
@@ -209,8 +209,8 @@
public class PendingRequest : Finalizable
{
- public Request Request { get; private set; }
- EventWaitHandle responded;
+ public Request Request { get; }
+ readonly EventWaitHandle responded;
public PendingRequest()
{
diff --git a/QtVsTools.Package/QML/Parser/QmlParserDiagnostics.cs b/QtVsTools.Package/QML/Parser/QmlParserDiagnostics.cs
index 484dc03..929bb80 100644
--- a/QtVsTools.Package/QML/Parser/QmlParserDiagnostics.cs
+++ b/QtVsTools.Package/QML/Parser/QmlParserDiagnostics.cs
@@ -37,8 +37,8 @@
/// </summary>
public class DiagnosticMessage
{
- public DiagnosticMessageKind Kind { get; set; }
- public SourceLocation Location { get; set; }
+ private DiagnosticMessageKind Kind { get; }
+ public SourceLocation Location { get; }
public DiagnosticMessage(DiagnosticMessageKind kind, int offset, int length)
{
Kind = kind;
diff --git a/QtVsTools.Package/QML/Parser/QmlParserInterop.cs b/QtVsTools.Package/QML/Parser/QmlParserInterop.cs
index 8ff5d87..d9965f2 100644
--- a/QtVsTools.Package/QML/Parser/QmlParserInterop.cs
+++ b/QtVsTools.Package/QML/Parser/QmlParserInterop.cs
@@ -148,28 +148,27 @@
IntPtr qmlTextPtr = IntPtr.Zero;
IntPtr qmlParserPtr = IntPtr.Zero;
-
- List<Token> tokens;
+ readonly List<Token> tokens;
public IEnumerable<Token> Tokens
{
get { return tokens; }
}
- List<DiagnosticMessage> diagnosticMessages;
+ readonly List<DiagnosticMessage> diagnosticMessages;
public IEnumerable<DiagnosticMessage> DiagnosticMessages
{
get { return diagnosticMessages; }
}
- public int FirstErrorOffset { get; private set; }
+ private int FirstErrorOffset { get; set; }
- List<AstNode> visitedNodes;
+ readonly List<AstNode> visitedNodes;
public IEnumerable<AstNode> AstNodes { get { return visitedNodes; } }
public bool ParsedCorrectly { get; private set; }
- Dictionary<IntPtr, AstNode> nodesBytPtr;
- Dictionary<IntPtr, List<KeyValuePair<AstNode, PropertyInfo>>> pendingDereferences;
+ readonly Dictionary<IntPtr, AstNode> nodesBytPtr;
+ readonly Dictionary<IntPtr, List<KeyValuePair<AstNode, PropertyInfo>>> pendingDereferences;
Parser()
{
@@ -315,8 +314,7 @@
if (ptrRef == IntPtr.Zero)
return;
- AstNode nodeRef;
- if (nodesBytPtr.TryGetValue(ptrRef, out nodeRef)) {
+ if (nodesBytPtr.TryGetValue(ptrRef, out AstNode nodeRef)) {
nodeProperty.SetValue(node, nodeRef);
} else {
List<KeyValuePair<AstNode, PropertyInfo>> pendingRefList;
diff --git a/QtVsTools.Package/QML/Syntax/QmlAst.cs b/QtVsTools.Package/QML/Syntax/QmlAst.cs
index 1b3b1d1..a5e5ff4 100644
--- a/QtVsTools.Package/QML/Syntax/QmlAst.cs
+++ b/QtVsTools.Package/QML/Syntax/QmlAst.cs
@@ -156,7 +156,7 @@
public class AstNode : SyntaxElement
{
- public AstNodeKind Kind { get; private set; }
+ public AstNodeKind Kind { get; }
public AstNode(AstNodeKind kind) { Kind = kind; }
public SourceLocation FirstSourceLocation { get; set; }
public SourceLocation LastSourceLocation { get; set; }
diff --git a/QtVsTools.Package/QML/Syntax/QmlSyntax.cs b/QtVsTools.Package/QML/Syntax/QmlSyntax.cs
index 1035815..0e5ac06 100644
--- a/QtVsTools.Package/QML/Syntax/QmlSyntax.cs
+++ b/QtVsTools.Package/QML/Syntax/QmlSyntax.cs
@@ -192,7 +192,7 @@
/// </summary>
public class Token : SyntaxElement
{
- public TokenKind Kind { get; private set; }
+ private TokenKind Kind { get; set; }
public SourceLocation Location { get; private set; }
protected Token() { }
public static Token Create(TokenKind kind, int offset, int length)
diff --git a/QtVsTools.Package/QtMenus.vsct_TT b/QtVsTools.Package/QtMenus.vsct_TT
index 76d066f..2f7f7d8 100644
--- a/QtVsTools.Package/QtMenus.vsct_TT
+++ b/QtVsTools.Package/QtMenus.vsct_TT
@@ -2,7 +2,7 @@
<!--
*****************************************************************************
**
- ** Copyright (C) 2016 The Qt Company Ltd.
+ ** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -152,15 +152,8 @@
<Group guid="ProjectContextMenuGuid" id="ProjectContextOthersMenuGroup" priority="0x0600">
<Parent guid="ProjectContextMenuGuid" id="QtProjectSubMenu"/>
</Group>
- <Group guid="ProjectContextMenuGuid" id="ProjectContextAddNewQtClassMenuGroup" priority="0x0600">
- <Parent guid="guidSHLMainMenu" id="cmdidShellWindowNavigate7"/>
- </Group>
<!-- Endregion Project context menu groups -->
-
- <Group guid="ProjectContextMenuGuid" id="ProjectContextAddNewQtClassMenuGroup" priority="0x0600">
- <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_PROJECT" />
- </Group>
<Group guid="ItemContextMenuGuid" id="ItemContextTsMenuGroup" priority="0x0600">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE" />
@@ -209,6 +202,15 @@
<ButtonText>qt.io</ButtonText>
</Strings>
</Button>
+ <Button guid="MainMenuGuid" id="ViewGettingStartedId" priority="0x0100" type="Button">
+ <Parent guid="MainMenuGuid" id="VersionMenuGroup" />
+ <Icon guid="MenuImages" id="QtLogoBitmap" />
+ <CommandFlag>DynamicVisibility</CommandFlag>
+ <CommandFlag>DefaultInvisible</CommandFlag>
+ <Strings>
+ <ButtonText>Getting Started</ButtonText>
+ </Strings>
+ </Button>
<Button guid="MainMenuGuid" id="F1QtHelpId" priority="0x0100" type="Button">
<Parent guid="MainMenuGuid" id="VersionMenuGroup" />
@@ -285,16 +287,6 @@
</Strings>
</Button>
- <Button guid="MainMenuGuid" id="CreateNewTsFileId" priority="0x0100" type="Button">
- <Parent guid="MainMenuGuid" id="OthersMenuGroup" />
- <CommandFlag>DefaultDisabled</CommandFlag>
- <CommandFlag>DynamicVisibility</CommandFlag>
- <CommandFlag>DefaultInvisible</CommandFlag>
- <Strings>
- <ButtonText>Create New Translation File</ButtonText>
- <ToolTipText>Create a new translation file that you can open in Qt Linguist</ToolTipText>
- </Strings>
- </Button>
<Button guid="MainMenuGuid" id="ConvertToQtMsBuild" priority="0x0100" type="Button">
<Parent guid="MainMenuGuid" id="OthersMenuGroup" />
<CommandFlag>DefaultDisabled</CommandFlag>
@@ -302,24 +294,6 @@
<CommandFlag>DynamicVisibility</CommandFlag>
<Strings>
<ButtonText>Convert custom build steps to Qt/MSBuild</ButtonText>
- </Strings>
- </Button>
- <Button guid="MainMenuGuid" id="ConvertToQtId" priority="0x0100" type="Button">
- <Parent guid="MainMenuGuid" id="OthersMenuGroup" />
- <CommandFlag>DefaultDisabled</CommandFlag>
- <CommandFlag>DefaultInvisible</CommandFlag>
- <CommandFlag>DynamicVisibility</CommandFlag>
- <Strings>
- <ButtonText>Convert Project to Qt VS Tools Project</ButtonText>
- </Strings>
- </Button>
- <Button guid="MainMenuGuid" id="ConvertToQmakeId" priority="0x0100" type="Button">
- <Parent guid="MainMenuGuid" id="OthersMenuGroup" />
- <CommandFlag>DefaultDisabled</CommandFlag>
- <CommandFlag>DynamicVisibility</CommandFlag>
- <CommandFlag>DefaultInvisible</CommandFlag>
- <Strings>
- <ButtonText>Convert Project to QMake Generated Project</ButtonText>
</Strings>
</Button>
<Button guid="MainMenuGuid" id="QtProjectSettingsId" priority="0x0100" type="Button">
@@ -451,15 +425,6 @@
</Strings>
</Button>
- <Button guid="ProjectContextMenuGuid" id="CreateNewTsFileProjectId" priority="0x0100" type="Button">
- <Parent guid="ProjectContextMenuGuid" id="ProjectContextTsMenuGroup" />
- <CommandFlag>DefaultDisabled</CommandFlag>
- <CommandFlag>DynamicVisibility</CommandFlag>
- <Strings>
- <ButtonText>Create New Translation File</ButtonText>
- <ToolTipText>Create a new translation file that you can open in Qt Linguist</ToolTipText>
- </Strings>
- </Button>
<Button guid="ProjectContextMenuGuid" id="lUpdateOnProjectId" priority="0x0100" type="Button">
<Parent guid="ProjectContextMenuGuid" id="ProjectContextTsMenuGroup" />
<Icon guid="MenuImages" id="LaunchLinguistBitmap" />
@@ -499,23 +464,6 @@
<ButtonText>Refresh IntelliSense</ButtonText>
</Strings>
</Button>
- <Button guid="ProjectContextMenuGuid" id="ConvertToQtProjectId" priority="0x0100" type="Button">
- <Parent guid="ProjectContextMenuGuid" id="ProjectContextOthersMenuGroup" />
- <CommandFlag>DefaultDisabled</CommandFlag>
- <CommandFlag>DefaultInvisible</CommandFlag>
- <CommandFlag>DynamicVisibility</CommandFlag>
- <Strings>
- <ButtonText>Convert Project to Qt VS Tools Project</ButtonText>
- </Strings>
- </Button>
- <Button guid="ProjectContextMenuGuid" id="ConvertToQmakeProjectId" priority="0x0100" type="Button">
- <Parent guid="ProjectContextMenuGuid" id="ProjectContextOthersMenuGroup" />
- <CommandFlag>DefaultDisabled</CommandFlag>
- <CommandFlag>DynamicVisibility</CommandFlag>
- <Strings>
- <ButtonText>Convert Project to QMake Generated Project</ButtonText>
- </Strings>
- </Button>
<Button guid="ProjectContextMenuGuid" id="QtProjectSettingsProjectId" priority="0x0100" type="Button">
<Parent guid="ProjectContextMenuGuid" id="ProjectContextOthersMenuGroup" />
<CommandFlag>DefaultDisabled</CommandFlag>
@@ -532,16 +480,6 @@
<CommandFlag>DynamicVisibility</CommandFlag>
<Strings>
<ButtonText>Change Project's Qt Version</ButtonText>
- </Strings>
- </Button>
- <Button guid="ProjectContextMenuGuid" id="ProjectAddNewQtClassProjectId" priority="0x0100" type="Button">
- <Parent guid="ProjectContextMenuGuid" id="ProjectContextAddNewQtClassMenuGroup" />
- <Icon guid="MenuImages" id="AddNewQtClassBitmap" />
- <CommandFlag>DefaultDisabled</CommandFlag>
- <CommandFlag>DefaultInvisible</CommandFlag>
- <CommandFlag>DynamicVisibility</CommandFlag>
- <Strings>
- <ButtonText>Add Qt Class...</ButtonText>
</Strings>
</Button>
@@ -586,7 +524,7 @@
-->
<Bitmap guid="MenuImages" href="Resources\menuimages.png" usedList="LaunchDesignerBitmap,
LaunchLinguistBitmap, OpenProFileBitmap, ImportPriFileBitmap, ExportProFileBitmap,
- CreateProFileBitmap, QtLogoBitmap, AddNewQtClassBitmap" />
+ CreateProFileBitmap, QtLogoBitmap" />
</Bitmaps>
</Commands>
@@ -605,6 +543,7 @@
<IDSymbol name="QtVersionId" value="0x0500" />
<IDSymbol name="ViewQtHelpId" value="0x0501" />
<IDSymbol name="F1QtHelpId" value="0x0502" />
+ <IDSymbol name="ViewGettingStartedId" value="0x0503" />
<IDSymbol name="LaunchMenuGroup" value="0x1021" />
<IDSymbol name="LaunchDesignerId" value="0x0100" />
@@ -617,10 +556,7 @@
<IDSymbol name="ExportProFileId" value="0x0105" />
<IDSymbol name="OthersMenuGroup" value="0x1023" />
- <IDSymbol name="CreateNewTsFileId" value="0x0107" />
<IDSymbol name="ConvertToQtMsBuild" value="0x0130" />
- <IDSymbol name="ConvertToQtId" value="0x0124" />
- <IDSymbol name="ConvertToQmakeId" value="0x0108" />
<IDSymbol name="QtProjectSettingsId" value="0x0109" />
<IDSymbol name="ChangeProjectQtVersionId" value="0x0126" />
@@ -665,20 +601,16 @@
<IDSymbol name="ExportProFileProjectId" value="0x0116" />
<IDSymbol name="ProjectContextTsMenuGroup" value="0x1028" />
- <IDSymbol name="CreateNewTsFileProjectId" value="0x0117" />
<IDSymbol name="lUpdateOnProjectId" value="0x0118" />
<IDSymbol name="lReleaseOnProjectId" value="0x0119" />
<IDSymbol name="ProjectContextOthersMenuGroup" value="0x1029" />
<IDSymbol name="ProjectConvertToQtMsBuild" value="0x0130" />
<IDSymbol name="ProjectRefreshIntelliSense" value="0x0131" />
- <IDSymbol name="ConvertToQtProjectId" value="0x0120" />
- <IDSymbol name="ConvertToQmakeProjectId" value="0x0121" />
<IDSymbol name="QtProjectSettingsProjectId" value="0x0122" />
<IDSymbol name="ChangeProjectQtVersionProjectId" value="0x0123" />
<IDSymbol name="ProjectContextAddNewQtClassMenuGroup" value="0x1031" />
- <IDSymbol name="ProjectAddNewQtClassProjectId" value="0x0200" />
<!-- Endregion Project context menu button Ids -->
@@ -700,7 +632,6 @@
<IDSymbol name="ExportProFileBitmap" value="5" />
<IDSymbol name="CreateProFileBitmap" value="6" />
<IDSymbol name="QtLogoBitmap" value="7" />
- <IDSymbol name="AddNewQtClassBitmap" value="8" />
</GuidSymbol>
</Symbols>
diff --git a/QtVsTools.Package/QtMsBuild/QtModulesEditor.cs b/QtVsTools.Package/QtMsBuild/QtModulesEditor.cs
index 8fbd145..e05e4ce 100644
--- a/QtVsTools.Package/QtMsBuild/QtModulesEditor.cs
+++ b/QtVsTools.Package/QtMsBuild/QtModulesEditor.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -28,15 +28,15 @@
using Microsoft.VisualStudio.ProjectSystem;
using Microsoft.VisualStudio.ProjectSystem.Properties;
-using Microsoft.Internal.VisualStudio.PlatformUI;
using System;
+using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Threading.Tasks;
namespace QtVsTools.QtMsBuild
{
- using QtVsTools.Core;
+ using Core;
[Export(typeof(IPropertyPageUIValueEditor))]
[ExportMetadata("Name", "QtModulesEditor")]
@@ -50,7 +50,15 @@
{
await Task.Yield();
- var modules = QtModules.Instance.GetAvailableModules()
+ var qtSettings = ruleProperty.ContainingRule;
+ var qtVersion = await qtSettings.GetPropertyValueAsync("QtInstall");
+
+ var vm = QtVersionManager.The();
+ var versionInfo = vm.GetVersionInfo(qtVersion);
+ if (versionInfo == null)
+ versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
+
+ var modules = QtModules.Instance.GetAvailableModules(versionInfo.qtMajor)
.Where(x => !string.IsNullOrEmpty(x.proVarQT))
.Select(x => new QtModulesPopup.Module
{
@@ -61,24 +69,28 @@
})
.ToList();
- var allQT = modules.SelectMany(x => x.QT).ToHashSet();
- var selectedQT = currentValue.ToString().Split(';').ToHashSet();
- var extraQT = selectedQT.Except(allQT);
+ HashSet<string> selectedQt = null;
+ IEnumerable<string> extraQt = null;
+ if (currentValue != null) {
+ var allQt = modules.SelectMany(x => x.QT).ToHashSet();
+ selectedQt = currentValue.ToString().Split(';').ToHashSet();
+ extraQt = selectedQt.Except(allQt);
- foreach (var module in modules)
- module.IsSelected = module.QT.Intersect(selectedQT).Count() == module.QT.Count;
+ foreach (var module in modules)
+ module.IsSelected = module.QT.Intersect(selectedQt).Count() == module.QT.Count;
+ }
var popup = new QtModulesPopup();
- popup.SetModules(modules);
+ popup.SetModules(modules.OrderBy(module => module.Name));
if (popup.ShowModal().GetValueOrDefault()) {
- selectedQT = modules
+ selectedQt = modules
.Where(x => x.IsSelected)
.SelectMany(x => x.QT)
- .Union(extraQT)
+ .Union(extraQt ?? Enumerable.Empty<string>())
.ToHashSet();
}
- return string.Join(";", selectedQT);
+ return selectedQt == null ? "" : string.Join(";", selectedQt);
}
}
}
diff --git a/QtVsTools.Package/QtMsBuild/QtModulesPopup.xaml b/QtVsTools.Package/QtMsBuild/QtModulesPopup.xaml
index 54e13a7..fd22f7b 100644
--- a/QtVsTools.Package/QtMsBuild/QtModulesPopup.xaml
+++ b/QtVsTools.Package/QtMsBuild/QtModulesPopup.xaml
@@ -1,7 +1,7 @@
<!--
*****************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -27,10 +27,10 @@
**
*****************************************************************************
-->
-<local:VsToolsDialogWindow x:Class="QtVsTools.QtMsBuild.QtModulesPopup"
+<vsui:DialogWindow x:Class="QtVsTools.QtMsBuild.QtModulesPopup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:local="clr-namespace:QtVsTools"
+ xmlns:vsui="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0"
ResizeMode="CanResize"
Width="800" MaxHeight="550"
MouseDown="Window_MouseDown"
@@ -108,4 +108,4 @@
<Button IsCancel="True" MinHeight="23" MinWidth="74">_Cancel</Button>
</WrapPanel>
</Grid>
-</local:VsToolsDialogWindow>
+</vsui:DialogWindow>
diff --git a/QtVsTools.Package/QtMsBuild/QtModulesPopup.xaml.cs b/QtVsTools.Package/QtMsBuild/QtModulesPopup.xaml.cs
index 19d045b..ba20831 100644
--- a/QtVsTools.Package/QtMsBuild/QtModulesPopup.xaml.cs
+++ b/QtVsTools.Package/QtMsBuild/QtModulesPopup.xaml.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -30,10 +30,11 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
+using Microsoft.VisualStudio.PlatformUI;
namespace QtVsTools.QtMsBuild
{
- public partial class QtModulesPopup : VsToolsDialogWindow
+ public partial class QtModulesPopup : DialogWindow
{
public class Module
{
@@ -81,8 +82,7 @@
private void PopupListBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter || e.Key == Key.Space) {
- var module = PopupListBox.SelectedItem as Module;
- if (module != null && module.IsEnabled)
+ if (PopupListBox.SelectedItem is Module module && module.IsEnabled)
module.CheckBox.IsChecked = (module.CheckBox.IsChecked != true);
}
}
diff --git a/QtVsTools.Package/QtMsBuild/QtProjectBuild.cs b/QtVsTools.Package/QtMsBuild/QtProjectBuild.cs
index f2fea0b..44023ee 100644
--- a/QtVsTools.Package/QtMsBuild/QtProjectBuild.cs
+++ b/QtVsTools.Package/QtMsBuild/QtProjectBuild.cs
@@ -40,36 +40,42 @@
using Microsoft.VisualStudio.TaskStatusCenter;
using Microsoft.VisualStudio.Threading;
using Microsoft.VisualStudio.VCProjectEngine;
-using EnvDTE;
+
+using Thread = System.Threading.Thread;
namespace QtVsTools.QtMsBuild
{
+ using Common;
using Core;
using VisualStudio;
- using Thread = System.Threading.Thread;
+ using static Common.EnumExt;
class QtProjectBuild : Concurrent<QtProjectBuild>
{
- static PunisherQueue<QtProjectBuild> _BuildQueue;
- static PunisherQueue<QtProjectBuild> BuildQueue =>
- StaticThreadSafeInit(() => _BuildQueue,
- () => _BuildQueue = new PunisherQueue<QtProjectBuild>(
- getItemKey: (QtProjectBuild build) =>
- {
- return build.ConfiguredProject;
- })
- );
+ static LazyFactory StaticLazy { get; } = new LazyFactory();
- static ConcurrentStopwatch _RequestTimer;
- static ConcurrentStopwatch RequestTimer =>
- StaticThreadSafeInit(() => _RequestTimer, () => _RequestTimer = new ConcurrentStopwatch());
+ public enum Target
+ {
+ // Mark project as dirty, but do not request a build
+ [String("QtVsTools.QtMsBuild.QtProjectBuild.Target.SetOutdated")] SetOutdated
+ }
- static IVsTaskStatusCenterService _StatusCenter;
- static IVsTaskStatusCenterService StatusCenter => StaticThreadSafeInit(() => _StatusCenter,
- () => _StatusCenter = VsServiceProvider
- .GetService<SVsTaskStatusCenterService, IVsTaskStatusCenterService>());
+ static PunisherQueue<QtProjectBuild> BuildQueue => StaticLazy.Get(() =>
+ BuildQueue, () => new PunisherQueue<QtProjectBuild>(
+ getItemKey: (QtProjectBuild build) =>
+ {
+ return build.ConfiguredProject;
+ }));
+
+ static ConcurrentStopwatch RequestTimer => StaticLazy.Get(() =>
+ RequestTimer, () => new ConcurrentStopwatch());
+
+ static IVsTaskStatusCenterService StatusCenter => StaticLazy.Get(() =>
+ StatusCenter, () => VsServiceProvider
+ .GetService<SVsTaskStatusCenterService, IVsTaskStatusCenterService>());
EnvDTE.Project Project { get; set; }
+ VCProject VcProject { get; set; }
UnconfiguredProject UnconfiguredProject { get; set; }
ConfiguredProject ConfiguredProject { get; set; }
Dictionary<string, string> Properties { get; set; }
@@ -80,6 +86,7 @@
public static void StartBuild(
EnvDTE.Project project,
+ string projectPath,
string configName,
Dictionary<string, string> properties,
IEnumerable<string> targets,
@@ -90,11 +97,13 @@
if (configName == null)
throw new ArgumentException("Configuration name cannot be null.");
- Task.Run(() => StartBuildAsync(project, configName, properties, targets, verbosity));
+ _ = Task.Run(() => StartBuildAsync(
+ project, projectPath, configName, properties, targets, verbosity));
}
public static async Task StartBuildAsync(
EnvDTE.Project project,
+ string projectPath,
string configName,
Dictionary<string, string> properties,
IEnumerable<string> targets,
@@ -106,15 +115,15 @@
throw new ArgumentException("Configuration name cannot be null.");
RequestTimer.Restart();
+ var tracker = QtProjectTracker.Get(project, projectPath);
+ await tracker.Initialized;
+
if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
Messages.Print(string.Format(
"{0:HH:mm:ss.FFF} QtProjectBuild({1}): Request [{2}] {3}",
DateTime.Now, Thread.CurrentThread.ManagedThreadId,
- configName, project.FullName));
+ configName, tracker.UnconfiguredProject.FullPath));
}
-
- var tracker = QtProjectTracker.Get(project);
- await tracker.Initialized;
var knownConfigs = await tracker.UnconfiguredProject.Services
.ProjectConfigurationsService.GetKnownProjectConfigurationsAsync();
@@ -134,6 +143,7 @@
BuildQueue.Enqueue(new QtProjectBuild()
{
Project = project,
+ VcProject = tracker.VcProject,
UnconfiguredProject = tracker.UnconfiguredProject,
ConfiguredProject = configuredProject,
Properties = properties?.ToDictionary(x => x.Key, x => x.Value),
@@ -143,6 +153,35 @@
StaticThreadSafeInit(() => BuildDispatcher,
() => BuildDispatcher = Task.Run(BuildDispatcherLoopAsync))
.Forget();
+ }
+
+ public static void SetOutdated(
+ EnvDTE.Project project,
+ string projectPath,
+ string configName,
+ LoggerVerbosity verbosity = LoggerVerbosity.Quiet)
+ {
+ if (project == null)
+ throw new ArgumentException("Project cannot be null.");
+ if (configName == null)
+ throw new ArgumentException("Configuration name cannot be null.");
+
+ _ = Task.Run(() => SetOutdatedAsync(project, projectPath, configName, verbosity));
+ }
+
+ public static async Task SetOutdatedAsync(
+ EnvDTE.Project project,
+ string projectPath,
+ string configName,
+ LoggerVerbosity verbosity = LoggerVerbosity.Quiet)
+ {
+ await StartBuildAsync(
+ project,
+ projectPath,
+ configName,
+ null,
+ new[] { Target.SetOutdated.Cast<string>() },
+ verbosity);
}
public static void Reset()
@@ -161,8 +200,7 @@
}
await Task.Delay(100);
}
- QtProjectBuild buildRequest;
- if (BuildQueue.TryDequeue(out buildRequest)) {
+ if (BuildQueue.TryDequeue(out QtProjectBuild buildRequest)) {
if (dispatchStatus == null) {
dispatchStatus = StatusCenter.PreRegister(
new TaskHandlerOptions
@@ -202,6 +240,140 @@
}
}
+ async Task<bool> BuildProjectAsync(ProjectWriteLockReleaser writeAccess)
+ {
+ var msBuildProject = await writeAccess.GetProjectAsync(ConfiguredProject);
+
+ if (Targets.Any(t => t == Target.SetOutdated.Cast<string>())) {
+ msBuildProject.MarkDirty();
+ await writeAccess.ReleaseAsync();
+ return true;
+ }
+
+ var solutionPath = QtProjectTracker.SolutionPath;
+ var configProps = new Dictionary<string, string>(
+ ConfiguredProject.ProjectConfiguration.Dimensions.ToImmutableDictionary())
+ {
+ { "SolutionPath", solutionPath },
+ { "SolutionFileName", Path.GetFileName(solutionPath) },
+ { "SolutionName", Path.GetFileNameWithoutExtension(solutionPath) },
+ { "SolutionExt", Path.GetExtension(solutionPath) },
+ { "SolutionDir", Path.GetDirectoryName(solutionPath).TrimEnd('\\') + '\\' }
+ };
+
+ foreach (var property in Properties)
+ configProps[property.Key] = property.Value;
+
+ var projectInstance = new ProjectInstance(msBuildProject.Xml,
+ configProps, null, new ProjectCollection());
+
+ var loggerVerbosity = LoggerVerbosity;
+ if (QtVsToolsPackage.Instance.Options.BuildDebugInformation)
+ loggerVerbosity = QtVsToolsPackage.Instance.Options.BuildLoggerVerbosity;
+ var buildParams = new BuildParameters()
+ {
+ Loggers = (loggerVerbosity != LoggerVerbosity.Quiet)
+ ? new[] { new QtProjectLogger() { Verbosity = loggerVerbosity } }
+ : null
+ };
+
+ var buildRequest = new BuildRequestData(projectInstance,
+ Targets.ToArray(),
+ hostServices: null,
+ flags: BuildRequestDataFlags.ProvideProjectStateAfterBuild);
+
+ if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
+ Messages.Print(string.Format(
+ "{0:HH:mm:ss.FFF} QtProjectBuild({1}): Build [{2}] {3}",
+ DateTime.Now, Thread.CurrentThread.ManagedThreadId,
+ ConfiguredProject.ProjectConfiguration.Name,
+ UnconfiguredProject.FullPath));
+ Messages.Print("=== Targets");
+ foreach (var target in buildRequest.TargetNames)
+ Messages.Print(string.Format(" {0}", target));
+ Messages.Print("=== Properties");
+ foreach (var property in Properties) {
+ Messages.Print(string.Format(" {0}={1}",
+ property.Key, property.Value));
+ }
+ }
+
+ BuildResult result = null;
+ while (result == null) {
+ try {
+ result = BuildManager.DefaultBuildManager.Build(
+ buildParams, buildRequest);
+ } catch (InvalidOperationException) {
+ if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
+ Messages.Print(string.Format(
+ "{0:HH:mm:ss.FFF} QtProjectBuild({1}): [{2}] "
+ + "Warning: Another build is in progress; waiting...",
+ DateTime.Now,
+ Thread.CurrentThread.ManagedThreadId,
+ ConfiguredProject.ProjectConfiguration.Name));
+ }
+ await Task.Delay(3000);
+ }
+ }
+
+ if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
+ string resMsg;
+ StringBuilder resInfo = new StringBuilder();
+ if (result?.OverallResult == BuildResultCode.Success) {
+ resMsg = "Build ok";
+ } else {
+ resMsg = "Build FAIL";
+ if (result == null) {
+ resInfo.AppendLine("####### Build returned 'null'");
+ } else {
+ resInfo.AppendLine("####### Build returned 'Failure' code");
+ if (result.ResultsByTarget != null) {
+ foreach (var tr in result.ResultsByTarget) {
+ var res = tr.Value;
+ if (res.ResultCode != TargetResultCode.Failure)
+ continue;
+ resInfo.AppendFormat("### Target '{0}' FAIL\r\n", tr.Key);
+ if (res.Items != null && res.Items.Length > 0) {
+ resInfo.AppendFormat(
+ "Items: {0}\r\n", string.Join(", ", res.Items
+ .Select(it => it.ItemSpec)));
+ }
+ var e = tr.Value?.Exception;
+ if (e != null) {
+ resInfo.AppendFormat(
+ "Exception: {0}\r\nStacktrace:\r\n{1}\r\n",
+ e.Message, e.StackTrace);
+ }
+ }
+ }
+ }
+ }
+ Messages.Print(string.Format(
+ "{0:HH:mm:ss.FFF} QtProjectBuild({1}): [{2}] {3}\r\n{4}",
+ DateTime.Now, Thread.CurrentThread.ManagedThreadId,
+ ConfiguredProject.ProjectConfiguration.Name,
+ resMsg, resInfo.ToString()));
+ }
+
+ bool ok = false;
+ if (result == null
+ || result.ResultsByTarget == null
+ || result.OverallResult != BuildResultCode.Success) {
+ Messages.Print(string.Format("{0}: background build FAILED!",
+ Path.GetFileName(UnconfiguredProject.FullPath)));
+ } else {
+ var checkResults = result.ResultsByTarget
+ .Where(x => Targets.Contains(x.Key))
+ .Select(x => x.Value);
+ ok = checkResults.Any()
+ && checkResults.All(x => x.ResultCode == TargetResultCode.Success);
+ if (ok)
+ msBuildProject.MarkDirty();
+ }
+ await writeAccess.ReleaseAsync();
+ return ok;
+ }
+
async Task BuildAsync()
{
if (LoggerVerbosity != LoggerVerbosity.Quiet) {
@@ -211,7 +383,7 @@
* Properties: {1}
* Targets: {2}
",
- /*{0}*/ Project.Name,
+ /*{0}*/ Path.GetFileNameWithoutExtension(UnconfiguredProject.FullPath),
/*{1}*/ string.Join("", Properties
.Select(property => string.Format(@"
{0} = {1}", /*{0}*/ property.Key, /*{1}*/ property.Value))),
@@ -222,151 +394,41 @@
bool ok = false;
try {
- ProjectWriteLockReleaser writeAccess;
var timer = ConcurrentStopwatch.StartNew();
while (timer.IsRunning) {
try {
- writeAccess = await lockService.WriteLockAsync();
+#if VS2017
+ using (var writeAccess = await lockService.WriteLockAsync())
+ ok = await BuildProjectAsync(writeAccess);
+#else
+ await lockService.WriteLockAsync(
+ async (ProjectWriteLockReleaser writeAccess) =>
+ {
+ ok = await BuildProjectAsync(writeAccess);
+ });
+#endif
timer.Stop();
} catch (InvalidOperationException) {
if (timer.ElapsedMilliseconds >= 5000)
throw;
+#if VS2017
using (var readAccess = await lockService.ReadLockAsync())
await readAccess.ReleaseAsync();
+#else
+ await lockService.ReadLockAsync(
+ async (ProjectLockReleaser readAccess) =>
+ {
+ await readAccess.ReleaseAsync();
+ });
+#endif
}
- }
-
- using (writeAccess) {
- var msBuildProject = await writeAccess.GetProjectAsync(ConfiguredProject);
-
- var solutionPath = QtProjectTracker.SolutionPath;
- var configProps = new Dictionary<string, string>(
- ConfiguredProject.ProjectConfiguration.Dimensions.ToImmutableDictionary())
- {
- { "SolutionPath", solutionPath },
- { "SolutionFileName", Path.GetFileName(solutionPath) },
- { "SolutionName", Path.GetFileNameWithoutExtension(solutionPath) },
- { "SolutionExt", Path.GetExtension(solutionPath) },
- { "SolutionDir", Path.GetDirectoryName(solutionPath).TrimEnd('\\') + '\\' }
- };
-
- foreach (var property in Properties)
- configProps[property.Key] = property.Value;
-
- var projectInstance = new ProjectInstance(msBuildProject.Xml,
- configProps, null, new ProjectCollection());
-
- var loggerVerbosity = LoggerVerbosity;
- if (QtVsToolsPackage.Instance.Options.BuildDebugInformation)
- loggerVerbosity = QtVsToolsPackage.Instance.Options.BuildLoggerVerbosity;
- var buildParams = new BuildParameters()
- {
- Loggers = (loggerVerbosity != LoggerVerbosity.Quiet)
- ? new[] { new QtProjectLogger() { Verbosity = loggerVerbosity } }
- : null
- };
-
- var buildRequest = new BuildRequestData(projectInstance,
- Targets.ToArray(),
- hostServices: null,
- flags: BuildRequestDataFlags.ProvideProjectStateAfterBuild);
-
- if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
- Messages.Print(string.Format(
- "{0:HH:mm:ss.FFF} QtProjectBuild({1}): Build [{2}] {3}",
- DateTime.Now, Thread.CurrentThread.ManagedThreadId,
- ConfiguredProject.ProjectConfiguration.Name,
- UnconfiguredProject.FullPath));
- Messages.Print("=== Targets");
- foreach (var target in buildRequest.TargetNames)
- Messages.Print(string.Format(" {0}", target));
- Messages.Print("=== Properties");
- foreach (var property in Properties) {
- Messages.Print(string.Format(" {0}={1}",
- property.Key, property.Value));
- }
- }
-
- BuildResult result = null;
- while (result == null) {
- try {
- result = BuildManager.DefaultBuildManager.Build(
- buildParams, buildRequest);
- } catch (InvalidOperationException) {
- if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
- Messages.Print(string.Format(
- "{0:HH:mm:ss.FFF} QtProjectBuild({1}): [{2}] "
- + "Warning: Another build is in progress; waiting...",
- DateTime.Now,
- Thread.CurrentThread.ManagedThreadId,
- ConfiguredProject.ProjectConfiguration.Name));
- }
- await Task.Delay(3000);
- }
- }
-
- if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
- string resMsg;
- StringBuilder resInfo = new StringBuilder();
- if (result?.OverallResult == BuildResultCode.Success) {
- resMsg = "Build ok";
- } else {
- resMsg = "Build FAIL";
- if (result == null) {
- resInfo.AppendLine("####### Build returned 'null'");
- } else {
- resInfo.AppendLine("####### Build returned 'Failure' code");
- if (result.ResultsByTarget != null) {
- foreach (var tr in result.ResultsByTarget) {
- var res = tr.Value;
- if (res.ResultCode != TargetResultCode.Failure)
- continue;
- resInfo.AppendFormat("### Target '{0}' FAIL\r\n", tr.Key);
- if (res.Items != null && res.Items.Length > 0) {
- resInfo.AppendFormat(
- "Items: {0}\r\n", string.Join(", ", res.Items
- .Select(it => it.ItemSpec)));
- }
- var e = tr.Value?.Exception;
- if (e != null) {
- resInfo.AppendFormat(
- "Exception: {0}\r\nStacktrace:\r\n{1}\r\n",
- e.Message, e.StackTrace);
- }
- }
- }
- }
- }
- Messages.Print(string.Format(
- "{0:HH:mm:ss.FFF} QtProjectBuild({1}): [{2}] {3}\r\n{4}",
- DateTime.Now, Thread.CurrentThread.ManagedThreadId,
- ConfiguredProject.ProjectConfiguration.Name,
- resMsg, resInfo.ToString()));
- }
-
- if (result == null
- || result.ResultsByTarget == null
- || result.OverallResult != BuildResultCode.Success) {
- Messages.Print(string.Format("{0}: background build FAILED!",
- Path.GetFileName(UnconfiguredProject.FullPath)));
- } else {
- var checkResults = result.ResultsByTarget
- .Where(x => Targets.Contains(x.Key))
- .Select(x => x.Value);
- ok = checkResults.Any()
- && checkResults.All(x => x.ResultCode == TargetResultCode.Success);
- if (ok)
- msBuildProject.MarkDirty();
- }
- await writeAccess.ReleaseAsync();
}
if (ok) {
- var vcProject = Project.Object as VCProject;
- var vcConfigs = vcProject.Configurations as IVCCollection;
+ var vcConfigs = VcProject.Configurations as IVCCollection;
var vcConfig = vcConfigs.Item(ConfiguredProject.ProjectConfiguration.Name) as VCConfiguration;
var props = vcConfig.Rules.Item("QtRule10_Settings") as IVCRulePropertyStorage;
- props.SetPropertyValue("QtLastBackgroundBuild", DateTime.UtcNow.ToString("o"));
+ props?.SetPropertyValue("QtLastBackgroundBuild", DateTime.UtcNow.ToString("o"));
}
} catch (Exception e) {
Messages.Print(string.Format("{0}: background build ERROR: {1}",
@@ -377,7 +439,8 @@
Messages.Print(string.Format(
@"
== {0}: build {1}",
- Project.Name, ok ? "successful" : "ERROR"));
+ Path.GetFileNameWithoutExtension(UnconfiguredProject.FullPath),
+ ok ? "successful" : "ERROR"));
}
}
}
diff --git a/QtVsTools.Package/QtMsBuild/QtProjectIntelliSense.cs b/QtVsTools.Package/QtMsBuild/QtProjectIntelliSense.cs
index 605763f..46ff9d4 100644
--- a/QtVsTools.Package/QtMsBuild/QtProjectIntelliSense.cs
+++ b/QtVsTools.Package/QtMsBuild/QtProjectIntelliSense.cs
@@ -31,12 +31,15 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Build.Framework;
+using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Threading;
+
+using Task = System.Threading.Tasks.Task;
+using Thread = System.Threading.Thread;
namespace QtVsTools.QtMsBuild
{
using Core;
- using Thread = System.Threading.Thread;
static class QtProjectIntellisense
{
@@ -45,25 +48,31 @@
string configId = null,
IEnumerable<string> selectedFiles = null)
{
- if (project == null || !QtProjectTracker.IsTracked(project))
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (project == null || !QtProjectTracker.IsTracked(project.FullName))
return;
+
if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
Messages.Print(string.Format(
"{0:HH:mm:ss.FFF} QtProjectIntellisense({1}): Refreshing: [{2}] {3}",
DateTime.Now, Thread.CurrentThread.ManagedThreadId,
(configId != null) ? configId : "(all configs)", project.FullName));
}
- Task.Run(() => RefreshAsync(project, configId, selectedFiles));
+ string projectPath = project.FullName;
+ _ = Task.Run(() => RefreshAsync(project, projectPath, configId, selectedFiles, false));
}
public static async Task RefreshAsync(
EnvDTE.Project project,
+ string projectPath,
string configId = null,
- IEnumerable<string> selectedFiles = null)
+ IEnumerable<string> selectedFiles = null,
+ bool refreshQtVars = false)
{
- if (project == null || !QtProjectTracker.IsTracked(project))
+ if (project == null || !QtProjectTracker.IsTracked(projectPath))
return;
- var tracker = QtProjectTracker.Get(project);
+ var tracker = QtProjectTracker.Get(project, projectPath);
await tracker.Initialized;
var properties = new Dictionary<string, string>();
@@ -84,9 +93,14 @@
}
foreach (var config in configs) {
- await QtProjectBuild.StartBuildAsync(
- project, config, properties, targets,
- LoggerVerbosity.Quiet);
+ if (refreshQtVars) {
+ await QtProjectBuild.StartBuildAsync(
+ project, projectPath, config, properties, targets,
+ LoggerVerbosity.Quiet);
+ } else {
+ await QtProjectBuild.SetOutdatedAsync(
+ project, projectPath, config, LoggerVerbosity.Quiet);
+ }
}
}
}
diff --git a/QtVsTools.Package/QtMsBuild/QtProjectTracker.cs b/QtVsTools.Package/QtMsBuild/QtProjectTracker.cs
index 66db5c7..1d8e719 100644
--- a/QtVsTools.Package/QtMsBuild/QtProjectTracker.cs
+++ b/QtVsTools.Package/QtMsBuild/QtProjectTracker.cs
@@ -29,41 +29,41 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
-using Microsoft.Build.Evaluation;
-using Microsoft.Build.Framework;
using Microsoft.VisualStudio.ProjectSystem;
using Microsoft.VisualStudio.ProjectSystem.Properties;
+using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.TaskStatusCenter;
using Microsoft.VisualStudio.Threading;
-using EnvDTE;
+using Microsoft.VisualStudio.VCProjectEngine;
+
+using Task = System.Threading.Tasks.Task;
namespace QtVsTools.QtMsBuild
{
+ using Common;
using Core;
using VisualStudio;
- using Thread = System.Threading.Thread;
+
using SubscriberAction = ActionBlock<IProjectVersionedValue<IProjectSubscriptionUpdate>>;
class QtProjectTracker : Concurrent<QtProjectTracker>
{
- static ConcurrentDictionary<string, QtProjectTracker> _Instances;
- static ConcurrentDictionary<string, QtProjectTracker> Instances =>
- StaticThreadSafeInit(() => _Instances, () =>
- _Instances = new ConcurrentDictionary<string, QtProjectTracker>());
+ static LazyFactory StaticLazy { get; } = new LazyFactory();
- static PunisherQueue<QtProjectTracker> _InitQueue;
- static PunisherQueue<QtProjectTracker> InitQueue =>
- StaticThreadSafeInit(() => _InitQueue, () =>
- _InitQueue = new PunisherQueue<QtProjectTracker>());
+ static ConcurrentDictionary<string, QtProjectTracker> Instances => StaticLazy.Get(() =>
+ Instances, () => new ConcurrentDictionary<string, QtProjectTracker>());
- static IVsTaskStatusCenterService _StatusCenter;
- static IVsTaskStatusCenterService StatusCenter => StaticThreadSafeInit(() => _StatusCenter,
- () => _StatusCenter = VsServiceProvider
- .GetService<SVsTaskStatusCenterService, IVsTaskStatusCenterService>());
+ static PunisherQueue<QtProjectTracker> InitQueue => StaticLazy.Get(() =>
+ InitQueue, () => new PunisherQueue<QtProjectTracker>());
+
+ static IVsTaskStatusCenterService StatusCenter => StaticLazy.Get(() =>
+ StatusCenter, () => VsServiceProvider
+ .GetService<SVsTaskStatusCenterService, IVsTaskStatusCenterService>());
static Task InitDispatcher { get; set; }
static ITaskHandler2 InitStatus { get; set; }
@@ -75,73 +75,37 @@
Initialized = new EventWaitHandle(false, EventResetMode.ManualReset);
}
- class Subscriber : IDisposable
- {
- public Subscriber(QtProjectTracker tracker, ConfiguredProject config)
- {
- Tracker = tracker;
- Config = config;
- Subscription = Config.Services.ProjectSubscription.JointRuleSource.SourceBlock
- .LinkTo(new SubscriberAction(ProjectUpdateAsync),
- ruleNames: new[]
- {
- "ClCompile",
- "QtRule10_Settings",
- "QtRule30_Moc",
- "QtRule40_Rcc",
- "QtRule60_Repc",
- "QtRule50_Uic",
- "QtRule_Translation",
- "QtRule70_Deploy",
- },
- initialDataAsNew: false
- );
- }
-
- QtProjectTracker Tracker { get; set; }
- ConfiguredProject Config { get; set; }
- IDisposable Subscription { get; set; }
-
- public void Dispose()
- {
- Subscription?.Dispose();
- Subscription = null;
- }
-
- async Task ProjectUpdateAsync(IProjectVersionedValue<IProjectSubscriptionUpdate> update)
- {
- await Tracker.OnProjectUpdateAsync(Config, update.Value);
- }
- }
-
public EnvDTE.Project Project { get; private set; }
+ public string ProjectPath { get; private set; }
+ public VCProject VcProject { get; private set; }
public UnconfiguredProject UnconfiguredProject { get; private set; }
- public EventWaitHandle Initialized { get; private set; }
- List<Subscriber> Subscribers { get; set; }
+ public EventWaitHandle Initialized { get; }
- public static bool IsTracked(EnvDTE.Project project)
+ public static bool IsTracked(string projectPath)
{
- return Instances.ContainsKey(project.FullName);
+ return Instances.ContainsKey(projectPath);
}
public static void Add(EnvDTE.Project project)
{
if (!QtVsToolsPackage.Instance.Options.ProjectTracking)
return;
- Get(project);
+
+ ThreadHelper.ThrowIfNotOnUIThread();
+ Get(project, project.FullName);
}
- public static QtProjectTracker Get(EnvDTE.Project project)
+ public static QtProjectTracker Get(EnvDTE.Project project, string projectPath)
{
lock (StaticCriticalSection) {
- QtProjectTracker tracker = null;
- if (Instances.TryGetValue(project.FullName, out tracker))
+ if (Instances.TryGetValue(projectPath, out QtProjectTracker tracker))
return tracker;
tracker = new QtProjectTracker
{
Project = project,
+ ProjectPath = projectPath
};
- Instances[project.FullName] = tracker;
+ Instances[projectPath] = tracker;
InitQueue.Enqueue(tracker);
if (InitDispatcher == null)
InitDispatcher = Task.Run(InitDispatcherLoopAsync);
@@ -162,14 +126,17 @@
while (!QtVsToolsPackage.Instance.Zombied) {
while (InitQueue.IsEmpty)
await Task.Delay(100);
- QtProjectTracker tracker;
- if (InitQueue.TryDequeue(out tracker)) {
+ if (InitQueue.TryDequeue(out QtProjectTracker tracker)) {
if (InitStatus == null) {
- await QtVsToolsPackage.Instance.JoinableTaskFactory.SwitchToMainThreadAsync();
+ await QtVsToolsPackage.Instance.JoinableTaskFactory
+ .SwitchToMainThreadAsync();
tracker.BeginInitStatus();
await TaskScheduler.Default;
} else {
+ await QtVsToolsPackage.Instance.JoinableTaskFactory
+ .SwitchToMainThreadAsync();
tracker.UpdateInitStatus(0);
+ await TaskScheduler.Default;
}
await tracker.InitializeAsync();
}
@@ -187,9 +154,12 @@
async Task InitializeAsync()
{
int p = 0;
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
UpdateInitStatus(p += 10);
- await QtVsToolsPackage.Instance.JoinableTaskFactory.SwitchToMainThreadAsync();
+ VcProject = Project.Object as VCProject;
+ if (VcProject == null)
+ return;
UpdateInitStatus(p += 10);
var context = Project.Object as IVsBrowseObjectContext;
@@ -211,57 +181,23 @@
Initialized.Set();
- Subscribers = new List<Subscriber>();
int n = configs.Count;
int d = (100 - p) / (n * 2);
foreach (var config in configs) {
var configProject = await UnconfiguredProject.LoadConfiguredProjectAsync(config);
UpdateInitStatus(p += d);
- Subscribers.Add(new Subscriber(this, configProject));
- configProject.ProjectUnloading += OnProjectUnloading;
+ configProject.ProjectUnloading += OnProjectUnloadingAsync;
if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
Messages.Print(string.Format(
"{0:HH:mm:ss.FFF} QtProjectTracker({1}): Started tracking [{2}] {3}",
DateTime.Now, Thread.CurrentThread.ManagedThreadId,
- config.Name,
- UnconfiguredProject.FullPath));
+ config.Name, ProjectPath));
}
UpdateInitStatus(p += d);
}
}
-
- async Task OnProjectUpdateAsync(ConfiguredProject config, IProjectSubscriptionUpdate update)
- {
- var changes = update.ProjectChanges.Values
- .Where(x => x.Difference.AnyChanges)
- .Select(x => x.Difference);
- var changesCount = changes
- .Select(x => x.AddedItems.Count
- + x.ChangedItems.Count
- + x.ChangedProperties.Count
- + x.RemovedItems.Count
- + x.RenamedItems.Count)
- .Sum();
- var changedProps = changes.SelectMany(x => x.ChangedProperties);
- if (changesCount == 0
- || (changesCount == 1
- && changedProps.Count() == 1
- && changedProps.First() == "QtLastBackgroundBuild")) {
- return;
- }
-
- if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
- Messages.Print(string.Format(
- "{0:HH:mm:ss.FFF} QtProjectTracker({1}): Changed [{2}] {3}",
- DateTime.Now, Thread.CurrentThread.ManagedThreadId,
- config.ProjectConfiguration.Name,
- config.UnconfiguredProject.FullPath));
- }
- await QtProjectIntellisense.RefreshAsync(Project, config.ProjectConfiguration.Name);
- }
-
- async Task OnProjectUnloading(object sender, EventArgs args)
+ async Task OnProjectUnloadingAsync(object sender, EventArgs args)
{
var project = sender as ConfiguredProject;
if (project == null || project.Services == null)
@@ -274,18 +210,16 @@
project.UnconfiguredProject.FullPath));
}
lock (CriticalSection) {
- if (Subscribers != null) {
- Subscribers.ForEach(s => s.Dispose());
- Subscribers.Clear();
- Subscribers = null;
- }
- project.ProjectUnloading -= OnProjectUnloading;
- Instances.TryRemove(Project.FullName, out QtProjectTracker tracker);
+ project.ProjectUnloading -= OnProjectUnloadingAsync;
+ Instances.TryRemove(project.UnconfiguredProject.FullPath, out QtProjectTracker _);
}
+ await Task.Yield();
}
void BeginInitStatus()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
lock (StaticCriticalSection) {
if (InitStatus != null)
return;
@@ -303,9 +237,8 @@
PercentComplete = 0
})
as ITaskHandler2;
- } catch (Exception e) {
- Messages.Print(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
}
InitStatus.RegisterTask(new Task(() => throw new InvalidOperationException()));
}
@@ -320,13 +253,12 @@
InitStatus.Progress.Report(new TaskProgressData
{
ProgressText = string.Format("{0} ({1} project(s) remaining)",
- Project.Name, InitQueue.Count),
+ Path.GetFileNameWithoutExtension(ProjectPath), InitQueue.Count),
CanBeCanceled = true,
PercentComplete = percentComplete
});
- } catch (Exception e) {
- Messages.Print(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
}
}
}
diff --git a/QtVsTools.Package/QtMsBuild/QtVersionProvider.cs b/QtVsTools.Package/QtMsBuild/QtVersionProvider.cs
index f9626ca..4fd6db9 100644
--- a/QtVsTools.Package/QtMsBuild/QtVersionProvider.cs
+++ b/QtVsTools.Package/QtMsBuild/QtVersionProvider.cs
@@ -57,7 +57,6 @@
public async Task<ICollection<IEnumValue>> GetListedValuesAsync()
{
- List<IEnumValue> values = new List<IEnumValue>();
using (var qtVersions = Registry.CurrentUser.OpenSubKey(@"Software\Digia\Versions")) {
return await Task.FromResult(
diff --git a/QtVsTools.Package/QtVsTools.Icons.pkgdef b/QtVsTools.Package/QtVsTools.Icons.pkgdef
new file mode 100644
index 0000000..5bc4660
--- /dev/null
+++ b/QtVsTools.Package/QtVsTools.Icons.pkgdef
@@ -0,0 +1,20 @@
+[$RootKey$\ShellFileAssociations\.prf]
+"DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:0"
+
+[$RootKey$\ShellFileAssociations\.pri]
+"DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:1"
+
+[$RootKey$\ShellFileAssociations\.pro]
+"DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:2"
+
+[$RootKey$\ShellFileAssociations\.qml]
+"DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:3"
+
+[$RootKey$\ShellFileAssociations\.qrc]
+"DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:4"
+
+[$RootKey$\ShellFileAssociations\.ts]
+"DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:5"
+
+[$RootKey$\ShellFileAssociations\.ui]
+"DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:6"
diff --git a/QtVsTools.Package/QtVsTools.Package.csproj b/QtVsTools.Package/QtVsTools.Package.csproj
index 270b6c9..e57b845 100644
--- a/QtVsTools.Package/QtVsTools.Package.csproj
+++ b/QtVsTools.Package/QtVsTools.Package.csproj
@@ -90,59 +90,45 @@
<Reference Include="System.Data" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
+ <Reference Include="System.ComponentModel.Composition" />
+ <Reference Include="System.Xaml" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="WindowsBase" />
- <Reference Include="Microsoft.VisualStudio.ProjectSystem">
- <HintPath>$(VsInstallRoot)\Common7\IDE\CommonExtensions\Microsoft\Project\Microsoft.VisualStudio.ProjectSystem.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.Composition">
- <HintPath>$(VsInstallRoot)\Common7\IDE\PrivateAssemblies\Microsoft.VisualStudio.Composition.dll</HintPath>
- </Reference>
</ItemGroup>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
- // Version specific references
+ // General package references
// -->
<Import Project="$(SolutionDir)\references.props" />
<ItemGroup>
- <PackageReference Include="System.ComponentModel.Composition"
- Version="$(Version_System_ComponentModel_Composition)" />
- <PackageReference Include="Stub.System.Data.SQLite.Core.NetFramework"
- Version="$(Version_Stub_System_Data_SQLite_Core_NetFramework)"
- GeneratePathProperty="true" />
- <PackageReference Include="Newtonsoft.Json"
- Version="$(Version_Newtonsoft_Json)" />
- <PackageReference Include="Microsoft.Build"
- Version="$(Version_Microsoft_Build)" />
- <PackageReference Include="Microsoft.Build.Framework"
- Version="$(Version_Microsoft_Build_Framework)" />
- <PackageReference Include="Microsoft.Build.Tasks.Core"
- Version="$(Version_Microsoft_Build_Tasks_Core)" />
- <PackageReference Include="Microsoft.VisualStudio.SDK"
- Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
- <PackageReference Include="Microsoft.VSSDK.BuildTools"
- Version="$(Version_Microsoft_VSSDK_BuildTools)" />
- <PackageReference Include="Microsoft.VisualStudio.Shell.Framework"
- Version="$(Version_Microsoft_VisualStudio_Shell_Framework)" />
- <PackageReference Include="Microsoft.VisualStudio.Validation"
- Version="$(Version_Microsoft_VisualStudio_Validation)" />
- <PackageReference Include="$(Name_Microsoft_VisualStudio_Threading)"
- Version="$(Version_Microsoft_VisualStudio_Threading)" />
- <PackageReference Include="System.Collections.Immutable"
- Version="$(Version_System_Collections_Immutable)" />
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_ProjectSystem)" Version="$(Version_Microsoft_VisualStudio_ProjectSystem)" />
+ <PackageReference Include="$(Name_Newtonsoft_Json)" Version="$(Version_Newtonsoft_Json)" />
+ <PackageReference Include="$(Name_Stub_System_Data_SQLite_Core_NetFramework)" Version="$(Version_Stub_System_Data_SQLite_Core_NetFramework)" GeneratePathProperty="true" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Shell_15)" Version="$(Version_Microsoft_VisualStudio_Shell_15)" />
</ItemGroup>
- <ItemGroup Condition="'$(VisualStudioVersion)'=='17.0'">
- <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
- Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
- </ItemGroup>
- <ItemGroup Condition="'$(VisualStudioVersion)'=='16.0'">
- <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
- Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
- </ItemGroup>
- <ItemGroup Condition="'$(VisualStudioVersion)'=='15.0'">
- <Reference Include="Microsoft.VisualStudio.VCProjectEngine" />
- </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ <Reference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Shell_Framework)" Version="$(Version_Microsoft_VisualStudio_Shell_Framework)" />
+ </ItemGroup>
+ </When>
+ </Choose>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
// Solution project references
@@ -173,6 +159,27 @@
<Project>{4cee73c9-fcfa-3a72-a0a3-036bdbb3240f}</Project>
<Name>qrceditor</Name>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ </ProjectReference>
+ <ProjectReference Include="..\Templates\qtclass\QtTemplate.Item.QtClass.csproj">
+ <Project>{4981AAE8-9AC7-4758-87EA-FB2397D6C404}</Project>
+ <Name>QtTemplate.Item.QtClass</Name>
+ <VSIXSubPath>ItemTemplates</VSIXSubPath>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ <IncludeOutputGroupsInVSIX>TemplateProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
+ </ProjectReference>
+ <ProjectReference Include="..\Templates\translation\QtTemplate.Item.Translation.csproj">
+ <Project>{202F4A6D-77CD-4992-AA53-01B585463287}</Project>
+ <Name>QtTemplate.Item.Translation</Name>
+ <VSIXSubPath>ItemTemplates</VSIXSubPath>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ <IncludeOutputGroupsInVSIX>TemplateProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
+ </ProjectReference>
+ <ProjectReference Include="..\Templates\widgetsclass\QtTemplate.Item.WidgetsClass.csproj">
+ <Project>{020422DA-33AB-4495-A439-7DAC2690795C}</Project>
+ <Name>QtTemplate.Item.WidgetsClass</Name>
+ <VSIXSubPath>ItemTemplates</VSIXSubPath>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ <IncludeOutputGroupsInVSIX>TemplateProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
</ProjectReference>
<ProjectReference Include="..\vsqml\vsqml.vcxproj">
<Project>{b12702ad-abfb-343a-a199-8e24837244a3}</Project>
@@ -303,6 +310,12 @@
<DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
<LastGenOutput>AssemblyInfo.tt.cs</LastGenOutput>
</T4Template>
+ <Compile Include="Legacy\ProjectQtSettings.cs" />
+ <Compile Include="Legacy\QtMenu.cs" />
+ <Compile Include="Legacy\QtOptionsPage.cs">
+ <SubType>Component</SubType>
+ </Compile>
+ <Compile Include="Legacy\Translation.cs" />
<Compile Include="Properties\AssemblyInfo.tt.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
@@ -321,15 +334,11 @@
<DesignTime>True</DesignTime>
<DependentUpon>QtMenus.vsct_TT</DependentUpon>
</VSCTCompile>
- <Content Include="Resources\Vsix.ico" />
<EmbeddedResource Include="VSPackage.resx">
<MergeWithCTO>true</MergeWithCTO>
<ManifestResourceName>VSPackage</ManifestResourceName>
</EmbeddedResource>
- <Compile Include="Package\AddTranslationDialog.cs">
- <SubType>Form</SubType>
- </Compile>
- <Compile Include="Package\ChangeFor.cs" />
+ <Compile Include="Legacy\ChangeFor.cs" />
<Compile Include="Common\Concurrent.cs" />
<Compile Include="Common\ConcurrentStopwatch.cs" />
<Compile Include="Common\Disposable.cs" />
@@ -348,20 +357,17 @@
<Compile Include="Editors\Editor.QtLinguist.cs" />
<Compile Include="Editors\Editor.QtResourceEditor.cs" />
<Compile Include="Package\ExtLoader.cs" />
- <Compile Include="Package\FormChangeQtVersion.cs">
+ <Compile Include="Legacy\FormChangeQtVersion.cs">
<SubType>Form</SubType>
</Compile>
- <Compile Include="Package\FormChangeQtVersion.Designer.cs">
+ <Compile Include="Legacy\FormChangeQtVersion.Designer.cs">
<DependentUpon>FormChangeQtVersion.cs</DependentUpon>
</Compile>
- <Compile Include="Package\FormProjectQtSettings.cs">
+ <Compile Include="Legacy\FormProjectQtSettings.cs">
<SubType>Form</SubType>
</Compile>
- <Compile Include="Package\FormProjectQtSettings.Designer.cs">
+ <Compile Include="Legacy\FormProjectQtSettings.Designer.cs">
<DependentUpon>FormProjectQtSettings.cs</DependentUpon>
- </Compile>
- <Compile Include="Options\QtLegacyOptionsPage.cs">
- <SubType>Component</SubType>
</Compile>
<Compile Include="Options\QtOptionsPage.cs">
<SubType>Component</SubType>
@@ -372,7 +378,6 @@
<Compile Include="Options\QtVersionsPage.cs">
<SubType>Component</SubType>
</Compile>
- <Compile Include="Package\ProjectQtSettings.cs" />
<Compile Include="Package\QMakeWrapper.cs" />
<Compile Include="QML\Classification\QmlAsyncClassifier.cs" />
<Compile Include="QML\Classification\QmlClassificationFormat.cs" />
@@ -437,9 +442,7 @@
<Compile Include="Package\QtSolutionContextMenu.cs" />
<Compile Include="Package\SR.cs" />
<Compile Include="Package\Translation.cs" />
- <Compile Include="Package\TranslationItem.cs" />
- <Compile Include="VisualStudio\VsShell.cs" />
- <Compile Include="Common\VsToolsDialogWindow.cs" />
+ <Compile Include="Package\Notifications.cs" />
<Content Include="..\Changelog">
<Link>Changelog</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
@@ -456,6 +459,9 @@
<DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
<LastGenOutput>source.extension.vsixmanifest</LastGenOutput>
</T4Template>
+ <Content Include="Icons\Monikers.imagemanifest">
+ <IncludeInVSIX>true</IncludeInVSIX>
+ </Content>
<None Include="source.extension.vsixmanifest">
<DependentUpon>source.extension.vsixmanifest_TT</DependentUpon>
<SubType>Designer</SubType>
@@ -473,6 +479,16 @@
<DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
<LastGenOutput>Overview.html</LastGenOutput>
</T4Template>
+ <Content Include="QtVsTools.Icons.pkgdef">
+ <IncludeInVSIX>true</IncludeInVSIX>
+ </Content>
+ <Resource Include="Icons\prf32.png" />
+ <Resource Include="Icons\pri32.png" />
+ <Resource Include="Icons\pro32.png" />
+ <Resource Include="Icons\qml32.png" />
+ <Resource Include="Icons\qrc32.png" />
+ <Resource Include="Icons\ts32.png" />
+ <Resource Include="Icons\ui32.png" />
<Content Include="Marketplace\Overview.html">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
@@ -499,6 +515,10 @@
<IncludeInVSIX>true</IncludeInVSIX>
<SubType>Designer</SubType>
</Content>
+ <Content Include="qt6modules.xml">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <IncludeInVSIX>true</IncludeInVSIX>
+ </Content>
<Content Include="QtVsTools.ico" />
<Content Include="QtVsTools.Qml.Debug.pkgdef">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
@@ -509,14 +529,12 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<IncludeInVSIX>true</IncludeInVSIX>
</Content>
- <EmbeddedResource Include="Package\AddTranslationDialog.resx">
- <DependentUpon>AddTranslationDialog.cs</DependentUpon>
- </EmbeddedResource>
- <EmbeddedResource Include="Package\FormChangeQtVersion.resx">
+ <EmbeddedResource Include="Legacy\FormChangeQtVersion.resx">
<DependentUpon>FormChangeQtVersion.cs</DependentUpon>
</EmbeddedResource>
- <EmbeddedResource Include="Package\FormProjectQtSettings.resx">
+ <EmbeddedResource Include="Legacy\FormProjectQtSettings.resx">
<DependentUpon>FormProjectQtSettings.cs</DependentUpon>
+ <SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Resources.resx">
<SubType>Designer</SubType>
@@ -546,8 +564,8 @@
</Page>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(SolutionDir)\transform.targets" />
+ <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
<Target Name="QtVsTools_PostBuild" AfterTargets="Build">
<Error Condition="!Exists('$(TargetPath)')" Text="Build failed." />
<PropertyGroup>
@@ -602,19 +620,13 @@
/////////////////////////////////////////////////////////////////////////////////////////////////
// NuGet native libs
// -->
- <PropertyGroup
- Condition="'$(PkgStub_System_Data_SQLite_Core_NetFramework)' != ''">
- <SQLitePkgDir Condition="'$(SQLitePkgDir)' == ''"
- >$(PkgStub_System_Data_SQLite_Core_NetFramework)</SQLitePkgDir>
+ <PropertyGroup Condition="'$(PkgStub_System_Data_SQLite_Core_NetFramework)' != ''">
+ <SQLitePkgDir Condition="'$(SQLitePkgDir)' == ''">$(PkgStub_System_Data_SQLite_Core_NetFramework)</SQLitePkgDir>
</PropertyGroup>
- <PropertyGroup
- Condition="'$(PkgStub_System_Data_SQLite_Core_NetFramework)' == ''">
- <NuGetGlobalPkgDir Condition="'$(NuGetGlobalPkgDir)' == ''"
- >$(USERPROFILE)\.nuget\packages</NuGetGlobalPkgDir>
- <SQLitePkgRoot
- >$(NuGetGlobalPkgDir)\Stub.System.Data.SQLite.Core.NetFramework</SQLitePkgRoot>
- <SQLitePkgDir Condition="'$(SQLitePkgDir)' == ''"
- >$(SQLitePkgRoot)\$(Version_Stub_System_Data_SQLite_Core_NetFramework)</SQLitePkgDir>
+ <PropertyGroup Condition="'$(PkgStub_System_Data_SQLite_Core_NetFramework)' == ''">
+ <NuGetGlobalPkgDir Condition="'$(NuGetGlobalPkgDir)' == ''">$(USERPROFILE)\.nuget\packages</NuGetGlobalPkgDir>
+ <SQLitePkgRoot>$(NuGetGlobalPkgDir)\Stub.System.Data.SQLite.Core.NetFramework</SQLitePkgRoot>
+ <SQLitePkgDir Condition="'$(SQLitePkgDir)' == ''">$(SQLitePkgRoot)\$(Version_Stub_System_Data_SQLite_Core_NetFramework)</SQLitePkgDir>
</PropertyGroup>
<ItemGroup>
<Content Include="$(SQLitePkgDir)\build\net46\x64\SQLite.Interop.dll">
diff --git a/QtVsTools.Package/QtVsToolsPackage.cs b/QtVsTools.Package/QtVsToolsPackage.cs
index aad01be..93325f3 100644
--- a/QtVsTools.Package/QtVsToolsPackage.cs
+++ b/QtVsTools.Package/QtVsToolsPackage.cs
@@ -27,20 +27,14 @@
****************************************************************************/
using System;
-using System.ComponentModel.Design;
using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
-using Task = System.Threading.Tasks.Task;
-using System.Windows.Forms;
using Microsoft.VisualStudio;
-using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Settings;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
@@ -49,13 +43,15 @@
using Microsoft.Win32;
using EnvDTE;
+using Task = System.Threading.Tasks.Task;
+
namespace QtVsTools
{
using Core;
using QtMsBuild;
- using SyntaxAnalysis;
- using static SyntaxAnalysis.RegExpr;
using VisualStudio;
+
+ using static SyntaxAnalysis.RegExpr;
[Guid(QtVsToolsPackage.PackageGuidString)]
[InstalledProductRegistration("#110", "#112", Version.PRODUCT_VERSION, IconResourceID = 400)]
@@ -97,7 +93,7 @@
"Qt", "Versions", 0, 0, true, Sort = 1)]
// Legacy options page
- [ProvideOptionPage(typeof(Options.QtLegacyOptionsPage),
+ [ProvideOptionPage(typeof(Legacy.QtOptionsPage),
"Qt", "Legacy Project Format", 0, 0, true, Sort = 2)]
public sealed class QtVsToolsPackage : AsyncPackage, IVsServiceProvider, IProjectTracker
@@ -109,13 +105,13 @@
public string PkgInstallPath { get; private set; }
public Options.QtOptionsPage Options
=> GetDialogPage(typeof(Options.QtOptionsPage)) as Options.QtOptionsPage;
- public Options.QtLegacyOptionsPage LegacyOptions
- => GetDialogPage(typeof(Options.QtLegacyOptionsPage)) as Options.QtLegacyOptionsPage;
+ public Legacy.QtOptionsPage LegacyOptions
+ => GetDialogPage(typeof(Legacy.QtOptionsPage)) as Legacy.QtOptionsPage;
public Editors.QtDesigner QtDesigner { get; private set; }
public Editors.QtLinguist QtLinguist { get; private set; }
- public Editors.QtResourceEditor QtResourceEditor { get; private set; }
+ private Editors.QtResourceEditor QtResourceEditor { get; set; }
- static EventWaitHandle initDone = new EventWaitHandle(false, EventResetMode.ManualReset);
+ static readonly EventWaitHandle initDone = new EventWaitHandle(false, EventResetMode.ManualReset);
static QtVsToolsPackage instance = null;
public static QtVsToolsPackage Instance
@@ -167,7 +163,6 @@
var timeInitBegin = initTimer.Elapsed;
VsServiceProvider.Instance = instance = this;
QtProject.ProjectTracker = this;
- Messages.JoinableTaskFactory = JoinableTaskFactory;
// determine the package installation directory
var uri = new Uri(System.Reflection.Assembly
@@ -180,7 +175,7 @@
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var timeUiThreadBegin = initTimer.Elapsed;
- if ((Dte = VsServiceProvider.GetService<DTE>()) == null)
+ if ((Dte = await VsServiceProvider.GetServiceAsync<DTE>()) == null)
throw new Exception("Unable to get service: DTE");
QtVSIPSettings.Options = Options;
@@ -188,14 +183,14 @@
eventHandler = new DteEventsHandler(Dte);
Qml.Debug.Launcher.Initialize();
- QtMainMenu.Initialize(this);
- QtSolutionContextMenu.Initialize(this);
- QtProjectContextMenu.Initialize(this);
- QtItemContextMenu.Initialize(this);
+ QtMainMenu.Initialize();
+ QtSolutionContextMenu.Initialize();
+ QtProjectContextMenu.Initialize();
+ QtItemContextMenu.Initialize();
RegisterEditorFactory(QtDesigner = new Editors.QtDesigner());
RegisterEditorFactory(QtLinguist = new Editors.QtLinguist());
RegisterEditorFactory(QtResourceEditor = new Editors.QtResourceEditor());
- QtHelp.Initialize(this);
+ QtHelp.Initialize();
if (!string.IsNullOrEmpty(VsShell.InstallRootDir))
HelperFunctions.VCPath = Path.Combine(VsShell.InstallRootDir, "VC");
@@ -209,9 +204,11 @@
var timeUiThreadEnd = initTimer.Elapsed;
var vm = QtVersionManager.The(initDone);
- var error = string.Empty;
- if (vm.HasInvalidVersions(out error))
+ if (vm.HasInvalidVersions(out string error, out bool defaultInvalid)) {
+ if (defaultInvalid)
+ vm.SetLatestQtVersionAsDefault();
Messages.Print(error);
+ }
///////////
// Install Qt/MSBuild files from package folder to standard location
@@ -306,9 +303,8 @@
================================================================",
urlDownloadQtIo, devRelease));
}
- } catch (Exception e) {
- Messages.Print(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
} finally {
initDone.Set();
initTimer.Stop();
@@ -326,11 +322,35 @@
eventHandler.SolutionEvents_Opened();
}
+ bool TestVersionInstalled()
+ {
+ bool newVersion = false;
+ string versionFile = Path.Combine(PkgInstallPath, "lastversion.txt");
+ if (File.Exists(versionFile)) {
+ string lastVersion = File.ReadAllText(versionFile);
+ newVersion = (lastVersion!= Version.PRODUCT_VERSION);
+ } else {
+ newVersion = true;
+ }
+ if (newVersion)
+ File.WriteAllText(versionFile, Version.PRODUCT_VERSION);
+ return newVersion;
+ }
+
+ public void VsMainWindowActivated()
+ {
+ if (QtVersionManager.The().GetVersions()?.Length == 0)
+ Notifications.NoQtVersion.Show();
+ if (Options.NotifyInstalled && TestVersionInstalled())
+ Notifications.NotifyInstall.Show();
+ }
+
protected override int QueryClose(out bool canClose)
{
- if (eventHandler != null) {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ if (eventHandler != null)
eventHandler.Disconnect();
- }
return base.QueryClose(out canClose);
}
@@ -381,14 +401,15 @@
File.WriteAllText(Path.Combine(visualizersPath, natvisFile),
natvis, System.Text.Encoding.UTF8);
- } catch (Exception e) {
- Messages.Print(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ } catch (Exception exception) {
+ exception.Log();
}
}
public string GetNatvisPath()
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
try {
using (var vsRootKey = Registry.CurrentUser.OpenSubKey(Dte.RegistryRoot)) {
if (vsRootKey.GetValue("VisualStudioLocation") is string vsLocation)
@@ -433,6 +454,7 @@
void IProjectTracker.AddProject(Project project)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
QtProjectTracker.Add(project);
}
diff --git a/QtVsTools.Package/Resources.resx b/QtVsTools.Package/Resources.resx
index 4c63e0b..cee5e85 100644
--- a/QtVsTools.Package/Resources.resx
+++ b/QtVsTools.Package/Resources.resx
@@ -117,24 +117,6 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
- <data name="ActionDialog_Properties" xml:space="preserve">
- <value>Properties</value>
- </data>
- <data name="AddQtVersionDialog_IncorrectMakefileGenerator" xml:space="preserve">
- <value>This Qt version uses an unsupported makefile generator (used: {0}, supported: MSVC.NET, MSBUILD)</value>
- </data>
- <data name="AddTranslationDialog_FileName" xml:space="preserve">
- <value>Filename:</value>
- </data>
- <data name="AddTranslationDialog_Language" xml:space="preserve">
- <value>Language:</value>
- </data>
- <data name="AddTranslationDialog_Title" xml:space="preserve">
- <value>Add Translation</value>
- </data>
- <data name="Cancel" xml:space="preserve">
- <value>&Cancel</value>
- </data>
<data name="CannotFindQMake" xml:space="preserve">
<value>Cannot find qmake. Make sure you have specified a Qt version.</value>
</data>
@@ -175,32 +157,11 @@
<data name="ImportPriFileNotResolved" xml:space="preserve">
<value>--- (importing .pri file) file: {0} cannot be resolved. Skipping file.</value>
</data>
- <data name="InstalledQtVersions" xml:space="preserve">
- <value>Installed Qt Versions</value>
- </data>
<data name="NoProjectOpened" xml:space="preserve">
<value>No Project Opened</value>
</data>
- <data name="OK" xml:space="preserve">
- <value>&OK</value>
- </data>
- <data name="IncompatibleMacros" xml:space="preserve">
- <value>The following macros are not compatible: {0}</value>
- </data>
- <data name="ProjectQtSettingsButtonText" xml:space="preserve">
- <value>Qt Project Settings</value>
- </data>
- <data name="ProjectQtVersion" xml:space="preserve">
- <value>Set Project's Qt Version</value>
- </data>
<data name="ProjectQtVersionNotFoundError" xml:space="preserve">
<value>There's no Qt version assigned to project {0} for configuration {1}/{2}. Please use the 'Qt Project Settings' editor to change the 'Version' to a valid Qt version for this platform.</value>
- </data>
- <data name="QtModules" xml:space="preserve">
- <value>Qt Modules</value>
- </data>
- <data name="SolutionQtVersion" xml:space="preserve">
- <value>Set Solution's Qt Version</value>
</data>
<data name="ExportProject_ImportPriFile" xml:space="preserve">
<value>Import from .pri File</value>
diff --git a/QtVsTools.Package/qt5.natvis.xml b/QtVsTools.Package/qt5.natvis.xml
index 237fbd9..fc3e557 100644
--- a/QtVsTools.Package/qt5.natvis.xml
+++ b/QtVsTools.Package/qt5.natvis.xml
@@ -224,14 +224,41 @@
</Type>
<Type Name="##NAMESPACE##::QString">
- <DisplayString>{((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub}</DisplayString>
- <StringView>((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub</StringView>
+ <DisplayString>{((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub}</DisplayString>
+ <StringView>((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub</StringView>
<Expand>
<Item Name="[size]">d->size</Item>
<Item Name="[referenced]">d->ref.atomic._q_value</Item>
<ArrayItems>
<Size>d->size</Size>
- <ValuePointer>((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),c</ValuePointer>
+ <ValuePointer>((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),c</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringRef">
+ <Intrinsic Name="offset" Expression="(reinterpret_cast<char16_t*>(m_string->d))
+ + m_string->d->offset / 2" />
+ <DisplayString Condition="m_string == nullptr">{m_string,[m_size]} u""</DisplayString>
+ <DisplayString Condition="m_string != nullptr">{offset() + m_position,[m_size]}</DisplayString>
+ <Expand>
+ <Item Name="[position]" ExcludeView="simple">m_position</Item>
+ <Item Name="[size]" ExcludeView="simple">m_size</Item>
+ <ArrayItems Condition="m_string != nullptr">
+ <Size>m_size</Size>
+ <ValuePointer>offset()+m_position</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringView">
+ <DisplayString>{m_data,[m_size]}</DisplayString>
+ <StringView>m_data,[m_size]</StringView>
+ <Expand>
+ <Item Name="[size]" ExcludeView="simple">m_size</Item>
+ <ArrayItems>
+ <Size>m_size</Size>
+ <ValuePointer>m_data</ValuePointer>
</ArrayItems>
</Expand>
</Type>
@@ -264,8 +291,8 @@
<Intrinsic Name="query" Expression="*((QString*)(((char*)(d) + memberOffset(5))))" />
<Intrinsic Name="fragment" Expression="*((QString*)(((char*)(d) + memberOffset(6))))" />
- <DisplayString Condition="!isEmpty(scheme().d->size)">{scheme()}://{host()}{path()}</DisplayString>
- <DisplayString Condition="isEmpty(scheme().d->size)">{path()}</DisplayString>
+ <DisplayString Condition="!isEmpty(scheme().d->size)">{scheme()}://{host()}{path()}</DisplayString>
+ <DisplayString Condition="isEmpty(scheme().d->size)">{path()}</DisplayString>
<Expand>
<Item Name="[scheme]">scheme()</Item>
<Item Name="[username]">username()</Item>
@@ -424,8 +451,8 @@
<IndexListItems>
<Size>d->end - d->begin</Size>
<ValueNode>*reinterpret_cast<$T1*>((sizeof($T1) > sizeof(void*))
- ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
- : reinterpret_cast<$T1*>(d->array + d->begin + $i))
+ ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
+ : reinterpret_cast<$T1*>(d->array + d->begin + $i))
</ValueNode>
</IndexListItems>
</Expand>
@@ -439,8 +466,8 @@
<Size>d->end - d->begin</Size>
<ValueNode>
*reinterpret_cast<QString*>((sizeof(QString) > sizeof(void*))
- ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
- : reinterpret_cast<QString*>(d->array + d->begin + $i))
+ ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
+ : reinterpret_cast<QString*>(d->array + d->begin + $i))
</ValueNode>
</IndexListItems>
</Expand>
@@ -454,8 +481,8 @@
<Size>d->end - d->begin</Size>
<ValueNode>
*reinterpret_cast<QVariant*>((sizeof(QVariant) > sizeof(void*))
- ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
- : reinterpret_cast<QVariant*>(d->array + d->begin + $i))
+ ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
+ : reinterpret_cast<QVariant*>(d->array + d->begin + $i))
</ValueNode>
</IndexListItems>
</Expand>
@@ -526,7 +553,7 @@
<Exec>node = *(bucket++)</Exec>
<Exec>--n</Exec>
<Loop>
- <Break Condition="!node || !node->next"/>
+ <Break Condition="!node || !node->next"/>
<Exec>keyValuePair = reinterpret_cast<Node *>(node)</Exec>
<Item Name="[{keyValuePair->key}]">keyValuePair->value</Item>
<Exec>node = node->next</Exec>
diff --git a/QtVsTools.Package/qt6.natvis.xml b/QtVsTools.Package/qt6.natvis.xml
index 5274053..18c7adf 100644
--- a/QtVsTools.Package/qt6.natvis.xml
+++ b/QtVsTools.Package/qt6.natvis.xml
@@ -259,7 +259,34 @@
</Expand>
</Type>
- <Type Name="##NAMESPACE##::QByteArray">
+ <Type Name="##NAMESPACE##::QStringRef">
+ <DisplayString Condition="m_string == nullptr">{m_string,[m_size]} u""</DisplayString>
+ <DisplayString Condition="m_string != nullptr">{m_string->d.ptr+m_position,[m_size]}</DisplayString>
+ <StringView Condition="m_string == nullptr">""</StringView>
+ <StringView Condition="m_string != nullptr">m_string,[m_position+m_size]</StringView>
+ <Expand>
+ <Item Name="[position]" ExcludeView="simple">m_position</Item>
+ <Item Name="[size]" ExcludeView="simple">m_size</Item>
+ <ArrayItems Condition="m_string != nullptr">
+ <Size>m_size</Size>
+ <ValuePointer>m_string->d.ptr+m_position</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringView">
+ <DisplayString>{m_data,[m_size]}</DisplayString>
+ <StringView>m_data,[m_size]</StringView>
+ <Expand>
+ <Item Name="[size]" ExcludeView="simple">m_size</Item>
+ <ArrayItems>
+ <Size>m_size</Size>
+ <ValuePointer>m_data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QByteArray">
<DisplayString>"{((reinterpret_cast<char*>(d.ptr))),sb}"</DisplayString>
<StringView>((reinterpret_cast<char*>(d.ptr))),sb</StringView>
<Expand>
@@ -286,8 +313,8 @@
<Intrinsic Name="query" Expression="*((QString*)(((char*)(d) + memberOffset(5))))" />
<Intrinsic Name="fragment" Expression="*((QString*)(((char*)(d) + memberOffset(6))))" />
- <DisplayString Condition="!isEmpty(scheme().d->size)">{scheme()}://{host()}{path()}</DisplayString>
- <DisplayString Condition="isEmpty(scheme().d->size)">{path()}</DisplayString>
+ <DisplayString Condition="!isEmpty(scheme().d->size)">{scheme()}://{host()}{path()}</DisplayString>
+ <DisplayString Condition="isEmpty(scheme().d->size)">{path()}</DisplayString>
<Expand>
<Item Name="[scheme]">scheme()</Item>
<Item Name="[username]">username()</Item>
diff --git a/QtVsTools.Package/qt6modules.xml b/QtVsTools.Package/qt6modules.xml
new file mode 100644
index 0000000..1754d1a
--- /dev/null
+++ b/QtVsTools.Package/qt6modules.xml
@@ -0,0 +1,510 @@
+<?xml version="1.0" encoding="utf-8"?>
+<QtVsTools>
+
+ <!-- Qt Essentials -->
+
+ <Module Id="1">
+ <Name>Qt Core</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtCore</LibraryPrefix>
+ <proVarQT>core</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtCore</IncludePath>
+ <Defines>QT_CORE_LIB</Defines>
+ <Tag>Essential</Tag>
+ </Module>
+ <Module Id="2">
+ <Name>Qt D-Bus</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtDBus</LibraryPrefix>
+ <proVarQT>dbus</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtDBus</IncludePath>
+ <Defines>QT_DBUS_LIB</Defines>
+ <Tag>Essential</Tag>
+ </Module>
+ <Module Id="3">
+ <Name>Qt GUI</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtGui</LibraryPrefix>
+ <proVarQT>gui</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtGui</IncludePath>
+ <Defines>QT_GUI_LIB</Defines>
+ <Tag>Essential</Tag>
+ </Module>
+ <Module Id="4">
+ <Name>Qt Network</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtNetwork</LibraryPrefix>
+ <proVarQT>network</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtNetwork</IncludePath>
+ <Defines>QT_NETWORK_LIB</Defines>
+ <Tag>Essential</Tag>
+ </Module>
+ <Module Id="5">
+ <Name>Qt QML</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtQml</LibraryPrefix>
+ <proVarQT>qml</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtQml</IncludePath>
+ <Defines>QT_QML_LIB</Defines>
+ <Tag>Essential</Tag>
+ </Module>
+ <Module Id="6">
+ <Name>Qt Quick</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtQuick</LibraryPrefix>
+ <proVarQT>quick</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtQuick</IncludePath>
+ <Defines>QT_QUICK_LIB</Defines>
+ <Tag>Essential</Tag>
+ </Module>
+ <Module Id="7">
+ <Name>Qt Quick Controls</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtQuickControls2</LibraryPrefix>
+ <proVarQT>quickcontrols2</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtQuickControls2</IncludePath>
+ <Defines>QT_QUICKCONTROLS2_LIB</Defines>
+ <Tag>Essential</Tag>
+ </Module>
+ <Module Id="8">
+ <Name>Qt Quick Dialogs</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtQuickDialogs2</LibraryPrefix>
+ <proVarQT>quickdialogs2</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtQuickDialogs2</IncludePath>
+ <Defines>QT_QUICKDIALOGS2_LIB</Defines>
+ <Tag>Essential</Tag>
+ </Module>
+ <Module Id="9">
+ <Name>Qt Quick Layouts</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtQuickLayouts</LibraryPrefix>
+ <proVarQT>quicklayouts</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtQuickLayouts</IncludePath>
+ <Defines>QT_QUICKLAYOUTS_LIB</Defines>
+ <Tag>Essential</Tag>
+ </Module>
+ <Module Id="10">
+ <Name>Qt Quick Test</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtQuickTest</LibraryPrefix>
+ <proVarQT>qmltest</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtQuickTest</IncludePath>
+ <Defines>QT_QMLTEST_LIB</Defines>
+ <Tag>Essential</Tag>
+ </Module>
+ <Module Id="11">
+ <Name>Qt Test</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtTest</LibraryPrefix>
+ <proVarQT>testlib</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtTest</IncludePath>
+ <Defines>QT_TESTLIB_LIB</Defines>
+ <Tag>Essential</Tag>
+ </Module>
+ <Module Id="12">
+ <Name>Qt Widgets</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtWidgets</LibraryPrefix>
+ <proVarQT>widgets</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtWidgets</IncludePath>
+ <Defines>QT_WIDGETS_LIB</Defines>
+ <Tag>Essential</Tag>
+ </Module>
+
+ <!-- Qt Add-Ons-->
+
+ <Module Id="13">
+ <Name>Active Qt (Server)</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtAxServer</LibraryPrefix>
+ <proVarQT>axserver</proVarQT>
+ <IncludePath>$(QTDIR)\include\ActiveQt</IncludePath>
+ <Defines>QAXSERVER</Defines>
+ <Defines>QT_AXSERVER_LIB</Defines>
+ <AdditionalLibraries>Qt6AxBase.lib</AdditionalLibraries>
+ <AdditionalLibrariesDebug>Qt6AxBased.lib</AdditionalLibrariesDebug>
+ </Module>
+ <Module Id="14">
+ <Name>Active Qt (Container)</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtAxContainer</LibraryPrefix>
+ <proVarQT>axcontainer</proVarQT>
+ <IncludePath>$(QTDIR)\include\ActiveQt</IncludePath>
+ <Defines>QT_AXCONTAINER_LIB</Defines>
+ <AdditionalLibraries>Qt6AxBase.lib</AdditionalLibraries>
+ <AdditionalLibrariesDebug>Qt6AxBased.lib</AdditionalLibrariesDebug>
+ </Module>
+ <Module Id="15">
+ <Name>Qt Bluetooth</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtBluetooth</LibraryPrefix>
+ <proVarQT>bluetooth</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtBluetooth</IncludePath>
+ <Defines>QT_BLUETOOTH_LIB</Defines>
+ </Module>
+ <Module Id="16">
+ <Name>Qt 3D</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>Qt3DCore</LibraryPrefix>
+ <proVarQT>3dcore 3danimation 3dextras 3dinput 3dlogic 3drender</proVarQT>
+ <IncludePath>$(QTDIR)\include\Qt3DCore</IncludePath>
+ <IncludePath>$(QTDIR)\include\Qt3DAnimation</IncludePath>
+ <IncludePath>$(QTDIR)\include\Qt3DExtras</IncludePath>
+ <IncludePath>$(QTDIR)\include\Qt3DInput</IncludePath>
+ <IncludePath>$(QTDIR)\include\Qt3DLogic</IncludePath>
+ <IncludePath>$(QTDIR)\include\Qt3DRender</IncludePath>
+ <Defines>QT_3DCORE_LIB</Defines>
+ <Defines>QT_3DANIMATION_LIB</Defines>
+ <Defines>QT_3DEXTRAS_LIB</Defines>
+ <Defines>QT_3DINPUT_LIB</Defines>
+ <Defines>QT_3DLOGIC_LIB</Defines>
+ <Defines>QT_3DRENDER_LIB</Defines>
+ <AdditionalLibraries>Qt63DCore.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt63DAnimation.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt63DExtras.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt63DInput.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt63DLogic.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt63DRender.lib</AdditionalLibraries>
+ <AdditionalLibrariesDebug>Qt63DCored.lib</AdditionalLibrariesDebug>
+ <AdditionalLibrariesDebug>Qt63DAnimationd.lib</AdditionalLibrariesDebug>
+ <AdditionalLibrariesDebug>Qt63DExtrasd.lib</AdditionalLibrariesDebug>
+ <AdditionalLibrariesDebug>Qt63DInputd.lib</AdditionalLibrariesDebug>
+ <AdditionalLibrariesDebug>Qt63DLogicd.lib</AdditionalLibrariesDebug>
+ <AdditionalLibrariesDebug>Qt63DRenderd.lib</AdditionalLibrariesDebug>
+ </Module>
+ <Module Id="17">
+ <Name>Qt 5 Core Compatibility APIs</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtCore5Compat</LibraryPrefix>
+ <proVarQT>core5compat</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtCore5Compat</IncludePath>
+ <Defines>QT_CORE5COMPAT_LIB</Defines>
+ </Module>
+ <Module Id="18"> <!-- TODO: Split? -->
+ <Name>Qt for Automation</Name>
+ <proVarQT>coap mqtt opcua</proVarQT>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtCoap</LibraryPrefix>
+ <AdditionalLibraries>Qt6Coap.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt6Coapd.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt6Mqtt.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt6Mqttd.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt6OpcUa.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt6OpcUad.lib</AdditionalLibraries>
+ </Module>
+ <Module Id="19">
+ <Name>Qt Concurrent</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtConcurrent</LibraryPrefix>
+ <proVarQT>concurrent</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtConcurrent</IncludePath>
+ <Defines>QT_CONCURRENT_LIB</Defines>
+ </Module>
+ <Module Id="20">
+ <Name>Qt Help</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtHelp</LibraryPrefix>
+ <proVarQT>help</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtHelp</IncludePath>
+ <Defines>QT_HELP_LIB</Defines>
+ </Module>
+ <!--
+ Image formats
+ -->
+ <Module Id="21">
+ <Name>Qt OpenGL</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtOpenGL</LibraryPrefix>
+ <proVarQT>opengl</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtOpenGL</IncludePath>
+ <Defines>QT_OPENGL_LIB</Defines>
+ </Module>
+ <Module Id="22">
+ <Name>Qt Multimedia</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtMultimedia</LibraryPrefix>
+ <proVarQT>multimedia</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtMultimedia</IncludePath>
+ <Defines>QT_MULTIMEDIA_LIB</Defines>
+ </Module>
+ <Module Id="23">
+ <Name>Qt Print Support</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtPrintSupport</LibraryPrefix>
+ <proVarQT>printsupport</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtPrintSupport</IncludePath>
+ <Defines>QT_PRINTSUPPORT_LIB</Defines>
+ </Module>
+ <Module Id="24">
+ <Name>Qt Quick Widgets</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtQuickWidgets</LibraryPrefix>
+ <proVarQT>quickwidgets</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtQuickWidgets</IncludePath>
+ <Defines>QT_QUICKWIDGETS_LIB</Defines>
+ </Module>
+ <Module Id="25">
+ <Name>Qt Remote Objects</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtRemoteObjects</LibraryPrefix>
+ <proVarQT>remoteobjects</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtRemoteObjects</IncludePath>
+ <Defines>QT_REMOTEOBJECTS_LIB</Defines>
+ </Module>
+ <Module Id="26">
+ <Name>Qt SCXML</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtScxml</LibraryPrefix>
+ <proVarQT>scxml</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtScxml</IncludePath>
+ <Defines>QT_SCXML_LIB</Defines>
+ </Module>
+ <Module Id="27">
+ <Name>Qt Sensors</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtSensors</LibraryPrefix>
+ <proVarQT>sensors</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtSensors</IncludePath>
+ <Defines>QT_SENSORS_LIB</Defines>
+ </Module>
+ <Module Id="28">
+ <Name>Qt Serial Bus</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtSerialBus</LibraryPrefix>
+ <proVarQT>serialbus</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtSerialBus</IncludePath>
+ <Defines>QT_SERIALBUS_LIB</Defines>
+ </Module>
+ <Module Id="29">
+ <Name>Qt Serial Port</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtSerialPort</LibraryPrefix>
+ <proVarQT>serialport</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtSerialPort</IncludePath>
+ <Defines>QT_SERIALPORT_LIB</Defines>
+ </Module>
+ <Module Id="30">
+ <Name>Qt SQL</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtSql</LibraryPrefix>
+ <proVarQT>sql</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtSql</IncludePath>
+ <Defines>QT_SQL_LIB</Defines>
+ </Module>
+ <Module Id="31">
+ <Name>Qt State Machine</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtStateMachine</LibraryPrefix>
+ <proVarQT>statemachine</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtStateMachine</IncludePath>
+ <Defines>QT_STATEMACHINE_LIB</Defines>
+ </Module>
+ <Module Id="32">
+ <Name>Qt SVG</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtSvg</LibraryPrefix>
+ <proVarQT>svg</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtSvg</IncludePath>
+ <Defines>QT_SVG_LIB</Defines>
+ </Module>
+ <Module Id="34">
+ <Name>Qt WebChannel</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtWebChannel</LibraryPrefix>
+ <proVarQT>webchannel</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtWebChannel</IncludePath>
+ <Defines>QT_WEBCHANNEL_LIB</Defines>
+ </Module>
+ <Module Id="35">
+ <Name>Qt WebEngine</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtWebEngine</LibraryPrefix>
+ <proVarQT>webenginecore</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtWebEngineCore</IncludePath>
+ <Defines>QT_WEBENGINECORE_LIB</Defines>
+ <AdditionalLibraries>Qt6WebEngine.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt6WebEngineCore.lib</AdditionalLibraries>
+ <AdditionalLibrariesDebug>Qt6WebEngined.lib</AdditionalLibrariesDebug>
+ <AdditionalLibrariesDebug>Qt6WebEngineCored.lib</AdditionalLibrariesDebug>
+ </Module>
+ <Module Id="36">
+ <Name>Qt WebSockets</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtWebSockets</LibraryPrefix>
+ <proVarQT>websockets</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtWebSockets</IncludePath>
+ <Defines>QT_WEBSOCKETS_LIB</Defines>
+ </Module>
+ <Module Id="37">
+ <Name>WebView</Name>
+ <proVarQT>webview</proVarQT>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtWebView</LibraryPrefix>
+ </Module>
+ <Module Id="38">
+ <Name>Qt XML</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtXml</LibraryPrefix>
+ <proVarQT>xml</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtXml</IncludePath>
+ <Defines>QT_XML_LIB</Defines>
+ </Module>
+ <Module Id="39">
+ <Name>Qt Positioning</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtPositioning</LibraryPrefix>
+ <proVarQT>positioning</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtPositioning</IncludePath>
+ <Defines>QT_POSITIONING_LIB</Defines>
+ </Module>
+ <Module Id="40">
+ <Name>Qt NFC</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtNfc</LibraryPrefix>
+ <proVarQT>nfc</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtNfc</IncludePath>
+ <Defines>QT_NFC_LIB</Defines>
+ </Module>
+ <Module Id="41">
+ <Name>Qt Charts</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtCharts</LibraryPrefix>
+ <proVarQT>charts</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtCharts</IncludePath>
+ <Defines>QT_CHARTS_LIB</Defines>
+ </Module>
+ <Module Id="42">
+ <Name>Qt Data Visualization</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtDataVisualization</LibraryPrefix>
+ <proVarQT>datavisualization</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtDataVisualization</IncludePath>
+ <Defines>QT_DATAVISUALIZATION_LIB</Defines>
+ </Module>
+ <!--
+ lottie
+ -->
+ <Module Id="44">
+ <Name>Qt Network Authorization</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtNetworkAuth</LibraryPrefix>
+ <proVarQT>networkauth</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtNetworkAuth</IncludePath>
+ <Defines>QT_NETWORKAUTH_LIB</Defines>
+ </Module>
+ <Module Id="45">
+ <Name>Qt Virtual Keyboard</Name>
+ <proVarQT>virtualkeyboard</proVarQT>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtVirtualKeyboard</LibraryPrefix>
+ </Module>
+ <Module Id="46">
+ <Name>Qt Quick 3D</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>Qt3DQuick</LibraryPrefix>
+ <proVarQT>3dquick</proVarQT>
+ <IncludePath>$(QTDIR)\include\Qt3DQuick</IncludePath>
+ <IncludePath>$(QTDIR)\include\Qt3DQuickAnimation</IncludePath>
+ <IncludePath>$(QTDIR)\include\Qt3DQuickExtras</IncludePath>
+ <IncludePath>$(QTDIR)\include\Qt3DQuickInput</IncludePath>
+ <IncludePath>$(QTDIR)\include\Qt3DQuickRender</IncludePath>
+ <IncludePath>$(QTDIR)\include\Qt3DQuickScene2D</IncludePath>
+ <Defines>QT_3DQUICK_LIB</Defines>
+ <Defines>QT_3DQUICKANIMATION_LIB</Defines>
+ <Defines>QT_3DQUICKEXTRAS_LIB</Defines>
+ <Defines>QT_3DQUICKINPUT_LIB</Defines>
+ <Defines>QT_3DQUICKRENDER_LIB</Defines>
+ <Defines>QT_3DQUICKSCENE2D_LIB</Defines>
+ <AdditionalLibraries>Qt63DQuick.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt63DQuickAnimation.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt63DQuickExtras.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt63DQuickInput.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt63DQuickRender.lib</AdditionalLibraries>
+ <AdditionalLibraries>Qt63DQuickScene2D.lib</AdditionalLibraries>
+ <AdditionalLibrariesDebug>Qt63DQuickd.lib</AdditionalLibrariesDebug>
+ <AdditionalLibrariesDebug>Qt63DQuickAnimationd.lib</AdditionalLibrariesDebug>
+ <AdditionalLibrariesDebug>Qt63DQuickExtrasd.lib</AdditionalLibrariesDebug>
+ <AdditionalLibrariesDebug>Qt63DQuickInputd.lib</AdditionalLibrariesDebug>
+ <AdditionalLibrariesDebug>Qt63DQuickRenderd.lib</AdditionalLibrariesDebug>
+ <AdditionalLibrariesDebug>Qt63DQuickScene2Dd.lib</AdditionalLibrariesDebug>
+ </Module>
+ <Module Id="47">
+ <Name>Qt Quick Timeline</Name>
+ <proVarQT>quicktimeline</proVarQT>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtQuickTimeline</LibraryPrefix>
+ </Module>
+ <Module Id="48">
+ <Name>Qt Shader Tools</Name>
+ <proVarQT>shadertools</proVarQT>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtShaderTools</LibraryPrefix>
+ </Module>
+ <Module Id="49">
+ <Name>Qt Wayland Compositor</Name>
+ <proVarQT>waylandcompositor</proVarQT>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtWaylandCompositor</LibraryPrefix>
+ </Module>
+ <Module Id="50">
+ <Name>Qt WebEngine Widgets</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtWebEngineWidgets</LibraryPrefix>
+ <proVarQT>webenginewidgets</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtWebEngineCore</IncludePath>
+ <IncludePath>$(QTDIR)\include\QtWebEngineWidgets</IncludePath>
+ <Defines>QT_WEBENGINECORE_LIB</Defines>
+ <Defines>QT_WEBENGINEWIDGETS_LIB</Defines>
+ <AdditionalLibraries>Qt6WebEngineCore.lib</AdditionalLibraries>
+ <AdditionalLibrariesDebug>Qt6WebEngineCored.lib</AdditionalLibrariesDebug>
+ <AdditionalLibraries>Qt6WebEngineWidgets.lib</AdditionalLibraries>
+ <AdditionalLibrariesDebug>Qt6WebEngineWidgetsd.lib</AdditionalLibrariesDebug>
+ </Module>
+ <Module Id="51">
+ <Name>Qt WebEngine Quick</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtWebEngineQuick</LibraryPrefix>
+ <proVarQT>webenginequick</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtWebEngineCore</IncludePath>
+ <IncludePath>$(QTDIR)\include\QtWebEngineQuick</IncludePath>
+ <Defines>QT_WEBENGINECORE_LIB</Defines>
+ <Defines>QT_WEBENGINEQUICK_LIB</Defines>
+ <AdditionalLibraries>Qt6WebEngineCore.lib</AdditionalLibraries>
+ <AdditionalLibrariesDebug>Qt6WebEngineCored.lib</AdditionalLibrariesDebug>
+ <AdditionalLibraries>Qt6WebEngineQuick.lib</AdditionalLibraries>
+ <AdditionalLibrariesDebug>Qt6WebEngineQuickd.lib</AdditionalLibrariesDebug>
+ </Module>
+
+ <!-- Designer -->
+ <Module Id="52">
+ <Name>Designer</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtDesigner</LibraryPrefix>
+ <HasDLL>true</HasDLL>
+ <proVarQT>designer</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtDesigner</IncludePath>
+ <Defines>QT_DESIGNER_LIB</Defines>
+ </Module>
+ <Module Id="53">
+ <Name>Qt UI Tools</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtUiTools</LibraryPrefix>
+ <HasDLL>true</HasDLL>
+ <proVarQT>uitools</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtUiTools</IncludePath>
+ <Defines>QT_UITOOLS_LIB</Defines>
+ </Module>
+ <Module Id="54">
+ <Name>Qt UI Plugin</Name>
+ <Selectable>true</Selectable>
+ <LibraryPrefix>QtUiPlugin</LibraryPrefix>
+ <HasDLL>false</HasDLL>
+ <proVarQT>uiplugin</proVarQT>
+ <IncludePath>$(QTDIR)\include\QtUiPlugin</IncludePath>
+ <Defines>QT_UIPLUGIN_LIB</Defines>
+ <Defines>QDESIGNER_EXPORT_WIDGETS</Defines>
+ </Module>
+ <!-- Designer -->
+
+</QtVsTools>
diff --git a/QtVsTools.Package/qtmodules.xml b/QtVsTools.Package/qtmodules.xml
index 1a56520..364a84a 100644
--- a/QtVsTools.Package/qtmodules.xml
+++ b/QtVsTools.Package/qtmodules.xml
@@ -4,7 +4,6 @@
<Name>Core</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtCore</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>core</proVarQT>
<IncludePath>$(QTDIR)\include\QtCore</IncludePath>
<Defines>QT_CORE_LIB</Defines>
@@ -13,7 +12,6 @@
<Name>Xml</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtXml</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>xml</proVarQT>
<IncludePath>$(QTDIR)\include\QtXml</IncludePath>
<Defines>QT_XML_LIB</Defines>
@@ -22,7 +20,6 @@
<Name>Sql</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtSql</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>sql</proVarQT>
<IncludePath>$(QTDIR)\include\QtSql</IncludePath>
<Defines>QT_SQL_LIB</Defines>
@@ -31,7 +28,6 @@
<Name>OpenGL</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtOpenGL</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>opengl</proVarQT>
<IncludePath>$(QTDIR)\include\QtOpenGL</IncludePath>
<Defines>QT_OPENGL_LIB</Defines>
@@ -40,7 +36,6 @@
<Name>Network</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtNetwork</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>network</proVarQT>
<IncludePath>$(QTDIR)\include\QtNetwork</IncludePath>
<Defines>QT_NETWORK_LIB</Defines>
@@ -49,7 +44,6 @@
<Name>Gui</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtGui</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>gui</proVarQT>
<IncludePath>$(QTDIR)\include\QtGui</IncludePath>
<IncludePath>$(QTDIR)\include\QtANGLE</IncludePath>
@@ -59,7 +53,6 @@
<Name>ActiveQtS</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtAxServer</LibraryPrefix>
- <HasDLL>false</HasDLL>
<proVarQT>axserver</proVarQT>
<IncludePath>$(QTDIR)\include\ActiveQt</IncludePath>
<Defines>QAXSERVER</Defines>
@@ -70,7 +63,6 @@
<Name>ActiveQtC</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtAxContainer</LibraryPrefix>
- <HasDLL>false</HasDLL>
<proVarQT>axcontainer</proVarQT>
<IncludePath>$(QTDIR)\include\ActiveQt</IncludePath>
<AdditionalLibraries>Qt5AxBase.lib</AdditionalLibraries>
@@ -80,13 +72,11 @@
<Name>Main</Name>
<Selectable>false</Selectable>
<LibraryPrefix>qtmain</LibraryPrefix>
- <HasDLL>false</HasDLL>
</Module>
<Module Id="13">
<Name>Svg</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtSvg</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>svg</proVarQT>
<IncludePath>$(QTDIR)\include\QtSvg</IncludePath>
<Defines>QT_SVG_LIB</Defines>
@@ -95,17 +85,14 @@
<Name>Designer</Name>
<Selectable>false</Selectable>
<LibraryPrefix>QtDesigner</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>designer</proVarQT>
<IncludePath>$(QTDIR)\include\QtDesigner</IncludePath>
- <Defines>QDESIGNER_EXPORT_WIDGETS</Defines>
<Defines>QT_DESIGNER_LIB</Defines>
</Module>
<Module Id="15">
<Name>Test</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtTest</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>testlib</proVarQT>
<IncludePath>$(QTDIR)\include\QtTest</IncludePath>
<Defines>QT_TESTLIB_LIB</Defines>
@@ -114,7 +101,6 @@
<Name>Script</Name>
<Selectable>false</Selectable>
<LibraryPrefix>QtScript</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>script</proVarQT>
<IncludePath>$(QTDIR)\include\QtScript</IncludePath>
<Defines>QT_SCRIPT_LIB</Defines>
@@ -123,7 +109,6 @@
<Name>Help</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtHelp</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>help</proVarQT>
<IncludePath>$(QTDIR)\include\QtHelp</IncludePath>
<Defines>QT_HELP_LIB</Defines>
@@ -132,7 +117,6 @@
<Name>WebKit</Name>
<Selectable>false</Selectable>
<LibraryPrefix>QtWebKit</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>webkit</proVarQT>
<IncludePath>$(QTDIR)\include\QtWebKit</IncludePath>
</Module>
@@ -140,7 +124,6 @@
<Name>XmlPatterns</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtXmlPatterns</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>xmlpatterns</proVarQT>
<IncludePath>$(QTDIR)\include\QtXmlPatterns</IncludePath>
<Defines>QT_XMLPATTERNS_LIB</Defines>
@@ -149,7 +132,6 @@
<Name>Enginio</Name>
<Selectable>false</Selectable>
<LibraryPrefix>Enginio</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>enginio</proVarQT>
<IncludePath>$(QTDIR)\include\Enginio</IncludePath>
<Defines>QT_ENGINIO_LIB</Defines>
@@ -158,7 +140,6 @@
<Name>Multimedia</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtMultimedia</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>multimedia</proVarQT>
<IncludePath>$(QTDIR)\include\QtMultimedia</IncludePath>
<Defines>QT_MULTIMEDIA_LIB</Defines>
@@ -167,7 +148,6 @@
<Name>ScriptTools</Name>
<Selectable>false</Selectable>
<LibraryPrefix>QtScriptTools</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>scripttools</proVarQT>
<IncludePath>$(QTDIR)\include\QtScriptTools</IncludePath>
<Defines>QT_SCRIPTTOOLS_LIB</Defines>
@@ -176,7 +156,6 @@
<Name>UiTools</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtUiTools</LibraryPrefix>
- <HasDLL>false</HasDLL>
<proVarQT>uitools</proVarQT>
<IncludePath>$(QTDIR)\include\QtUiTools</IncludePath>
<Defines>QT_UITOOLS_LIB</Defines>
@@ -185,7 +164,6 @@
<Name>Widgets</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtWidgets</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>widgets</proVarQT>
<IncludePath>$(QTDIR)\include\QtWidgets</IncludePath>
<Defines>QT_WIDGETS_LIB</Defines>
@@ -194,7 +172,6 @@
<Name>Location</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtLocation</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>location</proVarQT>
<IncludePath>$(QTDIR)\include\QtLocation</IncludePath>
<Defines>QT_LOCATION_LIB</Defines>
@@ -203,7 +180,6 @@
<Name>Nfc</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtNfc</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>nfc</proVarQT>
<IncludePath>$(QTDIR)\include\QtNfc</IncludePath>
<Defines>QT_NFC_LIB</Defines>
@@ -212,7 +188,6 @@
<Name>Qml</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtQml</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>qml</proVarQT>
<IncludePath>$(QTDIR)\include\QtQml</IncludePath>
<Defines>QT_QML_LIB</Defines>
@@ -221,7 +196,6 @@
<Name>Bluetooth</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtBluetooth</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>bluetooth</proVarQT>
<IncludePath>$(QTDIR)\include\QtBluetooth</IncludePath>
<Defines>QT_BLUETOOTH_LIB</Defines>
@@ -230,7 +204,6 @@
<Name>Positioning</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtPositioning</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>positioning</proVarQT>
<IncludePath>$(QTDIR)\include\QtPositioning</IncludePath>
<Defines>QT_POSITIONING_LIB</Defines>
@@ -239,7 +212,6 @@
<Name>SerialPort</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtSerialPort</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>serialport</proVarQT>
<IncludePath>$(QTDIR)\include\QtSerialPort</IncludePath>
<Defines>QT_SERIALPORT_LIB</Defines>
@@ -248,7 +220,6 @@
<Name>PrintSupport</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtPrintSupport</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>printsupport</proVarQT>
<IncludePath>$(QTDIR)\include\QtPrintSupport</IncludePath>
<Defines>QT_PRINTSUPPORT_LIB</Defines>
@@ -257,7 +228,6 @@
<Name>WebChannel</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtWebChannel</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>webchannel</proVarQT>
<IncludePath>$(QTDIR)\include\QtWebChannel</IncludePath>
<Defines>QT_WEBCHANNEL_LIB</Defines>
@@ -266,7 +236,6 @@
<Name>WebSockets</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtWebSockets</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>websockets</proVarQT>
<IncludePath>$(QTDIR)\include\QtWebSockets</IncludePath>
<Defines>QT_WEBSOCKETS_LIB</Defines>
@@ -275,7 +244,6 @@
<Name>Sensors</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtSensors</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>sensors</proVarQT>
<IncludePath>$(QTDIR)\include\QtSensors</IncludePath>
<Defines>QT_SENSORS_LIB</Defines>
@@ -284,7 +252,6 @@
<Name>WindowsExtras</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtWinExtras</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>winextras</proVarQT>
<IncludePath>$(QTDIR)\include\QtWinExtras</IncludePath>
<Defines>QT_WINEXTRAS_LIB</Defines>
@@ -293,7 +260,6 @@
<Name>QuickWidgets</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtQuickWidgets</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>quickwidgets</proVarQT>
<IncludePath>$(QTDIR)\include\QtQuickWidgets</IncludePath>
<Defines>QT_QUICKWIDGETS_LIB</Defines>
@@ -302,7 +268,6 @@
<Name>Quick</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtQuick</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>quick</proVarQT>
<IncludePath>$(QTDIR)\include\QtQuick</IncludePath>
<Defines>QT_QUICK_LIB</Defines>
@@ -311,7 +276,6 @@
<Name>WebkitWidgets</Name>
<Selectable>false</Selectable>
<LibraryPrefix>QtWebkitWidgets</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>webkitwidgets</proVarQT>
<IncludePath>$(QTDIR)\include\QtWebkitWidgets</IncludePath>
<Defines>QT_WEBKITWIDGETS_LIB</Defines>
@@ -320,7 +284,6 @@
<Name>Concurrent</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtConcurrent</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>concurrent</proVarQT>
<IncludePath>$(QTDIR)\include\QtConcurrent</IncludePath>
<Defines>QT_CONCURRENT_LIB</Defines>
@@ -329,7 +292,6 @@
<Name>MultimediaWidgets</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtMultimediaWidgets</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>multimediawidgets</proVarQT>
<IncludePath>$(QTDIR)\include\QtMultimediaWidgets</IncludePath>
<Defines>QT_MULTIMEDIAWIDGETS_LIB</Defines>
@@ -338,7 +300,6 @@
<Name>3D</Name>
<Selectable>true</Selectable>
<LibraryPrefix>Qt3DCore</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>3dcore 3danimation 3dextras 3dinput 3dlogic 3drender</proVarQT>
<IncludePath>$(QTDIR)\include\Qt3DCore</IncludePath>
<IncludePath>$(QTDIR)\include\Qt3DAnimation</IncludePath>
@@ -369,7 +330,6 @@
<Name>3D Quick</Name>
<Selectable>true</Selectable>
<LibraryPrefix>Qt3DQuick</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>3dquick</proVarQT>
<IncludePath>$(QTDIR)\include\Qt3DQuick</IncludePath>
<IncludePath>$(QTDIR)\include\Qt3DQuickAnimation</IncludePath>
@@ -400,7 +360,6 @@
<Name>DBus</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtDBus</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>dbus</proVarQT>
<IncludePath>$(QTDIR)\include\QtDBus</IncludePath>
<Defines>QT_DBUS_LIB</Defines>
@@ -409,7 +368,6 @@
<Name>Gamepad</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtGamepad</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>gamepad</proVarQT>
<IncludePath>$(QTDIR)\include\QtGamepad</IncludePath>
<Defines>QT_GAMEPAD_LIB</Defines>
@@ -418,7 +376,6 @@
<Name>OpenGL Extensions</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtOpenGLExtensions</LibraryPrefix>
- <HasDLL>false</HasDLL>
<proVarQT>openglextensions</proVarQT>
<IncludePath>$(QTDIR)\include\QtOpenGLExtensions</IncludePath>
<Defines>QT_OPENGLEXTENSIONS_LIB</Defines>
@@ -427,7 +384,6 @@
<Name>QuickTest</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtQuickTest</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>qmltest</proVarQT>
<IncludePath>$(QTDIR)\include\QtQuickTest</IncludePath>
<Defines>QT_QMLTEST_LIB</Defines>
@@ -436,7 +392,6 @@
<Name>Quick Controls2</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtQuickControls2</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>quickcontrols2</proVarQT>
<IncludePath>$(QTDIR)\include\QtQuickControls2</IncludePath>
<Defines>QT_QUICKCONTROLS2_LIB</Defines>
@@ -445,7 +400,6 @@
<Name>Scxml</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtScxml</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>scxml</proVarQT>
<IncludePath>$(QTDIR)\include\QtScxml</IncludePath>
<Defines>QT_SCXML_LIB</Defines>
@@ -454,7 +408,6 @@
<Name>Serial Bus</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtSerialBus</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>serialbus</proVarQT>
<IncludePath>$(QTDIR)\include\QtSerialBus</IncludePath>
<Defines>QT_SERIALBUS_LIB</Defines>
@@ -463,16 +416,15 @@
<Name>UI Plugin</Name>
<Selectable>false</Selectable>
<LibraryPrefix>QtUiPlugin</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>uiplugin</proVarQT>
<IncludePath>$(QTDIR)\include\QtUiPlugin</IncludePath>
<Defines>QT_UIPLUGIN_LIB</Defines>
+ <Defines>QDESIGNER_EXPORT_WIDGETS</Defines>
</Module>
<Module Id="111">
<Name>WebEngine</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtWebEngine</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>webengine</proVarQT>
<IncludePath>$(QTDIR)\include\QtWebEngine</IncludePath>
<IncludePath>$(QTDIR)\include\QtWebEngineCore</IncludePath>
@@ -487,7 +439,6 @@
<Name>WebEngine Widgets</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtWebEngineWidgets</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>webenginewidgets</proVarQT>
<IncludePath>$(QTDIR)\include\QtWebEngineWidgets</IncludePath>
<IncludePath>$(QTDIR)\include\QtWebEngineCore</IncludePath>
@@ -502,7 +453,6 @@
<Name>Charts</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtCharts</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>charts</proVarQT>
<IncludePath>$(QTDIR)\include\QtCharts</IncludePath>
<Defines>QT_CHARTS_LIB</Defines>
@@ -511,7 +461,6 @@
<Name>Data Visualization</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtDataVisualization</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>datavisualization</proVarQT>
<IncludePath>$(QTDIR)\include\QtDataVisualization</IncludePath>
<Defines>QT_DATAVISUALIZATION_LIB</Defines>
@@ -520,7 +469,6 @@
<Name>Network Authorization</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtNetworkAuth</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>networkauth</proVarQT>
<IncludePath>$(QTDIR)\include\QtNetworkAuth</IncludePath>
<Defines>QT_NETWORKAUTH_LIB</Defines>
@@ -529,7 +477,6 @@
<Name>Speech</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtTextToSpeech</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>texttospeech</proVarQT>
<IncludePath>$(QTDIR)\include\QtTextToSpeech</IncludePath>
<Defines>QT_TEXTTOSPEECH_LIB</Defines>
@@ -538,7 +485,6 @@
<Name>Remote Objects</Name>
<Selectable>true</Selectable>
<LibraryPrefix>QtRemoteObjects</LibraryPrefix>
- <HasDLL>true</HasDLL>
<proVarQT>remoteobjects</proVarQT>
<IncludePath>$(QTDIR)\include\QtRemoteObjects</IncludePath>
<Defines>QT_REMOTEOBJECTS_LIB</Defines>
diff --git a/QtVsTools.Package/source.extension.vsixmanifest_TT b/QtVsTools.Package/source.extension.vsixmanifest_TT
index 7321b70..1aa4a5d 100644
--- a/QtVsTools.Package/source.extension.vsixmanifest_TT
+++ b/QtVsTools.Package/source.extension.vsixmanifest_TT
@@ -88,9 +88,9 @@
<DisplayName>Qt Visual Studio Tools</DisplayName>
<Description xml:space="preserve">The Qt VS Tools for Visual Studio <#=VS_NAME#> allow developers to use the standard development environment without having to worry about any Qt-related build steps or tools.</Description>
<#=XML_COMMENT_BEGIN#> END Generated Text -->
- <MoreInfo>http://www.qt.io</MoreInfo>
+ <MoreInfo>https://doc.qt.io/qtvstools/index.html</MoreInfo>
<License>LICENSE.GPL3-EXCEPT</License>
- <ReleaseNotes>Changelog</ReleaseNotes>
+ <ReleaseNotes>https://code.qt.io/cgit/qt-labs/vstools.git/tree/Changelog</ReleaseNotes>
<Icon>qt.ico</Icon>
<PreviewImage>preview.png</PreviewImage>
</Metadata>
@@ -195,6 +195,20 @@
d:TargetPath="|QtTemplate.Item.Widget;TemplateProjectOutputGroup|" Path="ItemTemplates"
d:VsixSubPath="ItemTemplates" />
<Asset
+ Type="Microsoft.VisualStudio.ItemTemplate" d:Source="Project" d:ProjectName="WidgetsClass"
+ d:TargetPath="|QtTemplate.Item.WidgetsClass;TemplateProjectOutputGroup|" Path="ItemTemplates"
+ d:VsixSubPath="ItemTemplates" />
+ <Asset
+ Type="Microsoft.VisualStudio.ItemTemplate" d:Source="Project" d:ProjectName="QtClass"
+ d:TargetPath="|QtTemplate.Item.QtClass;TemplateProjectOutputGroup|" Path="ItemTemplates"
+ d:VsixSubPath="ItemTemplates" />
+ <Asset
+ Type="Microsoft.VisualStudio.ItemTemplate" d:Source="Project" d:ProjectName="Translation"
+ d:TargetPath="|QtTemplate.Item.Translation;TemplateProjectOutputGroup|" Path="ItemTemplates"
+ d:VsixSubPath="ItemTemplates" />
+ <Asset
Type="Microsoft.VisualStudio.VsPackage" d:Source="File" Path="QtVsTools.Qml.Debug.pkgdef" />
+ <Asset
+ Type="Microsoft.VisualStudio.VsPackage" d:Source="File" Path="QtVsTools.Icons.pkgdef" />
</Assets>
</PackageManifest>
diff --git a/QtVsTools.RegExpr/Properties/AssemblyInfo.cs b/QtVsTools.RegExpr/Properties/AssemblyInfo.cs
index 87d3c5e..4753562 100644
--- a/QtVsTools.RegExpr/Properties/AssemblyInfo.cs
+++ b/QtVsTools.RegExpr/Properties/AssemblyInfo.cs
@@ -1,5 +1,4 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
diff --git a/QtVsTools.RegExpr/QtVsTools.RegExpr.csproj b/QtVsTools.RegExpr/QtVsTools.RegExpr.csproj
index 92577c4..b309bab 100644
--- a/QtVsTools.RegExpr/QtVsTools.RegExpr.csproj
+++ b/QtVsTools.RegExpr/QtVsTools.RegExpr.csproj
@@ -66,21 +66,18 @@
// -->
<ItemGroup>
<Reference Include="System" />
- <Reference Include="System.Xml.Linq" />
</ItemGroup>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
// Version specific references
// -->
+ <!--<Import Project="$(SolutionDir)\references.props" />-->
<!-- // Visual Studio 2022 -->
- <ItemGroup Condition="'$(VisualStudioVersion)'=='17.0'">
- </ItemGroup>
+ <ItemGroup Condition="'$(VisualStudioVersion)'=='17.0'" />
<!-- // Visual Studio 2019 -->
- <ItemGroup Condition="'$(VisualStudioVersion)'=='16.0'">
- </ItemGroup>
+ <ItemGroup Condition="'$(VisualStudioVersion)'=='16.0'" />
<!-- // Visual Studio 2017 -->
- <ItemGroup Condition="'$(VisualStudioVersion)'=='15.0'">
- </ItemGroup>
+ <ItemGroup Condition="'$(VisualStudioVersion)'=='15.0'" />
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
// Solution project references
diff --git a/QtVsTools.RegExpr/expression/CharClassSet.cs b/QtVsTools.RegExpr/expression/CharClassSet.cs
index 36e1fa6..16cc9ba 100644
--- a/QtVsTools.RegExpr/expression/CharClassSet.cs
+++ b/QtVsTools.RegExpr/expression/CharClassSet.cs
@@ -26,7 +26,6 @@
**
****************************************************************************/
-using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@@ -48,8 +47,8 @@
///
public partial class CharClassSet : CharClass, IEnumerable<IEnumerable<Element>>
{
- public IEnumerable<Element> Positives { get; set; }
- public IEnumerable<Element> Negatives { get; set; }
+ private IEnumerable<Element> Positives { get; set; }
+ private IEnumerable<Element> Negatives { get; set; }
bool IsSubSet { get; set; }
bool HasPositive { get { return Positives != null && Positives.Any(); } }
@@ -210,13 +209,13 @@
public class Expr
{
- public Op Operator { get; private set; }
+ public Op Operator { get; }
- public List<Expr> Factors { get; private set; }
+ public List<Expr> Factors { get; }
public Expr(Op op, List<Expr> factors) { Operator = op; Factors = factors; }
public Expr(Op op, params Expr[] factors) : this(op, factors.ToList()) { }
- public CharClass Term { get; private set; }
+ public CharClass Term { get; }
public Expr(CharClass c) { Operator = Op.Term; Term = c; }
public static implicit operator Expr(CharClass c) { return new Expr(c); }
public static implicit operator Expr(string s) { return Char[s]; }
@@ -325,7 +324,7 @@
{
public Expr Expr { get; set; }
public Queue<Expr> Children { get; set; }
- public List<CharClassSet> SubSets { get; set; }
+ public List<CharClassSet> SubSets { get; }
public StackFrame()
{
Expr = null;
diff --git a/QtVsTools.RegExpr/expression/RegExprAssert.cs b/QtVsTools.RegExpr/expression/RegExprAssert.cs
index 09172c0..82c6721 100644
--- a/QtVsTools.RegExpr/expression/RegExprAssert.cs
+++ b/QtVsTools.RegExpr/expression/RegExprAssert.cs
@@ -26,9 +26,7 @@
**
****************************************************************************/
-using System;
using System.Collections.Generic;
-using System.Collections.Concurrent;
using System.Text;
namespace QtVsTools.SyntaxAnalysis
@@ -140,7 +138,7 @@
public class AssertExprBuilder
{
- AssertTemplate Template { get; set; }
+ AssertTemplate Template { get; }
public AssertExprBuilder(AssertTemplate template)
{
diff --git a/QtVsTools.RegExpr/expression/RegExprRepeat.cs b/QtVsTools.RegExpr/expression/RegExprRepeat.cs
index a6ee1fa..d49b9ba 100644
--- a/QtVsTools.RegExpr/expression/RegExprRepeat.cs
+++ b/QtVsTools.RegExpr/expression/RegExprRepeat.cs
@@ -26,7 +26,6 @@
**
****************************************************************************/
-using System;
using System.Collections.Generic;
using System.Text;
diff --git a/QtVsTools.RegExpr/expression/RegExprToken.cs b/QtVsTools.RegExpr/expression/RegExprToken.cs
index 08152b1..47dce8e 100644
--- a/QtVsTools.RegExpr/expression/RegExprToken.cs
+++ b/QtVsTools.RegExpr/expression/RegExprToken.cs
@@ -57,13 +57,13 @@
{
public string Id { get; set; }
- public bool SkipLeadingWhitespace { get; set; }
- public RegExpr LeadingWhitespace { get; set; }
+ private bool SkipLeadingWhitespace { get; }
+ private RegExpr LeadingWhitespace { get; }
- public RegExpr Expr { get; set; }
+ private RegExpr Expr { get; }
- public HashSet<Token> Children { get; set; }
- public Dictionary<string, Token> Parents { get; set; }
+ private HashSet<Token> Children { get; }
+ public Dictionary<string, Token> Parents { get; }
public IEnumerable<string> CaptureIds => Parents.Keys;
public Token(string id, RegExpr skipWs, RegExpr expr)
@@ -170,7 +170,7 @@
/// <summary>
/// Set of rules that can be applied to the token.
/// </summary>
- TokenRules Rules { get; set; }
+ TokenRules Rules { get; }
public void Add(IProductionRule rule)
{
@@ -221,7 +221,7 @@
public class TokenGroup : IEnumerable<string>
{
- HashSet<string> TokenIds { get; set; }
+ HashSet<string> TokenIds { get; }
public TokenGroup(params string[] tokenIds)
{
@@ -261,7 +261,7 @@
public class TokenRules : IEnumerable<IProductionRule>
{
- Dictionary<RuleCallback.Selector, IProductionRule> Rules { get; set; }
+ Dictionary<RuleCallback.Selector, IProductionRule> Rules { get; }
IProductionRule DefaultRule { get; set; }
public TokenRules()
@@ -383,6 +383,6 @@
public object Production { get; }
}
- static TokenEndOfList EndOfList = new TokenEndOfList();
+ static readonly TokenEndOfList EndOfList = new TokenEndOfList();
}
}
diff --git a/QtVsTools.RegExpr/expression/Renderer.cs b/QtVsTools.RegExpr/expression/Renderer.cs
index c79da8c..3f8b334 100644
--- a/QtVsTools.RegExpr/expression/Renderer.cs
+++ b/QtVsTools.RegExpr/expression/Renderer.cs
@@ -26,7 +26,6 @@
**
****************************************************************************/
-using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
diff --git a/QtVsTools.RegExpr/parser/ParseTree.cs b/QtVsTools.RegExpr/parser/ParseTree.cs
index 1ee054c..4ff56d0 100644
--- a/QtVsTools.RegExpr/parser/ParseTree.cs
+++ b/QtVsTools.RegExpr/parser/ParseTree.cs
@@ -26,11 +26,8 @@
**
****************************************************************************/
-using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
-using System.Text.RegularExpressions;
namespace QtVsTools.SyntaxAnalysis
{
@@ -70,7 +67,7 @@
}
}
- static NodeComparer _Comparer = new NodeComparer();
+ static readonly NodeComparer _Comparer = new NodeComparer();
public static IComparer<Node> Comparer { get { return _Comparer; } }
public Token Token { get; set; }
@@ -80,11 +77,9 @@
public Node Parent { get; set; }
- SortedList<int, Node> _ChildNodes = new SortedList<int, Node>();
- public SortedList<int, Node> ChildNodes { get { return _ChildNodes; } }
+ public SortedList<int, Node> ChildNodes { get; } = new SortedList<int, Node>();
- ProductionObjects _ChildProductions = new ProductionObjects();
- public ProductionObjects ChildProductions { get { return _ChildProductions; } }
+ public ProductionObjects ChildProductions { get; } = new ProductionObjects();
public Queue<Node> TokenStream { get; set; }
public Stack<Node> OperatorStack { get; set; }
diff --git a/QtVsTools.RegExpr/parser/Parser.cs b/QtVsTools.RegExpr/parser/Parser.cs
index f69cae4..e2b9f36 100644
--- a/QtVsTools.RegExpr/parser/Parser.cs
+++ b/QtVsTools.RegExpr/parser/Parser.cs
@@ -27,8 +27,6 @@
****************************************************************************/
using System;
-using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
@@ -46,7 +44,7 @@
/// </summary>
public partial class Parser
{
- Renderer Renderer { get; set; }
+ Renderer Renderer { get; }
Pattern Pattern { get; set; }
public Regex Regex { get; private set; }
@@ -118,11 +116,9 @@
foreach (var node in nodes.Where(n => n.Token != Pattern.Root)) {
// Get nodes captured by parent token
- Token parentToken;
- if (!node.Token.Parents.TryGetValue(node.CaptureId, out parentToken))
+ if (!node.Token.Parents.TryGetValue(node.CaptureId, out Token parentToken))
throw new ParseErrorException("Unknown capture ID");
- ParseTree.Node[] parentNodes;
- if (!nodesByToken.TryGetValue(parentToken, out parentNodes))
+ if (!nodesByToken.TryGetValue(parentToken, out ParseTree.Node[] parentNodes))
throw new ParseErrorException("Missing parent nodes");
// Find parent node
int idx = Array.BinarySearch(parentNodes, node, ParseTree.Node.Comparer);
diff --git a/QtVsTools.RegExpr/production/Production.cs b/QtVsTools.RegExpr/production/Production.cs
index 8dc30cc..39d770b 100644
--- a/QtVsTools.RegExpr/production/Production.cs
+++ b/QtVsTools.RegExpr/production/Production.cs
@@ -30,11 +30,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
-using System.IO;
using System.Linq;
-using System.Linq.Expressions;
-using System.Reflection;
-using System.Text;
namespace QtVsTools.SyntaxAnalysis
{
@@ -215,8 +211,8 @@
/// </summary>
public partial class ProductionObjects : IEnumerable<KeyValuePair<string, object>>
{
- List<KeyValuePair<string, object>> Productions { get; set; }
- Dictionary<string, List<object>> ProductionsByTokenId { get; set; }
+ List<KeyValuePair<string, object>> Productions { get; }
+ Dictionary<string, List<object>> ProductionsByTokenId { get; }
public ProductionObjects()
{
@@ -227,8 +223,7 @@
public void Add(string tokenId, object prodObj)
{
Productions.Add(new KeyValuePair<string, object>(tokenId, prodObj));
- List<object> prodObjs;
- if (!ProductionsByTokenId.TryGetValue(tokenId, out prodObjs))
+ if (!ProductionsByTokenId.TryGetValue(tokenId, out List<object> prodObjs))
ProductionsByTokenId.Add(tokenId, prodObjs = new List<object>());
prodObjs.Add(prodObj);
}
@@ -238,8 +233,7 @@
if (string.IsNullOrEmpty(tokenId))
return Empty<T>();
- List<object> tokenProds;
- if (!ProductionsByTokenId.TryGetValue(tokenId, out tokenProds))
+ if (!ProductionsByTokenId.TryGetValue(tokenId, out List<object> tokenProds))
return Empty<T>();
return tokenProds
diff --git a/QtVsTools.RegExpr/production/ProductionRule.cs b/QtVsTools.RegExpr/production/ProductionRule.cs
index 8884aae..2299177 100644
--- a/QtVsTools.RegExpr/production/ProductionRule.cs
+++ b/QtVsTools.RegExpr/production/ProductionRule.cs
@@ -29,11 +29,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
-using System.Linq.Expressions;
using System.Reflection;
-using System.Text;
namespace QtVsTools.SyntaxAnalysis
{
@@ -66,7 +63,7 @@
public virtual Delimiter Delimiters { get { return Delimiter.None; } }
public virtual Operand Operands { get { return Operand.None; } }
- protected List<IRuleAction<T>> Actions = new List<IRuleAction<T>>();
+ private readonly List<IRuleAction<T>> Actions = new List<IRuleAction<T>>();
protected void Init(
int priority, RuleCallback.Selector select, RuleCallback.PreCondition pre)
diff --git a/QtVsTools.RegExpr/production/ProductionRuleAction.cs b/QtVsTools.RegExpr/production/ProductionRuleAction.cs
index 71662d8..7d7a2e0 100644
--- a/QtVsTools.RegExpr/production/ProductionRuleAction.cs
+++ b/QtVsTools.RegExpr/production/ProductionRuleAction.cs
@@ -135,11 +135,9 @@
public bool Execute(ref T prod, string value, params object[] operands)
{
int idx = 0;
- T1 x;
- T2 y;
- if (!GetOperand(out x, operands, ref idx))
+ if (!GetOperand(out T1 x, operands, ref idx))
return false;
- if (!GetOperand(out y, operands, ref idx))
+ if (!GetOperand(out T2 y, operands, ref idx))
return false;
if (!TestAssert(prod, value, x, y))
diff --git a/QtVsTools.RegExpr/utils/Consts.cs b/QtVsTools.RegExpr/utils/Consts.cs
index 4835958..ec1e394 100644
--- a/QtVsTools.RegExpr/utils/Consts.cs
+++ b/QtVsTools.RegExpr/utils/Consts.cs
@@ -26,11 +26,6 @@
**
****************************************************************************/
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
namespace QtVsTools.SyntaxAnalysis
{
using static CharClass;
@@ -82,7 +77,7 @@
/// <summary><![CDATA[
/// Equivalent to: [\S]
/// ]]></summary>
- public static CharClassLiteral CharNonSpace
+ private static CharClassLiteral CharNonSpace
{ get { return new CharClassLiteral { LiteralChars = @"\S" }; } }
/// <summary><![CDATA[
@@ -181,21 +176,17 @@
public static RegExpr SkipWs
{ get { return new Token(); } }
- static CharExprBuilder _Char = new CharExprBuilder();
+ static readonly CharExprBuilder _Char = new CharExprBuilder();
public static CharExprBuilder Char { get { return _Char; } }
public static CharExprBuilder Chars { get { return _Char; } }
- static CharSetExprBuilder _CharSet = new CharSetExprBuilder();
- public static CharSetExprBuilder CharSet { get { return _CharSet; } }
+ public static CharSetExprBuilder CharSet { get; } = new CharSetExprBuilder();
- static CharSetRawExprBuilder _CharSetRaw = new CharSetRawExprBuilder();
- public static CharSetRawExprBuilder CharSetRaw { get { return _CharSetRaw; } }
+ public static CharSetRawExprBuilder CharSetRaw { get; } = new CharSetRawExprBuilder();
- static AssertExprBuilder _LookAhead = new AssertExprBuilder(AssertLookAhead);
- public static AssertExprBuilder LookAhead { get { return _LookAhead; } }
+ public static AssertExprBuilder LookAhead { get; } = new AssertExprBuilder(AssertLookAhead);
- static AssertExprBuilder _LookBehind = new AssertExprBuilder(AssertLookBehind);
- public static AssertExprBuilder LookBehind { get { return _LookBehind; } }
+ public static AssertExprBuilder LookBehind { get; } = new AssertExprBuilder(AssertLookBehind);
public const SkipWhitespace SkipWs_Disable = SkipWhitespace.Disable;
}
diff --git a/QtVsTools.Wizards/Common/GuiPage.xaml b/QtVsTools.Wizards/Common/GuiPage.xaml
new file mode 100644
index 0000000..cdbc560
--- /dev/null
+++ b/QtVsTools.Wizards/Common/GuiPage.xaml
@@ -0,0 +1,307 @@
+<!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+-->
+
+<common:WizardPage x:Class="QtVsTools.Wizards.Common.GuiPage"
+ xmlns:common="clr-namespace:QtVsTools.Wizards.Common"
+ xmlns:util="clr-namespace:QtVsTools.Wizards.Util"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ KeepAlive="True"
+ mc:Ignorable="d"
+ d:DesignHeight="445"
+ d:DesignWidth="585">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="100" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Image Grid.Column="0"
+ HorizontalAlignment="Center"
+ Source="/QtVsTools.Wizards;component/Resources/Qt-logo-small.png"
+ VerticalAlignment="Top"
+ Margin="0,25,0,0"
+ RenderTransformOrigin="1,0">
+ <Image.RenderTransform>
+ <TransformGroup>
+ <ScaleTransform ScaleY="0.86"
+ ScaleX="0.86" />
+ </TransformGroup>
+ </Image.RenderTransform>
+ </Image>
+ <Grid Grid.Column="1"
+ Margin="25,25,10,0">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TextBlock TextWrapping="Wrap"
+ Grid.Row="0">
+ <Run FontWeight="Bold"
+ Text="{Binding Path=Header}" />
+ <LineBreak />
+ <LineBreak />
+ <Run Text="{Binding Path=Message}" />
+ <LineBreak />
+ </TextBlock>
+ <Grid Grid.Row="1">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Grid.Resources>
+ <Style TargetType="TextBox">
+ <Style.Triggers>
+ <Trigger Property="Validation.HasError"
+ Value="true">
+ <Setter Property="ToolTip"
+ Value="{Binding RelativeSource={RelativeSource Self},
+ Path=(Validation.Errors)[0].ErrorContent}" />
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Resources>
+ <StackPanel Grid.Column="0">
+ <TextBlock Text="Class Name:"
+ Margin="0,0,10,0" />
+ <TextBox Margin="0,0,10,15"
+ Name="ClassName"
+ TextChanged="OnClassNameChanged"
+ TabIndex="0">
+ <TextBox.Text>
+ <Binding Path="Data.ClassName"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:ClassNameValidationRule SupportNamespaces="True"/>
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Text="User Interface (.ui) file:"
+ Margin="0,0,10,0" />
+ <TextBox Name="UiFile"
+ Margin="0,0,10,52"
+ TabIndex="2">
+ <TextBox.Text>
+ <Binding Path="Data.UiFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".ui" />
+ <util:FileExistsinFilterValidationRule Filter="FL_UiFiles" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Text="Header (.h) file:"
+ Margin="0,0,10,0" />
+ <TextBox Name="ClassHeaderFile"
+ Margin="0,0,10,5"
+ TabIndex="6">
+ <TextBox.Text>
+ <Binding Path="Data.ClassHeaderFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".h" />
+ <util:FileExistsinFilterValidationRule Filter="FL_HFiles" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Text="Source (.cpp) file:"
+ Margin="0,0,0,0" />
+ <TextBox Name="ClassSourceFile"
+ Margin="0,0,10,15"
+ TabIndex="8">
+ <TextBox.Text>
+ <Binding Path="Data.ClassSourceFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".cpp" />
+ <util:FileExistsinFilterValidationRule Filter="FL_CppFiles" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+
+ </StackPanel>
+ <StackPanel Grid.Column="1">
+ <TextBlock Text="Base class:" />
+ <ComboBox Margin="0,0,0,11"
+ IsEditable="{Binding Path=IsClassWizardPage}"
+ SelectedIndex="0"
+ Text="{Binding Path=Data.BaseClass}"
+ IsSynchronizedWithCurrentItem="True"
+ TabIndex="1">
+ <ComboBoxItem Content="QMainWindow"
+ IsSelected="True" />
+ <ComboBoxItem Content="QWidget" />
+ <ComboBoxItem Content="QDialog" />
+ </ComboBox>
+ <TextBlock TextWrapping="Wrap"
+ Text="Ui Class Inclusion as:"
+ Margin="0,0,0,5"
+ VerticalAlignment="Top"/>
+ <StackPanel Grid.Column="1"
+ Margin="10,0,0,10">
+ <StackPanel.Resources>
+ <util:UiClassInclusionConverter x:Key="UiClassInclusionConverter" />
+ </StackPanel.Resources>
+ <RadioButton Content="Member"
+ Margin="0,0,0,5"
+ IsChecked="{
+ Binding Path=Data.UiClassInclusion,
+ Converter={StaticResource UiClassInclusionConverter},
+ ConverterParameter={x:Static common:UiClassInclusion.Member}
+ }"
+ TabIndex="3" />
+ <RadioButton Content="Member Pointer"
+ Margin="0,0,0,5"
+ IsChecked="{
+ Binding Path=Data.UiClassInclusion,
+ Converter={StaticResource UiClassInclusionConverter},
+ ConverterParameter={x:Static common:UiClassInclusion.MemberPointer}
+ }"
+ TabIndex="4" />
+ <RadioButton Content="Multiple Inheritance"
+ IsChecked="{
+ Binding Path=Data.UiClassInclusion,
+ Converter={StaticResource UiClassInclusionConverter},
+ ConverterParameter={x:Static common:UiClassInclusion.MultipleInheritance}
+ }"
+ TabIndex="5" />
+ </StackPanel>
+ <CheckBox Content="Insert Q_OBJECT macro"
+ TabIndex="7"
+ Margin="0,0,0,-17"
+ Name="InsertQObjectMacro"
+ Visibility="{Binding Path=QObjectMacro}"
+ IsChecked="{Binding Path=Data.InsertQObjectMacro}" />
+ <TextBlock Margin="0,0,10,0"
+ Text="Resource (.qrc) file:"
+ Visibility="{Binding Path=ClassPageVisible}" />
+ <TextBox Name="QrcFile"
+ Margin="0,0,0,23"
+ TabIndex="7"
+ Visibility="{Binding Path=ClassPageVisible}" >
+ <TextBox.Text>
+ <Binding Path="Data.QrcFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".qrc" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <CheckBox Content="Lower case file names"
+ Margin="0,0,0,5"
+ Name="LowerCaseFileNames"
+ TabIndex="9"
+ Click="OnLowerCaseFileNamesClick" />
+ <CheckBox Content="Precompiled header"
+ Margin="0,0,0,5"
+ IsChecked="{Binding Path=Data.UsePrecompiledHeader}"
+ TabIndex="10"
+ Visibility="{Binding Path=ClassPageVisible}"/>
+ <CheckBox Content="Add default application icon"
+ Margin="0,0,0,0"
+ IsChecked="{Binding Path=Data.AddDefaultAppIcon}"
+ TabIndex="11"
+ Visibility="{Binding Path=ClassPageVisible}" />
+ </StackPanel>
+ </Grid>
+ <StackPanel HorizontalAlignment="Right"
+ Orientation="Horizontal"
+ Grid.Row="2"
+ Margin="0,0,0,10">
+ <Button Click="OnPreviousButtonClick"
+ Name="PreviousButton"
+ IsEnabled="{Binding Path=PreviousButtonEnabled}"
+ MinWidth="75">< _Previous</Button>
+ <Button MinWidth="75"
+ Name="NextButton"
+ Click="OnNextButtonClick"
+ IsEnabled="{Binding Path=NextButtonEnabled}"
+ Margin="10,0,0,0">_Next ></Button>
+ <Button MinWidth="75"
+ Click="OnFinishButtonClick"
+ Margin="10,0,0,0"
+ IsDefault="True"
+ Name="FinishButton"
+ Content="_Finish"
+ VerticalAlignment="Bottom">
+ <Button.Style>
+ <Style TargetType="Button">
+ <Setter Property="IsEnabled"
+ Value="false" />
+ <Style.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding Path=FinishButtonEnabled}"
+ Value="true" />
+ <Condition Binding="{Binding ElementName=ClassName,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=ClassHeaderFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=ClassSourceFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=UiFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=QrcFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ </MultiDataTrigger.Conditions>
+ <Setter Property="IsEnabled"
+ Value="true" />
+ </MultiDataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+ <Button Click="OnCancelButtonClick"
+ MinWidth="75"
+ Margin="10,0,0,0"
+ Name="CancelButton"
+ IsEnabled="{Binding Path=CancelButtonEnabled}"
+ IsCancel="True">_Cancel</Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+</common:WizardPage>
diff --git a/QtVsTools.Wizards/Common/GuiPage.xaml.cs b/QtVsTools.Wizards/Common/GuiPage.xaml.cs
new file mode 100644
index 0000000..764ca09
--- /dev/null
+++ b/QtVsTools.Wizards/Common/GuiPage.xaml.cs
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Windows;
+using System.Windows.Controls;
+
+namespace QtVsTools.Wizards.Common
+{
+ public partial class GuiPage : WizardPage
+ {
+ public bool IsClassWizardPage { get; set; } = false;
+ public Visibility ClassPageVisible => IsClassWizardPage ? Visibility.Hidden : Visibility.Visible;
+ public Visibility QObjectMacro => IsClassWizardPage ? Visibility.Visible : Visibility.Collapsed;
+
+ public GuiPage()
+ {
+ InitializeComponent();
+ DataContext = this;
+ UpdateFileNames();
+ }
+
+ private void OnClassNameChanged(object sender, TextChangedEventArgs e)
+ {
+ UpdateFileNames();
+ }
+
+ private void OnLowerCaseFileNamesClick(object sender, RoutedEventArgs e)
+ {
+ UpdateFileNames();
+ }
+
+ private void UpdateFileNames()
+ {
+ var filename = ClassName.Text;
+ if (LowerCaseFileNames.IsChecked.GetValueOrDefault())
+ filename = filename.ToLower();
+
+ // support namespaces in class name
+ var index = filename.LastIndexOf(@":", System.StringComparison.Ordinal);
+ if (index >= 0)
+ filename = filename.Substring(index + 1);
+
+ ClassHeaderFile.Text = filename + @".h";
+ ClassSourceFile.Text = filename + @".cpp";
+ UiFile.Text = filename + @".ui";
+ QrcFile.Text = filename + @".qrc";
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/Common/UiClassInclusion.cs b/QtVsTools.Wizards/Common/UiClassInclusion.cs
new file mode 100644
index 0000000..b99c71f
--- /dev/null
+++ b/QtVsTools.Wizards/Common/UiClassInclusion.cs
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+namespace QtVsTools.Wizards.Common
+{
+ public enum UiClassInclusion
+ {
+ Member,
+ MemberPointer,
+ MultipleInheritance
+ }
+}
diff --git a/QtVsTools.Wizards/Common/WizardData.cs b/QtVsTools.Wizards/Common/WizardData.cs
new file mode 100644
index 0000000..8424f5e
--- /dev/null
+++ b/QtVsTools.Wizards/Common/WizardData.cs
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Collections.Generic;
+
+namespace QtVsTools.Wizards.Common
+{
+ using ProjectWizard;
+
+ public class WizardData
+ {
+ public WizardData()
+ {
+ Modules = new List<string>();
+ DefaultModules = new List<string>();
+ }
+
+ public string ClassName { get; set; }
+ public string BaseClass { get; set; }
+ public string PluginClass { get; set; }
+ public string ConstructorSignature { get; set; }
+
+ public string ClassHeaderFile { get; set; }
+ public string ClassSourceFile { get; set; }
+ public string PluginHeaderFile { get; set; }
+ public string PluginSourceFile { get; set; }
+
+ public string UiFile { get; set; }
+ public string QrcFile { get; set; }
+
+ private List<string> Modules { get; }
+ public List<string> DefaultModules { get; set; }
+
+ public bool AddDefaultAppIcon { get; set; }
+ public bool CreateStaticLibrary { get; set; }
+ public bool UsePrecompiledHeader { get; set; }
+ public bool InsertQObjectMacro { get; set; }
+ public bool LowerCaseFileNames { get; set; }
+ public UiClassInclusion UiClassInclusion { get; set; }
+
+ public IEnumerable<IWizardConfiguration> Configs { get; set; }
+ }
+}
diff --git a/QtVsTools.Wizards/Common/WizardIntroPage.xaml b/QtVsTools.Wizards/Common/WizardIntroPage.xaml
new file mode 100644
index 0000000..5db4608
--- /dev/null
+++ b/QtVsTools.Wizards/Common/WizardIntroPage.xaml
@@ -0,0 +1,102 @@
+<!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2016 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+-->
+
+<common:WizardPage x:Class="QtVsTools.Wizards.Common.WizardIntroPage"
+ xmlns:common="clr-namespace:QtVsTools.Wizards.Common"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ KeepAlive="True"
+ mc:Ignorable="d"
+ d:DesignHeight="445"
+ d:DesignWidth="585">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="100" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Image Grid.Column="0"
+ HorizontalAlignment="Center"
+ Source="/QtVsTools.Wizards;component/Resources/Qt-logo-small.png"
+ VerticalAlignment="Top"
+ Margin="0,25,0,0"
+ RenderTransformOrigin="1,0">
+ <Image.RenderTransform>
+ <TransformGroup>
+ <ScaleTransform ScaleY="0.86"
+ ScaleX="0.86" />
+ </TransformGroup>
+ </Image.RenderTransform>
+ </Image>
+ <Grid Grid.Column="1"
+ Margin="25,25,10,0">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TextBlock TextWrapping="Wrap"
+ Grid.Row="0">
+ <Run FontWeight="Bold"
+ Text="{Binding Path=Header}" />
+ <LineBreak />
+ <LineBreak />
+ <Run Text="{Binding Path=Message}" />
+ </TextBlock>
+ <StackPanel HorizontalAlignment="Right"
+ Orientation="Horizontal"
+ Grid.Row="1"
+ Margin="0,0,0,10">
+ <Button Click="OnPreviousButtonClick"
+ Name="PreviousButton"
+ IsEnabled="{Binding Path=PreviousButtonEnabled}"
+ MinWidth="75">< _Previous</Button>
+ <Button MinWidth="75"
+ Name="NextButton"
+ Click="OnNextButtonClick"
+ IsEnabled="{Binding Path=NextButtonEnabled}"
+ Margin="10,0,0,0">_Next ></Button>
+ <Button MinWidth="75"
+ Click="OnFinishButtonClick"
+ Margin="10,0,0,0"
+ IsDefault="True"
+ IsEnabled="{Binding Path=FinishButtonEnabled}"
+ Name="FinishButton"
+ VerticalAlignment="Bottom">_Finish</Button>
+ <Button Click="OnCancelButtonClick"
+ MinWidth="75"
+ Margin="10,0,0,0"
+ Name="CancelButton"
+ IsEnabled="{Binding Path=CancelButtonEnabled}"
+ IsCancel="True">_Cancel</Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+</common:WizardPage>
diff --git a/QtVsTools.Wizards/Common/WizardIntroPage.xaml.cs b/QtVsTools.Wizards/Common/WizardIntroPage.xaml.cs
new file mode 100644
index 0000000..5bee6ff
--- /dev/null
+++ b/QtVsTools.Wizards/Common/WizardIntroPage.xaml.cs
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+namespace QtVsTools.Wizards.Common
+{
+ public partial class WizardIntroPage : WizardPage
+ {
+ public WizardIntroPage()
+ {
+ InitializeComponent();
+ DataContext = this;
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/Common/WizardPage.cs b/QtVsTools.Wizards/Common/WizardPage.cs
new file mode 100644
index 0000000..e3959ae
--- /dev/null
+++ b/QtVsTools.Wizards/Common/WizardPage.cs
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Windows;
+using System.Windows.Navigation;
+
+namespace QtVsTools.Wizards.Common
+{
+ public class WizardPage : PageFunction<WizardResult>
+ {
+ public string Header { get; set; }
+ public string Message { get; set; }
+
+ public WizardData Data { get; set; }
+ public WizardWindow Wizard { get; set; }
+
+ public bool PreviousButtonEnabled { get; set; }
+ public bool NextButtonEnabled { get; set; }
+ public bool FinishButtonEnabled { get; set; }
+ public bool CancelButtonEnabled { get; set; }
+
+ public event EventHandler NavigateForward;
+ public event EventHandler NavigatedBackward;
+
+ public event ReturnEventHandler<WizardResult> ReturnEx;
+ public void OnReturnEx(ReturnEventArgs<WizardResult> e)
+ {
+ if (ReturnEx != null)
+ ReturnEx.Invoke(this, e);
+ }
+
+ protected virtual void OnPreviousButtonClick(object sender, RoutedEventArgs e)
+ {
+ if (NavigationService == null || !NavigationService.CanGoBack)
+ return;
+
+ NavigationService.GoBack();
+ OnNavigatedBackward(new EventArgs());
+ }
+
+ protected virtual void OnNextButtonClick(object sender, RoutedEventArgs e)
+ {
+ if (NavigationService == null || Wizard == null)
+ return;
+
+ try {
+ OnNavigateForward(new EventArgs());
+ } catch (InvalidOperationException) {
+ return; // we can't navigate any further
+ }
+
+ if (!NavigationService.CanGoForward) {
+ Wizard.NextPage.ReturnEx += OnPageReturn;
+ NavigationService.Navigate(Wizard.NextPage);
+ } else {
+ NavigationService.GoForward();
+ }
+ }
+
+ protected virtual void OnFinishButtonClick(object sender, RoutedEventArgs e)
+ {
+ OnReturnEx(new ReturnEventArgs<WizardResult>(WizardResult.Finished));
+ }
+
+ protected virtual void OnCancelButtonClick(object sender, RoutedEventArgs e)
+ {
+ OnReturnEx(new ReturnEventArgs<WizardResult>(WizardResult.Canceled));
+ OnReturn(null);
+ }
+
+ protected virtual void OnNavigateForward(EventArgs e)
+ {
+ if (NavigateForward != null)
+ NavigateForward.Invoke(this, e);
+ }
+
+ protected virtual void OnNavigatedBackward(EventArgs e)
+ {
+ if (NavigatedBackward != null)
+ NavigatedBackward.Invoke(this, e);
+ }
+
+ private void OnPageReturn(object sender, ReturnEventArgs<WizardResult> e)
+ {
+ OnReturnEx(e);
+ OnReturn(null);
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/Common/WizardResult.cs b/QtVsTools.Wizards/Common/WizardResult.cs
new file mode 100644
index 0000000..96bc3f4
--- /dev/null
+++ b/QtVsTools.Wizards/Common/WizardResult.cs
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+namespace QtVsTools.Wizards.Common
+{
+ public enum WizardResult
+ {
+ Canceled,
+ Finished,
+ Exception
+ }
+}
diff --git a/QtVsTools.Wizards/Common/WizardWindow.xaml b/QtVsTools.Wizards/Common/WizardWindow.xaml
new file mode 100644
index 0000000..9b461e7
--- /dev/null
+++ b/QtVsTools.Wizards/Common/WizardWindow.xaml
@@ -0,0 +1,44 @@
+<!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2016 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+-->
+
+<NavigationWindow x:Class="QtVsTools.Wizards.Common.WizardWindow"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ WindowStartupLocation="CenterOwner"
+ ShowInTaskbar="False"
+ ShowsNavigationUI="False"
+ Title="Wizard Window"
+ ResizeMode="CanResizeWithGrip"
+ MinHeight="480"
+ MinWidth="640"
+ Height="480"
+ Width="640"
+ MaxHeight="768"
+ MaxWidth="1024" />
diff --git a/QtVsTools.Wizards/Common/WizardWindow.xaml.cs b/QtVsTools.Wizards/Common/WizardWindow.xaml.cs
new file mode 100644
index 0000000..95028a3
--- /dev/null
+++ b/QtVsTools.Wizards/Common/WizardWindow.xaml.cs
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Windows.Navigation;
+
+namespace QtVsTools.Wizards.Common
+{
+ using Wizards.Util;
+
+ public partial class WizardWindow : NavigationWindow, IEnumerable<WizardPage>
+ {
+
+ public WizardWindow(IEnumerable<WizardPage> pages = null, string title = null)
+ {
+ InitializeComponent();
+ SourceInitialized += OnSourceInitialized;
+
+ if (title != null)
+ Title = title;
+
+ Pages = new List<WizardPage>();
+
+ if (pages != null) {
+ foreach (var page in pages)
+ Add(page);
+ }
+ }
+
+ public void Add(WizardPage page)
+ {
+ bool isFirstPage = (Pages.Count == 0);
+ page.Wizard = this;
+ page.NavigateForward += OnNavigateForward;
+ page.NavigatedBackward += OnNavigatedBackwards;
+ Pages.Add(page);
+
+ if (isFirstPage) {
+ NextPage.ReturnEx += OnPageReturn;
+ Navigate(NextPage); // put on navigation stack
+ }
+ }
+
+ public WizardPage NextPage
+ {
+ get
+ {
+ return Pages[currentPage];
+ }
+ }
+
+ private List<WizardPage> Pages
+ {
+ get;
+ }
+
+ public IEnumerator<WizardPage> GetEnumerator()
+ {
+ return ((IEnumerable<WizardPage>)Pages).GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable<WizardPage>)Pages).GetEnumerator();
+ }
+
+ private int currentPage;
+
+ private void OnSourceInitialized(object sender, EventArgs e)
+ {
+ try {
+ var STYLE = -16; // see winuser.h
+ var hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
+ UnsafeNativeMethods.SetWindowLong(hwnd, STYLE,
+ NativeMethods.GetWindowLong(hwnd, STYLE) & ~(0x10000 | 0x20000));
+ } catch {
+ // Ignore if we can't remove the buttons.
+ SourceInitialized -= OnSourceInitialized;
+ }
+ }
+
+ private void OnNavigateForward(object sender, EventArgs e)
+ {
+ var tmp = currentPage + 1;
+ if (tmp >= Pages.Count) {
+ throw new InvalidOperationException(@"Current wizard page "
+ + @"cannot be equal or greater than pages count.");
+ }
+ currentPage++;
+ }
+
+ private void OnPageReturn(object sender, ReturnEventArgs<WizardResult> e)
+ {
+ if (DialogResult == null)
+ DialogResult = (e.Result == WizardResult.Finished);
+ }
+
+ private void OnNavigatedBackwards(object sender, EventArgs e)
+ {
+ var tmp = currentPage - 1;
+ if (tmp < 0)
+ throw new InvalidOperationException(@"Current wizard page cannot be less then 0.");
+ currentPage--;
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ItemWizard/QtClass/QtClassPage.xaml b/QtVsTools.Wizards/ItemWizard/QtClass/QtClassPage.xaml
new file mode 100644
index 0000000..fe00ef0
--- /dev/null
+++ b/QtVsTools.Wizards/ItemWizard/QtClass/QtClassPage.xaml
@@ -0,0 +1,298 @@
+<!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+-->
+
+<common:WizardPage x:Class="QtVsTools.Wizards.ItemWizard.QtClassPage"
+ xmlns:common="clr-namespace:QtVsTools.Wizards.Common"
+ xmlns:util="clr-namespace:QtVsTools.Wizards.Util"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ KeepAlive="True"
+ mc:Ignorable="d"
+ d:DesignHeight="445"
+ d:DesignWidth="585">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="100" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Image Grid.Column="0"
+ HorizontalAlignment="Center"
+ Source="/QtVsTools.Wizards;component/Resources/Qt-logo-small.png"
+ VerticalAlignment="Top"
+ Margin="0,25,0,0"
+ RenderTransformOrigin="1,0">
+ <Image.RenderTransform>
+ <TransformGroup>
+ <ScaleTransform ScaleY="0.86"
+ ScaleX="0.86" />
+ </TransformGroup>
+ </Image.RenderTransform>
+ </Image>
+ <Grid Grid.Column="1"
+ Margin="25,25,10,0">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TextBlock TextWrapping="Wrap"
+ Grid.Row="0">
+ <Run FontWeight="Bold"
+ Text="{Binding Path=Header}" />
+ <LineBreak />
+ <LineBreak />
+ <Run Text="{Binding Path=Message}" />
+ <LineBreak />
+ </TextBlock>
+ <Grid Grid.Row="1">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Grid.Resources>
+ <Style TargetType="TextBox">
+ <Style.Triggers>
+ <Trigger Property="Validation.HasError"
+ Value="true">
+ <Setter Property="ToolTip"
+ Value="{Binding RelativeSource={RelativeSource Self},
+ Path=(Validation.Errors)[0].ErrorContent}" />
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Resources>
+ <TextBlock Grid.Row="0"
+ Text="Class Name:"
+ Margin="0,0,10,0" />
+ <TextBox Grid.Row="1"
+ Margin="0,0,10,10"
+ Name="ClassName"
+ TextChanged="OnClassNameChanged"
+ TabIndex="0">
+ <TextBox.Text>
+ <Binding Path="Data.ClassName"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:ClassNameValidationRule SupportNamespaces="True" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock TextWrapping="Wrap"
+ Text="Constructor signature:"
+ Grid.Row="2"
+ Margin="0,0,10,5" />
+ <ComboBox Grid.Row="3"
+ VerticalAlignment="Top"
+ TabIndex="2"
+ IsSynchronizedWithCurrentItem="True"
+ Margin="0,0,10,30"
+ SelectedIndex="0"
+ Text="{Binding Path=Data.ConstructorSignature}">
+ <ComboBoxItem Content="QObject *parent"
+ IsSelected="True" />
+ <ComboBoxItem Content="QWidget *parent" />
+ <ComboBoxItem Content="" />
+ <ComboBox.Style>
+ <Style TargetType="ComboBox">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding ElementName=BaseClass, Path=Text}"
+ Value="">
+ <Setter Property="IsEnabled"
+ Value="false" />
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </ComboBox.Style>
+ </ComboBox>
+ <TextBlock TextWrapping="Wrap"
+ Text="Base class:"
+ Margin="0,0,10,0"
+ Grid.Column="1" />
+ <TextBox Margin="0,0,0,10"
+ TabIndex="1"
+ Grid.Column="1"
+ Grid.Row="1"
+ Name="BaseClass">
+ <TextBox.Text>
+ <Binding Path="Data.BaseClass"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:ClassNameValidationRule AllowEmptyIdentifier="True"/>
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <Grid Grid.Row="4"
+ Grid.ColumnSpan="2">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <TextBlock Grid.Row="0"
+ Margin="0,0,10,5"
+ Text="Header (.h) file:" />
+ <TextBox Grid.Row="1"
+ Margin="0,0,10,0"
+ Name="ClassHeaderFile"
+ TabIndex="4">
+ <TextBox.Text>
+ <Binding Path="Data.ClassHeaderFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".h" />
+ <util:FileExistsinFilterValidationRule Filter="FL_HFiles" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Grid.Row="0"
+ Grid.Column="1"
+ Margin="0,0,0,5"
+ Text="Source (.cpp) file:" />
+ <TextBox Grid.Row="1"
+ Grid.Column="1"
+ Margin="0,0,0,00"
+ Name="ClassSourceFile"
+ TabIndex="5">
+ <TextBox.Text>
+ <Binding Path="Data.ClassSourceFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".cpp" />
+ <util:FileExistsinFilterValidationRule Filter="FL_CppFiles" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ </Grid>
+ <CheckBox Grid.Row="5"
+ Content="Lower case file names"
+ Name="LowerCaseFileNames"
+ Click="OnLowerCaseFileNamesClick"
+ Margin="0,20,10,5"
+ TabIndex="6" />
+ <CheckBox Content="Insert Q_OBJECT macro"
+ Grid.Column="1"
+ Grid.Row="3"
+ VerticalAlignment="Center"
+ Margin="0,0,0,30"
+ TabIndex="3"
+ IsChecked="{Binding Path=Data.InsertQObjectMacro}">
+ <CheckBox.Style>
+ <Style TargetType="CheckBox">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding ElementName=BaseClass, Path=Text}"
+ Value="">
+ <Setter Property="IsEnabled"
+ Value="false" />
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </CheckBox.Style>
+ </CheckBox>
+ </Grid>
+ <StackPanel HorizontalAlignment="Right"
+ Orientation="Horizontal"
+ Grid.Row="2"
+ Margin="0,0,0,10">
+ <Button Click="OnPreviousButtonClick"
+ Name="PreviousButton"
+ IsEnabled="{Binding Path=PreviousButtonEnabled}"
+ MinWidth="75">< _Previous</Button>
+ <Button MinWidth="75"
+ Name="NextButton"
+ Click="OnNextButtonClick"
+ IsEnabled="{Binding Path=NextButtonEnabled}"
+ Margin="10,0,0,0">_Next ></Button>
+ <Button MinWidth="75"
+ Click="OnFinishButtonClick"
+ Margin="10,0,0,0"
+ IsDefault="True"
+ Name="FinishButton"
+ Content="_Finish"
+ VerticalAlignment="Bottom">
+ <Button.Style>
+ <Style TargetType="Button">
+ <Setter Property="IsEnabled"
+ Value="false" />
+ <Style.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding Path=FinishButtonEnabled}"
+ Value="true" />
+ <Condition Binding="{Binding ElementName=ClassName,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=BaseClass,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=ClassHeaderFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=ClassSourceFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ </MultiDataTrigger.Conditions>
+ <Setter Property="IsEnabled"
+ Value="true" />
+ </MultiDataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+ <Button Click="OnCancelButtonClick"
+ MinWidth="75"
+ Margin="10,0,0,0"
+ Name="CancelButton"
+ IsEnabled="{Binding Path=CancelButtonEnabled}"
+ IsCancel="True">_Cancel</Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+</common:WizardPage>
diff --git a/QtVsTools.Wizards/ItemWizard/QtClass/QtClassPage.xaml.cs b/QtVsTools.Wizards/ItemWizard/QtClass/QtClassPage.xaml.cs
new file mode 100644
index 0000000..fcc4960
--- /dev/null
+++ b/QtVsTools.Wizards/ItemWizard/QtClass/QtClassPage.xaml.cs
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Windows;
+using System.Windows.Controls;
+
+namespace QtVsTools.Wizards.ItemWizard
+{
+ using Wizards.Common;
+
+ public partial class QtClassPage : WizardPage
+ {
+ public QtClassPage()
+ {
+ InitializeComponent();
+ DataContext = this;
+ }
+
+ private void OnClassNameChanged(object sender, TextChangedEventArgs e)
+ {
+ UpdateFileNames();
+ }
+
+ private void OnLowerCaseFileNamesClick(object sender, RoutedEventArgs e)
+ {
+ UpdateFileNames();
+ }
+
+ private void UpdateFileNames()
+ {
+ var filename = ClassName.Text;
+ if (LowerCaseFileNames.IsChecked.GetValueOrDefault())
+ filename = filename.ToLower();
+
+ var index = filename.LastIndexOf(@":", System.StringComparison.Ordinal);
+ if (index >= 0)
+ filename = filename.Substring(index + 1);
+
+ ClassHeaderFile.Text = filename + @".h";
+ ClassSourceFile.Text = filename + @".cpp";
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ItemWizard/QtClass/QtClassWizard.cs b/QtVsTools.Wizards/ItemWizard/QtClass/QtClassWizard.cs
new file mode 100644
index 0000000..970c585
--- /dev/null
+++ b/QtVsTools.Wizards/ItemWizard/QtClass/QtClassWizard.cs
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows.Controls;
+using Microsoft.VisualStudio.Shell;
+using EnvDTE;
+
+namespace QtVsTools.Wizards.ItemWizard
+{
+ using QtVsTools.Common;
+ using Core;
+ using Wizards.Common;
+ using Wizards.ProjectWizard;
+ using Wizards.Util;
+
+ using static QtVsTools.Common.EnumExt;
+
+ public sealed class QtClassWizard : ProjectTemplateWizard
+ {
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ protected override Options TemplateType => Options.ConsoleSystem;
+
+ enum NewClass
+ {
+ [String("safeitemname")] SafeItemName,
+ [String("sourcefilename")] SourceFileName,
+ [String("headerfilename")] HeaderFileName
+ }
+
+ enum NewQtItem
+ {
+ [String("classname")] ClassName,
+ [String("baseclass")] BaseClass,
+ [String("include")] Include,
+ [String("qobject")] QObject,
+ [String("baseclassdecl")] BaseClassDecl,
+ [String("signature")] Signature,
+ [String("baseclassinclude")] BaseClassInclude,
+ [String("baseclasswithparent")] BaseClassWithParent
+ }
+
+ enum Meta
+ {
+ [String("namespacebegin")] NamespaceBegin,
+ [String("namespaceend")] NamespaceEnd
+ }
+
+ protected override WizardData WizardData => Lazy.Get(() =>
+ WizardData, () => new WizardData
+ {
+ InsertQObjectMacro = true,
+ LowerCaseFileNames = false,
+ UsePrecompiledHeader = false,
+ DefaultModules = new List<string> { "core" }
+ });
+
+ protected override WizardWindow WizardWindow => Lazy.Get(() =>
+ WizardWindow, () => new WizardWindow(title: "Qt Class Wizard")
+ {
+ new WizardIntroPage
+ {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Class Wizard",
+ Message = @"This wizard will add a new Qt class to your project. The "
+ + @"wizard creates a .h and .cpp file." + System.Environment.NewLine
+ + System.Environment.NewLine + "To continue, click Next.",
+ PreviousButtonEnabled = false,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true
+ },
+ new QtClassPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Class Wizard",
+ Message = @"This wizard will add a new Qt class to your project. The "
+ + @"wizard creates a .h and .cpp file.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = false,
+ FinishButtonEnabled = true,
+ CancelButtonEnabled = true
+ }
+ });
+
+ protected override void BeforeWizardRun()
+ {
+ var className = Parameter[NewClass.SafeItemName];
+ className = Regex.Replace(className, @"[^a-zA-Z0-9_]", string.Empty);
+ className = Regex.Replace(className, @"^[\d-]*\s*", string.Empty);
+ var result = new Util.ClassNameValidationRule().Validate(className, null);
+ if (result != ValidationResult.ValidResult)
+ className = @"QtClass";
+
+ WizardData.ClassName = className;
+ WizardData.BaseClass = @"QObject";
+ WizardData.ClassHeaderFile = className + @".h";
+ WizardData.ClassSourceFile = className + @".cpp";
+ WizardData.ConstructorSignature = "QObject *parent";
+
+ Parameter[NewQtItem.QObject] = "";
+ Parameter[NewQtItem.BaseClassDecl] = "";
+ Parameter[NewQtItem.Signature] = "";
+ Parameter[NewQtItem.BaseClassInclude] = "";
+ Parameter[NewQtItem.BaseClassWithParent] = "";
+ }
+
+ protected override void BeforeTemplateExpansion()
+ {
+ Parameter[NewClass.SourceFileName] = WizardData.ClassSourceFile;
+ Parameter[NewClass.HeaderFileName] = WizardData.ClassHeaderFile;
+
+ var array = WizardData.ClassName.Split(new[] { "::" },
+ StringSplitOptions.RemoveEmptyEntries);
+ var className = array.LastOrDefault();
+ var baseClass = WizardData.BaseClass;
+
+ Parameter[NewQtItem.ClassName] = className;
+ Parameter[NewQtItem.BaseClass] = baseClass;
+
+ var include = new StringBuilder();
+ var pro = HelperFunctions.GetSelectedQtProject(Dte);
+ if (pro != null) {
+ var qtProject = QtProject.Create(pro);
+ if (qtProject != null && qtProject.UsesPrecompiledHeaders()) {
+ include.AppendLine(string.Format("#include \"{0}\"", qtProject
+ .GetPrecompiledHeaderThrough()));
+ }
+ }
+ include.AppendLine(string.Format("#include \"{0}\"", WizardData.ClassHeaderFile));
+ Parameter[NewQtItem.Include] = FormatParam(include);
+
+ if (!string.IsNullOrEmpty(baseClass)) {
+ Parameter[NewQtItem.QObject] = WizardData.InsertQObjectMacro
+ ? "\r\n Q_OBJECT\r\n" : "";
+ Parameter[NewQtItem.BaseClassDecl] = " : public " + baseClass;
+ Parameter[NewQtItem.Signature] = WizardData.ConstructorSignature;
+ Parameter[NewQtItem.BaseClassInclude] = "#include <" + baseClass + ">\r\n\r\n";
+ Parameter[NewQtItem.BaseClassWithParent] = string.IsNullOrEmpty(WizardData
+ .ConstructorSignature) ? "" : "\r\n : " + baseClass + "(parent)";
+ }
+
+ string nsBegin = string.Empty, nsEnd = string.Empty;
+ for (var i = 0; i < array.Length - 1; ++i) {
+ nsBegin += "namespace " + array[i] + " {\r\n";
+ nsEnd = "} // namespace " + array[i] + "\r\n" + nsEnd;
+ }
+ Parameter[Meta.NamespaceBegin] = nsBegin;
+ Parameter[Meta.NamespaceEnd] = nsEnd;
+ }
+
+ protected override void Expand()
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ VCRulePropertyStorageHelper.SetQtModules(Dte, WizardData.DefaultModules);
+ }
+
+ public override void ProjectItemFinishedGenerating(ProjectItem projectItem)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ QtProject.AdjustWhitespace(Dte, projectItem.Properties.Item("FullPath").Value.ToString());
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml b/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml
new file mode 100644
index 0000000..2f707b2
--- /dev/null
+++ b/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml
@@ -0,0 +1,149 @@
+<!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+-->
+
+<common:WizardPage x:Class="QtVsTools.Wizards.ItemWizard.TranslationPage"
+ xmlns:common="clr-namespace:QtVsTools.Wizards.Common"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ KeepAlive="True"
+ mc:Ignorable="d"
+ d:DesignHeight="445"
+ d:DesignWidth="585" >
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="100" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+
+ <Image Grid.Column="0"
+ HorizontalAlignment="Center"
+ Source="/QtVsTools.Wizards;component/Resources/Qt-logo-small.png"
+ VerticalAlignment="Top"
+ Margin="0,25,0,0"
+ RenderTransformOrigin="1,0">
+ <Image.RenderTransform>
+ <TransformGroup>
+ <ScaleTransform ScaleY="0.86"
+ ScaleX="0.86" />
+ </TransformGroup>
+ </Image.RenderTransform>
+ </Image>
+
+ <Grid Grid.Column="1"
+ Margin="25,25,25,0">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TextBlock TextWrapping="Wrap"
+ Grid.Row="0">
+ <Run FontWeight="Bold"
+ Text="{Binding Path=Header}" />
+ <LineBreak />
+ <LineBreak />
+ <Run Text="{Binding Path=Message}" />
+ <LineBreak />
+ </TextBlock>
+
+ <Grid Grid.Row="1"
+ Margin="0,20,0,20">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TextBlock Grid.Row="0"
+ Margin="0,0,0,5"
+ Text="Select a Language:" />
+ <Grid Grid.Row="1">
+ <Grid Name="searchControlHost" />
+ </Grid>
+ <ListBox Grid.Row="2"
+ Margin="0,10,0,8"
+ Name="LanguageListBox"
+ DisplayMemberPath="Value"
+ SelectedValuePath="Key"
+ ItemsSource="{Binding Path=Data.CultureInfos}"
+ SelectedValue="{Binding Path=Data.CultureInfoName}"
+ SelectionChanged="OnLanguageBoxSelectionChanged" />
+ <TextBlock Grid.Row="3"
+ Margin="0,0,0,5"
+ Text="Save as:"/>
+ <Grid Grid.Row="4">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <TextBox Text="{Binding Path=Data.TsFile}"/>
+ <TextBlock Grid.Column="1"
+ Margin="5,0,0,0"
+ VerticalAlignment="Center">
+ <Run FontWeight="Bold"
+ Text="{Binding Path=Data.CultureInfoName}" />
+ <Run Text=".ts" />
+ </TextBlock>
+ </Grid>
+ </Grid>
+
+ <StackPanel Grid.Row="2"
+ HorizontalAlignment="Right"
+ Orientation="Horizontal"
+ Margin="0,0,0,10">
+ <Button Click="OnPreviousButtonClick"
+ Name="PreviousButton"
+ IsEnabled="{Binding Path=PreviousButtonEnabled}"
+ MinWidth="75">< _Previous</Button>
+ <Button MinWidth="75"
+ Name="NextButton"
+ Click="OnNextButtonClick"
+ IsEnabled="{Binding Path=NextButtonEnabled}"
+ Margin="10,0,0,0">_Next ></Button>
+ <Button MinWidth="75"
+ Click="OnFinishButtonClick"
+ Margin="10,0,0,0"
+ IsDefault="True"
+ IsEnabled="{Binding Path=FinishButtonEnabled}"
+ Name="FinishButton"
+ VerticalAlignment="Bottom">_Finish</Button>
+ <Button Click="OnCancelButtonClick"
+ MinWidth="75"
+ Margin="10,0,0,0"
+ Name="CancelButton"
+ IsEnabled="{Binding Path=CancelButtonEnabled}"
+ IsCancel="True">_Cancel</Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+</common:WizardPage>
diff --git a/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml.cs b/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml.cs
new file mode 100644
index 0000000..adcc38b
--- /dev/null
+++ b/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml.cs
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+
+namespace QtVsTools.Wizards.ItemWizard
+{
+ using QtVsTools.VisualStudio;
+ using Wizards.Common;
+
+ public partial class TranslationPage : WizardPage
+ {
+ private string SearchText { get; set; }
+
+ public TranslationPage()
+ {
+ InitializeComponent();
+ DataContext = this;
+ Loaded += OnTranslationPageLoaded;
+ }
+
+ private void OnTranslationPageLoaded(object sender, RoutedEventArgs e)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ var view = CollectionViewSource.GetDefaultView(LanguageListBox.ItemsSource);
+ view.Filter = obj =>
+ {
+ if (string.IsNullOrEmpty(SearchText))
+ return true;
+
+ var item = (KeyValuePair<string, string>)obj;
+ return item.Value.IndexOf(SearchText, StringComparison.OrdinalIgnoreCase) >= 0;
+ };
+ LanguageListBox.SelectedIndex = 0;
+
+ var factory = VsServiceProvider
+ .GetService<SVsWindowSearchHostFactory, IVsWindowSearchHostFactory>();
+ var host = factory.CreateWindowSearchHost(searchControlHost);
+
+ host.SetupSearch(new ListBoxSearch(LanguageListBox, value => SearchText = value));
+ host.Activate(); // set focus
+ }
+
+ private void OnSearchBoxTextChanged(object sender, TextChangedEventArgs e)
+ {
+ CollectionViewSource.GetDefaultView(LanguageListBox.ItemsSource).Refresh();
+ if (LanguageListBox.Items.Count == 1 || LanguageListBox.SelectedItem == null)
+ LanguageListBox.SelectedIndex = 0;
+ }
+
+ private void OnLanguageBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (e.RemovedItems != null && (e.AddedItems == null || e.AddedItems.Count == 0)) {
+ if (LanguageListBox.Items.Count != 0)
+ LanguageListBox.SelectedIndex = 0;
+ }
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ItemWizard/Translation/TranslationWizard.cs b/QtVsTools.Wizards/ItemWizard/Translation/TranslationWizard.cs
new file mode 100644
index 0000000..0c6c8c5
--- /dev/null
+++ b/QtVsTools.Wizards/ItemWizard/Translation/TranslationWizard.cs
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using Microsoft.VisualStudio.Shell;
+using EnvDTE;
+
+namespace QtVsTools.Wizards.ItemWizard
+{
+ using QtVsTools.Common;
+ using Core;
+ using Wizards.Common;
+ using Wizards.ProjectWizard;
+ using Wizards.Util;
+
+ using static QtVsTools.Common.EnumExt;
+
+ public sealed class TsWizardData : WizardData
+ {
+ public string TsFile { get; set; }
+ public string CultureInfoName { get; set; }
+ public List<KeyValuePair<string, string>> CultureInfos { get; set; }
+ }
+
+ public sealed class TranslationWizard : ProjectTemplateWizard
+ {
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ protected override Options TemplateType => Options.ConsoleSystem | Options.GUISystem;
+
+ enum NewTranslationItem
+ {
+ [String("safeitemname")] SafeItemName,
+ [String("tsfilename")] TsFileName,
+ [String("cultureinfoname")] CultureInfoName
+ }
+
+ protected override WizardData WizardData => Lazy.Get(() =>
+ WizardData, () => new TsWizardData
+ {
+ DefaultModules = new List<string> { "core"}
+ });
+
+ protected override WizardWindow WizardWindow => Lazy.Get(() =>
+ WizardWindow, () => new WizardWindow(title: "Qt Translation File Wizard")
+ {
+ new TranslationPage
+ {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Translation File Wizard",
+ Message = @"This wizard will add a new Qt empty translation file to your "
+ + @"project. The wizard creates a .ts for the selected language.",
+ PreviousButtonEnabled = false,
+ NextButtonEnabled = false,
+ FinishButtonEnabled = true,
+ CancelButtonEnabled = true
+ },
+ });
+
+ protected override void BeforeWizardRun()
+ {
+ var tmp = WizardData as TsWizardData;
+ tmp.TsFile = Parameter[NewTranslationItem.SafeItemName];
+ tmp.CultureInfos = CultureInfo.GetCultures(CultureTypes.AllCultures)
+ .ToDictionary(
+ mc => mc.Name.Replace("-", "_"),
+ mc => mc.EnglishName,
+ StringComparer.OrdinalIgnoreCase
+ ).OrderBy(item => item.Value).ToList();
+ }
+
+ protected override void BeforeTemplateExpansion()
+ {
+ var tmp = WizardData as TsWizardData;
+ Parameter[NewTranslationItem.CultureInfoName] = tmp.CultureInfoName;
+ Parameter[NewTranslationItem.TsFileName] = tmp.TsFile + "_" + tmp.CultureInfoName + ".ts";
+ }
+
+ protected override void Expand()
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ VCRulePropertyStorageHelper.SetQtModules(Dte, WizardData.DefaultModules);
+ }
+
+ public override void ProjectItemFinishedGenerating(ProjectItem projectItem)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ QtProject.AdjustWhitespace(Dte, projectItem.Properties.Item("FullPath").Value.ToString());
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ItemWizard/WidgetsClass/WidgetsClassWizard.cs b/QtVsTools.Wizards/ItemWizard/WidgetsClass/WidgetsClassWizard.cs
new file mode 100644
index 0000000..8fc0d97
--- /dev/null
+++ b/QtVsTools.Wizards/ItemWizard/WidgetsClass/WidgetsClassWizard.cs
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows.Controls;
+using Microsoft.VisualStudio.Shell;
+using EnvDTE;
+
+namespace QtVsTools.Wizards.ItemWizard
+{
+ using QtVsTools.Common;
+ using Core;
+ using Wizards.Common;
+ using Wizards.ProjectWizard;
+ using Wizards.Util;
+
+ using static QtVsTools.Common.EnumExt;
+
+ public sealed class WidgetsClassWizard : ProjectTemplateWizard
+ {
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ protected override Options TemplateType => Options.GUISystem;
+
+ enum NewClass
+ {
+ [String("safeitemname")] SafeItemName,
+ [String("sourcefilename")] SourceFileName,
+ [String("headerfilename")] HeaderFileName,
+ [String("uifilename")] UiFileName
+ }
+
+ enum NewWidgetsItem
+ {
+ [String("classname")] ClassName,
+ [String("baseclass")] BaseClass,
+ [String("include")] Include,
+ [String("qobject")] QObject,
+ [String("ui_hdr")] UiHeaderName,
+ [String("centralwidget")] CentralWidget,
+ [String("forward_declare_class")] ForwardDeclClass,
+ [String("multiple_inheritance")] MultipleInheritance,
+ [String("ui_classname")] UiClassName,
+ [String("member")] Member
+ }
+
+ enum Meta
+ {
+ [String("namespacebegin")] NamespaceBegin,
+ [String("operator")] Operator,
+ [String("asterisk")] Asterisk,
+ [String("semicolon")] Semicolon,
+ [String("new")] New,
+ [String("delete")] Delete,
+ [String("namespaceend")] NamespaceEnd
+ }
+
+ protected override WizardData WizardData => Lazy.Get(() =>
+ WizardData, () => new WizardData
+ {
+ InsertQObjectMacro = true,
+ LowerCaseFileNames = false,
+ UsePrecompiledHeader = false,
+ DefaultModules = new List<string> { "core", "gui", "widgets" }
+ });
+
+ protected override WizardWindow WizardWindow => Lazy.Get(() =>
+ WizardWindow, () => new WizardWindow(title: "Qt Widgets Class Wizard")
+ {
+ new WizardIntroPage
+ {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Widgets Class Wizard",
+ Message = @"This wizard will add a new Qt Widgets class to your project. "
+ + @"The wizard creates a .h and .cpp file. It also creates a new "
+ + @"empty form." + System.Environment.NewLine
+ + System.Environment.NewLine + "To continue, click Next.",
+ PreviousButtonEnabled = false,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true
+ },
+ new GuiPage
+ {
+ Data = WizardData,
+ IsClassWizardPage = true,
+ Header = @"Welcome to the Qt Widgets Class Wizard",
+ Message = @"This wizard will add a new Qt Widgets class to your project. "
+ + @"The wizard creates a .h and .cpp file. It also creates a new "
+ + @"empty form.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = false,
+ FinishButtonEnabled = true,
+ CancelButtonEnabled = true
+ }
+ });
+
+ protected override void BeforeWizardRun()
+ {
+ var className = Parameter[NewClass.SafeItemName];
+ className = Regex.Replace(className, @"[^a-zA-Z0-9_]", string.Empty);
+ className = Regex.Replace(className, @"^[\d-]*\s*", string.Empty);
+ var result = new Util.ClassNameValidationRule().Validate(className, null);
+ if (result != ValidationResult.ValidResult)
+ className = @"QtWidgetsClass";
+
+ WizardData.ClassName = className;
+ WizardData.BaseClass = @"QMainWindow";
+ WizardData.ClassHeaderFile = className + @".h";
+ WizardData.ClassSourceFile = className + @".cpp";
+ WizardData.UiFile = WizardData.ClassName + @".ui";
+ WizardData.QrcFile = WizardData.ClassName + @".qrc";
+ WizardData.UiClassInclusion = UiClassInclusion.Member;
+
+ Parameter[NewWidgetsItem.ForwardDeclClass] = "";
+ Parameter[NewWidgetsItem.MultipleInheritance] = "";
+ Parameter[NewWidgetsItem.UiClassName] = "";
+ Parameter[NewWidgetsItem.Member] = "ui";
+
+ Parameter[Meta.Asterisk] ="";
+ Parameter[Meta.Operator] = ".";
+ Parameter[Meta.Semicolon] = ";";
+ Parameter[Meta.New] = "";
+ Parameter[Meta.Delete] = "";
+ }
+
+ protected override void BeforeTemplateExpansion()
+ {
+ Parameter[NewClass.SourceFileName] = WizardData.ClassSourceFile;
+ Parameter[NewClass.HeaderFileName] = WizardData.ClassHeaderFile;
+ Parameter[NewClass.UiFileName] = WizardData.UiFile;
+
+ var array = WizardData.ClassName.Split(new[] { "::" },
+ StringSplitOptions.RemoveEmptyEntries);
+ var className = array.LastOrDefault();
+
+ Parameter[NewWidgetsItem.ClassName] = className;
+ Parameter[NewWidgetsItem.BaseClass] = WizardData.BaseClass;
+
+ var include = new StringBuilder();
+ var pro = HelperFunctions.GetSelectedQtProject(Dte);
+ if (pro != null) {
+ var qtProject = QtProject.Create(pro);
+ if (qtProject != null && qtProject.UsesPrecompiledHeaders()) {
+ include.AppendLine(string.Format("#include \"{0}\"", qtProject
+ .GetPrecompiledHeaderThrough()));
+ }
+ }
+ include.AppendLine(string.Format("#include \"{0}\"", WizardData.ClassHeaderFile));
+ Parameter[NewWidgetsItem.Include] = FormatParam(include);
+
+ Parameter[NewWidgetsItem.QObject] = WizardData.InsertQObjectMacro
+ ? "\r\n Q_OBJECT\r\n" : "";
+
+ Parameter[NewWidgetsItem.UiHeaderName] = string.Format("ui_{0}.h",
+ Path.GetFileNameWithoutExtension(WizardData.UiFile));
+
+ if (WizardData.BaseClass == "QMainWindow") {
+ Parameter[NewWidgetsItem.CentralWidget] = FormatParam(
+ @" <widget class=""QMenuBar"" name=""menuBar"" />"
+ + @" <widget class=""QToolBar"" name=""mainToolBar"" />"
+ + @" <widget class=""QWidget"" name=""centralWidget"" />"
+ + @" <widget class=""QStatusBar"" name=""statusBar"" />"
+ );
+ }
+
+ switch (WizardData.UiClassInclusion) {
+ case UiClassInclusion.MemberPointer:
+ Parameter[NewWidgetsItem.ForwardDeclClass] =
+ string.Format(
+ "\r\nQT_BEGIN_NAMESPACE\r\n"
+ + "namespace Ui {{ class {0}Class; }};\r\n"
+ + "QT_END_NAMESPACE\r\n", className
+ );
+ Parameter[Meta.Asterisk] = "*";
+ Parameter[Meta.Operator] = "->";
+ Parameter[Meta.New] = string.Format("\r\n , {0}(new Ui::{1}Class())",
+ Parameter[NewWidgetsItem.Member], className);
+ Parameter[Meta.Delete] = string.Format("\r\n delete {0};\r\n",
+ Parameter[NewWidgetsItem.Member]);
+ goto case UiClassInclusion.Member;
+ case UiClassInclusion.Member:
+ Parameter[NewWidgetsItem.UiClassName] = string.Format("Ui::{0}Class", className);
+ break;
+ case UiClassInclusion.MultipleInheritance:
+ Parameter[NewWidgetsItem.MultipleInheritance] =
+ string.Format(", public Ui::{0}Class", className);
+ Parameter[NewWidgetsItem.Member] = "";
+ Parameter[Meta.Operator] = "";
+ Parameter[Meta.Semicolon] = "";
+ break;
+ }
+
+ string nsBegin = string.Empty, nsEnd = string.Empty;
+ for (var i = 0; i < array.Length - 1; ++i) {
+ nsBegin += "namespace " + array[i] + " {\r\n";
+ nsEnd = "} // namespace " + array[i] + "\r\n" + nsEnd;
+ }
+ Parameter[Meta.NamespaceBegin] = nsBegin;
+ Parameter[Meta.NamespaceEnd] = nsEnd;
+ }
+
+ protected override void Expand()
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ VCRulePropertyStorageHelper.SetQtModules(Dte, WizardData.DefaultModules);
+ }
+
+ public override void ProjectItemFinishedGenerating(ProjectItem projectItem)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ QtProject.AdjustWhitespace(Dte, projectItem.Properties.Item("FullPath").Value.ToString());
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ProjectWizard/ConfigPage.xaml b/QtVsTools.Wizards/ProjectWizard/ConfigPage.xaml
new file mode 100644
index 0000000..034113e
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/ConfigPage.xaml
@@ -0,0 +1,298 @@
+<!--
+*****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+*****************************************************************************
+-->
+<common:WizardPage x:Class="QtVsTools.Wizards.ProjectWizard.ConfigPage"
+ xmlns:common="clr-namespace:QtVsTools.Wizards.Common"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" KeepAlive="True"
+ mc:Ignorable="d" d:DesignHeight="445" d:DesignWidth="585">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="100" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Image Grid.Column="0" HorizontalAlignment="Center"
+ Source="/QtVsTools.Wizards;component/Resources/Qt-logo-small.png" VerticalAlignment="Top"
+ Margin="0,25,0,0" RenderTransformOrigin="1,0">
+ <Image.RenderTransform>
+ <TransformGroup>
+ <ScaleTransform ScaleY="0.86" ScaleX="0.86" />
+ </TransformGroup>
+ </Image.RenderTransform>
+ </Image>
+ <Grid Grid.Column="1" Margin="25,25,10,0">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TextBlock TextWrapping="Wrap" Grid.Row="0">
+ <Run FontWeight="Bold" Text="{Binding Path=Header}" />
+ <LineBreak />
+ <LineBreak />
+ <Run Text="{Binding Path=Message}" />
+ <LineBreak />
+ </TextBlock>
+ <Grid Grid.Row="1" Name="ModuleGrid">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Grid.Resources>
+ <Style TargetType="ListBox">
+ <Setter Property="Background" Value="Transparent" />
+ </Style>
+ </Grid.Resources>
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <DataGrid Margin="0,20,0,0" Name="ConfigTable" AutoGenerateColumns="False"
+ IsReadOnly="True" BorderThickness="1" BorderBrush="LightGray"
+ GridLinesVisibility="All" HorizontalGridLinesBrush="LightGray"
+ VerticalGridLinesBrush="LightGray" CanUserReorderColumns="False"
+ CanUserSortColumns="False" CanUserResizeRows="False" RowHeaderWidth="0"
+ FrozenColumnCount="1" Grid.Row="0">
+ <DataGrid.Resources>
+ <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
+ <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
+ </DataGrid.Resources>
+ <DataGrid.CellStyle>
+ <Style TargetType="DataGridCell">
+ <Setter Property="BorderThickness" Value="0" />
+ <Setter Property="FocusVisualStyle" Value="{x:Null}" />
+ </Style>
+ </DataGrid.CellStyle>
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="Configuration">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
+ <Button Cursor="Hand" ButtonBase.Click="RemoveConfig_Click">
+ <Button.Template>
+ <ControlTemplate TargetType="Button">
+ <Grid HorizontalAlignment="Center" VerticalAlignment="Center"
+ Margin="2,0">
+ <Ellipse Fill="Red" Width="13" Height="13" />
+ <Rectangle Width="8" Height="2" Fill="White" />
+ </Grid>
+ </ControlTemplate>
+ </Button.Template>
+ </Button>
+ <Button Cursor="Hand" ButtonBase.Click="DuplicateConfig_Click">
+ <Button.Template>
+ <ControlTemplate TargetType="Button">
+ <Grid HorizontalAlignment="Center" VerticalAlignment="Center"
+ Margin="2,0">
+ <Ellipse Fill="#FF36B31A" Width="13" Height="13" />
+ <Rectangle Width="8" Height="2" Fill="White" />
+ <Rectangle Width="2" Height="8" Fill="White" />
+ </Grid>
+ </ControlTemplate>
+ </Button.Template>
+ </Button>
+ <TextBox Text="{Binding Name}" Margin="2,8" BorderThickness="0"
+ Background="Transparent" TextBoxBase.TextChanged="Name_TextChanged">
+ <TextBox.Resources>
+ <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
+ Color="LimeGreen" />
+ </TextBox.Resources>
+ </TextBox>
+ </StackPanel>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTemplateColumn Header="Qt Version">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <ComboBox Text="{Binding QtVersionName}" IsEditable="True" Height="22"
+ SelectedIndex="0" BorderThickness="0" Background="Transparent"
+ FrameworkElement.Loaded="QtVersion_ComboBox_Loaded"
+ TextBoxBase.TextChanged="QtVersion_TextChanged">
+ <ComboBox.Resources>
+ <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
+ Color="LimeGreen" />
+ </ComboBox.Resources>
+ </ComboBox>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTemplateColumn Header="Target">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <ComboBox Text="{Binding Target}" IsEditable="True" Height="22"
+ SelectedIndex="0" BorderThickness="0" Background="Transparent"
+ FrameworkElement.Loaded="Target_ComboBox_Loaded"
+ TextBoxBase.TextChanged="Target_TextChanged">
+ <ComboBox.Resources>
+ <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
+ Color="LimeGreen" />
+ </ComboBox.Resources>
+ </ComboBox>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTemplateColumn Header="Platform">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <ComboBox Text="{Binding Platform}" IsEditable="True" Height="22"
+ SelectedIndex="0" BorderThickness="0" Background="Transparent"
+ FrameworkElement.Loaded="Platform_ComboBox_Loaded"
+ TextBoxBase.TextChanged="Platform_TextChanged">
+ <ComboBox.Resources>
+ <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
+ Color="LimeGreen" />
+ </ComboBox.Resources>
+ </ComboBox>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTemplateColumn Header="Debug">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <CheckBox VerticalAlignment="Center" HorizontalAlignment="Center"
+ IsChecked="{Binding IsDebug}" Click="Debug_Click" />
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTemplateColumn Header="Qt Modules" Width="*">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <ComboBox Name="Modules">
+ <ComboBox.Template>
+ <ControlTemplate TargetType="ComboBox">
+ <Grid>
+ <ListView Name="SelectedModules" ItemsSource="{Binding SelectedModules}"
+ ScrollViewer.HorizontalScrollBarVisibility="Disabled"
+ BorderThickness="0" IsEnabled="False">
+ <ListView.ItemsPanel>
+ <ItemsPanelTemplate>
+ <WrapPanel />
+ </ItemsPanelTemplate>
+ </ListView.ItemsPanel>
+ <ListView.ItemTemplate>
+ <DataTemplate>
+ <Grid>
+ <Rectangle Fill="#FF36B31A" RadiusX="4" RadiusY="4" Height="20" />
+ <Label Content="{Binding Name}" Foreground="White" />
+ </Grid>
+ </DataTemplate>
+ </ListView.ItemTemplate>
+ </ListView>
+ <ToggleButton Opacity="0" Name="ToggleButton" Focusable="false"
+ IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
+ ClickMode="Press" Cursor="Hand" />
+ <Popup Name="Popup" Placement="Bottom"
+ IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True"
+ Focusable="False" PopupAnimation="Slide">
+ <Grid Name="DropDown" SnapsToDevicePixels="True"
+ MinWidth="{TemplateBinding ActualWidth}"
+ MaxHeight="{TemplateBinding MaxDropDownHeight}">
+ <Border x:Name="DropDownBorder" Background="White"
+ BorderThickness="2" BorderBrush="Gray" />
+ <ListView Name="PopupListBox" BorderThickness="0"
+ ScrollViewer.VerticalScrollBarVisibility="Disabled"
+ ScrollViewer.HorizontalScrollBarVisibility="Auto"
+ Margin="10,10,10,10" ItemsSource="{Binding AllModules}">
+ <ListView.ItemsPanel>
+ <ItemsPanelTemplate>
+ <WrapPanel Orientation="Vertical" />
+ </ItemsPanelTemplate>
+ </ListView.ItemsPanel>
+ <ListView.ItemTemplate>
+ <DataTemplate>
+ <CheckBox Content="{Binding Name}"
+ IsChecked="{Binding IsSelected}"
+ IsEnabled="{Binding IsEnabled}" VerticalAlignment="Center"
+ VerticalContentAlignment="Center" Click="Module_Click"
+ Margin="4">
+ <CheckBox.ContentTemplate>
+ <DataTemplate>
+ <Grid>
+ <Rectangle Fill="#FF36B31A" RadiusX="4" RadiusY="4"
+ Height="20" />
+ <Label Content="{Binding}" Foreground="White" />
+ </Grid>
+ </DataTemplate>
+ </CheckBox.ContentTemplate>
+ </CheckBox>
+ </DataTemplate>
+ </ListView.ItemTemplate>
+ <ListView.ItemContainerStyle>
+ <Style TargetType="ListViewItem">
+ <Style.Setters>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="ListViewItem">
+ <ContentPresenter
+ HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
+ VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
+ SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style.Setters>
+ </Style>
+ </ListView.ItemContainerStyle>
+ </ListView>
+ </Grid>
+ </Popup>
+ </Grid>
+ </ControlTemplate>
+ </ComboBox.Template>
+ </ComboBox>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ </DataGrid.Columns>
+ </DataGrid>
+ <StackPanel Name="ErrorPanel" Orientation="Horizontal" Grid.Row="1" Margin="0,10"
+ Visibility="Hidden">
+ <Image Name="ErrorIcon" Height="16" Width="16" Margin="5,0" />
+ <Label Name="ErrorMsg" Foreground="Red" />
+ </StackPanel>
+ </Grid>
+ </Grid>
+ <StackPanel HorizontalAlignment="Right" Orientation="Horizontal" Grid.Row="2"
+ Margin="0,0,0,10">
+ <Button Click="OnPreviousButtonClick" Name="PreviousButton"
+ IsEnabled="{Binding Path=PreviousButtonEnabled}" MinWidth="75">< _Previous</Button>
+ <Button MinWidth="75" Name="NextButton" Click="OnNextButtonClick"
+ IsEnabled="{Binding Path=NextButtonEnabled}" Margin="10,0,0,0">_Next ></Button>
+ <Button MinWidth="75" Click="OnFinishButtonClick" Margin="10,0,0,0" IsDefault="True"
+ IsEnabled="{Binding Path=FinishButtonEnabled}" Name="FinishButton"
+ VerticalAlignment="Bottom">_Finish</Button>
+ <Button Click="OnCancelButtonClick" MinWidth="75" Margin="10,0,0,0" Name="CancelButton"
+ IsEnabled="{Binding Path=CancelButtonEnabled}" IsCancel="True">_Cancel</Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+</common:WizardPage>
diff --git a/QtVsTools.Wizards/ProjectWizard/ConfigPage.xaml.cs b/QtVsTools.Wizards/ProjectWizard/ConfigPage.xaml.cs
new file mode 100644
index 0000000..408cc45
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/ConfigPage.xaml.cs
@@ -0,0 +1,489 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Interop;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using Microsoft.Win32;
+
+namespace QtVsTools.Wizards.ProjectWizard
+{
+ using Core;
+ using QtVsTools.Common;
+ using Wizards.Common;
+
+ public partial class ConfigPage : WizardPage
+ {
+ interface ICloneable<T> where T : ICloneable<T>
+ {
+ T Clone();
+ }
+
+ class Module : ICloneable<Module>
+ {
+ public string Name { get; set; }
+ public string Id { get; set; }
+ public bool IsSelected { get; set; }
+ public bool IsReadOnly { get; set; }
+ public bool IsEnabled => !IsReadOnly;
+
+ public Module Clone()
+ {
+ return new Module
+ {
+ Name = Name,
+ Id = Id,
+ IsSelected = IsSelected,
+ IsReadOnly = IsReadOnly
+ };
+ }
+ }
+
+ class Config : ICloneable<Config>, IWizardConfiguration
+ {
+ public string Name { get; set; }
+ public VersionInformation QtVersion { get; set; }
+ public string QtVersionName { get; set; }
+ public string QtVersionPath { get; set; }
+ public string Target { get; set; }
+ public string Platform { get; set; }
+ public bool IsDebug { get; set; }
+
+ public Dictionary<string, Module> Modules { get; set; }
+
+ public IEnumerable<Module> AllModules
+ => Modules.Values.OrderBy(module => module.Name);
+ public IEnumerable<Module> SelectedModules
+ => Modules.Values.Where((Module m) => m.IsSelected);
+
+ IEnumerable<string> IWizardConfiguration.Modules
+ => SelectedModules.SelectMany((Module m) => m.Id.Split(' '));
+
+ public Config Clone()
+ {
+ return new Config
+ {
+ Name = Name,
+ QtVersion = QtVersion,
+ QtVersionName = QtVersionName,
+ Target = Target,
+ Platform = Platform,
+ IsDebug = IsDebug,
+ Modules = AllModules
+ .Select((Module m) => m.Clone())
+ .ToDictionary((Module m) => m.Name)
+ };
+ }
+ }
+
+ class CloneableList<T> : List<T> where T : ICloneable<T>
+ {
+ public CloneableList() : base()
+ { }
+
+ public CloneableList(IEnumerable<T> collection) : base(collection)
+ { }
+
+ public CloneableList<T> Clone()
+ {
+ return new CloneableList<T>(this.Select(x => x.Clone()));
+ }
+ }
+
+ const string QT_VERSION_DEFAULT = "<Default>";
+ const string QT_VERSION_BROWSE = "<Browse...>";
+
+ IEnumerable<string> qtVersionList = new[] { QT_VERSION_DEFAULT, QT_VERSION_BROWSE }
+ .Union(QtVersionManager.The().GetVersions());
+
+ readonly QtVersionManager qtVersionManager = QtVersionManager.The();
+ readonly VersionInformation defaultQtVersionInfo;
+
+ CloneableList<Config> defaultConfigs;
+ List<Config> currentConfigs;
+ bool initialNextButtonIsEnabled;
+ bool initialFinishButtonIsEnabled;
+
+ public ConfigPage()
+ {
+ InitializeComponent();
+
+ string defaultQtVersionName = qtVersionManager.GetDefaultVersion();
+ defaultQtVersionInfo = qtVersionManager.GetVersionInfo(defaultQtVersionName);
+
+ ErrorIcon.Source = Imaging.CreateBitmapSourceFromHIcon(
+ SystemIcons.Exclamation.Handle, Int32Rect.Empty,
+ BitmapSizeOptions.FromEmptyOptions());
+
+ DataContext = this;
+ Loaded += OnLoaded;
+ }
+
+ void OnLoaded(object sender, RoutedEventArgs e)
+ {
+ Loaded -= OnLoaded;
+
+ qtVersionList = new[] { QT_VERSION_DEFAULT, QT_VERSION_BROWSE }
+ .Union(QtVersionManager.The().GetVersions());
+
+ if (defaultQtVersionInfo == null) {
+ Validate();
+ return;
+ }
+
+ var qtModules = QtModules.Instance.GetAvailableModules(defaultQtVersionInfo.qtMajor)
+ .Where((QtModule mi) => mi.Selectable)
+ .Select((QtModule mi) => new Module()
+ {
+ Name = mi.Name,
+ Id = mi.proVarQT,
+ IsSelected = Data.DefaultModules.Contains(mi.LibraryPrefix),
+ IsReadOnly = Data.DefaultModules.Contains(mi.LibraryPrefix),
+ });
+
+ defaultConfigs = new CloneableList<Config> {
+ new Config {
+ Name = "Debug",
+ IsDebug = true,
+ QtVersion = defaultQtVersionInfo,
+ QtVersionName = defaultQtVersionInfo.name,
+ Target = defaultQtVersionInfo.isWinRT()
+ ? ProjectTargets.WindowsStore.Cast<string>()
+ : ProjectTargets.Windows.Cast<string>(),
+ Platform = defaultQtVersionInfo.is64Bit()
+ ? ProjectPlatforms.X64.Cast<string>()
+ : ProjectPlatforms.Win32.Cast<string>(),
+ Modules = qtModules.ToDictionary((Module m) => m.Name),
+ },
+ new Config {
+ Name = "Release",
+ IsDebug = false,
+ QtVersion = defaultQtVersionInfo,
+ QtVersionName = defaultQtVersionInfo.name,
+ Target = defaultQtVersionInfo.isWinRT()
+ ? ProjectTargets.WindowsStore.Cast<string>()
+ : ProjectTargets.Windows.Cast<string>(),
+ Platform = defaultQtVersionInfo.is64Bit()
+ ? ProjectPlatforms.X64.Cast<string>()
+ : ProjectPlatforms.Win32.Cast<string>(),
+ Modules = qtModules.ToDictionary((Module m) => m.Name),
+ }
+ };
+ currentConfigs = defaultConfigs.Clone();
+ ConfigTable.ItemsSource = currentConfigs;
+
+ initialNextButtonIsEnabled = NextButton.IsEnabled;
+ initialFinishButtonIsEnabled = FinishButton.IsEnabled;
+
+ Validate();
+ }
+
+ /// <summary>
+ /// Callback to validate selected configurations.
+ /// Must return an error message in case of failed validation.
+ /// Otherwise, return empty string or null.
+ /// </summary>
+ public Func<IEnumerable<IWizardConfiguration>, string> ValidateConfigs { get; set; }
+
+ void Validate()
+ {
+ if (currentConfigs == null) {
+ ErrorMsg.Content = "Register at least one Qt version using \"Qt VS Tools\"" +
+ " -> \"Qt Options\".";
+ ErrorPanel.Visibility = Visibility.Visible;
+ NextButton.IsEnabled = false;
+ FinishButton.IsEnabled = false;
+ } else if (currentConfigs // "$(Configuration)|$(Platform)" must be unique
+ .GroupBy((Config c) => string.Format("{0}|{1}", c.Name, c.Platform))
+ .Where((IGrouping<string, Config> g) => g.Count() > 1)
+ .Any()) {
+ ErrorMsg.Content = "(Configuration, Platform) must be unique";
+ ErrorPanel.Visibility = Visibility.Visible;
+ NextButton.IsEnabled = false;
+ FinishButton.IsEnabled = false;
+ } else if (ValidateConfigs != null
+ && ValidateConfigs(currentConfigs) is string errorMsg
+ && !string.IsNullOrEmpty(errorMsg)) {
+ ErrorMsg.Content = errorMsg;
+ ErrorPanel.Visibility = Visibility.Visible;
+ NextButton.IsEnabled = false;
+ FinishButton.IsEnabled = false;
+ } else {
+ ErrorMsg.Content = string.Empty;
+ ErrorPanel.Visibility = Visibility.Hidden;
+ NextButton.IsEnabled = initialNextButtonIsEnabled;
+ FinishButton.IsEnabled = initialFinishButtonIsEnabled;
+ }
+ }
+
+ void RemoveConfig_Click(object sender, RoutedEventArgs e)
+ {
+ if (sender is Button buttonRemove
+ && GetBinding(buttonRemove) is Config config) {
+ currentConfigs.Remove(config);
+ if (!currentConfigs.Any()) {
+ currentConfigs = defaultConfigs.Clone();
+ ConfigTable.ItemsSource = currentConfigs;
+ }
+ ConfigTable.Items.Refresh();
+ Validate();
+ }
+ }
+
+ void DuplicateConfig_Click(object sender, RoutedEventArgs e)
+ {
+ if (sender is Button buttonDuplicate
+ && GetBinding(buttonDuplicate) is Config config) {
+ currentConfigs.Add(config.Clone());
+ ConfigTable.Items.Refresh();
+ Validate();
+ }
+ }
+
+ void Name_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (sender is TextBox txt && GetBinding(txt) is Config cfg)
+ cfg.Name = txt.Text;
+ Validate();
+ }
+
+ void QtVersion_ComboBox_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (sender is ComboBox comboBoxQtVersion
+ && GetBinding(comboBoxQtVersion) is Config config) {
+ comboBoxQtVersion.IsEnabled = false;
+ comboBoxQtVersion.ItemsSource = qtVersionList;
+ comboBoxQtVersion.Text = config.QtVersionName;
+ comboBoxQtVersion.IsEnabled = true;
+ }
+ }
+
+ void QtVersion_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (sender is ComboBox comboBoxQtVersion
+ && comboBoxQtVersion.IsEnabled
+ && GetBinding(comboBoxQtVersion) is Config config
+ && config.QtVersionName != comboBoxQtVersion.Text) {
+ var oldQtVersion = config.QtVersion;
+ if (comboBoxQtVersion.Text == QT_VERSION_DEFAULT) {
+ config.QtVersion = defaultQtVersionInfo;
+ config.QtVersionName = defaultQtVersionInfo.name;
+ config.QtVersionPath = defaultQtVersionInfo.qtDir;
+ comboBoxQtVersion.Text = defaultQtVersionInfo.name;
+ } else if (comboBoxQtVersion.Text == QT_VERSION_BROWSE) {
+ var openFileDialog = new OpenFileDialog
+ {
+ Filter = "qmake (qmake.exe)|qmake.exe"
+ };
+ if (openFileDialog.ShowDialog() == true) {
+ IEnumerable<string> binPath = Path.GetDirectoryName(openFileDialog.FileName)
+ .Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
+ string lastDirName = binPath.LastOrDefault();
+ if ("bin".Equals(lastDirName, StringComparison.InvariantCultureIgnoreCase))
+ binPath = binPath.Take(binPath.Count() - 1);
+
+ var qtVersion = string.Join(
+ Path.DirectorySeparatorChar.ToString(), binPath);
+ var versionInfo = VersionInformation.Get(qtVersion);
+ if (versionInfo != null) {
+ versionInfo.name = qtVersion;
+ config.QtVersion = versionInfo;
+ config.QtVersionName = versionInfo.name;
+ config.QtVersionPath = config.QtVersion.qtDir;
+ }
+ }
+ comboBoxQtVersion.Text = config.QtVersionName;
+ } else if (qtVersionManager.GetVersions().Contains(comboBoxQtVersion.Text)) {
+ config.QtVersion = qtVersionManager.GetVersionInfo(comboBoxQtVersion.Text);
+ config.QtVersionName = comboBoxQtVersion.Text;
+ config.QtVersionPath = qtVersionManager.GetInstallPath(comboBoxQtVersion.Text);
+ } else {
+ config.QtVersion = null;
+ config.QtVersionName = config.QtVersionPath = comboBoxQtVersion.Text;
+ }
+
+ if (oldQtVersion != config.QtVersion) {
+ if (config.QtVersion != null) {
+ config.Target = config.QtVersion.isWinRT()
+ ? ProjectTargets.WindowsStore.Cast<string>()
+ : ProjectTargets.Windows.Cast<string>();
+ config.Platform = config.QtVersion.is64Bit()
+ ? ProjectPlatforms.X64.Cast<string>()
+ : ProjectPlatforms.Win32.Cast<string>();
+ config.Modules =
+ QtModules.Instance.GetAvailableModules(config.QtVersion.qtMajor)
+ .Where((QtModule mi) => mi.Selectable)
+ .Select((QtModule mi) => new Module()
+ {
+ Name = mi.Name,
+ Id = mi.proVarQT,
+ IsSelected = Data.DefaultModules.Contains(mi.LibraryPrefix),
+ IsReadOnly = Data.DefaultModules.Contains(mi.LibraryPrefix),
+ }).ToDictionary((Module m) => m.Name);
+ } else if (config.QtVersionPath.StartsWith("SSH:")) {
+ config.Target = ProjectTargets.LinuxSSH.Cast<string>();
+ } else if (config.QtVersionPath.StartsWith("WSL:")) {
+ config.Target = ProjectTargets.LinuxWSL.Cast<string>();
+ }
+ ConfigTable.Items.Refresh();
+ }
+ Validate();
+ }
+ }
+
+ void Target_ComboBox_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (sender is ComboBox comboBoxTarget
+ && GetBinding(comboBoxTarget) is Config config) {
+ comboBoxTarget.IsEnabled = false;
+ comboBoxTarget.ItemsSource = EnumExt.GetValues<string>(typeof(ProjectTargets));
+ comboBoxTarget.Text = config.Target;
+ comboBoxTarget.IsEnabled = true;
+ }
+ }
+
+ void Target_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (sender is ComboBox comboBoxTarget
+ && comboBoxTarget.IsEnabled
+ && GetBinding(comboBoxTarget) is Config config
+ && config.Target != comboBoxTarget.Text) {
+ config.Target = comboBoxTarget.Text;
+ ConfigTable.Items.Refresh();
+ Validate();
+ }
+ }
+
+ void Platform_ComboBox_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (sender is ComboBox comboBoxPlatform
+ && GetBinding(comboBoxPlatform) is Config config) {
+ comboBoxPlatform.IsEnabled = false;
+ comboBoxPlatform.ItemsSource = EnumExt.GetValues<string>(typeof(ProjectPlatforms));
+ comboBoxPlatform.Text = config.Platform;
+ comboBoxPlatform.IsEnabled = true;
+ }
+ }
+
+ void Platform_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (sender is ComboBox comboBoxPlatform
+ && comboBoxPlatform.IsEnabled
+ && GetBinding(comboBoxPlatform) is Config config
+ && config.Platform != comboBoxPlatform.Text) {
+ config.Platform = comboBoxPlatform.Text;
+ ConfigTable.Items.Refresh();
+ Validate();
+ }
+ }
+
+ void Debug_Click(object sender, RoutedEventArgs e)
+ {
+ if (sender is CheckBox checkBox && GetBinding(checkBox) is Config config) {
+ config.IsDebug = checkBox.IsChecked ?? false;
+ if (config.IsDebug && config.Name.EndsWith("Release")) {
+ config.Name = string.Format("{0}Debug",
+ config.Name.Substring(0, config.Name.Length - "Release".Length));
+ ConfigTable.Items.Refresh();
+ } else if (!config.IsDebug && config.Name.EndsWith("Debug")) {
+ config.Name = string.Format("{0}Release",
+ config.Name.Substring(0, config.Name.Length - "Debug".Length));
+ ConfigTable.Items.Refresh();
+ }
+ Validate();
+ }
+ }
+
+ void Module_Click(object sender, RoutedEventArgs e)
+ {
+ if (sender is CheckBox checkBoxModule
+ && (checkBoxModule.TemplatedParent as ContentPresenter)?.Content is Module
+ && GetBinding(checkBoxModule) is Config config
+ && FindAncestor(checkBoxModule, "Modules") is ComboBox comboBoxModules
+ && FindDescendant(comboBoxModules, "SelectedModules") is ListView selectedModules) {
+ selectedModules.ItemsSource = config.SelectedModules;
+ Validate();
+ }
+ }
+
+ protected override void OnNextButtonClick(object sender, RoutedEventArgs e)
+ {
+ Data.Configs = currentConfigs.Cast<IWizardConfiguration>();
+ base.OnNextButtonClick(sender, e);
+ }
+
+ protected override void OnFinishButtonClick(object sender, RoutedEventArgs e)
+ {
+ Data.Configs = currentConfigs.Cast<IWizardConfiguration>();
+ base.OnFinishButtonClick(sender, e);
+ }
+
+ static object GetBinding(FrameworkElement control)
+ {
+ if (control.BindingGroup == null
+ || control.BindingGroup.Items == null
+ || control.BindingGroup.Items.Count == 0) {
+ return null;
+ }
+ return control.BindingGroup.Items[0];
+ }
+
+ static FrameworkElement FindAncestor(FrameworkElement control, string name)
+ {
+ while (control != null && control.Name != name) {
+ object parent = control.Parent
+ ?? control.TemplatedParent
+ ?? VisualTreeHelper.GetParent(control);
+ control = parent as FrameworkElement;
+ }
+ return control;
+ }
+
+ static FrameworkElement FindDescendant(FrameworkElement control, string name)
+ {
+ var stack = new Stack<FrameworkElement>(new[] { control });
+ while (stack.Any()) {
+ control = stack.Pop();
+ if (control?.Name == name && control is FrameworkElement result)
+ return result;
+ for (int i = 0; i < VisualTreeHelper.GetChildrenCount(control); ++i) {
+ if (VisualTreeHelper.GetChild(control, i) is FrameworkElement child)
+ stack.Push(child);
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ProjectWizard/Console/ConsoleWizard.cs b/QtVsTools.Wizards/ProjectWizard/Console/ConsoleWizard.cs
new file mode 100644
index 0000000..76c8365
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Console/ConsoleWizard.cs
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Collections.Generic;
+
+namespace QtVsTools.Wizards.ProjectWizard
+{
+ using QtVsTools.Common;
+ using Wizards.Common;
+
+ public class ConsoleWizard : ProjectTemplateWizard
+ {
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ protected override Options TemplateType => Options.Application | Options.ConsoleSystem;
+
+ protected override WizardData WizardData => Lazy.Get(() =>
+ WizardData, () => new WizardData
+ {
+ DefaultModules = new List<string> { "QtCore" }
+ });
+
+ protected override WizardWindow WizardWindow => Lazy.Get(() =>
+ WizardWindow, () => new WizardWindow(title: "Qt Console Application Wizard")
+ {
+ new WizardIntroPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Console Application Wizard",
+ Message = @"This wizard generates a Qt console application "
+ + @"project. The application derives from QCoreApplication "
+ + @"and does not present a GUI." + System.Environment.NewLine
+ + System.Environment.NewLine + "To continue, click Next.",
+ PreviousButtonEnabled = false,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true
+ },
+ new ConfigPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Console Application Wizard",
+ Message =
+ @"Setup the configurations you want to include in your project. "
+ + @"The recommended settings for this project are selected by default.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = false,
+ FinishButtonEnabled = true,
+ CancelButtonEnabled = true,
+ ValidateConfigs = ValidateConfigsForConsoleApp
+ }
+ });
+
+ string ValidateConfigsForConsoleApp(IEnumerable<IWizardConfiguration> configs)
+ {
+ foreach (var config in configs) {
+ if (config.Target.EqualTo(ProjectTargets.WindowsStore)) {
+ return string.Format(
+ "Console Application project not available for the '{0}' target.",
+ config.Target);
+ }
+ }
+ return string.Empty;
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ProjectWizard/Designer/DesignerPage.xaml b/QtVsTools.Wizards/ProjectWizard/Designer/DesignerPage.xaml
new file mode 100644
index 0000000..1a7b71f
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Designer/DesignerPage.xaml
@@ -0,0 +1,310 @@
+<!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2016 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+-->
+
+<common:WizardPage x:Class="QtVsTools.Wizards.ProjectWizard.DesignerPage"
+ xmlns:common="clr-namespace:QtVsTools.Wizards.Common"
+ xmlns:util="clr-namespace:QtVsTools.Wizards.Util"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ KeepAlive="True"
+ mc:Ignorable="d"
+ d:DesignHeight="445"
+ d:DesignWidth="585">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="100" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Image Grid.Column="0"
+ HorizontalAlignment="Center"
+ Source="/QtVsTools.Wizards;component/Resources/Qt-logo-small.png"
+ VerticalAlignment="Top"
+ Margin="0,25,0,0"
+ RenderTransformOrigin="1,0">
+ <Image.RenderTransform>
+ <TransformGroup>
+ <ScaleTransform ScaleY="0.86"
+ ScaleX="0.86" />
+ </TransformGroup>
+ </Image.RenderTransform>
+ </Image>
+ <Grid Grid.Column="1"
+ Margin="25,25,10,0">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TextBlock TextWrapping="Wrap"
+ Grid.Row="0">
+ <Run FontWeight="Bold"
+ Text="{Binding Path=Header}" />
+ <LineBreak />
+ <LineBreak />
+ <Run Text="{Binding Path=Message}" />
+ <LineBreak />
+ </TextBlock>
+ <Grid Grid.Row="1">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Grid.Resources>
+ <Style TargetType="TextBox">
+ <Style.Triggers>
+ <Trigger Property="Validation.HasError"
+ Value="true">
+ <Setter Property="ToolTip"
+ Value="{Binding RelativeSource={RelativeSource Self},
+ Path=(Validation.Errors)[0].ErrorContent}" />
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Resources>
+ <TextBlock Grid.Row="0"
+ Margin="0,0,10,5">
+ <Run FontWeight="Bold"
+ Text="Custom Widget "/>
+ <Run Text="- Class Name:"/>
+ </TextBlock>
+ <TextBox Grid.Row="1"
+ Margin="0,0,10,10"
+ x:Name="ClassName"
+ TextChanged="OnClassNameChanged">
+ <TextBox.Text>
+ <Binding Path="Data.ClassName"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:ClassNameValidationRule />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Grid.Column="1"
+ Grid.Row="0"
+ Text="Base class:"
+ Margin="0,0,0,5" />
+ <TextBox Grid.Column="1"
+ Grid.Row="1"
+ Name="BaseClass"
+ Margin="0,0,0,10">
+ <TextBox.Text>
+ <Binding Path="Data.BaseClass"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:ClassNameValidationRule AllowEmptyIdentifier="True"/>
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Grid.Row="2"
+ Margin="0,0,10,5"
+ Text="Header (.h) file:" />
+ <TextBox Grid.Row="3"
+ Margin="0,0,10,30"
+ Name="ClassHeaderFile">
+ <TextBox.Text>
+ <Binding Path="Data.ClassHeaderFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".h" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Grid.Column="1"
+ Grid.Row="2"
+ Margin="0,0,0,5"
+ Text="Source (.cpp) file:" />
+ <TextBox Grid.Column="1"
+ Grid.Row="3"
+ Margin="0,0,0,30"
+ Name="ClassSourceFile">
+ <TextBox.Text>
+ <Binding Path="Data.ClassSourceFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".cpp" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Grid.Column="0"
+ Grid.Row="4"
+ Margin="0,0,0,5"
+ >
+ <Run FontWeight="Bold"
+ Text="Plugin"/>
+ <Run Text=" - Class Name:"/>
+ </TextBlock>
+ <TextBox Grid.Column="0"
+ Grid.Row="5"
+ Margin="0,0,0,10"
+ Name="PluginClass">
+ <TextBox.Text>
+ <Binding Path="Data.PluginClass"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:ClassNameValidationRule />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Grid.Row="6"
+ Margin="0,0,10,5"
+ Text="Header (.h) file:" />
+ <TextBox Grid.Row="7"
+ Margin="0,0,10,0"
+ Name="PluginHeaderFile">
+ <TextBox.Text>
+ <Binding Path="Data.PluginHeaderFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".h" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Grid.Column="1"
+ Grid.Row="6"
+ Margin="0,0,0,5"
+ Text="Source (.cpp) file:" />
+ <TextBox Grid.Column="1"
+ Grid.Row="7"
+ Margin="0"
+ Name="PluginSourceFile">
+ <TextBox.Text>
+ <Binding Path="Data.PluginSourceFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".cpp" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <CheckBox Grid.Row="8"
+ Content="Lower case file names"
+ Margin="0,20,0,5"
+ Name="LowerCaseFileNames"
+ Click="OnLowerCaseFileNamesClick" />
+ <CheckBox Grid.Row="9"
+ Content="Precompiled header"
+ Margin="0,10,0,0"
+ IsChecked="{Binding Path=Data.UsePrecompiledHeader}" />
+ </Grid>
+ <StackPanel HorizontalAlignment="Right"
+ Orientation="Horizontal"
+ Grid.Row="2"
+ Margin="0,0,0,10">
+ <Button Click="OnPreviousButtonClick"
+ Name="PreviousButton"
+ IsEnabled="{Binding Path=PreviousButtonEnabled}"
+ MinWidth="75">< _Previous</Button>
+ <Button MinWidth="75"
+ Name="NextButton"
+ Click="OnNextButtonClick"
+ IsEnabled="{Binding Path=NextButtonEnabled}"
+ Margin="10,0,0,0">_Next ></Button>
+ <Button MinWidth="75"
+ Click="OnFinishButtonClick"
+ Margin="10,0,0,0"
+ IsDefault="True"
+ Name="FinishButton"
+ Content="_Finish"
+ VerticalAlignment="Bottom">
+ <Button.Style>
+ <Style TargetType="Button">
+ <Setter Property="IsEnabled"
+ Value="false" />
+ <Style.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding Path=FinishButtonEnabled}"
+ Value="true" />
+ <Condition Binding="{Binding ElementName=ClassName,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=BaseClass,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=ClassHeaderFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=ClassSourceFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=PluginClass,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=PluginHeaderFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=PluginSourceFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ </MultiDataTrigger.Conditions>
+ <Setter Property="IsEnabled"
+ Value="true" />
+ </MultiDataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+ <Button Click="OnCancelButtonClick"
+ MinWidth="75"
+ Margin="10,0,0,0"
+ Name="CancelButton"
+ IsEnabled="{Binding Path=CancelButtonEnabled}"
+ IsCancel="True">_Cancel</Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+</common:WizardPage>
diff --git a/QtVsTools.Wizards/ProjectWizard/Designer/DesignerPage.xaml.cs b/QtVsTools.Wizards/ProjectWizard/Designer/DesignerPage.xaml.cs
new file mode 100644
index 0000000..fb1f10e
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Designer/DesignerPage.xaml.cs
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Windows;
+using System.Windows.Controls;
+
+namespace QtVsTools.Wizards.ProjectWizard
+{
+ using Wizards.Common;
+
+ public partial class DesignerPage : WizardPage
+ {
+ public DesignerPage()
+ {
+ InitializeComponent();
+ DataContext = this;
+ }
+
+ private void OnClassNameChanged(object sender, TextChangedEventArgs e)
+ {
+ UpdateFileNames();
+ }
+
+ private void OnLowerCaseFileNamesClick(object sender, RoutedEventArgs e)
+ {
+ UpdateFileNames();
+ }
+
+ private void UpdateFileNames()
+ {
+ var filename = ClassName.Text;
+ var pluginFilename = PluginClass.Text;
+ if (LowerCaseFileNames.IsChecked.GetValueOrDefault()) {
+ filename = filename.ToLower();
+ pluginFilename = pluginFilename.ToLower();
+ }
+
+ ClassHeaderFile.Text = filename + @".h";
+ ClassSourceFile.Text = filename + @".cpp";
+
+ PluginHeaderFile.Text = pluginFilename + @".h";
+ PluginSourceFile.Text = pluginFilename + @".cpp";
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ProjectWizard/Designer/DesignerWizard.cs b/QtVsTools.Wizards/ProjectWizard/Designer/DesignerWizard.cs
new file mode 100644
index 0000000..f93f677
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Designer/DesignerWizard.cs
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Collections.Generic;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows.Controls;
+using EnvDTE;
+
+namespace QtVsTools.Wizards.ProjectWizard
+{
+ using Core;
+ using Legacy = Core.Legacy;
+ using QtVsTools.Common;
+ using Wizards.Common;
+
+ using static QtVsTools.Common.EnumExt;
+
+ public class DesignerWizard : ProjectTemplateWizard
+ {
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ protected override Options TemplateType =>
+ Options.PluginProject | Options.DynamicLibrary | Options.GUISystem;
+
+ enum NewClass
+ {
+ [String("classname")] ClassName,
+ [String("baseclass")] BaseClass,
+ [String("sourcefilename")] SourceFileName,
+ [String("headerfilename")] HeaderFileName,
+ [String("include")] Include,
+ }
+
+ enum NewDesignerPlugin
+ {
+ [String("plugin_class")] ClassName,
+ [String("objname")] ObjectName,
+ [String("pluginsourcefilename")] SourceFileName,
+ [String("pluginheaderfilename")] HeaderFileName,
+ [String("plugin_json")] JsonFileName,
+ }
+
+ protected override WizardData WizardData => Lazy.Get(() =>
+ WizardData, () => new WizardData
+ {
+ DefaultModules = new List<string> {
+ "QtCore", "QtGui", "QtWidgets", "QtDesigner"
+ }
+ });
+
+ protected override WizardWindow WizardWindow => Lazy.Get(() =>
+ WizardWindow, () => new WizardWindow(title: "Qt Custom Designer Widget")
+ {
+ new WizardIntroPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Custom Designer Widget",
+ Message = @"This wizard generates a custom designer widget which can be "
+ + @"used in Qt Designer or Visual Studio."
+ + System.Environment.NewLine + System.Environment.NewLine
+ + "To continue, click Next.",
+ PreviousButtonEnabled = false,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true
+ },
+ new ConfigPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Custom Designer Widget",
+ Message =
+ @"Setup the configurations you want to include in your project. "
+ + @"The recommended settings for this project are selected by default.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true,
+ ValidateConfigs = ValidateConfigsForDesignerWidget
+ },
+ new DesignerPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Custom Designer Widget",
+ Message = @"This wizard generates a custom designer widget which can be "
+ + @"used in Qt Designer or Visual Studio.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = false,
+ FinishButtonEnabled = true,
+ CancelButtonEnabled = true
+ }
+ }
+ );
+
+ string ValidateConfigsForDesignerWidget(IEnumerable<IWizardConfiguration> configs)
+ {
+ foreach (var config in configs) {
+ if (config.Target.EqualTo(ProjectTargets.WindowsStore)) {
+ return string.Format(
+ "Custom Designer Widget project not available for the '{0}' target.",
+ config.Target);
+ }
+ }
+ return string.Empty;
+ }
+
+ protected override void BeforeWizardRun()
+ {
+ var className = Parameter[NewProject.SafeName];
+ className = Regex.Replace(className, @"[^a-zA-Z0-9_]", string.Empty);
+ className = Regex.Replace(className, @"^[\d-]*\s*", string.Empty);
+ var result = new Util.ClassNameValidationRule().Validate(className, null);
+ if (result != ValidationResult.ValidResult)
+ className = @"MyDesignerWidget";
+
+ WizardData.ClassName = className;
+ WizardData.BaseClass = @"QWidget";
+ WizardData.ClassHeaderFile = className + @".h";
+ WizardData.ClassSourceFile = className + @".cpp";
+
+ WizardData.PluginClass = className + @"Plugin";
+ WizardData.PluginHeaderFile = WizardData.PluginClass + @".h";
+ WizardData.PluginSourceFile = WizardData.PluginClass + @".cpp";
+ }
+
+ protected override void BeforeTemplateExpansion()
+ {
+ Parameter[NewClass.ClassName] = WizardData.ClassName;
+ Parameter[NewClass.BaseClass] = WizardData.BaseClass;
+ Parameter[NewClass.HeaderFileName] = WizardData.ClassHeaderFile;
+ Parameter[NewClass.SourceFileName] = WizardData.ClassSourceFile;
+
+ var include = new StringBuilder();
+ if (UsePrecompiledHeaders)
+ include.AppendLine(string.Format("#include \"{0}\"", PrecompiledHeader.Include));
+ include.AppendLine(string.Format("#include \"{0}\"", WizardData.ClassHeaderFile));
+ Parameter[NewClass.Include] = FormatParam(include);
+
+ Parameter[NewDesignerPlugin.ClassName] = WizardData.PluginClass;
+ Parameter[NewDesignerPlugin.HeaderFileName] = WizardData.PluginHeaderFile;
+ Parameter[NewDesignerPlugin.SourceFileName] = WizardData.PluginSourceFile;
+ Parameter[NewDesignerPlugin.JsonFileName] = WizardData.PluginClass.ToLower() + ".json";
+ Parameter[NewDesignerPlugin.ObjectName] = string.Format("{0}{1}",
+ WizardData.ClassName[0],
+ WizardData.ClassName.Substring(1));
+ }
+
+ protected override void OnProjectGenerated(Project project)
+ {
+ var qtPro = Core.QtProject.Create(project);
+ if (qtPro != null) {
+ QtProject.MarkAsQtPlugin(qtPro);
+ Legacy.QtProject.MarkAsDesignerPluginProject(qtPro);
+ }
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ProjectWizard/Empty/EmptyWizard.cs b/QtVsTools.Wizards/ProjectWizard/Empty/EmptyWizard.cs
new file mode 100644
index 0000000..b223170
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Empty/EmptyWizard.cs
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Collections.Generic;
+
+namespace QtVsTools.Wizards.ProjectWizard
+{
+ using QtVsTools.Common;
+ using Wizards.Common;
+
+ public class EmptyWizard : ProjectTemplateWizard
+ {
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ protected override Options TemplateType => Options.Application | Options.GUISystem;
+
+ protected override WizardData WizardData => Lazy.Get(() =>
+ WizardData, () => new WizardData
+ {
+ DefaultModules = new List<string> { }
+ });
+
+ protected override WizardWindow WizardWindow => Lazy.Get(() =>
+ WizardWindow, () => new WizardWindow(title: "Qt Empty Application Wizard")
+ {
+ new WizardIntroPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Empty Application Wizard",
+ Message = @"This wizard generates an empty Qt application project."
+ + System.Environment.NewLine
+ + "Click Finish to create the project.",
+ PreviousButtonEnabled = false,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true
+ },
+ new ConfigPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Empty Application Wizard",
+ Message =
+ @"Setup the configurations you want to include in your project. "
+ + @"The recommended settings for this project are selected by default.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = false,
+ FinishButtonEnabled = true,
+ CancelButtonEnabled = true,
+ }
+ });
+ }
+}
diff --git a/QtVsTools.Wizards/ProjectWizard/Gui/GuiWizard.cs b/QtVsTools.Wizards/ProjectWizard/Gui/GuiWizard.cs
new file mode 100644
index 0000000..a4f6f21
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Gui/GuiWizard.cs
@@ -0,0 +1,365 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows.Controls;
+using EnvDTE;
+
+namespace QtVsTools.Wizards.ProjectWizard
+{
+ using QtVsTools.Common;
+ using Core;
+ using Wizards.Common;
+
+ using static QtVsTools.Common.EnumExt;
+
+ public class GuiWizard : ProjectTemplateWizard
+ {
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ protected override Options TemplateType => Options.Application | Options.GUISystem;
+
+ readonly Func<IWizardConfiguration, bool> whereConfigTargetIsWindowsStore
+ = (IWizardConfiguration config) => config.Target.EqualTo(ProjectTargets.WindowsStore);
+
+ enum NewClass
+ {
+ [String("classname")] ClassName,
+ [String("baseclass")] BaseClass,
+ [String("sourcefilename")] SourceFileName,
+ [String("headerfilename")] HeaderFileName,
+ [String("include")] Include,
+ }
+
+ enum NewGuiProject
+ {
+ [String("centralwidget")] CentralWidget,
+ [String("qrcfilename")] QrcFileName,
+ [String("uifilename")] UiFileName,
+ [String("ui_hdr")] UiHeaderName,
+ [String("forward_declare_class")] ForwardDeclClass,
+ [String("multiple_inheritance")] MultipleInheritance,
+ [String("ui_classname")] UiClassName,
+ [String("member")] Member,
+ }
+
+ enum Meta
+ {
+ [String("namespace")] Namespace,
+ [String("namespacebegin")] NamespaceBegin,
+ [String("operator")] Operator,
+ [String("asterisk")] Asterisk,
+ [String("semicolon")] Semicolon,
+ [String("new")] New,
+ [String("delete")] Delete,
+ [String("namespaceend")] NamespaceEnd
+ }
+
+ protected override WizardData WizardData => Lazy.Get(() =>
+ WizardData, () => new WizardData
+ {
+ DefaultModules = new List<string> { "QtCore", "QtGui", "QtWidgets" }
+ });
+
+ protected override WizardWindow WizardWindow => Lazy.Get(() =>
+ WizardWindow, () => new WizardWindow(title: "Qt Widgets Application Wizard")
+ {
+ new WizardIntroPage
+ {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Widgets Application Wizard",
+ Message = @"This wizard generates a Qt Widgets application project. The "
+ + @"application derives from QApplication and includes an empty "
+ + @"widget." + System.Environment.NewLine
+ + System.Environment.NewLine + "To continue, click Next.",
+ PreviousButtonEnabled = false,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true
+ },
+ new ConfigPage
+ {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Widgets Application Wizard",
+ Message =
+ @"Setup the configurations you want to include in your project. "
+ + @"The recommended settings for this project are selected by default.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true
+ },
+ new GuiPage
+ {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Widgets Application Wizard",
+ Message = @"This wizard generates a Qt Widgets application project. The "
+ + @"application derives from QApplication and includes an empty "
+ + @"widget.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = false,
+ FinishButtonEnabled = true,
+ CancelButtonEnabled = true
+ }
+ });
+
+ readonly List<ItemDef> GuiExtraItems;
+ protected override IEnumerable<ItemDef> ExtraItems => GuiExtraItems;
+
+ public GuiWizard()
+ {
+ GuiExtraItems = new List<ItemDef>
+ {
+ new ItemDef
+ {
+ ItemType = "AppxManifest",
+ Include = "Package.appxmanifest",
+ Filter = "Resource Files",
+ WhereConfig = whereConfigTargetIsWindowsStore
+ },
+ new ItemDef
+ {
+ ItemType = "Image",
+ Include = "assets/logo_store.png",
+ Filter = "Resource Files",
+ WhereConfig = whereConfigTargetIsWindowsStore
+ },
+ new ItemDef
+ {
+ ItemType = "Image",
+ Include = "assets/logo_620x300.png",
+ Filter = "Resource Files",
+ WhereConfig = whereConfigTargetIsWindowsStore
+ },
+ new ItemDef
+ {
+ ItemType = "Image",
+ Include = "assets/logo_150x150.png",
+ Filter = "Resource Files",
+ WhereConfig = whereConfigTargetIsWindowsStore
+ },
+ new ItemDef
+ {
+ ItemType = "Image",
+ Include = "assets/logo_44x44.png",
+ Filter = "Resource Files",
+ WhereConfig = whereConfigTargetIsWindowsStore
+ },
+ };
+ }
+
+ protected override void BeforeWizardRun()
+ {
+ var className = Parameter[NewProject.SafeName];
+ className = Regex.Replace(className, @"[^a-zA-Z0-9_]", string.Empty);
+ className = Regex.Replace(className, @"^[\d-]*\s*", string.Empty);
+ var result = new Util.ClassNameValidationRule().Validate(className, null);
+ if (result != ValidationResult.ValidResult)
+ className = @"QtWidgetsApplication";
+
+ WizardData.ClassName = className;
+ WizardData.BaseClass = @"QMainWindow";
+ WizardData.ClassHeaderFile = className + @".h";
+ WizardData.ClassSourceFile = className + @".cpp";
+ WizardData.UiFile = WizardData.ClassName + @".ui";
+ WizardData.QrcFile = WizardData.ClassName + @".qrc";
+ WizardData.UiClassInclusion = UiClassInclusion.Member;
+
+ Parameter[NewGuiProject.ForwardDeclClass] = "";
+ Parameter[NewGuiProject.MultipleInheritance] = "";
+ Parameter[NewGuiProject.UiClassName] = "";
+ Parameter[NewGuiProject.Member] = "ui";
+
+ Parameter[Meta.Asterisk] ="";
+ Parameter[Meta.Operator] = ".";
+ Parameter[Meta.Semicolon] = ";";
+ Parameter[Meta.New] = "";
+ Parameter[Meta.Delete] = "";
+ }
+
+ protected override void BeforeTemplateExpansion()
+ {
+ var array = WizardData.ClassName.Split(new[] { "::" },
+ StringSplitOptions.RemoveEmptyEntries);
+ var className = array.LastOrDefault();
+
+ Parameter[NewClass.ClassName] = className;
+ Parameter[NewClass.BaseClass] = WizardData.BaseClass;
+ Parameter[NewClass.HeaderFileName] = WizardData.ClassHeaderFile;
+ Parameter[NewClass.SourceFileName] = WizardData.ClassSourceFile;
+ Parameter[NewGuiProject.UiFileName] = WizardData.UiFile;
+
+ var include = new StringBuilder();
+ if (UsePrecompiledHeaders)
+ include.AppendLine(string.Format("#include \"{0}\"", PrecompiledHeader.Include));
+ include.AppendLine(string.Format("#include \"{0}\"", WizardData.ClassHeaderFile));
+ Parameter[NewClass.Include] = FormatParam(include);
+
+ Parameter[NewGuiProject.UiHeaderName] = string.Format("ui_{0}.h",
+ Path.GetFileNameWithoutExtension(WizardData.UiFile));
+ Parameter[NewGuiProject.QrcFileName] = WizardData.QrcFile;
+
+ if (WizardData.BaseClass == "QMainWindow") {
+ Parameter[NewGuiProject.CentralWidget] = FormatParam(@"
+ <widget class=""QMenuBar"" name=""menuBar"" />
+ <widget class=""QToolBar"" name=""mainToolBar"" />
+ <widget class=""QWidget"" name=""centralWidget"" />
+ <widget class=""QStatusBar"" name=""statusBar"" />");
+ }
+
+ StringBuilder winRcFile = new StringBuilder();
+
+ if (WizardData.AddDefaultAppIcon) {
+ var projectIcon = Path.Combine(
+ Parameter[NewProject.DestinationDirectory],
+ Parameter[NewProject.SafeName] + ".ico");
+ var iconExists = File.Exists(projectIcon);
+ if (!iconExists) {
+ try {
+ var uri =
+ new Uri(System.Reflection.Assembly.GetExecutingAssembly().EscapedCodeBase);
+ var pkgInstallPath
+ = Path.GetDirectoryName(Uri.UnescapeDataString(uri.AbsolutePath)) + @"\";
+ var templateIcon
+ = Path.Combine(pkgInstallPath, @"ProjectTemplates\VC\Qt\1033\gui\gui.ico");
+ File.Copy(templateIcon, projectIcon);
+ File.SetAttributes(projectIcon,
+ File.GetAttributes(projectIcon) & (~FileAttributes.ReadOnly));
+ iconExists = true;
+ } catch (Exception /*ex*/) {
+ // Silently ignore any error, the project is working
+ // without icon too.
+ }
+ }
+
+ if (iconExists) {
+ GuiExtraItems.Add(new ItemDef
+ {
+ ItemType = "None",
+ Include = Parameter[NewProject.SafeName] + ".ico",
+ Filter = "Resource Files"
+ });
+ winRcFile.AppendLine(
+ string.Format("IDI_ICON1\t\tICON\t\tDISCARDABLE\t\"{0}.ico\"",
+ /*{0}*/ Parameter[NewProject.SafeName]));
+ }
+ }
+
+ if (winRcFile.Length > 0) {
+ GuiExtraItems.Add(new ItemDef
+ {
+ ItemType = "ResourceCompile",
+ Include = Parameter[NewProject.SafeName] + ".rc",
+ Filter = "Resource Files"
+ });
+ File.WriteAllText(
+ Path.Combine(
+ Parameter[NewProject.DestinationDirectory],
+ Parameter[NewProject.SafeName] + ".rc"),
+ winRcFile.ToString());
+ }
+
+ switch (WizardData.UiClassInclusion) {
+ case UiClassInclusion.MemberPointer:
+ Parameter[NewGuiProject.ForwardDeclClass] =
+ string.Format(
+ "\r\nQT_BEGIN_NAMESPACE\r\n"
+ + "namespace Ui {{ class {0}Class; }};\r\n"
+ + "QT_END_NAMESPACE\r\n", className
+ );
+ Parameter[Meta.Asterisk] = "*";
+ Parameter[Meta.Operator] = "->";
+ Parameter[Meta.New] = string.Format("\r\n , {0}(new Ui::{1}Class())",
+ Parameter[NewGuiProject.Member], className);
+ Parameter[Meta.Delete] = string.Format("\r\n delete {0};\r\n",
+ Parameter[NewGuiProject.Member]);
+ goto case UiClassInclusion.Member;
+ case UiClassInclusion.Member:
+ Parameter[NewGuiProject.UiClassName] = string.Format("Ui::{0}Class", className);
+ break;
+ case UiClassInclusion.MultipleInheritance:
+ Parameter[NewGuiProject.MultipleInheritance] =
+ string.Format(", public Ui::{0}Class", className);
+ Parameter[NewGuiProject.Member] = "";
+ Parameter[Meta.Operator] = "";
+ Parameter[Meta.Semicolon] = "";
+ break;
+ }
+
+ string ns = "", nsBegin = "", nsEnd = "";
+ for (var i = 0; i < array.Length - 1; ++i) {
+ ns += array[i] + "::";
+ nsBegin += "namespace " + array[i] + " {\r\n";
+ nsEnd = "} // namespace " + array[i] + "\r\n" + nsEnd;
+ }
+ Parameter[Meta.Namespace] = ns;
+ Parameter[Meta.NamespaceBegin] = nsBegin;
+ Parameter[Meta.NamespaceEnd] = nsEnd;
+ }
+
+ protected override void OnProjectGenerated(Project project)
+ {
+ IWizardConfiguration configWinRT = Configurations
+ .Where(whereConfigTargetIsWindowsStore)
+ .FirstOrDefault();
+
+ if (configWinRT != null) {
+ var projDir = Parameter[NewProject.DestinationDirectory];
+ var qmakeTmpDir = Path.Combine(projDir, "qmake_tmp");
+ Directory.CreateDirectory(qmakeTmpDir);
+
+ var dummyPro = Path.Combine(qmakeTmpDir,
+ string.Format("{0}.pro", Parameter[NewProject.SafeName]));
+ File.WriteAllText(dummyPro, "SOURCES = main.cpp\r\n");
+
+ var qmake = new QMakeImport(configWinRT.QtVersion, dummyPro);
+ qmake.Run(setVCVars: true);
+
+ var qmakeAssetsDir = Path.Combine(qmakeTmpDir, "assets");
+ var projAssetsDir = Path.Combine(projDir, "assets");
+ if (Directory.Exists(qmakeAssetsDir)) {
+ if (Directory.Exists(projAssetsDir))
+ Directory.Delete(projAssetsDir, recursive: true);
+ Directory.Move(qmakeAssetsDir, projAssetsDir);
+ }
+
+ var manifestFile = Path.Combine(qmakeTmpDir, "Package.appxmanifest");
+ if (File.Exists(manifestFile)) {
+ File.Move(manifestFile, Path.Combine(projDir, "Package.appxmanifest"));
+ }
+
+ Directory.Delete(qmakeTmpDir, recursive: true);
+ }
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ProjectWizard/Library/LibraryClassPage.xaml b/QtVsTools.Wizards/ProjectWizard/Library/LibraryClassPage.xaml
new file mode 100644
index 0000000..aebfe6f
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Library/LibraryClassPage.xaml
@@ -0,0 +1,238 @@
+<!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2016 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+-->
+
+<common:WizardPage x:Class="QtVsTools.Wizards.ProjectWizard.LibraryClassPage"
+ xmlns:common="clr-namespace:QtVsTools.Wizards.Common"
+ xmlns:util="clr-namespace:QtVsTools.Wizards.Util"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ KeepAlive="True"
+ mc:Ignorable="d"
+ d:DesignHeight="445"
+ d:DesignWidth="585">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="100" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Image Grid.Column="0"
+ HorizontalAlignment="Center"
+ Source="/QtVsTools.Wizards;component/Resources/Qt-logo-small.png"
+ VerticalAlignment="Top"
+ Margin="0,25,0,0"
+ RenderTransformOrigin="1,0">
+ <Image.RenderTransform>
+ <TransformGroup>
+ <ScaleTransform ScaleY="0.86"
+ ScaleX="0.86" />
+ </TransformGroup>
+ </Image.RenderTransform>
+ </Image>
+ <Grid Grid.Column="1"
+ Margin="25,25,10,0">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TextBlock TextWrapping="Wrap"
+ Grid.Row="0">
+ <Run FontWeight="Bold"
+ Text="{Binding Path=Header}" />
+ <LineBreak />
+ <LineBreak />
+ <Run Text="{Binding Path=Message}" />
+ <LineBreak />
+ </TextBlock>
+ <Grid Grid.Row="1">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Grid.Resources>
+ <Style TargetType="TextBox">
+ <Style.Triggers>
+ <Trigger Property="Validation.HasError"
+ Value="true">
+ <Setter Property="ToolTip"
+ Value="{Binding RelativeSource={RelativeSource Self},
+ Path=(Validation.Errors)[0].ErrorContent}" />
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Resources>
+ <TextBlock Grid.Row="0"
+ Text="Class Name:"
+ Margin="0,0,10,0" />
+ <TextBox Grid.Row="1"
+ Margin="0,0,10,30"
+ Name="ClassName"
+ TextChanged="OnClassNameChanged"
+ TabIndex="0">
+ <TextBox.Text>
+ <Binding Path="Data.ClassName"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:ClassNameValidationRule />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <Grid Grid.Row="2"
+ Grid.ColumnSpan="2">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <TextBlock Grid.Row="0"
+ Margin="0,0,10,5"
+ Text="Header (.h) file:" />
+ <TextBox Grid.Row="1"
+ Margin="0,0,10,0"
+ Name="ClassHeaderFile"
+ TabIndex="1">
+ <TextBox.Text>
+ <Binding Path="Data.ClassHeaderFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".h" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Grid.Row="0"
+ Grid.Column="1"
+ Margin="0,0,0,5"
+ Text="Source (.cpp) file:" />
+ <TextBox Grid.Row="1"
+ Grid.Column="1"
+ Margin="0,0,0,00"
+ Name="ClassSourceFile"
+ TabIndex="2">
+ <TextBox.Text>
+ <Binding Path="Data.ClassSourceFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".cpp" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ </Grid>
+ <CheckBox Grid.Row="3"
+ Content="Lower case file names"
+ Name="LowerCaseFileNames"
+ Click="OnLowerCaseFileNamesClick"
+ Margin="0,20,10,5"
+ TabIndex="3" />
+ <CheckBox Grid.Row="4"
+ Content="Precompiled header"
+ IsChecked="{Binding Path=Data.UsePrecompiledHeader}"
+ Margin="0,10,10,5"
+ TabIndex="4" />
+ <CheckBox Grid.Row="5"
+ Content="Create Static Library (.lib)"
+ IsChecked="{Binding Path=Data.CreateStaticLibrary}"
+ Margin="0,0,10,0"
+ TabIndex="5" />
+ </Grid>
+ <StackPanel HorizontalAlignment="Right"
+ Orientation="Horizontal"
+ Grid.Row="2"
+ Margin="0,0,0,10">
+ <Button Click="OnPreviousButtonClick"
+ Name="PreviousButton"
+ IsEnabled="{Binding Path=PreviousButtonEnabled}"
+ MinWidth="75">< _Previous</Button>
+ <Button MinWidth="75"
+ Name="NextButton"
+ Click="OnNextButtonClick"
+ IsEnabled="{Binding Path=NextButtonEnabled}"
+ Margin="10,0,0,0">_Next ></Button>
+ <Button MinWidth="75"
+ Click="OnFinishButtonClick"
+ Margin="10,0,0,0"
+ IsDefault="True"
+ Name="FinishButton"
+ Content="_Finish"
+ VerticalAlignment="Bottom">
+ <Button.Style>
+ <Style TargetType="Button">
+ <Setter Property="IsEnabled"
+ Value="false" />
+ <Style.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding Path=FinishButtonEnabled}"
+ Value="true" />
+ <Condition Binding="{Binding ElementName=ClassName,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=ClassHeaderFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=ClassSourceFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ </MultiDataTrigger.Conditions>
+ <Setter Property="IsEnabled"
+ Value="true" />
+ </MultiDataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+ <Button Click="OnCancelButtonClick"
+ MinWidth="75"
+ Margin="10,0,0,0"
+ Name="CancelButton"
+ IsEnabled="{Binding Path=CancelButtonEnabled}"
+ IsCancel="True">_Cancel</Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+</common:WizardPage>
diff --git a/QtVsTools.Wizards/ProjectWizard/Library/LibraryClassPage.xaml.cs b/QtVsTools.Wizards/ProjectWizard/Library/LibraryClassPage.xaml.cs
new file mode 100644
index 0000000..93f8fd0
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Library/LibraryClassPage.xaml.cs
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Windows;
+using System.Windows.Controls;
+
+namespace QtVsTools.Wizards.ProjectWizard
+{
+ using Wizards.Common;
+
+ public partial class LibraryClassPage : WizardPage
+ {
+ public LibraryClassPage()
+ {
+ InitializeComponent();
+ DataContext = this;
+ }
+
+ private void OnClassNameChanged(object sender, TextChangedEventArgs e)
+ {
+ UpdateFileNames();
+ }
+
+ private void OnLowerCaseFileNamesClick(object sender, RoutedEventArgs e)
+ {
+ UpdateFileNames();
+ }
+
+ private void UpdateFileNames()
+ {
+ var filename = ClassName.Text;
+ if (LowerCaseFileNames.IsChecked.GetValueOrDefault())
+ filename = filename.ToLower();
+
+ ClassHeaderFile.Text = filename + @".h";
+ ClassSourceFile.Text = filename + @".cpp";
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ProjectWizard/Library/LibraryWizard.cs b/QtVsTools.Wizards/ProjectWizard/Library/LibraryWizard.cs
new file mode 100644
index 0000000..0968343
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Library/LibraryWizard.cs
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Collections.Generic;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows.Controls;
+
+namespace QtVsTools.Wizards.ProjectWizard
+{
+ using QtVsTools.Common;
+ using Wizards.Common;
+
+ using static QtVsTools.Common.EnumExt;
+
+ public class LibraryWizard : ProjectTemplateWizard
+ {
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ protected override Options TemplateType => Options.GUISystem
+ | (WizardData.CreateStaticLibrary ? Options.StaticLibrary : Options.DynamicLibrary);
+
+ enum NewLibClass
+ {
+ [String("classname")] ClassName,
+ [String("sourcefilename")] SourceFileName,
+ [String("headerfilename")] HeaderFileName,
+ [String("include")] Include,
+ [String("saveglobal")] GlobalHeader,
+ [String("pro_lib_define")] LibDefine,
+ [String("pro_lib_export")] LibExport,
+ }
+
+ protected override WizardData WizardData => Lazy.Get(() =>
+ WizardData, () => new WizardData
+ {
+ DefaultModules = new List<string> { "QtCore" }
+ });
+
+ readonly List<string> LibExtraDefines = new List<string>();
+ protected override IEnumerable<string> ExtraDefines => LibExtraDefines;
+
+ protected override WizardWindow WizardWindow => Lazy.Get(() =>
+ WizardWindow, () => new WizardWindow(title: "Qt Class Library Wizard")
+ {
+ new WizardIntroPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Class Library Wizard",
+ Message = @"This wizard generates a Qt Class Library project. The "
+ + @"resulting library is linked dynamically with Qt."
+ + System.Environment.NewLine + System.Environment.NewLine
+ + @"To continue, click Next.",
+ PreviousButtonEnabled = false,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true
+ },
+ new ConfigPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Class Library Wizard",
+ Message =
+ @"Setup the configurations you want to include in your project. "
+ + @"The recommended settings for this project are selected by default.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true
+ },
+ new LibraryClassPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Class Library Wizard",
+ Message = @"This wizard generates a Qt Class Library project. The "
+ + @"resulting library is linked dynamically with Qt.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = false,
+ FinishButtonEnabled = true,
+ CancelButtonEnabled = true
+ }
+ });
+
+ protected override void BeforeWizardRun()
+ {
+ var safeprojectname = Parameter[NewProject.SafeName];
+ safeprojectname = Regex.Replace(safeprojectname, @"[^a-zA-Z0-9_]", string.Empty);
+ safeprojectname = Regex.Replace(safeprojectname, @"^[\d-]*\s*", string.Empty);
+ var result = new Util.ClassNameValidationRule().Validate(safeprojectname, null);
+ if (result != ValidationResult.ValidResult)
+ safeprojectname = @"QtClassLibrary";
+
+ WizardData.ClassName = safeprojectname;
+ WizardData.ClassHeaderFile = safeprojectname + @".h";
+ WizardData.ClassSourceFile = safeprojectname + @".cpp";
+ }
+
+ protected override void BeforeTemplateExpansion()
+ {
+ Parameter[NewLibClass.ClassName] = WizardData.ClassName;
+ Parameter[NewLibClass.HeaderFileName] = WizardData.ClassHeaderFile;
+ Parameter[NewLibClass.SourceFileName] = WizardData.ClassSourceFile;
+
+ var include = new StringBuilder();
+ if (UsePrecompiledHeaders)
+ include.AppendLine(string.Format("#include \"{0}\"", PrecompiledHeader.Include));
+ include.AppendLine(string.Format("#include \"{0}\"", WizardData.ClassHeaderFile));
+ Parameter[NewLibClass.Include] = FormatParam(include);
+
+ var safeprojectname = Parameter[NewProject.SafeName];
+ Parameter[NewLibClass.GlobalHeader] = safeprojectname.ToLower();
+ Parameter[NewLibClass.LibDefine] = safeprojectname.ToUpper() + "_LIB";
+ Parameter[NewLibClass.LibExport] = safeprojectname.ToUpper() + "_EXPORT";
+
+ LibExtraDefines.Add(Parameter[NewLibClass.LibDefine]);
+ if (WizardData.CreateStaticLibrary)
+ LibExtraDefines.Add("BUILD_STATIC");
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ProjectWizard/ProjectTemplateWizard.cs b/QtVsTools.Wizards/ProjectWizard/ProjectTemplateWizard.cs
new file mode 100644
index 0000000..9ae6ae8
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/ProjectTemplateWizard.cs
@@ -0,0 +1,722 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using Microsoft.Internal.VisualStudio.PlatformUI;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+using Microsoft.VisualStudio.TemplateWizard;
+using EnvDTE;
+
+
+namespace QtVsTools.Wizards.ProjectWizard
+{
+ using QtVsTools.Common;
+ using Core;
+ using Core.QtMsBuild;
+ using VisualStudio;
+ using Wizards.Common;
+
+ using WhereConfig = Func<IWizardConfiguration, bool>;
+
+ using static QtVsTools.Common.EnumExt;
+
+ public interface IWizardConfiguration
+ {
+ string Name { get; }
+ VersionInformation QtVersion { get; }
+ string QtVersionName { get; }
+ string QtVersionPath { get; }
+ string Target { get; }
+ string Platform { get; }
+ bool IsDebug { get; }
+ IEnumerable<string> Modules { get; }
+ }
+
+ public enum ProjectTargets
+ {
+ Windows,
+ [String("Windows Store")] WindowsStore,
+ [String("Linux (SSH)")] LinuxSSH,
+ [String("Linux (WSL)")] LinuxWSL
+ }
+
+ public enum ProjectPlatforms
+ {
+ [String("x64")] X64,
+ Win32,
+ ARM64,
+ ARM,
+ }
+
+ public abstract class ProjectTemplateWizard : IWizard
+ {
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ private readonly WhereConfig WhereConfig_SelectAll = (x => true);
+
+ protected struct ItemProperty
+ {
+ public string Key { get; }
+ public string Value { get; }
+ public WhereConfig WhereConfig { get; }
+
+ public ItemProperty(string key, string value, WhereConfig whereConfig = null)
+ {
+ Key = key;
+ Value = value;
+ WhereConfig = whereConfig;
+ }
+
+ public static implicit operator ItemProperty[](ItemProperty that)
+ {
+ return new[] { that };
+ }
+ }
+
+ protected class ItemGlobalDef
+ {
+ public string ItemType { get; set; }
+ public ItemProperty[] Properties { get; set; }
+ }
+
+ protected class ItemDef
+ {
+ public string ItemType { get; set; }
+ public string Include { get; set; }
+ public ItemProperty[] Properties { get; set; }
+ public string Filter { get; set; }
+ public WhereConfig WhereConfig { get; set; }
+ }
+
+ [Flags]
+ protected enum Options : uint
+ {
+ Application = 0x000,
+ DynamicLibrary = 0x001,
+ StaticLibrary = 0x002,
+ GUISystem = 0x004,
+ ConsoleSystem = 0x008,
+ PluginProject = 0x100
+ }
+
+ protected abstract Options TemplateType { get; }
+ protected abstract WizardData WizardData { get; }
+ protected abstract WizardWindow WizardWindow { get; }
+
+ protected virtual IDictionary<string, ItemGlobalDef> ItemGlobals => null;
+ protected virtual IEnumerable<ItemDef> ExtraItems => Enumerable.Empty<ItemDef>();
+ protected virtual IEnumerable<string> ExtraModules => Enumerable.Empty<string>();
+ protected virtual IEnumerable<string> ExtraDefines => Enumerable.Empty<string>();
+
+ protected virtual IEnumerable<IWizardConfiguration> Configurations => WizardData.Configs;
+ protected virtual bool UsePrecompiledHeaders => WizardData.UsePrecompiledHeader;
+
+ private Dictionary<string, string> ParameterValues { get; set; }
+ protected EnvDTE.DTE Dte { get; private set; }
+
+ protected virtual ItemDef PrecompiledHeader => Lazy.Get(() =>
+ PrecompiledHeader, () => new ItemDef
+ {
+ ItemType = "ClInclude",
+ Include = "stdafx.h",
+ Filter = "Header Files"
+ });
+
+ protected virtual ItemDef PrecompiledHeaderSource => Lazy.Get(() =>
+ PrecompiledHeaderSource, () => new ItemDef
+ {
+ ItemType = "ClCompile",
+ Include = "stdafx.cpp",
+ Properties = new ItemProperty("PrecompiledHeader", "Create"),
+ Filter = "Source Files",
+ });
+
+ protected class TemplateParameters
+ {
+ public ProjectTemplateWizard Template { get; set; }
+
+ string ParamKey(Enum param)
+ {
+ return string.Format("${0}$", param.Cast<string>());
+ }
+
+ public string this[Enum param]
+ {
+ get => Template.ParameterValues[ParamKey(param)];
+ set => Template.ParameterValues[ParamKey(param)] = value;
+ }
+ }
+
+ protected enum NewProject
+ {
+ // Read-only parameters
+ [String("projectname")] Name,
+ [String("safeprojectname")] SafeName,
+ [String("destinationdirectory")] DestinationDirectory,
+ [String("solutiondirectory")] SolutionDirectory,
+
+ // Custom parameters
+ ToolsVersion,
+ ProjectConfigurations,
+ Properties,
+ ProjectGuid,
+ Keyword,
+ Globals,
+ Configurations,
+ PropertySheets,
+ QtSettings,
+ BuildSettings,
+ ProjectItems,
+ FilterItems,
+ }
+
+ protected TemplateParameters Parameter => Lazy.Get(() =>
+ Parameter, () => new TemplateParameters { Template = this });
+
+ protected QtVersionManager VersionManager => QtVersionManager.The();
+
+ public virtual void ProjectItemFinishedGenerating(ProjectItem projectItem) { }
+ public virtual void BeforeOpeningFile(ProjectItem projectItem) { }
+ public virtual void RunFinished() { }
+ public virtual bool ShouldAddProjectItem(string filePath) => true;
+
+ protected virtual void BeforeWizardRun() { }
+ protected virtual void BeforeTemplateExpansion() { }
+ protected virtual void OnProjectGenerated(Project project) { }
+
+ public virtual void RunStarted(
+ object automationObject,
+ Dictionary<string, string> parameterValues,
+ WizardRunKind runKind,
+ object[] customParams)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ Dte = automationObject as DTE;
+ ParameterValues = parameterValues;
+
+ Debug.Assert(WizardWindow != null);
+
+ BeforeWizardRun();
+
+ var iVsUIShell = VsServiceProvider.GetService<SVsUIShell, IVsUIShell>();
+ if (iVsUIShell == null)
+ throw new NullReferenceException("IVsUIShell");
+
+ try {
+ iVsUIShell.EnableModeless(0);
+ iVsUIShell.GetDialogOwnerHwnd(out IntPtr hwnd);
+ WindowHelper.ShowModal(WizardWindow, hwnd);
+ } catch (QtVSException exception) {
+ exception.Log(false, true);
+ throw;
+ } finally {
+ iVsUIShell.EnableModeless(1);
+ }
+ if (!WizardWindow.DialogResult ?? false) {
+ try {
+ Directory.Delete(Parameter[NewProject.DestinationDirectory]);
+ Directory.Delete(Parameter[NewProject.SolutionDirectory]);
+ } catch { }
+ throw new WizardBackoutException();
+ }
+
+ BeforeTemplateExpansion();
+ Expand();
+ }
+
+ public virtual void ProjectFinishedGenerating(Project project)
+ {
+ OnProjectGenerated(project);
+ }
+
+ protected static bool IsLinux(IWizardConfiguration wizConfig)
+ {
+ return wizConfig.Target.EqualTo(ProjectTargets.LinuxSSH)
+ || wizConfig.Target.EqualTo(ProjectTargets.LinuxWSL);
+ }
+
+ protected static string GetLinuxCompilerPath(IWizardConfiguration wizConfig)
+ {
+ if (!IsLinux(wizConfig))
+ return string.Empty;
+ if (string.IsNullOrEmpty(wizConfig.QtVersionPath))
+ return string.Empty;
+ string[] linuxPaths = wizConfig.QtVersionPath.Split(':');
+ if (linuxPaths == null || linuxPaths.Length <= 2)
+ return string.Empty;
+ return linuxPaths[2];
+ }
+
+ protected virtual void Expand()
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ Debug.Assert(ParameterValues != null);
+ Debug.Assert(Dte != null);
+ Debug.Assert(Configurations != null);
+ Debug.Assert(ExtraItems != null);
+
+ StringBuilder xml;
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // Tools version = VS version
+ //
+ Parameter[NewProject.ToolsVersion] = Dte.Version;
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // Configurations
+ //
+ xml = new StringBuilder();
+ foreach (IWizardConfiguration c in Configurations) {
+ xml.AppendLine(string.Format(@"
+ <ProjectConfiguration Include=""{0}|{1}"">
+ <Configuration>{0}</Configuration>
+ <Platform>{1}</Platform>
+ </ProjectConfiguration>",
+ /*{0}*/ c.Name,
+ /*{1}*/ c.Platform));
+ }
+ Parameter[NewProject.ProjectConfigurations] = FormatParam(xml);
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // Properties
+ //
+ xml = new StringBuilder();
+ foreach (IWizardConfiguration c in Configurations) {
+ xml.AppendLine(string.Format(@"
+ <PropertyGroup Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">",
+ /*{0}*/ c.Name,
+ /*{1}*/ c.Platform));
+ if (IsLinux(c)) {
+ var compilerPath = GetLinuxCompilerPath(c);
+ if (!string.IsNullOrEmpty(compilerPath))
+ xml.AppendLine(string.Format(@"
+ <RemoteCCompileToolExe>{0}</RemoteCCompileToolExe>
+ <RemoteCppCompileToolExe>{0}</RemoteCppCompileToolExe>
+ <RemoteLdToolExe>{0}</RemoteLdToolExe>",
+ /*{0}*/ compilerPath));
+ }
+ xml.AppendLine(@"
+ </PropertyGroup>");
+ }
+ Parameter[NewProject.Properties] = FormatParam(xml);
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // Globals
+ //
+ xml = new StringBuilder();
+ Parameter[NewProject.ProjectGuid] = HelperFunctions.NewProjectGuid();
+ Parameter[NewProject.Keyword] = Resources.QtVSVersionTag;
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // Globals: Windows
+ //
+ foreach (IWizardConfiguration c in Configurations
+ .Where(c => c.Target.EqualTo(ProjectTargets.Windows))) {
+ if (!string.IsNullOrEmpty(c.QtVersion.VC_WindowsTargetPlatformVersion)) {
+ xml.AppendLine(string.Format(@"
+ <WindowsTargetPlatformVersion Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">{2}</WindowsTargetPlatformVersion>",
+ /*{0}*/ c.Name,
+ /*{1}*/ c.Platform,
+ /*{2}*/ c.QtVersion.VC_WindowsTargetPlatformVersion));
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // Globals: Windows Store
+ //
+ foreach (IWizardConfiguration c in Configurations
+ .Where(c => c.Target.EqualTo(ProjectTargets.WindowsStore))) {
+ xml.AppendLine(string.Format(@"
+ <ApplicationType Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">Windows Store</ApplicationType>
+ <WindowsTargetPlatformVersion Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">{2}</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformMinVersion Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">{3}</WindowsTargetPlatformMinVersion>
+ <MinimumVisualStudioVersion Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">{4}</MinimumVisualStudioVersion>
+ <ApplicationTypeRevision Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">{5}</ApplicationTypeRevision>
+ <DefaultLanguage Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">en</DefaultLanguage>
+ <AppContainerApplication Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">true</AppContainerApplication>",
+ /*{0}*/ c.Name,
+ /*{1}*/ c.Platform,
+ /*{2}*/ c.QtVersion.VC_WindowsTargetPlatformVersion,
+ /*{3}*/ c.QtVersion.VC_WindowsTargetPlatformMinVersion,
+ /*{4}*/ c.QtVersion.VC_MinimumVisualStudioVersion,
+ /*{5}*/ c.QtVersion.VC_ApplicationTypeRevision));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // Globals: Linux
+ //
+ foreach (IWizardConfiguration c in Configurations.Where(c => IsLinux(c))) {
+ xml.AppendLine(string.Format(@"
+ <ApplicationType Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">Linux</ApplicationType>
+ <ApplicationTypeRevision Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">1.0</ApplicationTypeRevision>
+ <TargetLinuxPlatform Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">Generic</TargetLinuxPlatform>
+ <LinuxProjectType Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">{{D51BCBC9-82E9-4017-911E-C93873C4EA2B}}</LinuxProjectType>",
+ /*{0}*/ c.Name,
+ /*{1}*/ c.Platform));
+ }
+
+ Parameter[NewProject.Globals] = FormatParam(xml);
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // VC Configurations
+ //
+ xml = new StringBuilder();
+ foreach (IWizardConfiguration c in Configurations) {
+ if (!c.Target.TryCast(out ProjectTargets target))
+ continue;
+ xml.AppendLine(string.Format(@"
+ <PropertyGroup Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"" Label=""Configuration"">",
+ /*{0}*/ c.Name,
+ /*{1}*/ c.Platform));
+ if (TemplateType.HasFlag(Options.DynamicLibrary)) {
+ xml.AppendLine(@"
+ <ConfigurationType>DynamicLibrary</ConfigurationType>");
+ } else if (TemplateType.HasFlag(Options.StaticLibrary)) {
+ xml.AppendLine(@"
+ <ConfigurationType>StaticLibrary</ConfigurationType>");
+ } else {
+ xml.AppendLine(@"
+ <ConfigurationType>Application</ConfigurationType>");
+ }
+ switch (target) {
+ case ProjectTargets.Windows:
+ case ProjectTargets.WindowsStore:
+ xml.AppendLine(string.Format(@"
+ <PlatformToolset>v{0}</PlatformToolset>",
+ /*{0}*/ BuildConfig.PlatformToolset));
+ break;
+ case ProjectTargets.LinuxSSH:
+ xml.AppendLine(@"
+ <PlatformToolset>Remote_GCC_1_0</PlatformToolset>");
+ break;
+ case ProjectTargets.LinuxWSL:
+ xml.AppendLine(@"
+ <PlatformToolset>WSL_1_0</PlatformToolset>");
+ break;
+ }
+ if (IsLinux(c)) {
+ xml.AppendLine(string.Format(@"
+ <UseDebugLibraries>{0}</UseDebugLibraries>",
+ /*{0}*/ c.IsDebug ? "true" : "false"));
+ } else if (target == ProjectTargets.WindowsStore) {
+ xml.AppendLine(@"
+ <GenerateManifest>false</GenerateManifest>
+ <EmbedManifest>false</EmbedManifest>");
+ }
+ xml.AppendLine(@"
+ </PropertyGroup>");
+ }
+ Parameter[NewProject.Configurations] = FormatParam(xml);
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // Property sheets
+ //
+ xml = new StringBuilder();
+ foreach (IWizardConfiguration c in Configurations) {
+ xml.AppendLine(string.Format(@"
+ <ImportGroup Label=""PropertySheets"" Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">
+ <Import Project=""$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"" Condition=""exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')"" Label=""LocalAppDataPlatform"" />
+ <Import Project=""$(QtMsBuild)\Qt.props"" />
+ </ImportGroup>",
+ /*{0}*/ c.Name,
+ /*{1}*/ c.Platform));
+ }
+ Parameter[NewProject.PropertySheets] = FormatParam(xml);
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // Qt settings
+ //
+ xml = new StringBuilder();
+ foreach (IWizardConfiguration c in Configurations) {
+ xml.AppendLine(string.Format(@"
+ <PropertyGroup Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"" Label=""QtSettings"">
+ <QtInstall>{2}</QtInstall>
+ <QtModules>{3}</QtModules>
+ <QtBuildConfig>{4}</QtBuildConfig>",
+ /*{0}*/ c.Name,
+ /*{1}*/ c.Platform,
+ /*{2}*/ c.QtVersionName,
+ /*{3}*/ string.Join(";", c.Modules.Union(ExtraModules)),
+ /*{4}*/ c.IsDebug ? "debug" : "release"));
+ if (c.Target.EqualTo(ProjectTargets.WindowsStore)) {
+ xml.AppendLine(@"
+ <QtDeploy>true</QtDeploy>
+ <QtDeployToProjectDir>true</QtDeployToProjectDir>
+ <QtDeployVsContent>true</QtDeployVsContent>");
+ }
+ xml.AppendLine(@"
+ </PropertyGroup>");
+ }
+ Parameter[NewProject.QtSettings] = FormatParam(xml);
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // Build settings
+ //
+ IEnumerable<ItemProperty> mocProperties
+ = ItemGlobals?[QtMoc.ItemTypeName]?.Properties ?? Enumerable.Empty<ItemProperty>();
+ IEnumerable<ItemProperty> clProperties
+ = ItemGlobals?["ClCompile"]?.Properties ?? Enumerable.Empty<ItemProperty>();
+ IEnumerable<ItemProperty> linkProperties
+ = ItemGlobals?["Link"]?.Properties ?? Enumerable.Empty<ItemProperty>();
+
+ xml = new StringBuilder();
+ foreach (IWizardConfiguration c in Configurations) {
+ xml.AppendLine(string.Format(@"
+ <ItemDefinitionGroup Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"" Label=""Configuration"">",
+ /*{0}*/ c.Name,
+ /*{1}*/ c.Platform));
+
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ // Build settings: C++ compiler
+ //
+ if (!IsLinux(c)) {
+ // Windows
+ xml.AppendLine(@"
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>");
+ if (c.IsDebug) {
+ xml.AppendLine(@"
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>");
+ } else {
+ xml.AppendLine(@"
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <Optimization>MaxSpeed</Optimization>");
+ }
+ if (c.Target.EqualTo(ProjectTargets.WindowsStore)) {
+ xml.AppendLine(@"
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <RuntimeTypeInfo>true</RuntimeTypeInfo>");
+ }
+ if (UsePrecompiledHeaders) {
+ xml.AppendLine(string.Format(@"
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>{0}</PrecompiledHeaderFile>",
+ /*{0}*/ PrecompiledHeader.Include));
+ }
+ if (ExtraDefines?.Any() == true) {
+ xml.AppendLine(string.Format(@"
+ <PreprocessorDefinitions>{0};%(PreprocessorDefinitions)</PreprocessorDefinitions>",
+ /*{0}*/ string.Join(";", ExtraDefines)));
+ }
+ foreach (ItemProperty p in clProperties) {
+ xml.AppendLine(string.Format(@"
+ <{0}>{1}</{0}>",
+ /*{0}*/ p.Key,
+ /*{1}*/ p.Value));
+ }
+ xml.AppendLine(@"
+ </ClCompile>");
+ } else {
+ // Linux
+ xml.AppendLine(@"
+ <ClCompile>
+ <PositionIndependentCode>true</PositionIndependentCode>
+ </ClCompile>");
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ // Build settings: Linker
+ //
+ if (!IsLinux(c)) {
+ // Windows
+ xml.AppendLine(string.Format(@"
+ <Link>
+ <SubSystem>{0}</SubSystem>
+ <GenerateDebugInformation>{1}</GenerateDebugInformation>",
+ /*{0}*/ TemplateType.HasFlag(Options.ConsoleSystem) ? "Console" : "Windows",
+ /*{1}*/ c.IsDebug ? "true" : "false"));
+ if (c.Target.EqualTo(ProjectTargets.WindowsStore)) {
+ xml.AppendLine(string.Format(@"
+ <AdditionalOptions>/APPCONTAINER %(AdditionalOptions)</AdditionalOptions>
+ <GenerateManifest>false</GenerateManifest>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ <TargetMachine>{0}</TargetMachine>",
+ /*{0}*/ c.QtVersion.VC_Link_TargetMachine));
+ }
+ foreach (ItemProperty p in linkProperties) {
+ xml.AppendLine(string.Format(@"
+ <{0}>{1}</{0}>",
+ /*{0}*/ p.Key,
+ /*{1}*/ p.Value));
+ }
+ xml.AppendLine(@"
+ </Link>");
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ // Build settings: moc
+ //
+ if (UsePrecompiledHeaders || mocProperties.Any()) {
+ xml.AppendLine(string.Format(@"
+ <{0}>", QtMoc.ItemTypeName));
+ foreach (ItemProperty p in mocProperties) {
+ xml.AppendLine(string.Format(@"
+ <{0}>{1}</{0}>",
+ /*{0}*/ p.Key,
+ /*{1}*/ p.Value));
+ }
+ if (UsePrecompiledHeaders) {
+ xml.AppendLine(string.Format(@"
+ <{0}>{1};%({0})</{0}>",
+ /*{0}*/ QtMoc.Property.PrependInclude,
+ /*{1}*/ PrecompiledHeader.Include));
+ }
+ xml.AppendLine(string.Format(@"
+ </{0}>", QtMoc.ItemTypeName));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ // Build settings: remaining item types
+ //
+ if (ItemGlobals != null) {
+ foreach (string itemType in ItemGlobals.Keys
+ .Except(new[] { "ClCompile", "Link", QtMoc.ItemTypeName })) {
+ xml.AppendLine(string.Format(@"
+ <{0}>",
+ /*{0}*/ itemType));
+ foreach (ItemProperty p in ItemGlobals[itemType].Properties) {
+ xml.AppendLine(string.Format(@"
+ <{0}>{1}</{0}>",
+ /*{0}*/ p.Key,
+ /*{1}*/ p.Value));
+ }
+ xml.AppendLine(string.Format(@"
+ </{0}>",
+ /*{0}*/ itemType));
+ }
+ }
+ xml.AppendLine(@"
+ </ItemDefinitionGroup>");
+ }
+
+ Parameter[NewProject.BuildSettings] = FormatParam(xml);
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ //
+ IEnumerable<ItemDef> projectItems = ExtraItems
+ .Where((ItemDef item) => item.WhereConfig == null
+ || Configurations.Where(item.WhereConfig).Any())
+ .Union(UsePrecompiledHeaders
+ ? new[] { PrecompiledHeader, PrecompiledHeaderSource }
+ : Enumerable.Empty<ItemDef>());
+
+ xml = new StringBuilder();
+ foreach (ItemDef item in projectItems) {
+ bool itemHasProperties = (item.WhereConfig != null || item.Properties != null);
+ xml.Append(string.Format(@"
+ <{0} Include=""{1}""{2}",
+ /*{0}*/ item.ItemType,
+ /*{1}*/ item.Include,
+ /*{2}*/ itemHasProperties ? ">" : " />"));
+
+ if (item.Properties != null) {
+ foreach (ItemProperty property in item.Properties) {
+ IEnumerable<IWizardConfiguration> configs = Configurations
+ .Where(property.WhereConfig ?? WhereConfig_SelectAll);
+ foreach (IWizardConfiguration config in configs) {
+ xml.AppendLine(string.Format(@"
+ <{0} Condition=""'$(Configuration)|$(Platform)' == '{1}|{2}'"">{3}</{0}>",
+ /*{0}*/ property.Key,
+ /*{1}*/ config.Name,
+ /*{2}*/ config.Platform,
+ /*{3}*/ property.Value));
+ }
+ }
+ }
+
+ if (item.WhereConfig != null) {
+ IEnumerable<IWizardConfiguration> excludedConfigs = Configurations
+ .Where(config => !item.WhereConfig(config));
+ foreach (var excludedConfig in excludedConfigs) {
+ xml.AppendLine(string.Format(@"
+ <ExcludedFromBuild Condition=""'$(Configuration)|$(Platform)' == '{0}|{1}'"">true</ExcludedFromBuild>",
+ /*{0}*/ excludedConfig.Name,
+ /*{1}*/ excludedConfig.Platform));
+ }
+ }
+
+ if (itemHasProperties) {
+ xml.AppendLine(string.Format(@"
+ </{0}>",
+ /*{0}*/ item.ItemType));
+ }
+ }
+ Parameter[NewProject.ProjectItems] = FormatParam(xml);
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // Project items: filters
+ //
+ xml = new StringBuilder();
+ foreach (ItemDef item in projectItems) {
+ xml.Append(string.Format(@"
+ <{0} Include=""{1}"">",
+ /*{0}*/ item.ItemType,
+ /*{1}*/ item.Include));
+ xml.AppendLine(string.Format(@"
+ <Filter>{0}</Filter>",
+ /*{0}*/ item.Filter));
+ xml.AppendLine(string.Format(@"
+ </{0}>",
+ /*{0}*/ item.ItemType));
+ }
+ Parameter[NewProject.FilterItems] = FormatParam(xml);
+ }
+
+ // Matches empty lines; captures first newline
+ static readonly Regex patternEmptyLines
+ = new Regex(@"(?:^|(?<FIRST_NL>\r\n))(?:\r\n)+(?![\r\n]|$)|(?:\r\n)+$");
+
+ protected static string FormatParam(StringBuilder paramValue)
+ {
+ return FormatParam(paramValue.ToString());
+ }
+
+ protected static string FormatParam(string paramValue)
+ {
+ // Remove empty lines; replace with first newline (if any)
+ paramValue = patternEmptyLines.Replace(paramValue,
+ (Match m) => m.Groups["FIRST_NL"].Value);
+
+ return paramValue;
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ProjectWizard/Quick/QuickWizard.cs b/QtVsTools.Wizards/ProjectWizard/Quick/QuickWizard.cs
new file mode 100644
index 0000000..87a0cc2
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Quick/QuickWizard.cs
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Collections.Generic;
+
+namespace QtVsTools.Wizards.ProjectWizard
+{
+ using QtVsTools.Common;
+ using Wizards.Common;
+
+ public class QuickWizard : ProjectTemplateWizard
+ {
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ protected override Options TemplateType => Options.Application | Options.GUISystem;
+
+ protected override WizardData WizardData => Lazy.Get(() =>
+ WizardData, () => new WizardData
+ {
+ DefaultModules = new List<string> { "QtQuick" }
+ });
+
+ protected override WizardWindow WizardWindow => Lazy.Get(() =>
+ WizardWindow, () => new WizardWindow(title: "Qt Quick Application Wizard")
+ {
+ new WizardIntroPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Quick Application Wizard",
+ Message = @"This wizard generates a Qt Quick application project."
+ + System.Environment.NewLine
+ + "Click Finish to create the project.",
+ PreviousButtonEnabled = false,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true
+ },
+ new ConfigPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt Quick Application Wizard",
+ Message =
+ @"Setup the configurations you want to include in your project. "
+ + @"The recommended settings for this project are selected by default.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = false,
+ FinishButtonEnabled = true,
+ CancelButtonEnabled = true,
+ }
+ });
+ }
+}
diff --git a/QtVsTools.Wizards/ProjectWizard/Server/ServerPage.xaml b/QtVsTools.Wizards/ProjectWizard/Server/ServerPage.xaml
new file mode 100644
index 0000000..8d7e946
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Server/ServerPage.xaml
@@ -0,0 +1,259 @@
+<!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2016 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+-->
+
+<common:WizardPage x:Class="QtVsTools.Wizards.ProjectWizard.ServerPage"
+ xmlns:common="clr-namespace:QtVsTools.Wizards.Common"
+ xmlns:util="clr-namespace:QtVsTools.Wizards.Util"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ KeepAlive="True"
+ mc:Ignorable="d"
+ d:DesignHeight="445"
+ d:DesignWidth="585">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="100" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Image Grid.Column="0"
+ HorizontalAlignment="Center"
+ Source="/QtVsTools.Wizards;component/Resources/Qt-logo-small.png"
+ VerticalAlignment="Top"
+ Margin="0,25,0,0"
+ RenderTransformOrigin="1,0">
+ <Image.RenderTransform>
+ <TransformGroup>
+ <ScaleTransform ScaleY="0.86"
+ ScaleX="0.86" />
+ </TransformGroup>
+ </Image.RenderTransform>
+ </Image>
+ <Grid Grid.Column="1"
+ Margin="25,25,10,0">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <TextBlock TextWrapping="Wrap"
+ Grid.Row="0">
+ <Run FontWeight="Bold"
+ Text="{Binding Path=Header}" />
+ <LineBreak />
+ <LineBreak />
+ <Run Text="{Binding Path=Message}" />
+ <LineBreak />
+ </TextBlock>
+ <Grid Grid.Row="1">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Grid.Resources>
+ <Style TargetType="TextBox">
+ <Style.Triggers>
+ <Trigger Property="Validation.HasError"
+ Value="true">
+ <Setter Property="ToolTip"
+ Value="{Binding RelativeSource={RelativeSource Self},
+ Path=(Validation.Errors)[0].ErrorContent}" />
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+ </Grid.Resources>
+ <TextBlock Grid.Row="0"
+ Text="Class Name:"
+ Margin="0,0,10,0" />
+ <TextBox Grid.Row="1"
+ Margin="0,0,10,30"
+ Name="ClassName"
+ TextChanged="OnClassNameChanged"
+ TabIndex="0">
+ <TextBox.Text>
+ <Binding Path="Data.ClassName"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:ClassNameValidationRule />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <Grid Grid.Row="2"
+ Grid.ColumnSpan="2">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <TextBlock Grid.Row="0"
+ Grid.Column="0"
+ Margin="0,0,10,5"
+ Text="Header (.h) file:" />
+ <TextBox Grid.Row="1"
+ Grid.Column="0"
+ Margin="0,0,10,10"
+ Name="ClassHeaderFile"
+ TabIndex="1">
+ <TextBox.Text>
+ <Binding Path="Data.ClassHeaderFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".h" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Grid.Row="2"
+ Grid.Column="0"
+ Margin="0,0,10,5"
+ Text="User Interface (.ui) file:" />
+ <TextBox Grid.Row="3"
+ Grid.Column="0"
+ Margin="0,0,10,0"
+ Name="UiFile"
+ TabIndex="3">
+ <TextBox.Text>
+ <Binding Path="Data.UiFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".ui" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ <TextBlock Grid.Row="0"
+ Grid.Column="1"
+ Margin="0,0,0,5"
+ Text="Source (.cpp) file:" />
+ <TextBox Grid.Row="1"
+ Grid.Column="1"
+ Margin="0,0,0,10"
+ Name="ClassSourceFile"
+ TabIndex="2">
+ <TextBox.Text>
+ <Binding Path="Data.ClassSourceFile"
+ NotifyOnValidationError="True"
+ UpdateSourceTrigger="PropertyChanged">
+ <Binding.ValidationRules>
+ <util:FileNameValidationRule FileExt=".cpp" />
+ </Binding.ValidationRules>
+ </Binding>
+ </TextBox.Text>
+ </TextBox>
+ </Grid>
+ <CheckBox Grid.Row="3"
+ Content="Lower case file names"
+ Name="LowerCaseFileNames"
+ Click="OnLowerCaseFileNamesClick"
+ Margin="0,20,10,5"
+ TabIndex="4" />
+ <CheckBox Grid.Row="4"
+ Content="Precompiled header"
+ IsChecked="{Binding Path=Data.UsePrecompiledHeader}"
+ Margin="0,10,10,5"
+ TabIndex="5" />
+ </Grid>
+ <StackPanel HorizontalAlignment="Right"
+ Orientation="Horizontal"
+ Grid.Row="2"
+ Margin="0,0,0,10">
+ <Button Click="OnPreviousButtonClick"
+ Name="PreviousButton"
+ IsEnabled="{Binding Path=PreviousButtonEnabled}"
+ MinWidth="75">< _Previous</Button>
+ <Button MinWidth="75"
+ Name="NextButton"
+ Click="OnNextButtonClick"
+ IsEnabled="{Binding Path=NextButtonEnabled}"
+ Margin="10,0,0,0">_Next ></Button>
+ <Button MinWidth="75"
+ Click="OnFinishButtonClick"
+ Margin="10,0,0,0"
+ IsDefault="True"
+ Name="FinishButton"
+ Content="_Finish"
+ VerticalAlignment="Bottom">
+ <Button.Style>
+ <Style TargetType="Button">
+ <Setter Property="IsEnabled"
+ Value="false" />
+ <Style.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding Path=FinishButtonEnabled}"
+ Value="true" />
+ <Condition Binding="{Binding ElementName=ClassName,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=ClassHeaderFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=ClassSourceFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ <Condition Binding="{Binding ElementName=UiFile,
+ Path=(Validation.HasError)}"
+ Value="false" />
+ </MultiDataTrigger.Conditions>
+ <Setter Property="IsEnabled"
+ Value="true" />
+ </MultiDataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+ <Button Click="OnCancelButtonClick"
+ MinWidth="75"
+ Margin="10,0,0,0"
+ Name="CancelButton"
+ IsEnabled="{Binding Path=CancelButtonEnabled}"
+ IsCancel="True">_Cancel</Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+</common:WizardPage>
diff --git a/QtVsTools.Wizards/ProjectWizard/Server/ServerPage.xaml.cs b/QtVsTools.Wizards/ProjectWizard/Server/ServerPage.xaml.cs
new file mode 100644
index 0000000..f0681b8
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Server/ServerPage.xaml.cs
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Windows;
+using System.Windows.Controls;
+
+namespace QtVsTools.Wizards.ProjectWizard
+{
+ using Wizards.Common;
+
+ public partial class ServerPage : WizardPage
+ {
+ public ServerPage()
+ {
+ InitializeComponent();
+ DataContext = this;
+ }
+
+ private void OnClassNameChanged(object sender, TextChangedEventArgs e)
+ {
+ UpdateFileNames();
+ }
+
+ private void OnLowerCaseFileNamesClick(object sender, RoutedEventArgs e)
+ {
+ UpdateFileNames();
+ }
+
+ private void UpdateFileNames()
+ {
+ Data.LowerCaseFileNames = LowerCaseFileNames.IsChecked.GetValueOrDefault();
+ var filename = Data.LowerCaseFileNames ? ClassName.Text.ToLower() : ClassName.Text;
+
+ ClassHeaderFile.Text = filename + @".h";
+ ClassSourceFile.Text = filename + @".cpp";
+ UiFile.Text = filename + @".ui";
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/ProjectWizard/Server/ServerWizard.cs b/QtVsTools.Wizards/ProjectWizard/Server/ServerWizard.cs
new file mode 100644
index 0000000..2f77f13
--- /dev/null
+++ b/QtVsTools.Wizards/ProjectWizard/Server/ServerWizard.cs
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows.Controls;
+using Microsoft.VisualStudio.Shell;
+using EnvDTE;
+
+namespace QtVsTools.Wizards.ProjectWizard
+{
+ using QtVsTools.Common;
+ using Core;
+ using Wizards.Common;
+
+ using static QtVsTools.Common.EnumExt;
+
+ public class ServerWizard : ProjectTemplateWizard
+ {
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ protected override Options TemplateType => Options.DynamicLibrary | Options.GUISystem;
+
+ enum NewClass
+ {
+ [String("classname")] ClassName,
+ [String("sourcefilename")] SourceFileName,
+ [String("headerfilename")] HeaderFileName,
+ [String("include")] Include,
+ }
+
+ enum NewActiveQtProject
+ {
+ [String("pro_name")] Name,
+ [String("uifilename")] UiFileName,
+ [String("ui_hdr")] UiHeaderName,
+ }
+
+ protected override WizardData WizardData => Lazy.Get(() =>
+ WizardData, () => new WizardData
+ {
+ DefaultModules = new List<string> { "QtCore", "QtGui", "QtWidgets", "QtAxServer" }
+ });
+
+ protected override WizardWindow WizardWindow => Lazy.Get(() =>
+ WizardWindow, () => new WizardWindow(title: "Qt ActiveQt Server Wizard")
+ {
+ new WizardIntroPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt ActiveQt Server Wizard",
+ Message = @"This wizard generates a Qt ActiveQt server project. It "
+ + @"creates a simple ActiveQt widget with the required files."
+ + System.Environment.NewLine + System.Environment.NewLine
+ + "To continue, click Next.",
+ PreviousButtonEnabled = false,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true
+ },
+ new ConfigPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt ActiveQt Server Wizard",
+ Message =
+ @"Setup the configurations you want to include in your project. "
+ + @"The recommended settings for this project are selected by default.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = true,
+ FinishButtonEnabled = false,
+ CancelButtonEnabled = true,
+ ValidateConfigs = ValidateConfigsForActiveQtServer
+ },
+ new ServerPage {
+ Data = WizardData,
+ Header = @"Welcome to the Qt ActiveQt Server Wizard",
+ Message = @"This wizard generates a Qt ActiveQt server project. It "
+ + @"creates a simple ActiveQt widget with the required files.",
+ PreviousButtonEnabled = true,
+ NextButtonEnabled = false,
+ FinishButtonEnabled = true,
+ CancelButtonEnabled = true
+ }
+ });
+
+ string ValidateConfigsForActiveQtServer(IEnumerable<IWizardConfiguration> configs)
+ {
+ foreach (var config in configs) {
+ if (config.Target.EqualTo(ProjectTargets.WindowsStore)) {
+ return string.Format(
+ "ActiveQt Server project not available for the '{0}' target.",
+ config.Target);
+ }
+ }
+ return string.Empty;
+ }
+
+ protected override void BeforeWizardRun()
+ {
+ // midl.exe does not support spaces in project name. Fails while generating the
+ // IDL file (library attribute), e.g. 'library Active QtServer1Lib' is illegal.
+ if (Parameter[NewProject.SafeName].Contains(" "))
+ throw new QtVSException("Project name shall not contain spaces.");
+
+ var className = Parameter[NewProject.SafeName];
+ className = Regex.Replace(className, @"[^a-zA-Z0-9_]", string.Empty);
+ className = Regex.Replace(className, @"^[\d-]*\s*", string.Empty);
+ var result = new Util.ClassNameValidationRule().Validate(className, null);
+ if (result != ValidationResult.ValidResult)
+ className = @"ActiveQtServer";
+
+ WizardData.ClassName = className;
+ WizardData.ClassHeaderFile = className + @".h";
+ WizardData.ClassSourceFile = className + @".cpp";
+ WizardData.UiFile = WizardData.ClassName + @".ui";
+ }
+
+ protected override void BeforeTemplateExpansion()
+ {
+ Parameter[NewClass.ClassName] = WizardData.ClassName;
+ Parameter[NewClass.HeaderFileName] = WizardData.ClassHeaderFile;
+ Parameter[NewClass.SourceFileName] = WizardData.ClassSourceFile;
+ Parameter[NewActiveQtProject.UiFileName] = WizardData.UiFile;
+
+ var include = new StringBuilder();
+ if (UsePrecompiledHeaders)
+ include.AppendLine(string.Format("#include \"{0}\"", PrecompiledHeader.Include));
+ include.AppendLine(string.Format("#include \"{0}\"", WizardData.ClassHeaderFile));
+ Parameter[NewClass.Include] = FormatParam(include);
+
+ Parameter[NewActiveQtProject.UiHeaderName] = string.Format("ui_{0}.h",
+ Path.GetFileNameWithoutExtension(WizardData.UiFile));
+
+ Parameter[NewActiveQtProject.Name] = WizardData.LowerCaseFileNames
+ ? Parameter[NewProject.SafeName].ToLower()
+ : Parameter[NewProject.SafeName];
+ }
+
+ protected override void OnProjectGenerated(Project project)
+ {
+ var qtProject = QtProject.Create(project);
+ qtProject.AddActiveQtBuildStep("1.0", Parameter[NewProject.SafeName] + ".def");
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/QtVsTools.Wizards.csproj b/QtVsTools.Wizards/QtVsTools.Wizards.csproj
index 0b333de..34aa9ff 100644
--- a/QtVsTools.Wizards/QtVsTools.Wizards.csproj
+++ b/QtVsTools.Wizards/QtVsTools.Wizards.csproj
@@ -71,42 +71,43 @@
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
<Reference Include="System" />
<Reference Include="System.Drawing" />
- <Reference Include="System.Xml.Linq" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
+ <Reference Include="System.Xaml" />
<Reference Include="WindowsBase" />
<Reference Include="Microsoft.VisualStudio.VCCodeModel" />
- <Reference Include="Microsoft.VisualStudio.ExtensionsExplorer.UI, Version=$(VisualStudioVersion).0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>$(DevEnvDir)PrivateAssemblies\Microsoft.VisualStudio.ExtensionsExplorer.UI.dll</HintPath>
- </Reference>
</ItemGroup>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
- // Version specific references
+ // General package references
// -->
<Import Project="$(SolutionDir)\references.props" />
<ItemGroup>
- <PackageReference Include="Microsoft.VisualStudio.SDK"
- Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
- <PackageReference Include="Microsoft.VSSDK.BuildTools"
- Version="$(Version_Microsoft_VSSDK_BuildTools)" />
- <PackageReference Include="Newtonsoft.Json"
- Version="$(Version_Newtonsoft_Json)" />
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
</ItemGroup>
- <ItemGroup Condition="'$(VisualStudioVersion)'=='17.0'">
- <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
- Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
- <PackageReference Include="$(Name_Microsoft_VisualStudio_TemplateWizardInterface)"
- Version="$(Version_Microsoft_VisualStudio_TemplateWizardInterface)" />
- </ItemGroup>
- <ItemGroup Condition="'$(VisualStudioVersion)'=='16.0'">
- <Reference Include="Microsoft.VisualStudio.TemplateWizardInterface" />
- </ItemGroup>
- <ItemGroup Condition="'$(VisualStudioVersion)'=='15.0'">
- <Reference Include="Microsoft.VisualStudio.VCProjectEngine" />
- <Reference Include="Microsoft.VisualStudio.TemplateWizardInterface" />
- </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_TemplateWizardInterface)" Version="$(Version_Microsoft_VisualStudio_TemplateWizardInterface)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_TemplateWizardInterface)" Version="$(Version_Microsoft_VisualStudio_TemplateWizardInterface)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ <Reference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)" />
+ <Reference Include="$(Name_Microsoft_VisualStudio_TemplateWizardInterface)" />
+ </ItemGroup>
+ </When>
+ </Choose>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
// Solution project references
@@ -123,58 +124,47 @@
// -->
<ItemGroup>
<Content Include="Resources\QtProjectWizard.ico" />
- <Resource Include="Resources\medium.png">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Resource>
<Resource Include="Resources\Qt-logo-small.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
- <Resource Include="Resources\small.png">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Resource>
</ItemGroup>
<ItemGroup>
- <Compile Include="Wizards\ClassWizard\AddClassPage.xaml.cs">
- <DependentUpon>AddClassPage.xaml</DependentUpon>
+ <Compile Include="ItemWizard\Translation\TranslationPage.xaml.cs">
+ <DependentUpon>TranslationPage.xaml</DependentUpon>
</Compile>
- <Compile Include="Wizards\ClassWizard\AddClassWizard.cs" />
- <Compile Include="Wizards\ClassWizard\Class.cs" />
- <Compile Include="Wizards\ClassWizard\ClassKind.cs" />
- <Compile Include="Wizards\ProjectWizard\ConfigPage.xaml.cs">
+ <Compile Include="ItemWizard\Translation\TranslationWizard.cs" />
+ <Compile Include="ProjectWizard\ConfigPage.xaml.cs">
<DependentUpon>ConfigPage.xaml</DependentUpon>
</Compile>
- <Compile Include="Wizards\ProjectWizard\ProjectTemplateWizard.cs" />
- <Compile Include="Wizards\ProjectWizard\Quick\QuickWizard.cs" />
- <Compile Include="Wizards\Util\ClassNameValidationRule.cs" />
- <Compile Include="Wizards\ProjectWizard\Console\ConsoleWizard.cs" />
- <Compile Include="Wizards\ClassWizard\Core\CoreClassPage.xaml.cs">
- <DependentUpon>CoreClassPage.xaml</DependentUpon>
+ <Compile Include="ProjectWizard\ProjectTemplateWizard.cs" />
+ <Compile Include="ProjectWizard\Quick\QuickWizard.cs" />
+ <Compile Include="Util\ClassNameValidationRule.cs" />
+ <Compile Include="ProjectWizard\Console\ConsoleWizard.cs" />
+ <Compile Include="ItemWizard\QtClass\QtClassPage.xaml.cs">
+ <DependentUpon>QtClassPage.xaml</DependentUpon>
</Compile>
- <Compile Include="Wizards\ClassWizard\Core\CoreClassWizard.cs" />
- <Compile Include="Wizards\ProjectWizard\Designer\DesignerPage.xaml.cs">
+ <Compile Include="ProjectWizard\Designer\DesignerPage.xaml.cs">
<DependentUpon>DesignerPage.xaml</DependentUpon>
</Compile>
- <Compile Include="Wizards\ProjectWizard\Designer\DesignerWizard.cs" />
- <Compile Include="Wizards\Util\FileExistsInFilterValidationRule.cs" />
- <Compile Include="Wizards\Util\FileNameValidationRule.cs" />
- <Compile Include="Wizards\ClassWizard\Gui\GuiClassPage.xaml.cs">
- <DependentUpon>GuiClassPage.xaml</DependentUpon>
- </Compile>
- <Compile Include="Wizards\ClassWizard\Gui\GuiClassWizard.cs" />
- <Compile Include="Wizards\ProjectWizard\Gui\GuiPage.xaml.cs">
+ <Compile Include="ProjectWizard\Designer\DesignerWizard.cs" />
+ <Compile Include="Util\FileExistsInFilterValidationRule.cs" />
+ <Compile Include="Util\FileNameValidationRule.cs" />
+ <Compile Include="Common\GuiPage.xaml.cs">
<DependentUpon>GuiPage.xaml</DependentUpon>
</Compile>
- <Compile Include="Wizards\ProjectWizard\Gui\GuiWizard.cs" />
- <Compile Include="Wizards\ProjectWizard\Empty\EmptyWizard.cs" />
- <Compile Include="Wizards\ClassWizard\IClassWizard.cs" />
- <Compile Include="Wizards\WizardIntroPage.xaml.cs">
+ <Compile Include="ProjectWizard\Gui\GuiWizard.cs" />
+ <Compile Include="ProjectWizard\Empty\EmptyWizard.cs" />
+ <Compile Include="Common\WizardIntroPage.xaml.cs">
<DependentUpon>WizardIntroPage.xaml</DependentUpon>
</Compile>
- <Compile Include="Wizards\ProjectWizard\Library\LibraryClassPage.xaml.cs">
+ <Compile Include="ProjectWizard\Library\LibraryClassPage.xaml.cs">
<DependentUpon>LibraryClassPage.xaml</DependentUpon>
</Compile>
- <Compile Include="Wizards\ProjectWizard\Library\LibraryWizard.cs" />
- <Compile Include="Wizards\Util\NativeMethods.cs" />
+ <Compile Include="ProjectWizard\Library\LibraryWizard.cs" />
+ <Compile Include="Util\NativeMethods.cs" />
+ <Compile Include="ItemWizard\QtClass\QtClassWizard.cs" />
+ <Compile Include="ItemWizard\WidgetsClass\WidgetsClassWizard.cs" />
+ <Compile Include="Util\VCRulePropertyStorageHelper.cs" />
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
<OutputFile>Properties\AssemblyInfo.tt.cs</OutputFile>
@@ -186,65 +176,58 @@
<DesignTime>True</DesignTime>
<DependentUpon>AssemblyInfo.cs</DependentUpon>
</Compile>
- <Compile Include="Wizards\ProjectWizard\Server\ServerPage.xaml.cs">
+ <Compile Include="ProjectWizard\Server\ServerPage.xaml.cs">
<DependentUpon>ServerPage.xaml</DependentUpon>
</Compile>
- <Compile Include="Wizards\ProjectWizard\Server\ServerWizard.cs" />
- <Compile Include="Wizards\Util\SortComboBoxItem.cs" />
- <Compile Include="Wizards\ClassWizard\UiClassInclusion.cs" />
- <Compile Include="Wizards\Util\UnsafeNativeMethods.cs" />
- <Compile Include="Wizards\Util\VCLanguageManagerValidationRule.cs" />
- <Compile Include="Wizards\WizardData.cs" />
- <Compile Include="Wizards\WizardPage.cs" />
- <Compile Include="Wizards\WizardResult.cs" />
- <Compile Include="Wizards\WizardWindow.xaml.cs">
+ <Compile Include="ProjectWizard\Server\ServerWizard.cs" />
+ <Compile Include="Util\UiClassInclusionConverter.cs" />
+ <Compile Include="Common\UiClassInclusion.cs" />
+ <Compile Include="Util\UnsafeNativeMethods.cs" />
+ <Compile Include="Util\VCLanguageManagerValidationRule.cs" />
+ <Compile Include="Common\WizardData.cs" />
+ <Compile Include="Common\WizardPage.cs" />
+ <Compile Include="Common\WizardResult.cs" />
+ <Compile Include="Common\WizardWindow.xaml.cs">
<DependentUpon>WizardWindow.xaml</DependentUpon>
</Compile>
- <Page Include="Wizards\ClassWizard\AddClassPage.xaml">
+ <Page Include="ItemWizard\QtClass\QtClassPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
- <Page Include="Wizards\ClassWizard\Core\CoreClassPage.xaml">
+ <Page Include="ItemWizard\Translation\TranslationPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
- <Page Include="Wizards\ProjectWizard\Designer\DesignerPage.xaml">
+ <Page Include="ProjectWizard\Designer\DesignerPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
- <Page Include="Wizards\ClassWizard\Gui\GuiClassPage.xaml">
+ <Page Include="Common\GuiPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
- <Page Include="Wizards\ProjectWizard\Gui\GuiPage.xaml">
- <SubType>Designer</SubType>
- <Generator>MSBuild:Compile</Generator>
- </Page>
- <Page Include="Wizards\ProjectWizard\ConfigPage.xaml">
+ <Page Include="ProjectWizard\ConfigPage.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
- <Page Include="Wizards\WizardIntroPage.xaml">
+ <Page Include="Common\WizardIntroPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
- <Page Include="Wizards\ProjectWizard\Library\LibraryClassPage.xaml">
+ <Page Include="ProjectWizard\Library\LibraryClassPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
- <Page Include="Resources\ExpanderStyle.xaml">
+ <Page Include="ProjectWizard\Server\ServerPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
- <Page Include="Wizards\ProjectWizard\Server\ServerPage.xaml">
- <SubType>Designer</SubType>
- <Generator>MSBuild:Compile</Generator>
- </Page>
- <Page Include="Wizards\WizardWindow.xaml">
+ <Page Include="Common\WizardWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
+ <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
</Project>
\ No newline at end of file
diff --git a/QtVsTools.Wizards/Util/ClassNameValidationRule.cs b/QtVsTools.Wizards/Util/ClassNameValidationRule.cs
new file mode 100644
index 0000000..a9304a8
--- /dev/null
+++ b/QtVsTools.Wizards/Util/ClassNameValidationRule.cs
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Globalization;
+using System.Text.RegularExpressions;
+using System.Windows.Controls;
+
+namespace QtVsTools.Wizards.Util
+{
+ internal class ClassNameValidationRule : VCLanguageManagerValidationRule
+ {
+ public ClassNameValidationRule()
+ {
+ SupportNamespaces = false;
+ AllowEmptyIdentifier = false;
+ }
+
+ public override ValidationResult Validate(object value, CultureInfo cultureInfo)
+ {
+ if (value is string) {
+ var identifier = value as string;
+ if (AllowEmptyIdentifier && string.IsNullOrEmpty(identifier))
+ return ValidationResult.ValidResult;
+
+ if (SupportNamespaces) {
+ var index = identifier.LastIndexOf(@"::", System.StringComparison.Ordinal);
+ if (index >= 0)
+ identifier = identifier.Substring(index + 2);
+ }
+
+ if (Regex.IsMatch(identifier, pattern) && !Vclm.IsReservedName(identifier))
+ return ValidationResult.ValidResult;
+ }
+ return new ValidationResult(false, @"Invalid identifier.");
+ }
+
+ public bool SupportNamespaces { get; set; }
+ public bool AllowEmptyIdentifier { get; set; }
+
+ const string pattern = @"^[a-zA-Z_][a-zA-Z0-9_]*$";
+ }
+}
diff --git a/QtVsTools.Wizards/Util/FileExistsInFilterValidationRule.cs b/QtVsTools.Wizards/Util/FileExistsInFilterValidationRule.cs
new file mode 100644
index 0000000..036c824
--- /dev/null
+++ b/QtVsTools.Wizards/Util/FileExistsInFilterValidationRule.cs
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Globalization;
+using System.Linq;
+using System.Windows.Controls;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+using EnvDTE;
+
+namespace QtVsTools.Wizards.Util
+{
+ using Core;
+ using VisualStudio;
+
+ internal class FileExistsinFilterValidationRule : VCLanguageManagerValidationRule
+ {
+ public override ValidationResult Validate(object value, CultureInfo cultureInfo)
+ {
+ if (value is string) {
+ var dte = VsServiceProvider.GetService<SDTE, DTE>();
+ if (dte == null)
+ return ValidationResult.ValidResult;
+
+ var project = HelperFunctions.GetSelectedProject(dte);
+ if (project == null)
+ return ValidationResult.ValidResult;
+
+ var files = HelperFunctions.GetProjectFiles(project, Filter);
+ if (files.Count == 0)
+ return ValidationResult.ValidResult;
+
+ var fileName = (value as string).ToUpperInvariant();
+ if (files.FirstOrDefault(x => x.ToUpperInvariant() == fileName) != null)
+ return new ValidationResult(false, @"File already exists.");
+ return ValidationResult.ValidResult;
+ }
+ return new ValidationResult(false, @"Invalid file name.");
+ }
+
+ public FilesToList Filter { get; set; }
+ }
+}
diff --git a/QtVsTools.Wizards/Util/FileNameValidationRule.cs b/QtVsTools.Wizards/Util/FileNameValidationRule.cs
new file mode 100644
index 0000000..e3ea756
--- /dev/null
+++ b/QtVsTools.Wizards/Util/FileNameValidationRule.cs
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Windows.Controls;
+
+namespace QtVsTools.Wizards.Util
+{
+ internal class FileNameValidationRule : VCLanguageManagerValidationRule
+ {
+ public override ValidationResult Validate(object value, CultureInfo cultureInfo)
+ {
+ if (value is string) {
+ var filename = value as string;
+ if (FileExt == @".ui" || FileExt == @".qrc") {
+ filename = filename.ToLower().Replace(@".h", @".x");
+ filename = filename.Replace(FileExt, @".h");
+ }
+
+ if (Vclm.ValidateFileName(filename)
+ && !Path.GetInvalidFileNameChars().Any(filename.Contains)) {
+ return ValidationResult.ValidResult;
+ }
+ }
+ return new ValidationResult(false, @"Invalid file name.");
+ }
+ }
+}
diff --git a/QtVsTools.Wizards/Util/NativeMethods.cs b/QtVsTools.Wizards/Util/NativeMethods.cs
new file mode 100644
index 0000000..00edfea
--- /dev/null
+++ b/QtVsTools.Wizards/Util/NativeMethods.cs
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+
+namespace QtVsTools.Wizards.Util
+{
+ internal static class NativeMethods
+ {
+ [ResourceExposure(ResourceScope.None)]
+ [DllImport("user32.dll", CharSet = CharSet.Auto)]
+ internal static extern int GetWindowLong(IntPtr hwnd, int index);
+ }
+}
diff --git a/QtVsTools.Wizards/Util/UiClassInclusionConverter.cs b/QtVsTools.Wizards/Util/UiClassInclusionConverter.cs
new file mode 100644
index 0000000..64ee165
--- /dev/null
+++ b/QtVsTools.Wizards/Util/UiClassInclusionConverter.cs
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace QtVsTools.Wizards.Util
+{
+ public class UiClassInclusionConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ => value?.Equals(parameter);
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ => value?.Equals(true) == true ? parameter : Binding.DoNothing;
+ }
+}
diff --git a/QtVsTools.Wizards/Util/UnsafeNativeMethods.cs b/QtVsTools.Wizards/Util/UnsafeNativeMethods.cs
new file mode 100644
index 0000000..8fc5f27
--- /dev/null
+++ b/QtVsTools.Wizards/Util/UnsafeNativeMethods.cs
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+
+namespace QtVsTools.Wizards.Util
+{
+ internal static class UnsafeNativeMethods
+ {
+ [ResourceExposure(ResourceScope.None)]
+ [DllImport("user32.dll", CharSet = CharSet.Auto)]
+ internal static extern int SetWindowLong(IntPtr hwnd, int index, int value);
+ }
+}
diff --git a/QtVsTools.Wizards/Util/VCLanguageManagerValidationRule.cs b/QtVsTools.Wizards/Util/VCLanguageManagerValidationRule.cs
new file mode 100644
index 0000000..996e91c
--- /dev/null
+++ b/QtVsTools.Wizards/Util/VCLanguageManagerValidationRule.cs
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Windows.Controls;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCCodeModel;
+using EnvDTE;
+
+namespace QtVsTools.Wizards.Util
+{
+ using VisualStudio;
+
+ internal abstract class VCLanguageManagerValidationRule : ValidationRule
+ {
+ protected VCLanguageManagerValidationRule()
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ ValidatesOnTargetUpdated = true;
+
+ var dte = VsServiceProvider.GetService<DTE>();
+ Vclm = dte.GetObject("VCLanguageManager") as VCLanguageManager;
+ }
+
+ public string FileExt { get; set; }
+ public VCLanguageManager Vclm { get; }
+ }
+}
diff --git a/QtVsTools.Wizards/Util/VCRulePropertyStorageHelper.cs b/QtVsTools.Wizards/Util/VCRulePropertyStorageHelper.cs
new file mode 100644
index 0000000..e183a82
--- /dev/null
+++ b/QtVsTools.Wizards/Util/VCRulePropertyStorageHelper.cs
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
+using EnvDTE;
+
+namespace QtVsTools.Wizards.Util
+{
+ using Core;
+
+ static class VCRulePropertyStorageHelper
+ {
+ public static void SetQtModules(DTE dte, List<string> modules)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+
+ var newModules = modules.ToHashSet();
+ if (modules.Count == 0)
+ return;
+
+ var project = HelperFunctions.GetSelectedQtProject(dte);
+ if (project == null)
+ return;
+
+ var vcproject = project.Object as VCProject;
+ if (vcproject == null)
+ return;
+
+ // TODO: There is already code providing such functionality, though it seems overly
+ // complicated to use compared to this simple for loop (see VCPropertyStorageProvider).
+ foreach (VCConfiguration config in vcproject.Configurations as IVCCollection) {
+ var props = config.Rules.Item("QtRule10_Settings") as IVCRulePropertyStorage;
+ var updatedModules = props.GetUnevaluatedPropertyValue("QtModules")
+ .Split(new char[] { ';' }, System.StringSplitOptions.RemoveEmptyEntries)
+ .ToHashSet()
+ .Union(newModules);
+ props.SetPropertyValue("QtModules", string.Join(";", updatedModules));
+ }
+ }
+ }
+}
diff --git a/README.md b/README.md
index fa5df16..cc2dbdd 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@
The following is required in order to build the Qt Visual Studio solution:
-- Visual Studio 2017, 2019 or 2022, with the following workloads:
+- Visual Studio 2017, 2019 or 2022, with the following workloads (A .vsconfig file per VS version can be found in the source tree):
- Desktop development with C++
- .NET desktop development
- [Visual Studio extension development](https://docs.microsoft.com/en-us/visualstudio/extensibility/installing-the-visual-studio-sdk)
diff --git a/Templates/console/QtTemplate.Project.Console.csproj b/Templates/console/QtTemplate.Project.Console.csproj
index d4bbdfe..c4d6e31 100644
--- a/Templates/console/QtTemplate.Project.Console.csproj
+++ b/Templates/console/QtTemplate.Project.Console.csproj
@@ -76,16 +76,45 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
<ItemGroup>
- <Reference Include="Microsoft.VisualStudio.CoreUtility">
- <Private>False</Private>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
</ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -126,6 +155,6 @@
</VSTemplate>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(SolutionDir)\transform.targets" />
-</Project>
+ <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project>
\ No newline at end of file
diff --git a/Templates/console/console.vcxproj.filters b/Templates/console/console.vcxproj.filters
index df883a8..64ad4dd 100644
--- a/Templates/console/console.vcxproj.filters
+++ b/Templates/console/console.vcxproj.filters
@@ -3,7 +3,7 @@
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
- <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ <Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
@@ -13,6 +13,10 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
+ <Filter Include="Form Files">
+ <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+ <Extensions>ui</Extensions>
+ </Filter>
<Filter Include="Translation Files">
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
<Extensions>ts</Extensions>
diff --git a/Templates/designer/QtTemplate.Project.Designer.csproj b/Templates/designer/QtTemplate.Project.Designer.csproj
index 0e19350..6e2e3b1 100644
--- a/Templates/designer/QtTemplate.Project.Designer.csproj
+++ b/Templates/designer/QtTemplate.Project.Designer.csproj
@@ -78,6 +78,45 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -122,17 +161,7 @@
<Content Include="widget.cpp" />
<Content Include="widget.h" />
</ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
- </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
</Project>
diff --git a/Templates/designer/designer.vcxproj.filters b/Templates/designer/designer.vcxproj.filters
index 7b7bab4..c2f3f8d 100644
--- a/Templates/designer/designer.vcxproj.filters
+++ b/Templates/designer/designer.vcxproj.filters
@@ -3,7 +3,7 @@
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
- <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ <Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
@@ -13,6 +13,10 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
+ <Filter Include="Form Files">
+ <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+ <Extensions>ui</Extensions>
+ </Filter>
<Filter Include="Translation Files">
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
<Extensions>ts</Extensions>
diff --git a/Templates/designer/plugin.h b/Templates/designer/plugin.h
index 1f88121..dfdacaa 100644
--- a/Templates/designer/plugin.h
+++ b/Templates/designer/plugin.h
@@ -9,7 +9,7 @@
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
- $plugin_class$(QObject *parent = Q_NULLPTR);
+ $plugin_class$(QObject *parent = nullptr);
bool isContainer() const;
bool isInitialized() const;
diff --git a/Templates/designer/widget.h b/Templates/designer/widget.h
index abf56e1..8c3d96b 100644
--- a/Templates/designer/widget.h
+++ b/Templates/designer/widget.h
@@ -7,5 +7,5 @@
Q_OBJECT
public:
- $classname$(QWidget *parent = Q_NULLPTR);
+ $classname$(QWidget *parent = nullptr);
};
diff --git a/Templates/dialogbuttonbottom/QtTemplate.Item.DialogButtonBottom.csproj b/Templates/dialogbuttonbottom/QtTemplate.Item.DialogButtonBottom.csproj
index 5c6cf84..decad55 100644
--- a/Templates/dialogbuttonbottom/QtTemplate.Item.DialogButtonBottom.csproj
+++ b/Templates/dialogbuttonbottom/QtTemplate.Item.DialogButtonBottom.csproj
@@ -78,6 +78,45 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -99,17 +138,7 @@
<SubType>Designer</SubType>
</VSTemplate>
</ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
- </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
</Project>
diff --git a/Templates/dialogbuttonright/QtTemplate.Item.DialogButtonRight.csproj b/Templates/dialogbuttonright/QtTemplate.Item.DialogButtonRight.csproj
index ad22581..aec8882 100644
--- a/Templates/dialogbuttonright/QtTemplate.Item.DialogButtonRight.csproj
+++ b/Templates/dialogbuttonright/QtTemplate.Item.DialogButtonRight.csproj
@@ -78,6 +78,45 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -98,17 +137,7 @@
<OutputSubPath>Qt</OutputSubPath>
</VSTemplate>
</ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
- </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
</Project>
diff --git a/Templates/empty/QtTemplate.Project.Empty.csproj b/Templates/empty/QtTemplate.Project.Empty.csproj
index 536168f..1e7bd4e 100644
--- a/Templates/empty/QtTemplate.Project.Empty.csproj
+++ b/Templates/empty/QtTemplate.Project.Empty.csproj
@@ -78,6 +78,45 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -113,17 +152,7 @@
<DependentUpon>empty.vstemplate_TT</DependentUpon>
</VSTemplate>
</ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
- </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
</Project>
diff --git a/Templates/gui/QtTemplate.Project.Gui.csproj b/Templates/gui/QtTemplate.Project.Gui.csproj
index 1b373ae..09a9d4f 100644
--- a/Templates/gui/QtTemplate.Project.Gui.csproj
+++ b/Templates/gui/QtTemplate.Project.Gui.csproj
@@ -76,16 +76,45 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
<ItemGroup>
- <Reference Include="Microsoft.VisualStudio.CoreUtility">
- <Private>False</Private>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
</ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -108,6 +137,7 @@
<SubType>Designer</SubType>
</None>
<None Include="main.cpp" />
+ <None Include="widget.qrc" />
<None Include="stdafx.cpp" />
<None Include="stdafx.h" />
<None Include="widget.cpp" />
@@ -130,13 +160,6 @@
</VSTemplate>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(SolutionDir)\transform.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project>
+ <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project>
\ No newline at end of file
diff --git a/Templates/gui/gui.vcxproj.filters b/Templates/gui/gui.vcxproj.filters
index 90f5b7a..b6e7201 100644
--- a/Templates/gui/gui.vcxproj.filters
+++ b/Templates/gui/gui.vcxproj.filters
@@ -3,7 +3,7 @@
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
- <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ <Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
diff --git a/Templates/gui/gui.vstemplate_TT b/Templates/gui/gui.vstemplate_TT
index 7a09db3..33fdd42 100644
--- a/Templates/gui/gui.vstemplate_TT
+++ b/Templates/gui/gui.vstemplate_TT
@@ -71,6 +71,8 @@
<ProjectItem ReplaceParameters="true"
TargetFileName="$safeprojectname$.vcxproj.filters">gui.vcxproj.filters</ProjectItem>
<ProjectItem ReplaceParameters="false">gui.ico</ProjectItem>
+ <ProjectItem ReplaceParameters="true"
+ TargetFileName="$qrcfilename$">widget.qrc</ProjectItem>
</Project>
</TemplateContent>
<WizardExtension>
diff --git a/Templates/gui/main.cpp b/Templates/gui/main.cpp
index 6478e3f..d3f5898 100644
--- a/Templates/gui/main.cpp
+++ b/Templates/gui/main.cpp
@@ -4,7 +4,7 @@
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
- $classname$ w;
+ $namespace$$classname$ w;
w.show();
return a.exec();
}
diff --git a/Templates/gui/widget.cpp b/Templates/gui/widget.cpp
index 28c285b..7718d6f 100644
--- a/Templates/gui/widget.cpp
+++ b/Templates/gui/widget.cpp
@@ -1,7 +1,11 @@
$include$
-$classname$::$classname$(QWidget *parent)
- : $baseclass$(parent)
+$namespacebegin$$classname$::$classname$(QWidget *parent)
+ : $baseclass$(parent)$new$
{
- ui.setupUi(this);
+ $member$$operator$setupUi(this);
}
+
+$classname$::~$classname$()
+{$delete$}
+$namespaceend$
\ No newline at end of file
diff --git a/Templates/gui/widget.h b/Templates/gui/widget.h
index 578cb5e..68646a0 100644
--- a/Templates/gui/widget.h
+++ b/Templates/gui/widget.h
@@ -2,14 +2,16 @@
#include <QtWidgets/$baseclass$>
#include "$ui_hdr$"
-
-class $classname$ : public $baseclass$
+$forward_declare_class$
+$namespacebegin$class $classname$ : public $baseclass$$multiple_inheritance$
{
Q_OBJECT
public:
- $classname$(QWidget *parent = Q_NULLPTR);
+ $classname$(QWidget *parent = nullptr);
+ ~$classname$();
private:
- Ui::$classname$Class ui;
+ $ui_classname$ $asterisk$$member$$semicolon$
};
+$namespaceend$
\ No newline at end of file
diff --git a/Templates/gui/widget.qrc b/Templates/gui/widget.qrc
new file mode 100644
index 0000000..f0fb159
--- /dev/null
+++ b/Templates/gui/widget.qrc
@@ -0,0 +1,4 @@
+<RCC>
+ <qresource prefix="$classname$">
+ </qresource>
+</RCC>
diff --git a/Templates/lib/QtTemplate.Project.Lib.csproj b/Templates/lib/QtTemplate.Project.Lib.csproj
index 1b7c02e..4065393 100644
--- a/Templates/lib/QtTemplate.Project.Lib.csproj
+++ b/Templates/lib/QtTemplate.Project.Lib.csproj
@@ -78,6 +78,45 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -120,17 +159,7 @@
<Content Include="stdafx.cpp" />
<Content Include="stdafx.h" />
</ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
- </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
</Project>
diff --git a/Templates/lib/lib.vcxproj.filters b/Templates/lib/lib.vcxproj.filters
index 1630278..af524ae 100644
--- a/Templates/lib/lib.vcxproj.filters
+++ b/Templates/lib/lib.vcxproj.filters
@@ -3,7 +3,7 @@
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
- <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ <Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
@@ -13,6 +13,10 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
+ <Filter Include="Form Files">
+ <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+ <Extensions>ui</Extensions>
+ </Filter>
<Filter Include="Translation Files">
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
<Extensions>ts</Extensions>
diff --git a/Templates/mainwindow/QtTemplate.Item.MainWindow.csproj b/Templates/mainwindow/QtTemplate.Item.MainWindow.csproj
index 9683ca1..c2b6ea5 100644
--- a/Templates/mainwindow/QtTemplate.Item.MainWindow.csproj
+++ b/Templates/mainwindow/QtTemplate.Item.MainWindow.csproj
@@ -78,6 +78,45 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -99,17 +138,7 @@
<SubType>Designer</SubType>
</VSTemplate>
</ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
- </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
</Project>
diff --git a/Templates/qml/QtTemplate.Item.QMLFile.csproj b/Templates/qml/QtTemplate.Item.QMLFile.csproj
index 1d26bac..f65cecb 100644
--- a/Templates/qml/QtTemplate.Item.QMLFile.csproj
+++ b/Templates/qml/QtTemplate.Item.QMLFile.csproj
@@ -78,6 +78,45 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -103,17 +142,7 @@
<ItemGroup>
<Content Include="qml.ico" />
</ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
- </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
</Project>
\ No newline at end of file
diff --git a/Templates/qmldir/QtTemplate.Item.QMLDir.csproj b/Templates/qmldir/QtTemplate.Item.QMLDir.csproj
index a3cdb07..d6f9d48 100644
--- a/Templates/qmldir/QtTemplate.Item.QMLDir.csproj
+++ b/Templates/qmldir/QtTemplate.Item.QMLDir.csproj
@@ -78,6 +78,45 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -103,17 +142,7 @@
<ItemGroup>
<Content Include="qml.ico" />
</ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
- </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
</Project>
\ No newline at end of file
diff --git a/Templates/qtclass/Properties/AssemblyInfo.cs b/Templates/qtclass/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..127025e
--- /dev/null
+++ b/Templates/qtclass/Properties/AssemblyInfo.cs
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************
+<#@output extension="tt.cs" #>
+<#@include file="$(SolutionDir)\version.tt" #>
+** <#=WARNING_GENERATED_FILE#>
+****************************************************************************/
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("QtClass")]
+[assembly: AssemblyDescription("The Qt Visual Studio Tools allow developers to use the standard development environment without having to worry about any Qt-related build steps or tools.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Qt Company Ltd.")]
+[assembly: AssemblyProduct("Qt Visual Studio Tools")]
+[assembly: AssemblyCopyright("Copyright (C) 2016-22 The Qt Company Ltd.")]
+[assembly: AssemblyTrademark("The Qt Company Ltd. Qt and their respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f375c22e-8c6d-4800-ad3a-ff301113dac6")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("<#=QT_VS_TOOLS_VERSION_ASSEMBLY#>")]
+[assembly: AssemblyFileVersion("<#=QT_VS_TOOLS_VERSION_ASSEMBLY_FILE#>")]
diff --git a/Templates/qtclass/QtTemplate.Item.QtClass.csproj b/Templates/qtclass/QtTemplate.Item.QtClass.csproj
new file mode 100644
index 0000000..24cf073
--- /dev/null
+++ b/Templates/qtclass/QtTemplate.Item.QtClass.csproj
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+-->
+<Project ToolsVersion="$(VisualStudioVersion)" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <MinimumVisualStudioVersion>$(VisualStudioVersion)</MinimumVisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <PropertyGroup>
+ <ApplicationIcon>qtclass.ico</ApplicationIcon>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ProjectGuid>{4981AAE8-9AC7-4758-87EA-FB2397D6C404}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>QtClass</RootNamespace>
+ <AssemblyName>QtClass</AssemblyName>
+ <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <GeneratePkgDefFile>false</GeneratePkgDefFile>
+ <IncludeAssemblyInVSIXContainer>false</IncludeAssemblyInVSIXContainer>
+ <IncludeDebugSymbolsInVSIXContainer>false</IncludeDebugSymbolsInVSIXContainer>
+ <IncludeDebugSymbolsInLocalVSIXDeployment>false</IncludeDebugSymbolsInLocalVSIXDeployment>
+ <CreateVsixContainer>false</CreateVsixContainer>
+ <DeployExtension>false</DeployExtension>
+ <DeployVSTemplates>false</DeployVSTemplates>
+ <CopyVsixManifestToOutput>false</CopyVsixManifestToOutput>
+ <CopyBuildOutputToOutputDirectory>false</CopyBuildOutputToOutputDirectory>
+ <CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
+ <ItemGroup>
+ <T4Template Include="Properties\AssemblyInfo.cs">
+ <Generator>TextTemplatingFileGenerator</Generator>
+ <OutputFile>Properties\AssemblyInfo.tt.cs</OutputFile>
+ <DependsOn>$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
+ <LastGenOutput>AssemblyInfo.tt.cs</LastGenOutput>
+ </T4Template>
+ <Compile Include="Properties\AssemblyInfo.tt.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>AssemblyInfo.cs</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="header.h" />
+ <None Include="source.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <T4Template Include="qtclass.vstemplate_TT">
+ <Generator>TextTemplatingFileGenerator</Generator>
+ <OutputFile>qtclass.vstemplate</OutputFile>
+ <DependsOn>$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
+ <LastGenOutput>qtclass.vstemplate</LastGenOutput>
+ <SubType>Designer</SubType>
+ </T4Template>
+ <VSTemplate Include="qtclass.vstemplate">
+ <SubType>Designer</SubType>
+ <OutputSubPath>Qt</OutputSubPath>
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>qtclass.vstemplate_TT</DependentUpon>
+ </VSTemplate>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="qtclass.ico" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(SolutionDir)\transform.targets" />
+ <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project>
\ No newline at end of file
diff --git a/Templates/qtclass/header.h b/Templates/qtclass/header.h
new file mode 100644
index 0000000..8495cfc
--- /dev/null
+++ b/Templates/qtclass/header.h
@@ -0,0 +1,9 @@
+#pragma once
+
+$baseclassinclude$$namespacebegin$class $classname$ $baseclassdecl$
+{$qobject$
+public:
+ $classname$($signature$);
+ ~$classname$();
+};
+$namespaceend$
\ No newline at end of file
diff --git a/Templates/qtclass/qtclass.ico b/Templates/qtclass/qtclass.ico
new file mode 100644
index 0000000..1c4fb80
--- /dev/null
+++ b/Templates/qtclass/qtclass.ico
Binary files differ
diff --git a/Templates/qtclass/qtclass.vstemplate_TT b/Templates/qtclass/qtclass.vstemplate_TT
new file mode 100644
index 0000000..b0ab4d8
--- /dev/null
+++ b/Templates/qtclass/qtclass.vstemplate_TT
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+<#@output extension="vstemplate" #>
+<#@include file="$(SolutionDir)\version.tt" #>
+ ** <#=WARNING_GENERATED_FILE#>
+ *****************************************************************************
+-->
+
+<VSTemplate Version="3.0.0"
+ xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"
+ xmlns:sdk="http://schemas.microsoft.com/developer/vstemplate-sdkextension/2010"
+ Type="Item" >
+ <TemplateData>
+ <Name>Qt Class</Name>
+ <Description>Adds a Qt class to the project.</Description>
+ <ProjectType>VC</ProjectType>
+ <CreateNewFolder>true</CreateNewFolder>
+ <DefaultName>QtClass</DefaultName>
+ <ProvideDefaultName>true</ProvideDefaultName>
+ <LocationField>Enabled</LocationField>
+ <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
+ <Icon>qtclass.ico</Icon>
+ <LanguageTag>Cpp</LanguageTag>
+ <PlatformTag>Windows</PlatformTag>
+ <PlatformTag>Linux</PlatformTag>
+ <ProjectTypeTag>Qt</ProjectTypeTag>
+ <ProjectTypeTag>IoT</ProjectTypeTag>
+ <ProjectTypeTag>Desktop</ProjectTypeTag>
+ <ProjectTypeTag>Console</ProjectTypeTag>
+ </TemplateData>
+ <TemplateContent>
+ <ProjectItem OpenInEditor="true"
+ ReplaceParameters="true"
+ TargetFileName="$sourcefilename$">source.cpp</ProjectItem>
+ <ProjectItem ReplaceParameters="true"
+ TargetFileName="$headerfilename$">header.h</ProjectItem>
+ </TemplateContent>
+ <WizardExtension>
+ <!-- BEGIN Generated Text <#=XML_COMMENT_END#>
+ <Assembly>QtVsTools.Wizards, Version=<#=QT_VS_TOOLS_VERSION_ASSEMBLY#>, Culture=neutral, PublicKeyToken=null</Assembly>
+ <#=XML_COMMENT_BEGIN#> END Generated Text -->
+ <FullClassName>QtVsTools.Wizards.ItemWizard.QtClassWizard</FullClassName>
+ </WizardExtension>
+</VSTemplate>
diff --git a/Templates/qtclass/source.cpp b/Templates/qtclass/source.cpp
new file mode 100644
index 0000000..7bdcd06
--- /dev/null
+++ b/Templates/qtclass/source.cpp
@@ -0,0 +1,8 @@
+$include$
+
+$namespacebegin$$classname$::$classname$($signature$)$baseclasswithparent$
+{}
+
+$classname$::~$classname$()
+{}
+$namespaceend$
\ No newline at end of file
diff --git a/Templates/quick/QtTemplate.Project.Quick.csproj b/Templates/quick/QtTemplate.Project.Quick.csproj
index 3137fb0..1fa7f47 100644
--- a/Templates/quick/QtTemplate.Project.Quick.csproj
+++ b/Templates/quick/QtTemplate.Project.Quick.csproj
@@ -78,6 +78,45 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -114,9 +153,6 @@
<DesignTime>True</DesignTime>
<DependentUpon>quick.vstemplate_TT</DependentUpon>
</VSTemplate>
- </ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
</ItemGroup>
<ItemGroup>
<Content Include="main.cpp" />
diff --git a/Templates/quick/quick.vcxproj.filters b/Templates/quick/quick.vcxproj.filters
index 1ed1ade..a26deb6 100644
--- a/Templates/quick/quick.vcxproj.filters
+++ b/Templates/quick/quick.vcxproj.filters
@@ -13,6 +13,10 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
+ <Filter Include="Form Files">
+ <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+ <Extensions>ui</Extensions>
+ </Filter>
<Filter Include="Translation Files">
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
<Extensions>ts</Extensions>
diff --git a/Templates/resource/QtTemplate.Item.Resource.csproj b/Templates/resource/QtTemplate.Item.Resource.csproj
index 6881f8a..7e22911 100644
--- a/Templates/resource/QtTemplate.Item.Resource.csproj
+++ b/Templates/resource/QtTemplate.Item.Resource.csproj
@@ -78,6 +78,45 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -103,17 +142,7 @@
<ItemGroup>
<Content Include="resource.ico" />
</ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
- </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
</Project>
diff --git a/Templates/server/QtTemplate.Project.Server.csproj b/Templates/server/QtTemplate.Project.Server.csproj
index b30bb48..4c24a53 100644
--- a/Templates/server/QtTemplate.Project.Server.csproj
+++ b/Templates/server/QtTemplate.Project.Server.csproj
@@ -78,6 +78,45 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -122,17 +161,7 @@
<Content Include="stdafx.h" />
<Content Include="widget.ui" />
</ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
- </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
</Project>
diff --git a/Templates/server/header.h b/Templates/server/header.h
index b3a1e6e..f404141 100644
--- a/Templates/server/header.h
+++ b/Templates/server/header.h
@@ -10,7 +10,7 @@
Q_OBJECT
public:
- $classname$(QWidget *parent = Q_NULLPTR);
+ $classname$(QWidget *parent = nullptr);
private:
Ui::$classname$Class ui;
diff --git a/Templates/server/server.vcxproj.filters b/Templates/server/server.vcxproj.filters
index 1dca9ac..eb9be8d 100644
--- a/Templates/server/server.vcxproj.filters
+++ b/Templates/server/server.vcxproj.filters
@@ -3,7 +3,7 @@
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
- <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ <Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
diff --git a/Templates/translation/Properties/AssemblyInfo.cs b/Templates/translation/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..7fcd1b7
--- /dev/null
+++ b/Templates/translation/Properties/AssemblyInfo.cs
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************
+<#@output extension="tt.cs" #>
+<#@include file="$(SolutionDir)\version.tt" #>
+** <#=WARNING_GENERATED_FILE#>
+****************************************************************************/
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Translation")]
+[assembly: AssemblyDescription("The Qt Visual Studio Tools allow developers to use the standard development environment without having to worry about any Qt-related build steps or tools.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Qt Company Ltd.")]
+[assembly: AssemblyProduct("Qt Visual Studio Tools")]
+[assembly: AssemblyCopyright("Copyright (C) 2016-2022 The Qt Company Ltd.")]
+[assembly: AssemblyTrademark("The Qt Company Ltd. Qt and their respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("131278ae-99ef-45c0-8455-423ee8f123dc")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("<#=QT_VS_TOOLS_VERSION_ASSEMBLY#>")]
+[assembly: AssemblyFileVersion("<#=QT_VS_TOOLS_VERSION_ASSEMBLY_FILE#>")]
diff --git a/Templates/translation/QtTemplate.Item.Translation.csproj b/Templates/translation/QtTemplate.Item.Translation.csproj
new file mode 100644
index 0000000..3b9a576
--- /dev/null
+++ b/Templates/translation/QtTemplate.Item.Translation.csproj
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+-->
+<Project ToolsVersion="$(VisualStudioVersion)" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <MinimumVisualStudioVersion>$(VisualStudioVersion)</MinimumVisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <PropertyGroup>
+ <ApplicationIcon>translation.ico</ApplicationIcon>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ProjectGuid>{202F4A6D-77CD-4992-AA53-01B585463287}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Translation</RootNamespace>
+ <AssemblyName>Translation</AssemblyName>
+ <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <GeneratePkgDefFile>false</GeneratePkgDefFile>
+ <IncludeAssemblyInVSIXContainer>false</IncludeAssemblyInVSIXContainer>
+ <IncludeDebugSymbolsInVSIXContainer>false</IncludeDebugSymbolsInVSIXContainer>
+ <IncludeDebugSymbolsInLocalVSIXDeployment>false</IncludeDebugSymbolsInLocalVSIXDeployment>
+ <CreateVsixContainer>false</CreateVsixContainer>
+ <DeployExtension>false</DeployExtension>
+ <DeployVSTemplates>false</DeployVSTemplates>
+ <CopyVsixManifestToOutput>false</CopyVsixManifestToOutput>
+ <CopyBuildOutputToOutputDirectory>false</CopyBuildOutputToOutputDirectory>
+ <CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
+ <ItemGroup>
+ <T4Template Include="Properties\AssemblyInfo.cs">
+ <Generator>TextTemplatingFileGenerator</Generator>
+ <OutputFile>Properties\AssemblyInfo.tt.cs</OutputFile>
+ <DependsOn>$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
+ <LastGenOutput>AssemblyInfo.tt.cs</LastGenOutput>
+ </T4Template>
+ <Compile Include="Properties\AssemblyInfo.tt.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>AssemblyInfo.cs</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="translation.ts" />
+ </ItemGroup>
+ <ItemGroup>
+ <T4Template Include="translation.vstemplate_TT">
+ <Generator>TextTemplatingFileGenerator</Generator>
+ <OutputFile>translation.vstemplate</OutputFile>
+ <DependsOn>$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
+ <LastGenOutput>translation.vstemplate</LastGenOutput>
+ </T4Template>
+ <VSTemplate Include="translation.vstemplate">
+ <SubType>Designer</SubType>
+ <OutputSubPath>Qt</OutputSubPath>
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>translation.vstemplate_TT</DependentUpon>
+ </VSTemplate>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="translation.ico" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(SolutionDir)\transform.targets" />
+ <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project>
\ No newline at end of file
diff --git a/Templates/translation/translation.ico b/Templates/translation/translation.ico
new file mode 100644
index 0000000..1c4fb80
--- /dev/null
+++ b/Templates/translation/translation.ico
Binary files differ
diff --git a/Templates/translation/translation.ts b/Templates/translation/translation.ts
new file mode 100644
index 0000000..fda00e7
--- /dev/null
+++ b/Templates/translation/translation.ts
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS >
+<TS version="2.1" language="$cultureinfoname$">
+</TS>
diff --git a/Templates/translation/translation.vstemplate_TT b/Templates/translation/translation.vstemplate_TT
new file mode 100644
index 0000000..6ec4f47
--- /dev/null
+++ b/Templates/translation/translation.vstemplate_TT
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+<#@output extension="vstemplate" #>
+<#@include file="$(SolutionDir)\version.tt" #>
+ ** <#=WARNING_GENERATED_FILE#>
+ *****************************************************************************
+-->
+
+<VSTemplate Version="3.0.0"
+ xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"
+ xmlns:sdk="http://schemas.microsoft.com/developer/vstemplate-sdkextension/2010"
+ Type="Item">
+ <TemplateData>
+ <Name>Qt Translation File</Name>
+ <Description>Qt Translation File (.ts)</Description>
+ <ProjectType>VC</ProjectType>
+ <DefaultName>Translation.ts</DefaultName>
+ <ProvideDefaultName>true</ProvideDefaultName>
+ <LocationField>Enabled</LocationField>
+ <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
+ <Icon>translation.ico</Icon>
+ <LanguageTag>Cpp</LanguageTag>
+ <PlatformTag>Windows</PlatformTag>
+ <PlatformTag>Linux</PlatformTag>
+ <ProjectTypeTag>Qt</ProjectTypeTag>
+ <ProjectTypeTag>Desktop</ProjectTypeTag>
+ <AppliesTo>VisualC</AppliesTo>
+ <TemplateGroupID>QtVsTools</TemplateGroupID>
+ <TemplateID>QtVsTools-QTranslation</TemplateID>
+ </TemplateData>
+ <TemplateContent>
+ <ProjectItem OpenInEditor="false"
+ ReplaceParameters="true"
+ TargetFileName="$tsfilename$">translation.ts</ProjectItem>
+ </TemplateContent>
+ <WizardExtension>
+ <!-- BEGIN Generated Text <#=XML_COMMENT_END#>
+ <Assembly>QtVsTools.Wizards, Version=<#=QT_VS_TOOLS_VERSION_ASSEMBLY#>, Culture=neutral, PublicKeyToken=null</Assembly>
+ <#=XML_COMMENT_BEGIN#> END Generated Text -->
+ <FullClassName>QtVsTools.Wizards.ItemWizard.TranslationWizard</FullClassName>
+ </WizardExtension>
+</VSTemplate>
diff --git a/Templates/widget/QtTemplate.Item.Widget.csproj b/Templates/widget/QtTemplate.Item.Widget.csproj
index c31a8ea..b843926 100644
--- a/Templates/widget/QtTemplate.Item.Widget.csproj
+++ b/Templates/widget/QtTemplate.Item.Widget.csproj
@@ -78,6 +78,45 @@
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
<ItemGroup>
<T4Template Include="Properties\AssemblyInfo.cs">
<Generator>TextTemplatingFileGenerator</Generator>
@@ -98,17 +137,7 @@
<OutputSubPath>Qt</OutputSubPath>
</VSTemplate>
</ItemGroup>
- <ItemGroup>
- <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
- </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\transform.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
</Project>
diff --git a/Templates/widgetsclass/Properties/AssemblyInfo.cs b/Templates/widgetsclass/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..e8d8a9c
--- /dev/null
+++ b/Templates/widgetsclass/Properties/AssemblyInfo.cs
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************
+<#@output extension="tt.cs" #>
+<#@include file="$(SolutionDir)\version.tt" #>
+** <#=WARNING_GENERATED_FILE#>
+****************************************************************************/
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("WidgetsClass")]
+[assembly: AssemblyDescription("The Qt Visual Studio Tools allow developers to use the standard development environment without having to worry about any Qt-related build steps or tools.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Qt Company Ltd.")]
+[assembly: AssemblyProduct("Qt Visual Studio Tools")]
+[assembly: AssemblyCopyright("Copyright (C) 2016-2022 The Qt Company Ltd.")]
+[assembly: AssemblyTrademark("The Qt Company Ltd. Qt and their respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("665d1b79-1498-4d1a-8376-58394e150276")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("<#=QT_VS_TOOLS_VERSION_ASSEMBLY#>")]
+[assembly: AssemblyFileVersion("<#=QT_VS_TOOLS_VERSION_ASSEMBLY_FILE#>")]
diff --git a/Templates/widgetsclass/QtTemplate.Item.WidgetsClass.csproj b/Templates/widgetsclass/QtTemplate.Item.WidgetsClass.csproj
new file mode 100644
index 0000000..5dbb07f
--- /dev/null
+++ b/Templates/widgetsclass/QtTemplate.Item.WidgetsClass.csproj
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+-->
+<Project ToolsVersion="$(VisualStudioVersion)" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <MinimumVisualStudioVersion>$(VisualStudioVersion)</MinimumVisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <PropertyGroup>
+ <ApplicationIcon>widgetsclass.ico</ApplicationIcon>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ProjectGuid>{020422DA-33AB-4495-A439-7DAC2690795C}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>WidgetsClass</RootNamespace>
+ <AssemblyName>WidgetsClass</AssemblyName>
+ <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <GeneratePkgDefFile>false</GeneratePkgDefFile>
+ <IncludeAssemblyInVSIXContainer>false</IncludeAssemblyInVSIXContainer>
+ <IncludeDebugSymbolsInVSIXContainer>false</IncludeDebugSymbolsInVSIXContainer>
+ <IncludeDebugSymbolsInLocalVSIXDeployment>false</IncludeDebugSymbolsInLocalVSIXDeployment>
+ <CreateVsixContainer>false</CreateVsixContainer>
+ <DeployExtension>false</DeployExtension>
+ <DeployVSTemplates>false</DeployVSTemplates>
+ <CopyVsixManifestToOutput>false</CopyVsixManifestToOutput>
+ <CopyBuildOutputToOutputDirectory>false</CopyBuildOutputToOutputDirectory>
+ <CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
+ <ItemGroup>
+ <T4Template Include="Properties\AssemblyInfo.cs">
+ <Generator>TextTemplatingFileGenerator</Generator>
+ <OutputFile>Properties\AssemblyInfo.tt.cs</OutputFile>
+ <DependsOn>$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
+ <LastGenOutput>AssemblyInfo.tt.cs</LastGenOutput>
+ </T4Template>
+ <Compile Include="Properties\AssemblyInfo.tt.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>AssemblyInfo.cs</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="widget.cpp" />
+ <None Include="widget.h" />
+ <None Include="widget.ui" />
+ </ItemGroup>
+ <ItemGroup>
+ <T4Template Include="widgetsclass.vstemplate_TT">
+ <Generator>TextTemplatingFileGenerator</Generator>
+ <OutputFile>widgetsclass.vstemplate</OutputFile>
+ <DependsOn>$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
+ <LastGenOutput>widgetsclass.vstemplate</LastGenOutput>
+ </T4Template>
+ <VSTemplate Include="widgetsclass.vstemplate">
+ <SubType>Designer</SubType>
+ <OutputSubPath>Qt</OutputSubPath>
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>widgetsclass.vstemplate_TT</DependentUpon>
+ </VSTemplate>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="widgetsclass.ico" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(SolutionDir)\transform.targets" />
+ <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project>
\ No newline at end of file
diff --git a/Templates/widgetsclass/widget.cpp b/Templates/widgetsclass/widget.cpp
new file mode 100644
index 0000000..7718d6f
--- /dev/null
+++ b/Templates/widgetsclass/widget.cpp
@@ -0,0 +1,11 @@
+$include$
+
+$namespacebegin$$classname$::$classname$(QWidget *parent)
+ : $baseclass$(parent)$new$
+{
+ $member$$operator$setupUi(this);
+}
+
+$classname$::~$classname$()
+{$delete$}
+$namespaceend$
\ No newline at end of file
diff --git a/Templates/widgetsclass/widget.h b/Templates/widgetsclass/widget.h
new file mode 100644
index 0000000..e0cb40e
--- /dev/null
+++ b/Templates/widgetsclass/widget.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <$baseclass$>
+#include "$ui_hdr$"
+$forward_declare_class$
+$namespacebegin$class $classname$ : public $baseclass$$multiple_inheritance$
+{$qobject$
+public:
+ $classname$(QWidget *parent = nullptr);
+ ~$classname$();
+
+private:
+ $ui_classname$ $asterisk$$member$$semicolon$
+};
+$namespaceend$
\ No newline at end of file
diff --git a/Templates/widgetsclass/widget.ui b/Templates/widgetsclass/widget.ui
new file mode 100644
index 0000000..74c429e
--- /dev/null
+++ b/Templates/widgetsclass/widget.ui
@@ -0,0 +1,22 @@
+<UI version="4.0" >
+ <class>$classname$Class</class>
+ <widget class="$baseclass$" name="$classname$Class" >
+ <property name="objectName" >
+ <string notr="true">$classname$Class</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>$classname$</string>
+ </property>$centralwidget$
+ </widget>
+ <layoutDefault spacing="6" margin="11" />
+ <pixmapfunction></pixmapfunction>
+ <connections/>
+</UI>
diff --git a/Templates/widgetsclass/widgetsclass.ico b/Templates/widgetsclass/widgetsclass.ico
new file mode 100644
index 0000000..1c4fb80
--- /dev/null
+++ b/Templates/widgetsclass/widgetsclass.ico
Binary files differ
diff --git a/Templates/widgetsclass/widgetsclass.vstemplate_TT b/Templates/widgetsclass/widgetsclass.vstemplate_TT
new file mode 100644
index 0000000..89c5e79
--- /dev/null
+++ b/Templates/widgetsclass/widgetsclass.vstemplate_TT
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+<#@output extension="vstemplate" #>
+<#@include file="$(SolutionDir)\version.tt" #>
+ ** <#=WARNING_GENERATED_FILE#>
+ *****************************************************************************
+-->
+
+<VSTemplate Version="3.0.0"
+ xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"
+ xmlns:sdk="http://schemas.microsoft.com/developer/vstemplate-sdkextension/2010"
+ Type="Item" >
+ <TemplateData>
+ <Name>Qt Widgets Class</Name>
+ <Description>Adds a Qt Widgets class to the project.</Description>
+ <ProjectType>VC</ProjectType>
+ <DefaultName>QtWidgetsClass</DefaultName>
+ <ProvideDefaultName>true</ProvideDefaultName>
+ <LocationField>Enabled</LocationField>
+ <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
+ <Icon>widgetsclass.ico</Icon>
+ <LanguageTag>Cpp</LanguageTag>
+ <PlatformTag>Windows</PlatformTag>
+ <PlatformTag>Linux</PlatformTag>
+ <ProjectTypeTag>Qt</ProjectTypeTag>
+ <ProjectTypeTag>Desktop</ProjectTypeTag>
+ </TemplateData>
+ <TemplateContent>
+ <ProjectItem OpenInEditor="true"
+ ReplaceParameters="true"
+ TargetFileName="$sourcefilename$">widget.cpp</ProjectItem>
+ <ProjectItem ReplaceParameters="true"
+ TargetFileName="$headerfilename$">widget.h</ProjectItem>
+ <ProjectItem ReplaceParameters="true"
+ TargetFileName="$uifilename$">widget.ui</ProjectItem>
+ </TemplateContent>
+ <WizardExtension>
+ <!-- BEGIN Generated Text <#=XML_COMMENT_END#>
+ <Assembly>QtVsTools.Wizards, Version=<#=QT_VS_TOOLS_VERSION_ASSEMBLY#>, Culture=neutral, PublicKeyToken=null</Assembly>
+ <#=XML_COMMENT_BEGIN#> END Generated Text -->
+ <FullClassName>QtVsTools.Wizards.ItemWizard.WidgetsClassWizard</FullClassName>
+ </WizardExtension>
+</VSTemplate>
diff --git a/Tests/BigSolution/generator/Program.cs b/Tests/BigSolution/generator/Program.cs
index 6100ac6..5624762 100644
--- a/Tests/BigSolution/generator/Program.cs
+++ b/Tests/BigSolution/generator/Program.cs
@@ -38,51 +38,27 @@
{
internal class Program
{
- static void Main(string[] args)
+ static void GenerateProject(
+ StringBuilder genSolutionProjectRef,
+ StringBuilder genSolutionProjectConfigs,
+ string pathToTemplateDir,
+ string pathToGeneratedDir,
+ int projectCount,
+ string projectGuid,
+ string projectName,
+ string projectRef,
+ IEnumerable<string> projectConfigsList)
{
- var projectCount = args.Length > 0 ? Convert.ToInt32(args[0]) : 400;
- var pathToTemplateDir = Path.GetFullPath(@"..\..\..\template");
- var pathToGeneratedDir = Path.GetFullPath(@"..\..\..\generated");
- var templateFiles = Directory.GetFiles(
- pathToTemplateDir, "*", SearchOption.AllDirectories);
- var solutionFilePath = templateFiles
- .Where(x => Path.GetExtension(x) == ".sln")
- .First();
- var solutionName = Path.GetFileName(solutionFilePath);
- var solutionText = File.ReadAllText(solutionFilePath);
- var projectFilePath = templateFiles
- .Where(x => Path.GetExtension(x) == ".vcxproj")
- .First();
- var projectText = File.ReadAllText(projectFilePath);
- var projectName = Path.GetFileNameWithoutExtension(projectFilePath);
- var projectGuidMatch = Regex.Match(projectText, @"<ProjectGuid>({[^}]+})<");
- var projectGuid = projectGuidMatch.Groups[1].Value;
-
- var projectRef = Regex
- .Match(solutionText,
- @"^Project.*" + projectGuid + @"""\r\nEndProject\r\n", RegexOptions.Multiline)
- .Value;
-
- var projectConfigsList = Regex
- .Matches(solutionText,
- @"^\s+" + projectGuid + @".*\r\n", RegexOptions.Multiline)
- .Cast<Match>()
- .Select(x => x.Value);
- var projectConfigs = string.Join("", projectConfigsList);
-
var projectFiles = Directory.GetFiles(
Path.Combine(pathToTemplateDir, projectName),
"*", SearchOption.TopDirectoryOnly);
- if (Directory.Exists(pathToGeneratedDir))
- Directory.Delete(pathToGeneratedDir, true);
-
- var genSolutionProjectRef = new StringBuilder();
- var genSolutionProjectConfigs = new StringBuilder();
-
- for (int i = 1; i <= projectCount; i++) {
+ bool singleProject = false;
+ for (int i = 1; !singleProject && i <= projectCount; i++) {
var idxStr = string.Format("{0:D3}", i);
var genProjectName = projectName.Replace("NNN", idxStr);
+ if (genProjectName == projectName)
+ singleProject = true;
var genProjectDirPath = Path.Combine(pathToGeneratedDir, genProjectName);
var genProjectGuid = projectGuid.Replace("000", idxStr);
@@ -110,9 +86,66 @@
genSolutionProjectConfigs.Append(genProjectConfig);
}
}
- var genSolutionText = solutionText
- .Replace(projectRef, genSolutionProjectRef.ToString())
- .Replace(projectConfigs, genSolutionProjectConfigs.ToString());
+ }
+
+ static void Main(string[] args)
+ {
+ int projectCount;
+ if (args.Length == 0 || !int.TryParse(args[0], out projectCount)) {
+ string userProjectCount;
+ do {
+ Console.Write("Project count: ");
+ userProjectCount = Console.ReadLine();
+ } while (!int.TryParse(userProjectCount, out projectCount));
+ }
+ var pathToTemplateDir = Path.GetFullPath(@"..\..\..\template");
+ var pathToGeneratedDir = Path.GetFullPath(
+ $@"..\..\..\generated_{DateTime.Now.ToString("yyyyMMddhhmmssfff")}");
+ var templateFiles = Directory.GetFiles(
+ pathToTemplateDir, "*", SearchOption.AllDirectories);
+ var solutionFilePath = templateFiles
+ .Where(x => Path.GetExtension(x) == ".sln")
+ .First();
+ var solutionName = Path.GetFileName(solutionFilePath);
+ var solutionText = File.ReadAllText(solutionFilePath);
+ var projectFilePaths = templateFiles
+ .Where(x => Path.GetExtension(x) == ".vcxproj");
+ var genSolutionText = solutionText;
+ if (Directory.Exists(pathToGeneratedDir))
+ Directory.Delete(pathToGeneratedDir, true);
+ foreach (var projectFilePath in projectFilePaths) {
+ var genSolutionProjectRef = new StringBuilder();
+ var genSolutionProjectConfigs = new StringBuilder();
+ var projectText = File.ReadAllText(projectFilePath);
+ var projectName = Path.GetFileNameWithoutExtension(projectFilePath);
+ var projectGuidMatch = Regex.Match(projectText, @"<ProjectGuid>({[^}]+})<");
+ var projectGuid = projectGuidMatch.Groups[1].Value;
+ var projectRef = Regex
+ .Match(solutionText,
+ @"^Project.*" + projectGuid + @"""\r\nEndProject\r\n",
+ RegexOptions.Multiline | RegexOptions.IgnoreCase)
+ .Value;
+ var projectConfigsList = Regex
+ .Matches(solutionText,
+ @"^\s+" + projectGuid + @".*\r\n",
+ RegexOptions.Multiline | RegexOptions.IgnoreCase)
+ .Cast<Match>()
+ .Select(x => x.Value);
+ var projectConfigs = string.Join("", projectConfigsList);
+ GenerateProject(
+ genSolutionProjectRef,
+ genSolutionProjectConfigs,
+ pathToTemplateDir,
+ pathToGeneratedDir,
+ projectCount,
+ projectGuid,
+ projectName,
+ projectRef,
+ projectConfigsList);
+ genSolutionText = genSolutionText
+ .Replace(projectRef, genSolutionProjectRef.ToString())
+ .Replace(projectConfigs, genSolutionProjectConfigs.ToString());
+ }
var genSolutionFilePath = Path.Combine(pathToGeneratedDir, solutionName);
File.WriteAllText(genSolutionFilePath, genSolutionText);
}
diff --git a/Tests/BigSolution/template/BigProjectNNN/BigProjectNNN.vcxproj b/Tests/BigSolution/template/BigProjectNNN/BigProjectNNN.vcxproj
index 2ec9d1f..886f40a 100644
--- a/Tests/BigSolution/template/BigProjectNNN/BigProjectNNN.vcxproj
+++ b/Tests/BigSolution/template/BigProjectNNN/BigProjectNNN.vcxproj
@@ -95,6 +95,14 @@
<QtUic Include="BigProjectNNN.ui" />
<QtRcc Include="BigProjectNNN.qrc" />
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\QtClassLibrary\QtClassLibrary.vcxproj">
+ <Project>{ce78ec51-c4a0-465b-a161-21c257bd057b}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\StaticLib\StaticLib.vcxproj">
+ <Project>{8463051a-b32c-43f0-9a77-9f223598aac9}</Project>
+ </ProjectReference>
+ </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
<Import Project="$(QtMsBuild)\qt.targets" />
diff --git a/Tests/BigSolution/template/BigProjectNNN/BigProjectQtClassNNN.h b/Tests/BigSolution/template/BigProjectNNN/BigProjectQtClassNNN.h
index 66561fb..cb4d382 100644
--- a/Tests/BigSolution/template/BigProjectNNN/BigProjectQtClassNNN.h
+++ b/Tests/BigSolution/template/BigProjectNNN/BigProjectQtClassNNN.h
@@ -36,7 +36,7 @@
Q_OBJECT
public:
- BigProjectQtClassNNN(QWidget *parent = Q_NULLPTR);
+ BigProjectQtClassNNN(QWidget *parent = nullptr);
private:
Ui::BigProjectNNNUi ui;
diff --git a/Tests/BigSolution/template/BigSolution.sln b/Tests/BigSolution/template/BigSolution.sln
index 66a56f1..ee2c8e6 100644
--- a/Tests/BigSolution/template/BigSolution.sln
+++ b/Tests/BigSolution/template/BigSolution.sln
@@ -3,6 +3,10 @@
# Visual Studio Version 16
VisualStudioVersion = 16.0.31229.387
MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QtClassLibrary", "QtClassLibrary\QtClassLibrary.vcxproj", "{CE78EC51-C4A0-465B-A161-21C257BD057B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StaticLib", "StaticLib\StaticLib.vcxproj", "{8463051A-B32C-43F0-9A77-9F223598AAC9}"
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BigProjectNNN", "BigProjectNNN\BigProjectNNN.vcxproj", "{C032BE4B-48F7-465F-BA2A-44962223E000}"
EndProject
Global
@@ -11,6 +15,14 @@
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CE78EC51-C4A0-465B-A161-21C257BD057B}.Debug|x64.ActiveCfg = Debug|x64
+ {CE78EC51-C4A0-465B-A161-21C257BD057B}.Debug|x64.Build.0 = Debug|x64
+ {CE78EC51-C4A0-465B-A161-21C257BD057B}.Release|x64.ActiveCfg = Release|x64
+ {CE78EC51-C4A0-465B-A161-21C257BD057B}.Release|x64.Build.0 = Release|x64
+ {8463051A-B32C-43F0-9A77-9F223598AAC9}.Debug|x64.ActiveCfg = Debug|x64
+ {8463051A-B32C-43F0-9A77-9F223598AAC9}.Debug|x64.Build.0 = Debug|x64
+ {8463051A-B32C-43F0-9A77-9F223598AAC9}.Release|x64.ActiveCfg = Release|x64
+ {8463051A-B32C-43F0-9A77-9F223598AAC9}.Release|x64.Build.0 = Release|x64
{C032BE4B-48F7-465F-BA2A-44962223E000}.Debug|x64.ActiveCfg = Debug|x64
{C032BE4B-48F7-465F-BA2A-44962223E000}.Debug|x64.Build.0 = Debug|x64
{C032BE4B-48F7-465F-BA2A-44962223E000}.Release|x64.ActiveCfg = Release|x64
diff --git a/Tests/BigSolution/template/QtClassLibrary/QtClass.cpp b/Tests/BigSolution/template/QtClassLibrary/QtClass.cpp
new file mode 100644
index 0000000..e0be39f
--- /dev/null
+++ b/Tests/BigSolution/template/QtClassLibrary/QtClass.cpp
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "QtClass.h"
+
+QtClass::QtClass(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QtClass::~QtClass()
+{
+}
diff --git a/Tests/BigSolution/template/QtClassLibrary/QtClass.h b/Tests/BigSolution/template/QtClassLibrary/QtClass.h
new file mode 100644
index 0000000..25117bf
--- /dev/null
+++ b/Tests/BigSolution/template/QtClassLibrary/QtClass.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#pragma once
+#include "qtclasslibrary_global.h"
+
+#include <QObject>
+
+class QTCLASSLIBRARY_EXPORT QtClass : public QObject
+{
+ Q_OBJECT
+
+public:
+ QtClass(QObject *parent);
+ ~QtClass();
+};
diff --git a/Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.cpp b/Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.cpp
new file mode 100644
index 0000000..2aea7ec
--- /dev/null
+++ b/Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.cpp
@@ -0,0 +1,33 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "QtClassLibrary.h"
+
+QtClassLibrary::QtClassLibrary()
+{
+}
diff --git a/Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.h b/Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.h
new file mode 100644
index 0000000..076f26a
--- /dev/null
+++ b/Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#pragma once
+
+#include "qtclasslibrary_global.h"
+
+class QTCLASSLIBRARY_EXPORT QtClassLibrary
+{
+public:
+ QtClassLibrary();
+};
diff --git a/Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.vcxproj b/Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.vcxproj
new file mode 100644
index 0000000..54fd6da
--- /dev/null
+++ b/Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.vcxproj
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="$(VisualStudioVersion)" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{CE78EC51-C4A0-465B-A161-21C257BD057B}</ProjectGuid>
+ <Keyword>QtVS_v304</Keyword>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0</WindowsTargetPlatformVersion>
+ <QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
+ <Import Project="$(QtMsBuild)\qt_defaults.props" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
+ <QtInstall>$(DefaultQtVersion)</QtInstall>
+ <QtModules>core</QtModules>
+ <QtBuildConfig>debug</QtBuildConfig>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
+ <QtInstall>$(DefaultQtVersion)</QtInstall>
+ <QtModules>core</QtModules>
+ <QtBuildConfig>release</QtBuildConfig>
+ </PropertyGroup>
+ <Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+ <Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+ </Target>
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(QtMsBuild)\Qt.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(QtMsBuild)\Qt.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <AllProjectIncludesArePublic>true</AllProjectIncludesArePublic>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <AllProjectIncludesArePublic>true</AllProjectIncludesArePublic>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ProjectReference>
+ <UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ProjectReference>
+ <UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PreprocessorDefinitions>QTCLASSLIBRARY_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <Optimization>MaxSpeed</Optimization>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PreprocessorDefinitions>QTCLASSLIBRARY_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <QtMoc Include="QtClass.h" />
+ <ClInclude Include="qtclasslibrary_global.h" />
+ <ClInclude Include="QtClassLibrary.h" />
+ <ClCompile Include="QtClass.cpp" />
+ <ClCompile Include="QtClassLibrary.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+ <Import Project="$(QtMsBuild)\qt.targets" />
+ </ImportGroup>
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.vcxproj.filters b/Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.vcxproj.filters
new file mode 100644
index 0000000..5797d00
--- /dev/null
+++ b/Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.vcxproj.filters
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="Translation Files">
+ <UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
+ <Extensions>ts</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="qtclasslibrary_global.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClCompile Include="QtClassLibrary.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClInclude Include="QtClassLibrary.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <QtMoc Include="QtClass.h">
+ <Filter>Header Files</Filter>
+ </QtMoc>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="QtClass.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/BigSolution/template/QtClassLibrary/qtclasslibrary_global.h b/Tests/BigSolution/template/QtClassLibrary/qtclasslibrary_global.h
new file mode 100644
index 0000000..30029ba
--- /dev/null
+++ b/Tests/BigSolution/template/QtClassLibrary/qtclasslibrary_global.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QtCore/qglobal.h>
+
+#ifndef BUILD_STATIC
+# if defined(QTCLASSLIBRARY_LIB)
+# define QTCLASSLIBRARY_EXPORT Q_DECL_EXPORT
+# else
+# define QTCLASSLIBRARY_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QTCLASSLIBRARY_EXPORT
+#endif
diff --git a/Tests/BigSolution/template/StaticLib/Header.h b/Tests/BigSolution/template/StaticLib/Header.h
new file mode 100644
index 0000000..69b048e
--- /dev/null
+++ b/Tests/BigSolution/template/StaticLib/Header.h
@@ -0,0 +1,4 @@
+#pragma once
+
+void foobar();
+
diff --git a/Tests/BigSolution/template/StaticLib/StaticLib.cpp b/Tests/BigSolution/template/StaticLib/StaticLib.cpp
new file mode 100644
index 0000000..85cd0de
--- /dev/null
+++ b/Tests/BigSolution/template/StaticLib/StaticLib.cpp
@@ -0,0 +1,31 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+void foobar()
+{
+}
diff --git a/Tests/BigSolution/template/StaticLib/StaticLib.vcxproj b/Tests/BigSolution/template/StaticLib/StaticLib.vcxproj
new file mode 100644
index 0000000..e250860
--- /dev/null
+++ b/Tests/BigSolution/template/StaticLib/StaticLib.vcxproj
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <Keyword>Win32Proj</Keyword>
+ <ProjectGuid>{8463051a-b32c-43f0-9a77-9f223598aac9}</ProjectGuid>
+ <RootNamespace>StaticLib</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <AllProjectIncludesArePublic>true</AllProjectIncludesArePublic>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <AllProjectIncludesArePublic>true</AllProjectIncludesArePublic>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>
+ </SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>
+ </SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="StaticLib.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Header.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/BigSolution/template/StaticLib/StaticLib.vcxproj.filters b/Tests/BigSolution/template/StaticLib/StaticLib.vcxproj.filters
new file mode 100644
index 0000000..55c2e2a
--- /dev/null
+++ b/Tests/BigSolution/template/StaticLib/StaticLib.vcxproj.filters
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="StaticLib.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Header.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/BigSolution/template/loop_msbuild.bat b/Tests/BigSolution/template/loop_msbuild.bat
new file mode 100644
index 0000000..24854c0
--- /dev/null
+++ b/Tests/BigSolution/template/loop_msbuild.bat
@@ -0,0 +1,36 @@
+@ECHO OFF
+
+SET TOTAL=0
+SET FAIL=0
+SET RATE=0
+SET USER_QUIT=0
+SET PAD=..00
+
+:loop
+ CLS
+ SET RATE=%PAD%%RATE%
+ ECHO ################################################################################
+ ECHO # Total: %TOTAL%, Failed: %FAIL%...%RATE:~-4,-2%,%RATE:~-2%%%
+ ECHO ################################################################################
+ IF %USER_QUIT% EQU 1 GOTO quit
+ SET /A "TOTAL+=1"
+ msbuild %* ^
+ /m /bl /v:m /nologo ^
+ && (
+ DEL last_build_ok.binlog 2> NUL
+ COPY msbuild.binlog last_build_ok.binlog > NUL
+ ) || (
+ SET /A "FAIL+=1"
+ COPY msbuild.binlog error_build_%TOTAL%.binlog > NUL
+ )
+ SET /A "RATE=(FAIL*100*100)/(TOTAL)"
+ ECHO ################################################################################
+ CHOICE /C QNOP /N /T 1 /D N /M "# [N]ext / [O]pen Log / [P]ause / [Q]uit ?"
+ IF %ERRORLEVEL% EQU 3 (
+ START "" msbuild.binlog
+ PAUSE
+ )
+ IF %ERRORLEVEL% EQU 4 PAUSE
+ SET USER_QUIT=%ERRORLEVEL%
+ GOTO :loop
+:quit
diff --git a/Tests/ProjectFormats/100/QtProjectV100.cpp b/Tests/ProjectFormats/100/QtProjectV100.cpp
new file mode 100644
index 0000000..19581ed
--- /dev/null
+++ b/Tests/ProjectFormats/100/QtProjectV100.cpp
@@ -0,0 +1,10 @@
+#include "QtProjectV100.h"
+
+QtProjectV100::QtProjectV100(QWidget *parent)
+ : QMainWindow(parent)
+{
+ ui.setupUi(this);
+}
+
+QtProjectV100::~QtProjectV100()
+{}
diff --git a/Tests/ProjectFormats/100/QtProjectV100.h b/Tests/ProjectFormats/100/QtProjectV100.h
new file mode 100644
index 0000000..17c9eff
--- /dev/null
+++ b/Tests/ProjectFormats/100/QtProjectV100.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <QtWidgets/QMainWindow>
+#include "ui_QtProjectV100.h"
+
+class QtProjectV100 : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ QtProjectV100(QWidget *parent = nullptr);
+ ~QtProjectV100();
+
+private:
+ Ui::QtProjectV100Class ui;
+};
diff --git a/Tests/ProjectFormats/100/QtProjectV100.pro b/Tests/ProjectFormats/100/QtProjectV100.pro
new file mode 100644
index 0000000..bcf1b07
--- /dev/null
+++ b/Tests/ProjectFormats/100/QtProjectV100.pro
@@ -0,0 +1,6 @@
+QT += widgets
+HEADERS = QtProjectV100.h
+FORMS = QtProjectV100.ui
+RESOURCES = QtProjectV100.qrc
+SOURCES = QtProjectV100.cpp \
+ main.cpp
diff --git a/Tests/ProjectFormats/100/QtProjectV100.qrc b/Tests/ProjectFormats/100/QtProjectV100.qrc
new file mode 100644
index 0000000..c2c4dd0
--- /dev/null
+++ b/Tests/ProjectFormats/100/QtProjectV100.qrc
@@ -0,0 +1,4 @@
+<RCC>
+ <qresource prefix="QtProjectV100">
+ </qresource>
+</RCC>
diff --git a/Tests/ProjectFormats/100/QtProjectV100.ui b/Tests/ProjectFormats/100/QtProjectV100.ui
new file mode 100644
index 0000000..4fe7f33
--- /dev/null
+++ b/Tests/ProjectFormats/100/QtProjectV100.ui
@@ -0,0 +1,28 @@
+<UI version="4.0" >
+ <class>QtProjectV100Class</class>
+ <widget class="QMainWindow" name="QtProjectV100Class" >
+ <property name="objectName" >
+ <string notr="true">QtProjectV100Class</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>QtProjectV100</string>
+ </property> <widget class="QMenuBar" name="menuBar" />
+ <widget class="QToolBar" name="mainToolBar" />
+ <widget class="QWidget" name="centralWidget" />
+ <widget class="QStatusBar" name="statusBar" />
+ </widget>
+ <layoutDefault spacing="6" margin="11" />
+ <pixmapfunction></pixmapfunction>
+ <resources>
+ <include location="QtProjectV100.qrc"/>
+ </resources>
+ <connections/>
+</UI>
diff --git a/Tests/ProjectFormats/100/QtProjectV100.vcxproj b/Tests/ProjectFormats/100/QtProjectV100.vcxproj
new file mode 100644
index 0000000..347aa54
--- /dev/null
+++ b/Tests/ProjectFormats/100/QtProjectV100.vcxproj
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{E5EA0EEF-BDC2-3484-A4F0-BA6C71E224CF}</ProjectGuid>
+ <RootNamespace>QtProjectV100</RootNamespace>
+ <Keyword>Qt4VSv1.0</Keyword>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <PlatformToolset>v142</PlatformToolset>
+ <OutputDirectory>release\</OutputDirectory>
+ <ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
+ <CharacterSet>NotSet</CharacterSet>
+ <ConfigurationType>Application</ConfigurationType>
+ <IntermediateDirectory>release\</IntermediateDirectory>
+ <PrimaryOutput>QtProjectV100</PrimaryOutput>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <PlatformToolset>v142</PlatformToolset>
+ <OutputDirectory>debug\</OutputDirectory>
+ <ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
+ <CharacterSet>NotSet</CharacterSet>
+ <ConfigurationType>Application</ConfigurationType>
+ <IntermediateDirectory>debug\</IntermediateDirectory>
+ <PrimaryOutput>QtProjectV100</PrimaryOutput>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\</IntDir>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">QtProjectV100</TargetName>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</IgnoreImportLibrary>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\</IntDir>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">QtProjectV100</TargetName>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</IgnoreImportLibrary>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>.;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtWidgets;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtGui;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtANGLE;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtCore;release;.;/include;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\mkspecs\win32-msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
+ <AssemblerListingLocation>release\</AssemblerListingLocation>
+ <BrowseInformation>false</BrowseInformation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <ObjectFileName>release\</ObjectFileName>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessToFile>false</PreprocessToFile>
+ <ProgramDataBaseFileName></ProgramDataBaseFileName>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <WarningLevel>Level3</WarningLevel>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>C:\lib\Qt\5.15.10\msvc2019_64\lib\Qt5Widgets.lib;C:\lib\Qt\5.15.10\msvc2019_64\lib\Qt5Gui.lib;C:\lib\Qt\5.15.10\msvc2019_64\lib\Qt5Core.lib;C:\lib\Qt\5.15.10\msvc2019_64\lib\qtmain.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>C:\openssl\lib;C:\Utils\my_sql\mysql-5.7.25-winx64\lib;C:\Utils\postgresql\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
+ <DataExecutionPrevention>true</DataExecutionPrevention>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <IgnoreImportLibrary>true</IgnoreImportLibrary>
+ <LinkIncremental>false</LinkIncremental>
+ <OptimizeReferences>true</OptimizeReferences>
+ <OutputFile>$(OutDir)\QtProjectV100.exe</OutputFile>
+ <RandomizedBaseAddress>true</RandomizedBaseAddress>
+ <SubSystem>Windows</SubSystem>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Link>
+ <Midl>
+ <DefaultCharType>Unsigned</DefaultCharType>
+ <EnableErrorChecks>None</EnableErrorChecks>
+ <WarningLevel>0</WarningLevel>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>.;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtWidgets;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtGui;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtANGLE;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtCore;debug;.;/include;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\mkspecs\win32-msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
+ <AssemblerListingLocation>debug\</AssemblerListingLocation>
+ <BrowseInformation>false</BrowseInformation>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <ObjectFileName>debug\</ObjectFileName>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessToFile>false</PreprocessToFile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <WarningLevel>Level3</WarningLevel>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>C:\lib\Qt\5.15.10\msvc2019_64\lib\Qt5Widgetsd.lib;C:\lib\Qt\5.15.10\msvc2019_64\lib\Qt5Guid.lib;C:\lib\Qt\5.15.10\msvc2019_64\lib\Qt5Cored.lib;C:\lib\Qt\5.15.10\msvc2019_64\lib\qtmaind.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>C:\openssl\lib;C:\Utils\my_sql\mysql-5.7.25-winx64\lib;C:\Utils\postgresql\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
+ <DataExecutionPrevention>true</DataExecutionPrevention>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <IgnoreImportLibrary>true</IgnoreImportLibrary>
+ <OutputFile>$(OutDir)\QtProjectV100.exe</OutputFile>
+ <RandomizedBaseAddress>true</RandomizedBaseAddress>
+ <SubSystem>Windows</SubSystem>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Link>
+ <Midl>
+ <DefaultCharType>Unsigned</DefaultCharType>
+ <EnableErrorChecks>None</EnableErrorChecks>
+ <WarningLevel>0</WarningLevel>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="QtProjectV100.cpp" />
+ <ClCompile Include="main.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV100.h">
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">QtProjectV100.h;release\moc_predefs.h;C:\lib\Qt\5.15.10\msvc2019_64\bin\moc.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\lib\Qt\5.15.10\msvc2019_64\bin\moc.exe -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DNDEBUG -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB --compiler-flavor=msvc --include C:/dev/tests/formats/100/release/moc_predefs.h -IC:/lib/Qt/5.15.10/msvc2019_64/mkspecs/win32-msvc -IC:/dev/tests/formats/100 -IC:/lib/Qt/5.15.10/msvc2019_64/include -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtWidgets -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtGui -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtANGLE -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtCore -I"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\ATLMFC\include" -I"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\include" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" QtProjectV100.h -o release\moc_QtProjectV100.cpp</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MOC QtProjectV100.h</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\moc_QtProjectV100.cpp;%(Outputs)</Outputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">QtProjectV100.h;debug\moc_predefs.h;C:\lib\Qt\5.15.10\msvc2019_64\bin\moc.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\lib\Qt\5.15.10\msvc2019_64\bin\moc.exe -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB --compiler-flavor=msvc --include C:/dev/tests/formats/100/debug/moc_predefs.h -IC:/lib/Qt/5.15.10/msvc2019_64/mkspecs/win32-msvc -IC:/dev/tests/formats/100 -IC:/lib/Qt/5.15.10/msvc2019_64/include -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtWidgets -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtGui -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtANGLE -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtCore -I"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\ATLMFC\include" -I"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\include" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" QtProjectV100.h -o debug\moc_QtProjectV100.cpp</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">MOC QtProjectV100.h</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\moc_QtProjectV100.cpp;%(Outputs)</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="debug\moc_QtProjectV100.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="release\moc_QtProjectV100.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <CustomBuild Include="debug\moc_predefs.h.cbt">
+ <FileType>Document</FileType>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\..\..\lib\Qt\5.15.10\msvc2019_64\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">cl -BxC:\lib\Qt\5.15.10\msvc2019_64\bin\qmake.exe -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E ..\..\..\..\lib\Qt\5.15.10\msvc2019_64\mkspecs\features\data\dummy.cpp 2>NUL >debug\moc_predefs.h</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Generate moc_predefs.h</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\moc_predefs.h;%(Outputs)</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="release\moc_predefs.h.cbt">
+ <FileType>Document</FileType>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\..\lib\Qt\5.15.10\msvc2019_64\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">cl -BxC:\lib\Qt\5.15.10\msvc2019_64\bin\qmake.exe -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E ..\..\..\..\lib\Qt\5.15.10\msvc2019_64\mkspecs\features\data\dummy.cpp 2>NUL >release\moc_predefs.h</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Generate moc_predefs.h</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\moc_predefs.h;%(Outputs)</Outputs>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </CustomBuild>
+ <ClCompile Include="debug\qrc_QtProjectV100.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="release\qrc_QtProjectV100.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClInclude Include="ui_QtProjectV100.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV100.ui">
+ <FileType>Document</FileType>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">QtProjectV100.ui;C:\lib\Qt\5.15.10\msvc2019_64\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\lib\Qt\5.15.10\msvc2019_64\bin\uic.exe QtProjectV100.ui -o ui_QtProjectV100.h</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">UIC QtProjectV100.ui</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ui_QtProjectV100.h;%(Outputs)</Outputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">QtProjectV100.ui;C:\lib\Qt\5.15.10\msvc2019_64\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\lib\Qt\5.15.10\msvc2019_64\bin\uic.exe QtProjectV100.ui -o ui_QtProjectV100.h</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">UIC QtProjectV100.ui</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ui_QtProjectV100.h;%(Outputs)</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV100.qrc">
+ <FileType>Document</FileType>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">QtProjectV100.qrc;C:\lib\Qt\5.15.10\msvc2019_64\bin\rcc.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\lib\Qt\5.15.10\msvc2019_64\bin\rcc.exe -name QtProjectV100 QtProjectV100.qrc -o release\qrc_QtProjectV100.cpp</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">RCC QtProjectV100.qrc</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\qrc_QtProjectV100.cpp;%(Outputs)</Outputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">QtProjectV100.qrc;C:\lib\Qt\5.15.10\msvc2019_64\bin\rcc.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\lib\Qt\5.15.10\msvc2019_64\bin\rcc.exe -name QtProjectV100 QtProjectV100.qrc -o debug\qrc_QtProjectV100.cpp</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">RCC QtProjectV100.qrc</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\qrc_QtProjectV100.cpp;%(Outputs)</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets" />
+</Project>
\ No newline at end of file
diff --git a/Tests/ProjectFormats/100/QtProjectV100.vcxproj.filters b/Tests/ProjectFormats/100/QtProjectV100.vcxproj.filters
new file mode 100644
index 0000000..0c6827d
--- /dev/null
+++ b/Tests/ProjectFormats/100/QtProjectV100.vcxproj.filters
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Form Files">
+ <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+ <Extensions>ui</Extensions>
+ <ParseFiles>false</ParseFiles>
+ </Filter>
+ <Filter Include="Form Files">
+ <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+ <Extensions>ui</Extensions>
+ <ParseFiles>false</ParseFiles>
+ </Filter>
+ <Filter Include="Generated Files">
+ <UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
+ </Filter>
+ <Filter Include="Generated Files">
+ <UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
+ <Extensions>qrc;*</Extensions>
+ <ParseFiles>false</ParseFiles>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
+ <Extensions>qrc;*</Extensions>
+ <ParseFiles>false</ParseFiles>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="QtProjectV100.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV100.h">
+ <Filter>Header Files</Filter>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="debug\moc_QtProjectV100.cpp">
+ <Filter>Generated Files</Filter>
+ </ClCompile>
+ <ClCompile Include="release\moc_QtProjectV100.cpp">
+ <Filter>Generated Files</Filter>
+ </ClCompile>
+ <CustomBuild Include="debug\moc_predefs.h.cbt">
+ <Filter>Generated Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="release\moc_predefs.h.cbt">
+ <Filter>Generated Files</Filter>
+ </CustomBuild>
+ <ClCompile Include="debug\qrc_QtProjectV100.cpp">
+ <Filter>Generated Files</Filter>
+ </ClCompile>
+ <ClCompile Include="release\qrc_QtProjectV100.cpp">
+ <Filter>Generated Files</Filter>
+ </ClCompile>
+ <ClInclude Include="ui_QtProjectV100.h">
+ <Filter>Generated Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV100.ui">
+ <Filter>Form Files</Filter>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV100.qrc">
+ <Filter>Resource Files</Filter>
+ </CustomBuild>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/ProjectFormats/100/main.cpp b/Tests/ProjectFormats/100/main.cpp
new file mode 100644
index 0000000..1c6e872
--- /dev/null
+++ b/Tests/ProjectFormats/100/main.cpp
@@ -0,0 +1,10 @@
+#include "QtProjectV100.h"
+#include <QtWidgets/QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ QtProjectV100 w;
+ w.show();
+ return a.exec();
+}
diff --git a/Tests/ProjectFormats/200/QtProjectV200.cpp b/Tests/ProjectFormats/200/QtProjectV200.cpp
new file mode 100644
index 0000000..9247eb2
--- /dev/null
+++ b/Tests/ProjectFormats/200/QtProjectV200.cpp
@@ -0,0 +1,7 @@
+#include "QtProjectV200.h"
+
+QtProjectV200::QtProjectV200(QWidget *parent)
+ : QMainWindow(parent)
+{
+ ui.setupUi(this);
+}
diff --git a/Tests/ProjectFormats/200/QtProjectV200.h b/Tests/ProjectFormats/200/QtProjectV200.h
new file mode 100644
index 0000000..dc1b953
--- /dev/null
+++ b/Tests/ProjectFormats/200/QtProjectV200.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <QtWidgets/QMainWindow>
+#include "ui_QtProjectV200.h"
+
+class QtProjectV200 : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ QtProjectV200(QWidget *parent = Q_NULLPTR);
+
+private:
+ Ui::QtProjectV200Class ui;
+};
diff --git a/Tests/ProjectFormats/200/QtProjectV200.qrc b/Tests/ProjectFormats/200/QtProjectV200.qrc
new file mode 100644
index 0000000..f5921b2
--- /dev/null
+++ b/Tests/ProjectFormats/200/QtProjectV200.qrc
@@ -0,0 +1,4 @@
+<RCC>
+ <qresource prefix="QtProjectV200">
+ </qresource>
+</RCC>
diff --git a/Tests/ProjectFormats/200/QtProjectV200.sln b/Tests/ProjectFormats/200/QtProjectV200.sln
new file mode 100644
index 0000000..32e1cd1
--- /dev/null
+++ b/Tests/ProjectFormats/200/QtProjectV200.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QtProjectV200", "QtProjectV200.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|x64
+ {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.Build.0 = Debug|x64
+ {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|x64
+ {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Tests/ProjectFormats/200/QtProjectV200.ui b/Tests/ProjectFormats/200/QtProjectV200.ui
new file mode 100644
index 0000000..8eed476
--- /dev/null
+++ b/Tests/ProjectFormats/200/QtProjectV200.ui
@@ -0,0 +1,29 @@
+<UI version="4.0" >
+ <class>QtProjectV200Class</class>
+ <widget class="QMainWindow" name="QtProjectV200Class" >
+ <property name="objectName" >
+ <string notr="true">QtProjectV200Class</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>QtProjectV200</string>
+ </property>
+ <widget class="QMenuBar" name="menuBar" />
+ <widget class="QToolBar" name="mainToolBar" />
+ <widget class="QWidget" name="centralWidget" />
+ <widget class="QStatusBar" name="statusBar" />
+ </widget>
+ <layoutDefault spacing="6" margin="11" />
+ <pixmapfunction></pixmapfunction>
+ <resources>
+ <include location="QtProjectV200.qrc"/>
+ </resources>
+ <connections/>
+</UI>
diff --git a/Tests/ProjectFormats/200/QtProjectV200.vcxproj b/Tests/ProjectFormats/200/QtProjectV200.vcxproj
new file mode 100644
index 0000000..1b4d671
--- /dev/null
+++ b/Tests/ProjectFormats/200/QtProjectV200.vcxproj
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{B12702AD-ABFB-343A-A199-8E24837244A3}</ProjectGuid>
+ <Keyword>Qt4VSv1.0</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <Optimization>Disabled</Optimization>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
+ <AdditionalLibraryDirectories>$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat />
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
+ <AdditionalLibraryDirectories>$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <AdditionalDependencies>qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="GeneratedFiles\Debug\moc_QtProjectV200.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="GeneratedFiles\qrc_QtProjectV200.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ </PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ </PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="GeneratedFiles\Release\moc_QtProjectV200.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="QtProjectV200.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV200.h">
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing QtProjectV200.h...</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets"</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing QtProjectV200.h...</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets"</Command>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV200.ui">
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Uic%27ing %(Identity)...</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Uic%27ing %(Identity)...</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="GeneratedFiles\ui_QtProjectV200.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV200.qrc">
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(FullPath);%(AdditionalInputs)</AdditionalInputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Rcc%27ing %(Identity)...</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(FullPath);%(AdditionalInputs)</AdditionalInputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Rcc%27ing %(Identity)...</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
+ </CustomBuild>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+ <ProjectExtensions>
+ <VisualStudio>
+ <UserProperties MocDir=".\GeneratedFiles\$(ConfigurationName)" UicDir=".\GeneratedFiles" RccDir=".\GeneratedFiles" lupdateOptions="" lupdateOnBuild="0" lreleaseOptions="" Qt5Version_x0020_x64="msvc2019_64" MocOptions="" />
+ </VisualStudio>
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/Tests/ProjectFormats/200/QtProjectV200.vcxproj.filters b/Tests/ProjectFormats/200/QtProjectV200.vcxproj.filters
new file mode 100644
index 0000000..81ea645
--- /dev/null
+++ b/Tests/ProjectFormats/200/QtProjectV200.vcxproj.filters
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
+ <Extensions>qrc;*</Extensions>
+ <ParseFiles>false</ParseFiles>
+ </Filter>
+ <Filter Include="Form Files">
+ <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+ <Extensions>ui</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
+ <Extensions>qrc;*</Extensions>
+ <ParseFiles>false</ParseFiles>
+ </Filter>
+ <Filter Include="Generated Files">
+ <UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
+ <Extensions>moc;h;cpp</Extensions>
+ <SourceControlFiles>False</SourceControlFiles>
+ </Filter>
+ <Filter Include="Generated Files\Debug">
+ <UniqueIdentifier>{61dba4ef-747b-4196-a5ef-706b88f740b6}</UniqueIdentifier>
+ <Extensions>cpp;moc</Extensions>
+ <SourceControlFiles>False</SourceControlFiles>
+ </Filter>
+ <Filter Include="Generated Files\Release">
+ <UniqueIdentifier>{52c84570-5db2-40f2-bcf4-841a0b66e6ee}</UniqueIdentifier>
+ <Extensions>cpp;moc</Extensions>
+ <SourceControlFiles>False</SourceControlFiles>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="QtProjectV200.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="GeneratedFiles\Debug\moc_QtProjectV200.cpp">
+ <Filter>Generated Files\Debug</Filter>
+ </ClCompile>
+ <ClCompile Include="GeneratedFiles\Release\moc_QtProjectV200.cpp">
+ <Filter>Generated Files\Release</Filter>
+ </ClCompile>
+ <ClCompile Include="GeneratedFiles\qrc_QtProjectV200.cpp">
+ <Filter>Generated Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV200.h">
+ <Filter>Header Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="QtProjectV200.ui">
+ <Filter>Form Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="QtProjectV200.qrc">
+ <Filter>Resource Files</Filter>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="GeneratedFiles\ui_QtProjectV200.h">
+ <Filter>Generated Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/ProjectFormats/200/main.cpp b/Tests/ProjectFormats/200/main.cpp
new file mode 100644
index 0000000..a033029
--- /dev/null
+++ b/Tests/ProjectFormats/200/main.cpp
@@ -0,0 +1,10 @@
+#include "QtProjectV200.h"
+#include <QtWidgets/QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ QtProjectV200 w;
+ w.show();
+ return a.exec();
+}
diff --git a/Tests/ProjectFormats/300/QtProjectV300.cpp b/Tests/ProjectFormats/300/QtProjectV300.cpp
new file mode 100644
index 0000000..f896a7a
--- /dev/null
+++ b/Tests/ProjectFormats/300/QtProjectV300.cpp
@@ -0,0 +1,7 @@
+#include "QtProjectV300.h"
+
+QtProjectV300::QtProjectV300(QWidget *parent)
+ : QMainWindow(parent)
+{
+ ui.setupUi(this);
+}
diff --git a/Tests/ProjectFormats/300/QtProjectV300.h b/Tests/ProjectFormats/300/QtProjectV300.h
new file mode 100644
index 0000000..ceb967c
--- /dev/null
+++ b/Tests/ProjectFormats/300/QtProjectV300.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <QtWidgets/QMainWindow>
+#include "ui_QtProjectV300.h"
+
+class QtProjectV300 : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ QtProjectV300(QWidget *parent = Q_NULLPTR);
+
+private:
+ Ui::QtProjectV300Class ui;
+};
diff --git a/Tests/ProjectFormats/300/QtProjectV300.qrc b/Tests/ProjectFormats/300/QtProjectV300.qrc
new file mode 100644
index 0000000..505a26b
--- /dev/null
+++ b/Tests/ProjectFormats/300/QtProjectV300.qrc
@@ -0,0 +1,4 @@
+<RCC>
+ <qresource prefix="QtProjectV300">
+ </qresource>
+</RCC>
diff --git a/Tests/ProjectFormats/300/QtProjectV300.sln b/Tests/ProjectFormats/300/QtProjectV300.sln
new file mode 100644
index 0000000..d48f3dd
--- /dev/null
+++ b/Tests/ProjectFormats/300/QtProjectV300.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32106.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QtProjectV300", "QtProjectV300.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|x64
+ {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.Build.0 = Debug|x64
+ {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|x64
+ {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {862404ED-03D5-41D1-B5BB-72FD8BD05038}
+ EndGlobalSection
+EndGlobal
diff --git a/Tests/ProjectFormats/300/QtProjectV300.ui b/Tests/ProjectFormats/300/QtProjectV300.ui
new file mode 100644
index 0000000..74ffe53
--- /dev/null
+++ b/Tests/ProjectFormats/300/QtProjectV300.ui
@@ -0,0 +1,29 @@
+<UI version="4.0" >
+ <class>QtProjectV300Class</class>
+ <widget class="QMainWindow" name="QtProjectV300Class" >
+ <property name="objectName" >
+ <string notr="true">QtProjectV300Class</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>QtProjectV300</string>
+ </property>
+ <widget class="QMenuBar" name="menuBar" />
+ <widget class="QToolBar" name="mainToolBar" />
+ <widget class="QWidget" name="centralWidget" />
+ <widget class="QStatusBar" name="statusBar" />
+ </widget>
+ <layoutDefault spacing="6" margin="11" />
+ <pixmapfunction></pixmapfunction>
+ <resources>
+ <include location="QtProjectV300.qrc"/>
+ </resources>
+ <connections/>
+</UI>
diff --git a/Tests/ProjectFormats/300/QtProjectV300.vcxproj b/Tests/ProjectFormats/300/QtProjectV300.vcxproj
new file mode 100644
index 0000000..276f090
--- /dev/null
+++ b/Tests/ProjectFormats/300/QtProjectV300.vcxproj
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{B12702AD-ABFB-343A-A199-8E24837244A3}</ProjectGuid>
+ <Keyword>QtVS_v300</Keyword>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <QtInstall>msvc2019_64</QtInstall>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <QtInstall>msvc2019_64</QtInstall>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">
+ <QtMsBuild>$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+ <Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+ </Target>
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
+ <Import Project="$(QtMsBuild)\qt.props" />
+ </ImportGroup>
+ <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <QtModules>core;gui;widgets</QtModules>
+ </PropertyGroup>
+ <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <QtModules>core;gui;widgets</QtModules>
+ </PropertyGroup>
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <Optimization>Disabled</Optimization>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat />
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="QtProjectV300.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtMoc Include="QtProjectV300.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtUic Include="QtProjectV300.ui" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV300.qrc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+ <Import Project="$(QtMsBuild)\qt.targets" />
+ </ImportGroup>
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/ProjectFormats/300/QtProjectV300.vcxproj.filters b/Tests/ProjectFormats/300/QtProjectV300.vcxproj.filters
new file mode 100644
index 0000000..8c77244
--- /dev/null
+++ b/Tests/ProjectFormats/300/QtProjectV300.vcxproj.filters
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
+ <Extensions>qrc;*</Extensions>
+ <ParseFiles>false</ParseFiles>
+ </Filter>
+ <Filter Include="Form Files">
+ <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+ <Extensions>ui</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
+ <Extensions>qrc;*</Extensions>
+ <ParseFiles>false</ParseFiles>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="QtProjectV300.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <QtMoc Include="QtProjectV300.h">
+ <Filter>Header Files</Filter>
+ </QtMoc>
+ </ItemGroup>
+ <ItemGroup>
+ <QtUic Include="QtProjectV300.ui">
+ <Filter>Form Files</Filter>
+ </QtUic>
+ </ItemGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV300.qrc">
+ <Filter>Resource Files</Filter>
+ </QtRcc>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/ProjectFormats/300/main.cpp b/Tests/ProjectFormats/300/main.cpp
new file mode 100644
index 0000000..48ff587
--- /dev/null
+++ b/Tests/ProjectFormats/300/main.cpp
@@ -0,0 +1,10 @@
+#include "QtProjectV300.h"
+#include <QtWidgets/QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ QtProjectV300 w;
+ w.show();
+ return a.exec();
+}
diff --git a/Tests/ProjectFormats/301/QtProjectV301.cpp b/Tests/ProjectFormats/301/QtProjectV301.cpp
new file mode 100644
index 0000000..7a1e8ea
--- /dev/null
+++ b/Tests/ProjectFormats/301/QtProjectV301.cpp
@@ -0,0 +1,7 @@
+#include "QtProjectV301.h"
+
+QtProjectV301::QtProjectV301(QWidget *parent)
+ : QMainWindow(parent)
+{
+ ui.setupUi(this);
+}
diff --git a/Tests/ProjectFormats/301/QtProjectV301.h b/Tests/ProjectFormats/301/QtProjectV301.h
new file mode 100644
index 0000000..bfe8d95
--- /dev/null
+++ b/Tests/ProjectFormats/301/QtProjectV301.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <QtWidgets/QMainWindow>
+#include "ui_QtProjectV301.h"
+
+class QtProjectV301 : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ QtProjectV301(QWidget *parent = Q_NULLPTR);
+
+private:
+ Ui::QtProjectV301Class ui;
+};
diff --git a/Tests/ProjectFormats/301/QtProjectV301.qrc b/Tests/ProjectFormats/301/QtProjectV301.qrc
new file mode 100644
index 0000000..3c3a0f3
--- /dev/null
+++ b/Tests/ProjectFormats/301/QtProjectV301.qrc
@@ -0,0 +1,4 @@
+<RCC>
+ <qresource prefix="QtProjectV301">
+ </qresource>
+</RCC>
diff --git a/Tests/ProjectFormats/301/QtProjectV301.sln b/Tests/ProjectFormats/301/QtProjectV301.sln
new file mode 100644
index 0000000..909bab4
--- /dev/null
+++ b/Tests/ProjectFormats/301/QtProjectV301.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32106.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QtProjectV301", "QtProjectV301.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|x64
+ {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.Build.0 = Debug|x64
+ {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|x64
+ {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {AD220BEA-2E4C-4346-9387-E61F9D9E6181}
+ EndGlobalSection
+EndGlobal
diff --git a/Tests/ProjectFormats/301/QtProjectV301.ui b/Tests/ProjectFormats/301/QtProjectV301.ui
new file mode 100644
index 0000000..c25f457
--- /dev/null
+++ b/Tests/ProjectFormats/301/QtProjectV301.ui
@@ -0,0 +1,29 @@
+<UI version="4.0" >
+ <class>QtProjectV301Class</class>
+ <widget class="QMainWindow" name="QtProjectV301Class" >
+ <property name="objectName" >
+ <string notr="true">QtProjectV301Class</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>QtProjectV301</string>
+ </property>
+ <widget class="QMenuBar" name="menuBar" />
+ <widget class="QToolBar" name="mainToolBar" />
+ <widget class="QWidget" name="centralWidget" />
+ <widget class="QStatusBar" name="statusBar" />
+ </widget>
+ <layoutDefault spacing="6" margin="11" />
+ <pixmapfunction></pixmapfunction>
+ <resources>
+ <include location="QtProjectV301.qrc"/>
+ </resources>
+ <connections/>
+</UI>
diff --git a/Tests/ProjectFormats/301/QtProjectV301.vcxproj b/Tests/ProjectFormats/301/QtProjectV301.vcxproj
new file mode 100644
index 0000000..78b4aa7
--- /dev/null
+++ b/Tests/ProjectFormats/301/QtProjectV301.vcxproj
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{B12702AD-ABFB-343A-A199-8E24837244A3}</ProjectGuid>
+ <Keyword>QtVS_v301</Keyword>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">
+ <QtMsBuild>$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+ <Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+ </Target>
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
+ <Import Project="$(QtMsBuild)\qt_defaults.props" />
+ </ImportGroup>
+ <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <QtInstall>msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ </PropertyGroup>
+ <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <QtInstall>msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ </PropertyGroup>
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
+ <Import Project="$(QtMsBuild)\qt.props" />
+ </ImportGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <Optimization>Disabled</Optimization>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat />
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="QtProjectV301.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtMoc Include="QtProjectV301.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtUic Include="QtProjectV301.ui" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV301.qrc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+ <Import Project="$(QtMsBuild)\qt.targets" />
+ </ImportGroup>
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/ProjectFormats/301/QtProjectV301.vcxproj.filters b/Tests/ProjectFormats/301/QtProjectV301.vcxproj.filters
new file mode 100644
index 0000000..62f11c2
--- /dev/null
+++ b/Tests/ProjectFormats/301/QtProjectV301.vcxproj.filters
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
+ <Extensions>qrc;*</Extensions>
+ <ParseFiles>false</ParseFiles>
+ </Filter>
+ <Filter Include="Form Files">
+ <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+ <Extensions>ui</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
+ <Extensions>qrc;*</Extensions>
+ <ParseFiles>false</ParseFiles>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="QtProjectV301.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <QtMoc Include="QtProjectV301.h">
+ <Filter>Header Files</Filter>
+ </QtMoc>
+ </ItemGroup>
+ <ItemGroup>
+ <QtUic Include="QtProjectV301.ui">
+ <Filter>Form Files</Filter>
+ </QtUic>
+ </ItemGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV301.qrc">
+ <Filter>Resource Files</Filter>
+ </QtRcc>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/ProjectFormats/301/main.cpp b/Tests/ProjectFormats/301/main.cpp
new file mode 100644
index 0000000..f12d171
--- /dev/null
+++ b/Tests/ProjectFormats/301/main.cpp
@@ -0,0 +1,10 @@
+#include "QtProjectV301.h"
+#include <QtWidgets/QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ QtProjectV301 w;
+ w.show();
+ return a.exec();
+}
diff --git a/Tests/ProjectFormats/302/QtProjectV302.cpp b/Tests/ProjectFormats/302/QtProjectV302.cpp
new file mode 100644
index 0000000..a7d523a
--- /dev/null
+++ b/Tests/ProjectFormats/302/QtProjectV302.cpp
@@ -0,0 +1,7 @@
+#include "QtProjectV302.h"
+
+QtProjectV302::QtProjectV302(QWidget *parent)
+ : QMainWindow(parent)
+{
+ ui.setupUi(this);
+}
diff --git a/Tests/ProjectFormats/302/QtProjectV302.h b/Tests/ProjectFormats/302/QtProjectV302.h
new file mode 100644
index 0000000..3cef345
--- /dev/null
+++ b/Tests/ProjectFormats/302/QtProjectV302.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <QtWidgets/QMainWindow>
+#include "ui_QtProjectV302.h"
+
+class QtProjectV302 : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ QtProjectV302(QWidget *parent = Q_NULLPTR);
+
+private:
+ Ui::QtProjectV302Class ui;
+};
diff --git a/Tests/ProjectFormats/302/QtProjectV302.qrc b/Tests/ProjectFormats/302/QtProjectV302.qrc
new file mode 100644
index 0000000..de388f6
--- /dev/null
+++ b/Tests/ProjectFormats/302/QtProjectV302.qrc
@@ -0,0 +1,4 @@
+<RCC>
+ <qresource prefix="QtProjectV302">
+ </qresource>
+</RCC>
diff --git a/Tests/ProjectFormats/302/QtProjectV302.sln b/Tests/ProjectFormats/302/QtProjectV302.sln
new file mode 100644
index 0000000..5cc4823
--- /dev/null
+++ b/Tests/ProjectFormats/302/QtProjectV302.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32106.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QtProjectV302", "QtProjectV302.vcxproj", "{10A7CC05-6663-4C63-906F-E56EDF8218CA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {10A7CC05-6663-4C63-906F-E56EDF8218CA}.Debug|x64.ActiveCfg = Debug|x64
+ {10A7CC05-6663-4C63-906F-E56EDF8218CA}.Debug|x64.Build.0 = Debug|x64
+ {10A7CC05-6663-4C63-906F-E56EDF8218CA}.Release|x64.ActiveCfg = Release|x64
+ {10A7CC05-6663-4C63-906F-E56EDF8218CA}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {4FB5DF86-4C19-4C53-B0CC-EAA09A44D321}
+ EndGlobalSection
+EndGlobal
diff --git a/Tests/ProjectFormats/302/QtProjectV302.ui b/Tests/ProjectFormats/302/QtProjectV302.ui
new file mode 100644
index 0000000..4e0ff07
--- /dev/null
+++ b/Tests/ProjectFormats/302/QtProjectV302.ui
@@ -0,0 +1,28 @@
+<UI version="4.0" >
+ <class>QtProjectV302Class</class>
+ <widget class="QMainWindow" name="QtProjectV302Class" >
+ <property name="objectName" >
+ <string notr="true">QtProjectV302Class</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>QtProjectV302</string>
+ </property> <widget class="QMenuBar" name="menuBar" />
+ <widget class="QToolBar" name="mainToolBar" />
+ <widget class="QWidget" name="centralWidget" />
+ <widget class="QStatusBar" name="statusBar" />
+ </widget>
+ <layoutDefault spacing="6" margin="11" />
+ <pixmapfunction></pixmapfunction>
+ <resources>
+ <include location="QtProjectV302.qrc"/>
+ </resources>
+ <connections/>
+</UI>
diff --git a/Tests/ProjectFormats/302/QtProjectV302.vcxproj b/Tests/ProjectFormats/302/QtProjectV302.vcxproj
new file mode 100644
index 0000000..05b8241
--- /dev/null
+++ b/Tests/ProjectFormats/302/QtProjectV302.vcxproj
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{10A7CC05-6663-4C63-906F-E56EDF8218CA}</ProjectGuid>
+ <Keyword>QtVS_v302</Keyword>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
+ <QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')"
+ >$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <Target Name="QtMsBuildNotFound"
+ BeforeTargets="CustomBuild;ClCompile"
+ Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+ <Message Importance="High"
+ Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+ </Target>
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
+ <Import Project="$(QtMsBuild)\qt_defaults.props" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
+ <QtInstall>msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ <QtBuildConfig>debug</QtBuildConfig>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
+ <QtInstall>msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ <QtBuildConfig>release</QtBuildConfig>
+ </PropertyGroup>
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
+ <Import Project="$(QtMsBuild)\qt.props" />
+ </ImportGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <Optimization>MaxSpeed</Optimization>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV302.qrc"/>
+ <QtUic Include="QtProjectV302.ui"/>
+ <QtMoc Include="QtProjectV302.h"/>
+ <ClCompile Include="QtProjectV302.cpp"/>
+ <ClCompile Include="main.cpp"/>
+
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+ <Import Project="$(QtMsBuild)\qt.targets" />
+ </ImportGroup>
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/ProjectFormats/302/QtProjectV302.vcxproj.filters b/Tests/ProjectFormats/302/QtProjectV302.vcxproj.filters
new file mode 100644
index 0000000..c68f29a
--- /dev/null
+++ b/Tests/ProjectFormats/302/QtProjectV302.vcxproj.filters
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="Form Files">
+ <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+ <Extensions>ui</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
+ <Extensions>qrc;*</Extensions>
+ <ParseFiles>false</ParseFiles>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <QtUic Include="QtProjectV302.ui">
+ <Filter>Resource Files</Filter>
+ </QtUic>
+ <QtMoc Include="QtProjectV302.h">
+ <Filter>Header Files</Filter>
+ </QtMoc>
+ <ClCompile Include="QtProjectV302.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ResourceCompile Include="$pro_name$.rc">
+ </ResourceCompile>
+ <None Include="$pro_name$.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="$pro_name$.def">
+ <Filter>Resource Files</Filter>
+ </None>
+
+ </ItemGroup>
+</Project>
diff --git a/Tests/ProjectFormats/302/main.cpp b/Tests/ProjectFormats/302/main.cpp
new file mode 100644
index 0000000..aa6a9e2
--- /dev/null
+++ b/Tests/ProjectFormats/302/main.cpp
@@ -0,0 +1,10 @@
+#include "QtProjectV302.h"
+#include <QtWidgets/QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ QtProjectV302 w;
+ w.show();
+ return a.exec();
+}
diff --git a/Tests/ProjectFormats/303/QtProjectV303.cpp b/Tests/ProjectFormats/303/QtProjectV303.cpp
new file mode 100644
index 0000000..9c2b3ff
--- /dev/null
+++ b/Tests/ProjectFormats/303/QtProjectV303.cpp
@@ -0,0 +1,7 @@
+#include "QtProjectV303.h"
+
+QtProjectV303::QtProjectV303(QWidget *parent)
+ : QMainWindow(parent)
+{
+ ui.setupUi(this);
+}
diff --git a/Tests/ProjectFormats/303/QtProjectV303.h b/Tests/ProjectFormats/303/QtProjectV303.h
new file mode 100644
index 0000000..777c5fd
--- /dev/null
+++ b/Tests/ProjectFormats/303/QtProjectV303.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <QtWidgets/QMainWindow>
+#include "ui_QtProjectV303.h"
+
+class QtProjectV303 : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ QtProjectV303(QWidget *parent = Q_NULLPTR);
+
+private:
+ Ui::QtProjectV303Class ui;
+};
diff --git a/Tests/ProjectFormats/303/QtProjectV303.qrc b/Tests/ProjectFormats/303/QtProjectV303.qrc
new file mode 100644
index 0000000..7af7692
--- /dev/null
+++ b/Tests/ProjectFormats/303/QtProjectV303.qrc
@@ -0,0 +1,4 @@
+<RCC>
+ <qresource prefix="QtProjectV303">
+ </qresource>
+</RCC>
diff --git a/Tests/ProjectFormats/303/QtProjectV303.sln b/Tests/ProjectFormats/303/QtProjectV303.sln
new file mode 100644
index 0000000..641c2a5
--- /dev/null
+++ b/Tests/ProjectFormats/303/QtProjectV303.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32106.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QtProjectV303", "QtProjectV303.vcxproj", "{812E4050-B861-4918-A0DC-53053B848372}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {812E4050-B861-4918-A0DC-53053B848372}.Debug|x64.ActiveCfg = Debug|x64
+ {812E4050-B861-4918-A0DC-53053B848372}.Debug|x64.Build.0 = Debug|x64
+ {812E4050-B861-4918-A0DC-53053B848372}.Release|x64.ActiveCfg = Release|x64
+ {812E4050-B861-4918-A0DC-53053B848372}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {7F50220B-20CF-415F-80A5-DA078F8F82BF}
+ EndGlobalSection
+EndGlobal
diff --git a/Tests/ProjectFormats/303/QtProjectV303.ui b/Tests/ProjectFormats/303/QtProjectV303.ui
new file mode 100644
index 0000000..8295da9
--- /dev/null
+++ b/Tests/ProjectFormats/303/QtProjectV303.ui
@@ -0,0 +1,28 @@
+<UI version="4.0" >
+ <class>QtProjectV303Class</class>
+ <widget class="QMainWindow" name="QtProjectV303Class" >
+ <property name="objectName" >
+ <string notr="true">QtProjectV303Class</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>QtProjectV303</string>
+ </property> <widget class="QMenuBar" name="menuBar" />
+ <widget class="QToolBar" name="mainToolBar" />
+ <widget class="QWidget" name="centralWidget" />
+ <widget class="QStatusBar" name="statusBar" />
+ </widget>
+ <layoutDefault spacing="6" margin="11" />
+ <pixmapfunction></pixmapfunction>
+ <resources>
+ <include location="QtProjectV303.qrc"/>
+ </resources>
+ <connections/>
+</UI>
diff --git a/Tests/ProjectFormats/303/QtProjectV303.vcxproj b/Tests/ProjectFormats/303/QtProjectV303.vcxproj
new file mode 100644
index 0000000..9c3febf
--- /dev/null
+++ b/Tests/ProjectFormats/303/QtProjectV303.vcxproj
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{812E4050-B861-4918-A0DC-53053B848372}</ProjectGuid>
+ <Keyword>QtVS_v303</Keyword>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
+ <QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')"
+ >$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <Target Name="QtMsBuildNotFound"
+ BeforeTargets="CustomBuild;ClCompile"
+ Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+ <Message Importance="High"
+ Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+ </Target>
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
+ <Import Project="$(QtMsBuild)\qt_defaults.props" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
+ <QtInstall>msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ <QtBuildConfig>debug</QtBuildConfig>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
+ <QtInstall>msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ <QtBuildConfig>release</QtBuildConfig>
+ </PropertyGroup>
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
+ <Import Project="$(QtMsBuild)\qt.props" />
+ </ImportGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <Optimization>MaxSpeed</Optimization>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV303.qrc"/>
+ <QtUic Include="QtProjectV303.ui"/>
+ <QtMoc Include="QtProjectV303.h"/>
+ <ClCompile Include="QtProjectV303.cpp"/>
+ <ClCompile Include="main.cpp"/>
+
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+ <Import Project="$(QtMsBuild)\qt.targets" />
+ </ImportGroup>
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/ProjectFormats/303/QtProjectV303.vcxproj.filters b/Tests/ProjectFormats/303/QtProjectV303.vcxproj.filters
new file mode 100644
index 0000000..ebb32d8
--- /dev/null
+++ b/Tests/ProjectFormats/303/QtProjectV303.vcxproj.filters
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="Form Files">
+ <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+ <Extensions>ui</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
+ <Extensions>qrc;*</Extensions>
+ <ParseFiles>false</ParseFiles>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV303.qrc">
+ <Filter>Resource Files</Filter>
+ </QtRcc>
+ <QtUic Include="QtProjectV303.ui">
+ <Filter>Resource Files</Filter>
+ </QtUic>
+ <QtMoc Include="QtProjectV303.h">
+ <Filter>Header Files</Filter>
+ </QtMoc>
+ <ClCompile Include="QtProjectV303.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ResourceCompile Include="$pro_name$.rc">
+ </ResourceCompile>
+ <None Include="$pro_name$.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="$pro_name$.def">
+ <Filter>Resource Files</Filter>
+ </None>
+
+ </ItemGroup>
+</Project>
diff --git a/Tests/ProjectFormats/303/main.cpp b/Tests/ProjectFormats/303/main.cpp
new file mode 100644
index 0000000..7d8e068
--- /dev/null
+++ b/Tests/ProjectFormats/303/main.cpp
@@ -0,0 +1,10 @@
+#include "QtProjectV303.h"
+#include <QtWidgets/QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ QtProjectV303 w;
+ w.show();
+ return a.exec();
+}
diff --git a/Tests/ProjectFormats/304/QtProjectV304.cpp b/Tests/ProjectFormats/304/QtProjectV304.cpp
new file mode 100644
index 0000000..5f32d67
--- /dev/null
+++ b/Tests/ProjectFormats/304/QtProjectV304.cpp
@@ -0,0 +1,10 @@
+#include "QtProjectV304.h"
+
+QtProjectV304::QtProjectV304(QWidget *parent)
+ : QMainWindow(parent)
+{
+ ui.setupUi(this);
+}
+
+QtProjectV304::~QtProjectV304()
+{}
diff --git a/Tests/ProjectFormats/304/QtProjectV304.h b/Tests/ProjectFormats/304/QtProjectV304.h
new file mode 100644
index 0000000..ecd09cd
--- /dev/null
+++ b/Tests/ProjectFormats/304/QtProjectV304.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <QtWidgets/QMainWindow>
+#include "ui_QtProjectV304.h"
+
+class QtProjectV304 : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ QtProjectV304(QWidget *parent = nullptr);
+ ~QtProjectV304();
+
+private:
+ Ui::QtProjectV304Class ui;
+};
diff --git a/Tests/ProjectFormats/304/QtProjectV304.qrc b/Tests/ProjectFormats/304/QtProjectV304.qrc
new file mode 100644
index 0000000..3466c73
--- /dev/null
+++ b/Tests/ProjectFormats/304/QtProjectV304.qrc
@@ -0,0 +1,4 @@
+<RCC>
+ <qresource prefix="QtProjectV304">
+ </qresource>
+</RCC>
diff --git a/Tests/ProjectFormats/304/QtProjectV304.sln b/Tests/ProjectFormats/304/QtProjectV304.sln
new file mode 100644
index 0000000..3ebf58a
--- /dev/null
+++ b/Tests/ProjectFormats/304/QtProjectV304.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31919.166
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QtProjectV304", "QtProjectV304.vcxproj", "{923588D5-2AA5-4B0F-8110-56BEEBB531D5}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {923588D5-2AA5-4B0F-8110-56BEEBB531D5}.Debug|x64.ActiveCfg = Debug|x64
+ {923588D5-2AA5-4B0F-8110-56BEEBB531D5}.Debug|x64.Build.0 = Debug|x64
+ {923588D5-2AA5-4B0F-8110-56BEEBB531D5}.Release|x64.ActiveCfg = Release|x64
+ {923588D5-2AA5-4B0F-8110-56BEEBB531D5}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {AE3F49BF-2193-402A-AA0C-E77FF9B63160}
+ EndGlobalSection
+EndGlobal
diff --git a/Tests/ProjectFormats/304/QtProjectV304.ui b/Tests/ProjectFormats/304/QtProjectV304.ui
new file mode 100644
index 0000000..73f83d6
--- /dev/null
+++ b/Tests/ProjectFormats/304/QtProjectV304.ui
@@ -0,0 +1,28 @@
+<UI version="4.0" >
+ <class>QtProjectV304Class</class>
+ <widget class="QMainWindow" name="QtProjectV304Class" >
+ <property name="objectName" >
+ <string notr="true">QtProjectV304Class</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>QtProjectV304</string>
+ </property> <widget class="QMenuBar" name="menuBar" />
+ <widget class="QToolBar" name="mainToolBar" />
+ <widget class="QWidget" name="centralWidget" />
+ <widget class="QStatusBar" name="statusBar" />
+ </widget>
+ <layoutDefault spacing="6" margin="11" />
+ <pixmapfunction></pixmapfunction>
+ <resources>
+ <include location="QtProjectV304.qrc"/>
+ </resources>
+ <connections/>
+</UI>
diff --git a/Tests/ProjectFormats/304/QtProjectV304.vcxproj b/Tests/ProjectFormats/304/QtProjectV304.vcxproj
new file mode 100644
index 0000000..9c43ee5
--- /dev/null
+++ b/Tests/ProjectFormats/304/QtProjectV304.vcxproj
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{923588D5-2AA5-4B0F-8110-56BEEBB531D5}</ProjectGuid>
+ <Keyword>QtVS_v304</Keyword>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
+ <QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')"
+ >$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v143</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v143</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
+ <Import Project="$(QtMsBuild)\qt_defaults.props" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
+ <QtInstall>5.15.10_msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ <QtBuildConfig>debug</QtBuildConfig>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
+ <QtInstall>5.15.10_msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ <QtBuildConfig>release</QtBuildConfig>
+ </PropertyGroup>
+ <Target Name="QtMsBuildNotFound"
+ BeforeTargets="CustomBuild;ClCompile"
+ Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+ <Message Importance="High"
+ Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+ </Target>
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(QtMsBuild)\Qt.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(QtMsBuild)\Qt.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <Optimization>MaxSpeed</Optimization>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV304.qrc"/>
+ <QtUic Include="QtProjectV304.ui"/>
+ <QtMoc Include="QtProjectV304.h"/>
+ <ClCompile Include="QtProjectV304.cpp"/>
+ <ClCompile Include="main.cpp"/>
+
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+ <Import Project="$(QtMsBuild)\qt.targets" />
+ </ImportGroup>
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/Tests/ProjectFormats/304/QtProjectV304.vcxproj.filters b/Tests/ProjectFormats/304/QtProjectV304.vcxproj.filters
new file mode 100644
index 0000000..a001b10
--- /dev/null
+++ b/Tests/ProjectFormats/304/QtProjectV304.vcxproj.filters
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="Form Files">
+ <UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
+ <Extensions>ui</Extensions>
+ </Filter>
+ <Filter Include="Translation Files">
+ <UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
+ <Extensions>ts</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV304.qrc">
+ <Filter>Resource Files</Filter>
+ </QtRcc>
+ <QtUic Include="QtProjectV304.ui">
+ <Filter>Form Files</Filter>
+ </QtUic>
+ <QtMoc Include="QtProjectV304.h">
+ <Filter>Header Files</Filter>
+ </QtMoc>
+ <ClCompile Include="QtProjectV304.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ResourceCompile Include="$pro_name$.rc">
+ </ResourceCompile>
+ <None Include="$pro_name$.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="$pro_name$.def">
+ <Filter>Resource Files</Filter>
+ </None>
+
+ </ItemGroup>
+</Project>
diff --git a/Tests/ProjectFormats/304/main.cpp b/Tests/ProjectFormats/304/main.cpp
new file mode 100644
index 0000000..d448992
--- /dev/null
+++ b/Tests/ProjectFormats/304/main.cpp
@@ -0,0 +1,10 @@
+#include "QtProjectV304.h"
+#include <QtWidgets/QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ QtProjectV304 w;
+ w.show();
+ return a.exec();
+}
diff --git a/Tests/ProjectFormats/ProjectFormats.md b/Tests/ProjectFormats/ProjectFormats.md
new file mode 100644
index 0000000..5702dc4
--- /dev/null
+++ b/Tests/ProjectFormats/ProjectFormats.md
@@ -0,0 +1,1324 @@
+# Qt VS Tools - Project format versions
+
+## Contents
+
+* [Project format v1.0](#project-format-v1.0)
+* [Project format v2.0](#project-format-v2.0)
+* [Project format v3.0](#project-format-v3.0)
+* [Project format v3.1](#project-format-v3.1)
+* [Project format v3.2](#project-format-v3.2)
+* [Project format v3.3](#project-format-v3.3)
+* [Project format v3.4](#project-format-v3.4)
+* [Example projects](#example-projects)
+ * [v1.0](#v1.0)
+ * [v2.0](#v2.0)
+ * [v3.0](#v3.0)
+ * [v3.1](#v3.1)
+ * [v3.2](#v3.2)
+ * [v3.3](#v3.3)
+ * [v3.4](#v3.4)
+
+## Project format v1.0
+
+Output of `qmake` using the VC template:
+
+ qmake -tp vc
+
+### Project file outline
+
+- ItemGroup **ProjectConfiguration**
+- PropertyGroup **Globals**
+ - Keyword **Qt4VSv1.0**
+- Import **Microsoft.Cpp.Default.props**
+- PropertyGroup **Configuration**
+- Import **Microsoft.Cpp.props**
+- ImportGroup **ExtensionSettings**
+- ImportGroup **PropertySheets**
+- PropertyGroup **UserMacros**
+- PropertyGroup
+ - Property **OutDir**
+ - Property **IntDir**
+ - ...
+- ItemDefinitionGroup
+ - **ClCompile**
+ - **Link**
+ - ...
+- ItemGroup
+ - **CustomBuild** (*MOC header*)
+ - *N* x **ClCompile** (*MOC-generated CPP source*), where N = number of configurations
+ - (*N* - 1) x **ExcludedFromBuild** (*configuration*)
+ - **CustomBuild** (*QRC resources*)
+ - *N* x **ClCompile** (*RCC-generated CPP source*), where N = number of configurations
+ - (*N* - 1) x **ExcludedFromBuild** (*configuration*)
+ - **CustomBuild** (*UI form*)
+ - **ClInclude** (*UIC-generated header*)
+ - **ClInclude** (*other headers*)
+ - **ClCompile** (*other CPP sources*)
+ - ...
+- Import **Microsoft.Cpp.targets**
+- ImportGroup **ExtensionTargets**
+
+## Project format v2.0
+**[Qt Visual Studio Tools v2.1.1](https://download.qt.io/official_releases/vsaddin/2.1.1/)**
+
+### Project file outline
+
+- ItemGroup **ProjectConfiguration**
+- PropertyGroup **Globals**
+ - Keyword **Qt4VSv1.0**
+- Import **Microsoft.Cpp.Default.props**
+- PropertyGroup **Configuration**
+- Import **Microsoft.Cpp.props**
+- ImportGroup **ExtensionSettings**
+- ImportGroup **Shared**
+- ImportGroup **PropertySheets**
+- PropertyGroup **UserMacros**
+- PropertyGroup
+ - Property **OutDir**
+ - Property **IntDir**
+ - ...
+- ItemDefinitionGroup
+ - **ClCompile**
+ - **Link**
+ - ...
+- ItemGroup
+ - **CustomBuild** (*MOC header*)
+ - *N* x **ClCompile** (*MOC-generated CPP source*), where N = number of configurations
+ - (*N* - 1) x **ExcludedFromBuild** (*configuration*)
+ - **CustomBuild** (*QRC resources*)
+ - *N* x **ClCompile** (*RCC-generated CPP source*), where N = number of configurations
+ - (*N* - 1) x **ExcludedFromBuild** (*configuration*)
+ - **CustomBuild** (*UI form*)
+ - **ClInclude** (*UIC-generated header*)
+ - **ClInclude** (*other headers*)
+ - **ClCompile** (*other CPP sources*)
+ - ...
+- Import **Microsoft.Cpp.targets**
+- ImportGroup **ExtensionTargets**
+- ProjectExtensions / VisualStudio
+ - UserProperties
+ - **MocDir**
+ - **UicDir**
+ - **RccDir**
+ - **lupdateOptions**
+ - **lupdateOnBuild**
+ - **lreleaseOptions**
+ - **Qt5Version_x0020_x64**
+ - **MocOptions**
+
+## Project format v3.0
+**[Qt Visual Studio Tools v2.4.0](https://download.qt.io/official_releases/vsaddin/2.4.0/)**
+
+**`Edit Qt settings in property pages (V3 format)`**
+`commit 805e9ed6f14fb0a4d9dd8ce6a23631ca215b304a`
+`Author: Miguel Costa <miguel.costa@qt.io>`
+`Date: Thu Jun 20 13:54:49 2019 +0200`
+
+ Qt settings are now configured in the project property pages. This
+ includes the possibility to have different versions of the Qt settings
+ per project configuration. Previously, the Qt settings were edited in a
+ custom dialog, allowing only a single version of the settings that
+ would apply to all project configurations.
+
+ This change breaks the current version of the support for Qt VS Tools
+ projects. A new version (V3) of the project format is introduced. This
+ new format allows Qt settings to be stored in the same way as other
+ project properties. Previous versions will still work and a later change
+ will introduce the possibility to convert from previous versions to V3.
+
+### Project file outline
+
+- ItemGroup **ProjectConfiguration**
+- PropertyGroup **Globals**
+ - Keyword **QtVS_v300**
+- Import **Microsoft.Cpp.Default.props**
+- PropertyGroup **Configuration**
+- Import **Microsoft.Cpp.props**
+- PropertyGroup **if %QTMSBUILD% undefined**
+ - Property **QtMsBuild** = $(MSBuildProjectDirectory)\QtMsBuild
+- PropertyGroup
+ - Property **OutDir**
+ - Property **IntDir**
+ - ...
+- Target **QtMsBuildNotFound**
+- Import **qt.props**
+- PropertyGroup **QtSettings**
+- ImportGroup **ExtensionSettings**
+- ImportGroup **Shared**
+- ImportGroup **PropertySheets**
+- PropertyGroup **UserMacros**
+- ItemDefinitionGroup
+ - **ClCompile**
+ - **Link**
+ - **QtMoc**
+ - **QtRcc**
+ - **QtUic**
+ - ...
+- ItemGroup
+ - **QtMoc** (*MOC header*)
+ - **QtRcc** (*QRC resources*)
+ - **QtUic** (*UI form*)
+ - **ClInclude** (*other headers*)
+ - **ClCompile** (*other CPP sources*)
+ - ...
+- Import **Microsoft.Cpp.targets**
+- Import **qt.targets**
+- ImportGroup **ExtensionTargets**
+
+## Project format v3.1
+**[Qt Visual Studio Tools v2.4.2](https://download.qt.io/official_releases/vsaddin/2.4.2/)**
+
+**`Implement project format v3.1`**
+`commit fdbec35c590f524f6f9ce8f2e6a7328f2f3df508`
+`Author: Miguel Costa <miguel.costa@qt.io>`
+`Date: Wed Sep 18 18:47:30 2019 +0200`
+
+ This change introduces a revision of the v3 project format, which will
+ now allow Qt settings to reference user macros defined in imported
+ property sheets. This includes the following changes to the order of
+ property evaluation:
+ - "QtSettings" property group moved to after the import of user
+ property sheets;
+ - QtInstall property moved from the "Configuration" property group
+ to the "QtSettings" property group;
+ - Import of qt.props moved to after the "QtSettings" property group.
+
+### Project file outline
+
+- ItemGroup **ProjectConfiguration**
+- PropertyGroup **Globals**
+ - Keyword **QtVS_v301**
+- Import **Microsoft.Cpp.Default.props**
+- PropertyGroup **Configuration**
+ - Property **QtInstall**
+- Import **Microsoft.Cpp.props**
+- PropertyGroup (*if `%QTMSBUILD%` undefined*)
+ - Property **QtMsBuild** = $(MSBuildProjectDirectory)\QtMsBuild
+- PropertyGroup
+ - Property **OutDir**
+ - Property **IntDir**
+ - ...
+- Target **QtMsBuildNotFound**
+- ImportGroup **ExtensionSettings**
+- ImportGroup **Shared**
+- ImportGroup **PropertySheets**
+- PropertyGroup **UserMacros**
+- Import **qt.props**
+- PropertyGroup **QtSettings**
+- ItemDefinitionGroup
+ - **ClCompile**
+ - **Link**
+ - **QtMoc**
+ - **QtRcc**
+ - **QtUic**
+ - ...
+- ItemGroup
+ - **QtMoc** (*MOC header*)
+ - **QtRcc** (*QRC resources*)
+ - **QtUic** (*UI form*)
+ - **ClInclude** (*other headers*)
+ - **ClCompile** (*other CPP sources*)
+ - ...
+- Import **Microsoft.Cpp.targets**
+- Import **qt.targets**
+- ImportGroup **ExtensionTargets**
+
+## Project format v3.2
+**[Qt Visual Studio Tools v2.5.1](https://download.qt.io/official_releases/vsaddin/2.5.1/)**
+
+**`Fix incompatibilities with property sheets`**
+`commit 1a93741cadaa26b49cc4dc02d09ea7249cbea6fe`
+`Author: Miguel Costa <miguel.costa@qt.io>`
+`Date: Thu Nov 21 16:21:35 2019 +0100`
+
+ Updated the format of Qt projects to better match the requirements for
+ Visual Studio C++ projects (*) that enable integrating with the IDE, in
+ particular, that allow external property sheets to be referenced.
+(*) https://docs.microsoft.com/en-us/cpp/build/reference/cxproj-file-structure#per-configuration-propertygroup-elements
+
+### Project file outline
+
+- ItemGroup **ProjectConfiguration**
+- PropertyGroup **Globals**
+ - Keyword **QtVS_v302**
+ - Property (*if `%QTMSBUILD%` undefined*) **QtMsBuild** = $(MSBuildProjectDirectory)\QtMsBuild
+- Import **Microsoft.Cpp.Default.props**
+- PropertyGroup **Configuration**
+ - Property **QtInstall**
+- Import **Microsoft.Cpp.props**
+- Target **QtMsBuildNotFound**
+- ImportGroup **ExtensionSettings**
+- ImportGroup **Shared**
+- ImportGroup **PropertySheets**
+- PropertyGroup **UserMacros**
+- Import **qt_defaults.props**
+- PropertyGroup **QtSettings**
+- Import **qt.props**
+- ItemDefinitionGroup
+ - **ClCompile**
+ - **Link**
+ - **QtMoc**
+ - **QtRcc**
+ - **QtUic**
+ - ...
+- ItemGroup
+ - **QtMoc** (*MOC header*)
+ - **QtRcc** (*QRC resources*)
+ - **QtUic** (*UI form*)
+ - **ClInclude** (*other headers*)
+ - **ClCompile** (*other CPP sources*)
+ - ...
+- Import **Microsoft.Cpp.targets**
+- Import **qt.targets**
+- ImportGroup **ExtensionTargets**
+
+## Project format v3.3
+**[Qt Visual Studio Tools v2.6.0](https://download.qt.io/official_releases/vsaddin/2.6.0/)**
+
+**`Fix ignoring VC property changes (project format v3.3)`**
+`commit 621efbcc92be6e1a9869a15a850b9bd8cccf2e97`
+`Author: Miguel Costa <miguel.costa@qt.io>`
+`Date: Tue Jun 9 10:24:54 2020 +0200`
+
+ This change introduces project format version 3.3, which fixes issues
+ related to modified values of VC properties (e.g. $(IntDir)) being
+ ignored when evaluating Qt build settings.
+
+ MSBuild evaluates properties by order of definition; dependencies are
+ resolved by using the latest evaluation of referred properties. As such,
+ any subsequent changes to the value of dependencies will not be
+ reflected in previously evaluated properties.
+
+ Redefinitions of VC properties are stored in uncategorized property
+ groups (i.e. <PropertyGroup> elements without a Label attrib) inside the
+ MSBuild project file; if no available group is found, Visual Studio will
+ create a new one. The incorrect evaluation of Qt properties happens when
+ new property groups are created after the definition of Qt properties,
+ such that the evaluation of Qt properties will be using outdated values
+ of VC properties.
+
+ Project format version 3.3 addresses this issue by adding property
+ groups for VC property storage in a correct location, with respect to
+ Qt build settings definitions.
+
+### Project file outline
+
+- ItemGroup **ProjectConfiguration**
+- PropertyGroup **Globals**
+ - Keyword **QtVS_v303**
+ - Property (*if `%QTMSBUILD%` undefined*) **QtMsBuild** = $(MSBuildProjectDirectory)\QtMsBuild
+- Import **Microsoft.Cpp.Default.props**
+- PropertyGroup **Configuration**
+ - Property **QtInstall**
+- Import **Microsoft.Cpp.props**
+- Target **QtMsBuildNotFound**
+- ImportGroup **ExtensionSettings**
+- ImportGroup **Shared**
+- ImportGroup **PropertySheets**
+- PropertyGroup **UserMacros**
+- Import **qt_defaults.props**
+- PropertyGroup
+ - Property **OutDir**
+ - Property **IntDir**
+ - ...
+- PropertyGroup **QtSettings**
+- Import **qt.props**
+- ItemDefinitionGroup
+ - **ClCompile**
+ - **Link**
+ - **QtMoc**
+ - **QtRcc**
+ - **QtUic**
+ - ...
+- ItemGroup
+ - **QtMoc** (*MOC header*)
+ - **QtRcc** (*QRC resources*)
+ - **QtUic** (*UI form*)
+ - **ClInclude** (*other headers*)
+ - **ClCompile** (*other CPP sources*)
+ - ...
+- Import **Microsoft.Cpp.targets**
+- Import **qt.targets**
+- ImportGroup **ExtensionTargets**
+
+## Project format v3.4
+**>= [Qt Visual Studio Tools v2.7.1](https://download.qt.io/official_releases/vsaddin/2.7.1/)**
+
+**`Integrate Qt.props in the VS Property Manager`**
+`commit cb9ec156845a9efc163a9c67d7a54c8ca790e805`
+`Author: Miguel Costa <miguel.costa@qt.io>`
+`Date: Fri Dec 11 16:58:06 2020 +0100`
+
+ The Qt property definitions file (Qt.props) will now be shown in the
+ evaluation list of the Property Manager window. This allows the user to
+ customize the order of evaluation of Qt.props in relation to other
+ property files loaded during the build, thereby defining the correct
+ dependency between Qt properties and other build settings. Previously,
+ the order of evaluation of Qt.props was fixed and could only be changed
+ by manually editing the project file's XML.
+
+ Allowing Qt.props to be manipulated in the Property Manager window will
+ enable the user to define properties and default metadata within the
+ Qt.props itself. To ensure these custom definitions are not lost when
+ installing Qt/MSBuild files, the Qt.props file will no longer be
+ replaced during start-up.
+
+### Project file outline
+
+- ItemGroup **ProjectConfiguration**
+- PropertyGroup **Globals**
+ - Keyword **QtVS_v304**
+ - Property (*if `%QTMSBUILD%` undefined*) **QtMsBuild** = $(MSBuildProjectDirectory)\QtMsBuild
+- Import **Microsoft.Cpp.Default.props**
+- PropertyGroup **Configuration**
+ - Property **QtInstall**
+- Import **Microsoft.Cpp.props**
+- Import **qt_defaults.props**
+- PropertyGroup **QtSettings**
+- Target **QtMsBuildNotFound**
+- ImportGroup **ExtensionSettings**
+- ImportGroup **Shared**
+- ImportGroup **PropertySheets**
+ - Import **Qt.props**
+- PropertyGroup **UserMacros**
+- PropertyGroup
+ - Property **OutDir**
+ - Property **IntDir**
+ - ...
+- ItemDefinitionGroup
+ - **ClCompile**
+ - **Link**
+ - **QtMoc**
+ - **QtRcc**
+ - **QtUic**
+ - ...
+- ItemGroup
+ - **QtMoc** (*MOC header*)
+ - **QtRcc** (*QRC resources*)
+ - **QtUic** (*UI form*)
+ - **ClInclude** (*other headers*)
+ - **ClCompile** (*other CPP sources*)
+ - ...
+- Import **Microsoft.Cpp.targets**
+- Import **qt.targets**
+- ImportGroup **ExtensionTargets**
+
+## Example projects
+
+### v1.0
+
+#### `.vcxproj`
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{E5EA0EEF-BDC2-3484-A4F0-BA6C71E224CF}</ProjectGuid>
+ <RootNamespace>QtProjectV100</RootNamespace>
+ <Keyword>Qt4VSv1.0</Keyword>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <PlatformToolset>v142</PlatformToolset>
+ <OutputDirectory>release\</OutputDirectory>
+ <ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
+ <CharacterSet>NotSet</CharacterSet>
+ <ConfigurationType>Application</ConfigurationType>
+ <IntermediateDirectory>release\</IntermediateDirectory>
+ <PrimaryOutput>QtProjectV100</PrimaryOutput>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <PlatformToolset>v142</PlatformToolset>
+ <OutputDirectory>debug\</OutputDirectory>
+ <ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
+ <CharacterSet>NotSet</CharacterSet>
+ <ConfigurationType>Application</ConfigurationType>
+ <IntermediateDirectory>debug\</IntermediateDirectory>
+ <PrimaryOutput>QtProjectV100</PrimaryOutput>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\</IntDir>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">QtProjectV100</TargetName>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</IgnoreImportLibrary>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\</IntDir>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">QtProjectV100</TargetName>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</IgnoreImportLibrary>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>.;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtWidgets;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtGui;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtANGLE;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtCore;release;.;/include;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\mkspecs\win32-msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
+ <AssemblerListingLocation>release\</AssemblerListingLocation>
+ <BrowseInformation>false</BrowseInformation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <ObjectFileName>release\</ObjectFileName>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessToFile>false</PreprocessToFile>
+ <ProgramDataBaseFileName></ProgramDataBaseFileName>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <WarningLevel>Level3</WarningLevel>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>C:\lib\Qt\5.15.10\msvc2019_64\lib\Qt5Widgets.lib;C:\lib\Qt\5.15.10\msvc2019_64\lib\Qt5Gui.lib;C:\lib\Qt\5.15.10\msvc2019_64\lib\Qt5Core.lib;C:\lib\Qt\5.15.10\msvc2019_64\lib\qtmain.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>C:\openssl\lib;C:\Utils\my_sql\mysql-5.7.25-winx64\lib;C:\Utils\postgresql\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
+ <DataExecutionPrevention>true</DataExecutionPrevention>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <IgnoreImportLibrary>true</IgnoreImportLibrary>
+ <LinkIncremental>false</LinkIncremental>
+ <OptimizeReferences>true</OptimizeReferences>
+ <OutputFile>$(OutDir)\QtProjectV100.exe</OutputFile>
+ <RandomizedBaseAddress>true</RandomizedBaseAddress>
+ <SubSystem>Windows</SubSystem>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Link>
+ <Midl>
+ <DefaultCharType>Unsigned</DefaultCharType>
+ <EnableErrorChecks>None</EnableErrorChecks>
+ <WarningLevel>0</WarningLevel>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>.;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtWidgets;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtGui;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtANGLE;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\include\QtCore;debug;.;/include;..\..\..\..\lib\Qt\5.15.10\msvc2019_64\mkspecs\win32-msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
+ <AssemblerListingLocation>debug\</AssemblerListingLocation>
+ <BrowseInformation>false</BrowseInformation>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <ObjectFileName>debug\</ObjectFileName>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessToFile>false</PreprocessToFile>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <WarningLevel>Level3</WarningLevel>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>C:\lib\Qt\5.15.10\msvc2019_64\lib\Qt5Widgetsd.lib;C:\lib\Qt\5.15.10\msvc2019_64\lib\Qt5Guid.lib;C:\lib\Qt\5.15.10\msvc2019_64\lib\Qt5Cored.lib;C:\lib\Qt\5.15.10\msvc2019_64\lib\qtmaind.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>C:\openssl\lib;C:\Utils\my_sql\mysql-5.7.25-winx64\lib;C:\Utils\postgresql\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
+ <DataExecutionPrevention>true</DataExecutionPrevention>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <IgnoreImportLibrary>true</IgnoreImportLibrary>
+ <OutputFile>$(OutDir)\QtProjectV100.exe</OutputFile>
+ <RandomizedBaseAddress>true</RandomizedBaseAddress>
+ <SubSystem>Windows</SubSystem>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Link>
+ <Midl>
+ <DefaultCharType>Unsigned</DefaultCharType>
+ <EnableErrorChecks>None</EnableErrorChecks>
+ <WarningLevel>0</WarningLevel>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="QtProjectV100.cpp" />
+ <ClCompile Include="main.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV100.h">
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">QtProjectV100.h;release\moc_predefs.h;C:\lib\Qt\5.15.10\msvc2019_64\bin\moc.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\lib\Qt\5.15.10\msvc2019_64\bin\moc.exe -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DNDEBUG -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB --compiler-flavor=msvc --include C:/dev/tests/formats/100/release/moc_predefs.h -IC:/lib/Qt/5.15.10/msvc2019_64/mkspecs/win32-msvc -IC:/dev/tests/formats/100 -IC:/lib/Qt/5.15.10/msvc2019_64/include -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtWidgets -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtGui -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtANGLE -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtCore -I"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\ATLMFC\include" -I"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\include" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" QtProjectV100.h -o release\moc_QtProjectV100.cpp</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MOC QtProjectV100.h</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\moc_QtProjectV100.cpp;%(Outputs)</Outputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">QtProjectV100.h;debug\moc_predefs.h;C:\lib\Qt\5.15.10\msvc2019_64\bin\moc.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\lib\Qt\5.15.10\msvc2019_64\bin\moc.exe -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB --compiler-flavor=msvc --include C:/dev/tests/formats/100/debug/moc_predefs.h -IC:/lib/Qt/5.15.10/msvc2019_64/mkspecs/win32-msvc -IC:/dev/tests/formats/100 -IC:/lib/Qt/5.15.10/msvc2019_64/include -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtWidgets -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtGui -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtANGLE -IC:/lib/Qt/5.15.10/msvc2019_64/include/QtCore -I"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\ATLMFC\include" -I"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\include" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" QtProjectV100.h -o debug\moc_QtProjectV100.cpp</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">MOC QtProjectV100.h</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\moc_QtProjectV100.cpp;%(Outputs)</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="debug\moc_QtProjectV100.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="release\moc_QtProjectV100.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <CustomBuild Include="debug\moc_predefs.h.cbt">
+ <FileType>Document</FileType>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\..\..\lib\Qt\5.15.10\msvc2019_64\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">cl -BxC:\lib\Qt\5.15.10\msvc2019_64\bin\qmake.exe -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E ..\..\..\..\lib\Qt\5.15.10\msvc2019_64\mkspecs\features\data\dummy.cpp 2>NUL >debug\moc_predefs.h</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Generate moc_predefs.h</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\moc_predefs.h;%(Outputs)</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="release\moc_predefs.h.cbt">
+ <FileType>Document</FileType>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\..\..\lib\Qt\5.15.10\msvc2019_64\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">cl -BxC:\lib\Qt\5.15.10\msvc2019_64\bin\qmake.exe -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E ..\..\..\..\lib\Qt\5.15.10\msvc2019_64\mkspecs\features\data\dummy.cpp 2>NUL >release\moc_predefs.h</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Generate moc_predefs.h</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\moc_predefs.h;%(Outputs)</Outputs>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </CustomBuild>
+ <ClCompile Include="debug\qrc_QtProjectV100.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="release\qrc_QtProjectV100.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClInclude Include="ui_QtProjectV100.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV100.ui">
+ <FileType>Document</FileType>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">QtProjectV100.ui;C:\lib\Qt\5.15.10\msvc2019_64\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\lib\Qt\5.15.10\msvc2019_64\bin\uic.exe QtProjectV100.ui -o ui_QtProjectV100.h</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">UIC QtProjectV100.ui</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ui_QtProjectV100.h;%(Outputs)</Outputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">QtProjectV100.ui;C:\lib\Qt\5.15.10\msvc2019_64\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\lib\Qt\5.15.10\msvc2019_64\bin\uic.exe QtProjectV100.ui -o ui_QtProjectV100.h</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">UIC QtProjectV100.ui</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ui_QtProjectV100.h;%(Outputs)</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV100.qrc">
+ <FileType>Document</FileType>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">QtProjectV100.qrc;C:\lib\Qt\5.15.10\msvc2019_64\bin\rcc.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\lib\Qt\5.15.10\msvc2019_64\bin\rcc.exe -name QtProjectV100 QtProjectV100.qrc -o release\qrc_QtProjectV100.cpp</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">RCC QtProjectV100.qrc</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\qrc_QtProjectV100.cpp;%(Outputs)</Outputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">QtProjectV100.qrc;C:\lib\Qt\5.15.10\msvc2019_64\bin\rcc.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\lib\Qt\5.15.10\msvc2019_64\bin\rcc.exe -name QtProjectV100 QtProjectV100.qrc -o debug\qrc_QtProjectV100.cpp</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">RCC QtProjectV100.qrc</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\qrc_QtProjectV100.cpp;%(Outputs)</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets" />
+</Project>
+```
+
+### v2.0
+
+#### `.vcxproj`
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{B12702AD-ABFB-343A-A199-8E24837244A3}</ProjectGuid>
+ <Keyword>Qt4VSv1.0</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <Optimization>Disabled</Optimization>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
+ <AdditionalLibraryDirectories>$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat />
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
+ <AdditionalLibraryDirectories>$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <AdditionalDependencies>qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="GeneratedFiles\Debug\moc_QtProjectV200.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="GeneratedFiles\qrc_QtProjectV200.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ </PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ </PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="GeneratedFiles\Release\moc_QtProjectV200.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="QtProjectV200.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV200.h">
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing QtProjectV200.h...</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets"</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing QtProjectV200.h...</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets"</Command>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV200.ui">
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Uic%27ing %(Identity)...</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Uic%27ing %(Identity)...</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="GeneratedFiles\ui_QtProjectV200.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="QtProjectV200.qrc">
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(FullPath);%(AdditionalInputs)</AdditionalInputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Rcc%27ing %(Identity)...</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(FullPath);%(AdditionalInputs)</AdditionalInputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Rcc%27ing %(Identity)...</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
+ </CustomBuild>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+ <ProjectExtensions>
+ <VisualStudio>
+ <UserProperties MocDir=".\GeneratedFiles\$(ConfigurationName)" UicDir=".\GeneratedFiles" RccDir=".\GeneratedFiles" lupdateOptions="" lupdateOnBuild="0" lreleaseOptions="" Qt5Version_x0020_x64="msvc2019_64" MocOptions="" />
+ </VisualStudio>
+ </ProjectExtensions>
+</Project>
+```
+
+### v3.0
+
+#### `.vcxproj`
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{B12702AD-ABFB-343A-A199-8E24837244A3}</ProjectGuid>
+ <Keyword>QtVS_v300</Keyword>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <QtInstall>msvc2019_64</QtInstall>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <QtInstall>msvc2019_64</QtInstall>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">
+ <QtMsBuild>$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+ <Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+ </Target>
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
+ <Import Project="$(QtMsBuild)\qt.props" />
+ </ImportGroup>
+ <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <QtModules>core;gui;widgets</QtModules>
+ </PropertyGroup>
+ <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <QtModules>core;gui;widgets</QtModules>
+ </PropertyGroup>
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <Optimization>Disabled</Optimization>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat />
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="QtProjectV300.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtMoc Include="QtProjectV300.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtUic Include="QtProjectV300.ui" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV300.qrc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+ <Import Project="$(QtMsBuild)\qt.targets" />
+ </ImportGroup>
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
+```
+
+### v3.1
+
+#### `.vcxproj`
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{B12702AD-ABFB-343A-A199-8E24837244A3}</ProjectGuid>
+ <Keyword>QtVS_v301</Keyword>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">
+ <QtMsBuild>$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+ </PropertyGroup>
+ <Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+ <Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+ </Target>
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
+ <Import Project="$(QtMsBuild)\qt_defaults.props" />
+ </ImportGroup>
+ <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <QtInstall>msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ </PropertyGroup>
+ <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <QtInstall>msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ </PropertyGroup>
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
+ <Import Project="$(QtMsBuild)\qt.props" />
+ </ImportGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <Optimization>Disabled</Optimization>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat />
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="QtProjectV301.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtMoc Include="QtProjectV301.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtUic Include="QtProjectV301.ui" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV301.qrc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+ <Import Project="$(QtMsBuild)\qt.targets" />
+ </ImportGroup>
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
+```
+
+### v3.2
+
+#### `.vcxproj`
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{10A7CC05-6663-4C63-906F-E56EDF8218CA}</ProjectGuid>
+ <Keyword>QtVS_v302</Keyword>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
+ <QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')"
+ >$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <Target Name="QtMsBuildNotFound"
+ BeforeTargets="CustomBuild;ClCompile"
+ Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+ <Message Importance="High"
+ Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+ </Target>
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
+ <Import Project="$(QtMsBuild)\qt_defaults.props" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
+ <QtInstall>msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ <QtBuildConfig>debug</QtBuildConfig>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
+ <QtInstall>msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ <QtBuildConfig>release</QtBuildConfig>
+ </PropertyGroup>
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
+ <Import Project="$(QtMsBuild)\qt.props" />
+ </ImportGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <Optimization>MaxSpeed</Optimization>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV302.qrc"/>
+ <QtUic Include="QtProjectV302.ui"/>
+ <QtMoc Include="QtProjectV302.h"/>
+ <ClCompile Include="QtProjectV302.cpp"/>
+ <ClCompile Include="main.cpp"/>
+
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+ <Import Project="$(QtMsBuild)\qt.targets" />
+ </ImportGroup>
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
+```
+
+### v3.3
+
+#### `.vcxproj`
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{812E4050-B861-4918-A0DC-53053B848372}</ProjectGuid>
+ <Keyword>QtVS_v303</Keyword>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
+ <QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')"
+ >$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <Target Name="QtMsBuildNotFound"
+ BeforeTargets="CustomBuild;ClCompile"
+ Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+ <Message Importance="High"
+ Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+ </Target>
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
+ <Import Project="$(QtMsBuild)\qt_defaults.props" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
+ <QtInstall>msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ <QtBuildConfig>debug</QtBuildConfig>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
+ <QtInstall>msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ <QtBuildConfig>release</QtBuildConfig>
+ </PropertyGroup>
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
+ <Import Project="$(QtMsBuild)\qt.props" />
+ </ImportGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <Optimization>MaxSpeed</Optimization>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV303.qrc"/>
+ <QtUic Include="QtProjectV303.ui"/>
+ <QtMoc Include="QtProjectV303.h"/>
+ <ClCompile Include="QtProjectV303.cpp"/>
+ <ClCompile Include="main.cpp"/>
+
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+ <Import Project="$(QtMsBuild)\qt.targets" />
+ </ImportGroup>
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
+```
+
+### v3.4
+
+#### `.vcxproj`
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{923588D5-2AA5-4B0F-8110-56BEEBB531D5}</ProjectGuid>
+ <Keyword>QtVS_v304</Keyword>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0.19041.0</WindowsTargetPlatformVersion>
+ <QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')"
+ >$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v143</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v143</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
+ <Import Project="$(QtMsBuild)\qt_defaults.props" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
+ <QtInstall>5.15.10_msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ <QtBuildConfig>debug</QtBuildConfig>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
+ <QtInstall>5.15.10_msvc2019_64</QtInstall>
+ <QtModules>core;gui;widgets</QtModules>
+ <QtBuildConfig>release</QtBuildConfig>
+ </PropertyGroup>
+ <Target Name="QtMsBuildNotFound"
+ BeforeTargets="CustomBuild;ClCompile"
+ Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+ <Message Importance="High"
+ Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+ </Target>
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(QtMsBuild)\Qt.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(QtMsBuild)\Qt.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <Optimization>MaxSpeed</Optimization>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <QtRcc Include="QtProjectV304.qrc"/>
+ <QtUic Include="QtProjectV304.ui"/>
+ <QtMoc Include="QtProjectV304.h"/>
+ <ClCompile Include="QtProjectV304.cpp"/>
+ <ClCompile Include="main.cpp"/>
+
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+ <Import Project="$(QtMsBuild)\qt.targets" />
+ </ImportGroup>
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
+```
diff --git a/Tests/Test_QtMsBuild.Tasks/Properties/AssemblyInfo.cs b/Tests/Test_QtMsBuild.Tasks/Properties/AssemblyInfo.cs
index d2a7f58..2b3b56c 100644
--- a/Tests/Test_QtMsBuild.Tasks/Properties/AssemblyInfo.cs
+++ b/Tests/Test_QtMsBuild.Tasks/Properties/AssemblyInfo.cs
@@ -1,5 +1,4 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Test_QtMsBuild.Tasks")]
diff --git a/Tests/Test_QtMsBuild.Tasks/TestTaskLoggingHelper.cs b/Tests/Test_QtMsBuild.Tasks/TestTaskLoggingHelper.cs
index b4c1272..0c5d72a 100644
--- a/Tests/Test_QtMsBuild.Tasks/TestTaskLoggingHelper.cs
+++ b/Tests/Test_QtMsBuild.Tasks/TestTaskLoggingHelper.cs
@@ -26,11 +26,11 @@
**
****************************************************************************/
-using Microsoft.Build.Framework;
using System;
using System.Collections.Generic;
-using System.IO;
using System.Diagnostics;
+using System.IO;
+using Microsoft.Build.Framework;
namespace QtVsTools.Test.QtMsBuild.Tasks
{
diff --git a/Tests/Test_QtMsBuild.Tasks/Test_Join.cs b/Tests/Test_QtMsBuild.Tasks/Test_Join.cs
index 0ae7973..3743125 100644
--- a/Tests/Test_QtMsBuild.Tasks/Test_Join.cs
+++ b/Tests/Test_QtMsBuild.Tasks/Test_Join.cs
@@ -26,19 +26,20 @@
**
****************************************************************************/
-using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
using System.Collections.Generic;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
-using QtVsTools.QtMsBuild.Tasks;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace QtVsTools.Test.QtMsBuild.Tasks
{
+ using QtVsTools.QtMsBuild.Tasks;
+
[TestClass]
public class Test_Join
{
- ITaskItem[] LeftItems = new TaskItem[]
+ readonly ITaskItem[] LeftItems = new TaskItem[]
{
new TaskItem("A", new Dictionary<string, string> {
{ "X", "foo" },
@@ -53,8 +54,7 @@
{ "Y", "3.14159" },
}),
};
-
- ITaskItem[] RightItems = new TaskItem[]
+ readonly ITaskItem[] RightItems = new TaskItem[]
{
new TaskItem("A", new Dictionary<string, string> {
{ "Z", "foo" },
@@ -90,9 +90,8 @@
// ---------------
var criteria = new string[] { "Y" };
- ITaskItem[] result;
Assert.IsTrue(
- Join.Execute(LeftItems, RightItems, out result, criteria));
+ Join.Execute(LeftItems, RightItems, out ITaskItem[] result, criteria));
Assert.IsTrue(result != null && result.Length == 3);
Assert.IsTrue(result[0].GetMetadata("X") == "foo");
@@ -124,9 +123,8 @@
// -------------------
var criteria = new string[] { "ROW_NUMBER" };
- ITaskItem[] result;
Assert.IsTrue(
- Join.Execute(LeftItems, RightItems, out result, criteria));
+ Join.Execute(LeftItems, RightItems, out ITaskItem[] result, criteria));
Assert.IsTrue(result != null && result.Length == 3);
Assert.IsTrue(result[0].GetMetadata("X") == "foo");
@@ -158,9 +156,8 @@
// -------------------
var criteria = new string[] { "ROW_NUMBER", "Y" };
- ITaskItem[] result;
Assert.IsTrue(
- Join.Execute(LeftItems, RightItems, out result, criteria));
+ Join.Execute(LeftItems, RightItems, out ITaskItem[] result, criteria));
Assert.IsTrue(result != null && result.Length == 0);
}
@@ -187,9 +184,8 @@
.ToArray();
var criteria = new string[] { "ROW_NUMBER", "Y" };
- ITaskItem[] result;
Assert.IsTrue(
- Join.Execute(newLeftItems, RightItems, out result, criteria));
+ Join.Execute(newLeftItems, RightItems, out ITaskItem[] result, criteria));
Assert.IsTrue(result != null && result.Length == 1);
Assert.IsTrue(result[0].GetMetadata("X") == "zzz");
@@ -212,9 +208,8 @@
// --------------------- A | bar | 99 B | bar | 99 | bar
// --------------------- ----------------------
- ITaskItem[] result;
Assert.IsTrue(
- Join.Execute(LeftItems, RightItems, out result));
+ Join.Execute(LeftItems, RightItems, out ITaskItem[] result));
Assert.IsTrue(result != null && result.Length == 4);
Assert.IsTrue(result[0].GetMetadata("X") == "foo");
diff --git a/Tests/Test_QtMsBuild.Tasks/Test_QtMsBuild.Tasks.csproj b/Tests/Test_QtMsBuild.Tasks/Test_QtMsBuild.Tasks.csproj
index 77bbb75..b4ae05a 100644
--- a/Tests/Test_QtMsBuild.Tasks/Test_QtMsBuild.Tasks.csproj
+++ b/Tests/Test_QtMsBuild.Tasks/Test_QtMsBuild.Tasks.csproj
@@ -76,17 +76,35 @@
</ItemGroup>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
- // Version specific references
+ // General package references
// -->
<Import Project="$(SolutionDir)\references.props" />
<ItemGroup>
- <PackageReference Include="Microsoft.Build" Version="$(Version_Microsoft_Build)" />
- <PackageReference Include="Microsoft.Build.Framework" Version="$(Version_Microsoft_Build_Framework)" />
- <PackageReference Include="Microsoft.Build.Tasks.Core" Version="$(Version_Microsoft_Build_Tasks_Core)" />
- <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="$(Version_Microsoft_Bcl_AsyncInterfaces)" />
- <PackageReference Include="MSTest.TestAdapter" Version="$(Version_MSTest_TestAdapter)" />
- <PackageReference Include="MSTest.TestFramework" Version="$(Version_MSTest_TestFramework)" />
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ <PackageReference Include="$(Name_Microsoft_Build)" Version="$(Version_Microsoft_Build)" />
+ <PackageReference Include="$(Name_Microsoft_Build_Tasks_Core)" Version="$(Version_Microsoft_Build_Tasks_Core)" />
+ <PackageReference Include="$(Name_MSTest_TestAdapter)" Version="$(Version_MSTest_TestAdapter)" />
+ <PackageReference Include="$(Name_MSTest_TestFramework)" Version="$(Version_MSTest_TestFramework)" />
</ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
// Solution project references
@@ -105,6 +123,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestTaskLoggingHelper.cs" />
<Compile Include="Test_Join.cs" />
+ <Compile Include="Test_QtRunTask.cs" />
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
diff --git a/Tests/Test_QtMsBuild.Tasks/Test_QtRunTask.cs b/Tests/Test_QtMsBuild.Tasks/Test_QtRunTask.cs
new file mode 100644
index 0000000..969e582
--- /dev/null
+++ b/Tests/Test_QtMsBuild.Tasks/Test_QtRunTask.cs
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace QtVsTools.Test.QtMsBuild.Tasks
+{
+ using QtVsTools.QtMsBuild.Tasks;
+
+ [TestClass]
+ public class Test_QtRunTask
+ {
+ [TestMethod]
+ public void CLCommandLine()
+ {
+ var argv = Environment.GetCommandLineArgs();
+ var path = argv[0];
+ if (string.IsNullOrEmpty(Path.GetPathRoot(path)))
+ Assert.Inconclusive("Executable path is not rooted.");
+
+ do
+ path = Path.GetFullPath(Path.GetDirectoryName(path));
+ while (path != Path.GetPathRoot(path)
+ && !File.Exists(Path.Combine(path, "devenv.exe")));
+
+ if (!File.Exists(Path.Combine(path, "devenv.exe")))
+ Assert.Inconclusive("devenv.exe not found");
+
+ string vsPath = Path.GetDirectoryName(Path.GetDirectoryName(path));
+ string vcTargetsPath = Path.Combine(vsPath, "MSBuild", "Microsoft", "VC");
+ if (Directory.Exists(Path.Combine(vcTargetsPath, "v170")))
+ vcTargetsPath = Path.Combine(vcTargetsPath, "v170");
+ else if (Directory.Exists(Path.Combine(vcTargetsPath, "v160")))
+ vcTargetsPath = Path.Combine(vcTargetsPath, "v160");
+ else if (Directory.Exists(Path.Combine(vcTargetsPath, "v150")))
+ vcTargetsPath = Path.Combine(vcTargetsPath, "v150");
+ else
+ Assert.Inconclusive("MSBuild VC targets directory not found");
+
+ ITaskItem[] sourceItems = new TaskItem[]
+ {
+ new TaskItem("main.cpp", new Dictionary<string, string> {
+ { "EnforceTypeConversionRules", "false" },
+ })
+ };
+
+ Assert.IsTrue(
+ QtRunTask.Execute(
+ sourceItems,
+ $@"{vcTargetsPath}\Microsoft.Build.CPPTasks.Common.dll",
+ "Microsoft.Build.CPPTasks.CLCommandLine",
+ "Sources",
+ out ITaskItem[] result,
+ "CommandLines",
+ "CommandLine"));
+ Assert.IsTrue(result != null && result.Length == 1);
+ Assert.IsTrue(result[0].GetMetadata("CommandLine").Contains("/Zc:rvalueCast-"));
+ }
+ }
+}
diff --git a/Tests/Test_QtVsTools.Core/Properties/AssemblyInfo.cs b/Tests/Test_QtVsTools.Core/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4c2fa40
--- /dev/null
+++ b/Tests/Test_QtVsTools.Core/Properties/AssemblyInfo.cs
@@ -0,0 +1,20 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Test_QtVsTools.Core")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Test_QtVsTools.Core")]
+[assembly: AssemblyCopyright("Copyright © 2022")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+
+[assembly: Guid("4b8fc08c-4901-45d4-bc00-c0c461292ff2")]
+
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Tests/Test_QtVsTools.Core/Test_LazyFactory.cs b/Tests/Test_QtVsTools.Core/Test_LazyFactory.cs
new file mode 100644
index 0000000..953f024
--- /dev/null
+++ b/Tests/Test_QtVsTools.Core/Test_LazyFactory.cs
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Collections.Concurrent;
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace QtVsTools.Test.Core
+{
+ using Common;
+
+ [TestClass]
+ public class Test_LazyFactory
+ {
+ class LazyClass
+ {
+ LazyFactory Lazy { get; } = new LazyFactory();
+
+ public ConcurrentBag<int> InitThread { get; } = new ConcurrentBag<int>();
+ public string LazyProperty => Lazy.Get(() =>
+ LazyProperty, () =>
+ {
+ InitThread.Add(Thread.CurrentThread.ManagedThreadId);
+ return "LAZYVALUE";
+ });
+ }
+
+ [TestMethod]
+ public void Test_ThreadSafety()
+ {
+ var lazyObject = new LazyClass();
+ var task = Task.Run(async () =>
+ {
+ var tasks = new Task[3000];
+ for (int i = 0; i < tasks.Length; i++) {
+ var n = i;
+ tasks[i] = Task.Run(() =>
+ {
+ Debug.WriteLine($"Lazy value #{n} is {lazyObject.LazyProperty}");
+ });
+ }
+ await Task.WhenAll(tasks);
+ });
+ while (!task.IsCompleted)
+ Thread.Sleep(100);
+
+ Assert.IsTrue(lazyObject.InitThread.Count == 1);
+ }
+ }
+}
diff --git a/Tests/Test_QtVsTools.Core/Test_QtVsTools.Core.csproj b/Tests/Test_QtVsTools.Core/Test_QtVsTools.Core.csproj
new file mode 100644
index 0000000..b6ab30a
--- /dev/null
+++ b/Tests/Test_QtVsTools.Core/Test_QtVsTools.Core.csproj
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="$(VisualStudioVersion)" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+-->
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{4B8FC08C-4901-45D4-BC00-C0C461292FF2}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>QtVsTools.Test.Core</RootNamespace>
+ <AssemblyName>Test_QtVsTools.Core</AssemblyName>
+ <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
+ <IsCodedUITest>False</IsCodedUITest>
+ <TestProjectType>UnitTest</TestProjectType>
+ <NuGetPackageImportStamp>
+ </NuGetPackageImportStamp>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ <PackageReference Include="$(Name_Microsoft_Build)" Version="$(Version_Microsoft_Build)" />
+ <PackageReference Include="$(Name_Microsoft_Build_Tasks_Core)" Version="$(Version_Microsoft_Build_Tasks_Core)" />
+ <PackageReference Include="$(Name_MSTest_TestAdapter)" Version="$(Version_MSTest_TestAdapter)" />
+ <PackageReference Include="$(Name_MSTest_TestFramework)" Version="$(Version_MSTest_TestFramework)" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Solution project references
+ // -->
+ <ItemGroup>
+ <ProjectReference Include="$(SolutionDir)\QtVsTools.Core\QtVsTools.Core.csproj">
+ <Project>{2621ad55-c4e9-4884-81e9-da0d00b4c6e5}</Project>
+ <Name>QtVsTools.Core</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Test_LazyFactory.cs" />
+ </ItemGroup>
+ <Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(SolutionDir)\transform.targets" />
+</Project>
\ No newline at end of file
diff --git a/Tests/Test_QtVsTools.Package/Properties/AssemblyInfo.cs b/Tests/Test_QtVsTools.Package/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..e33cba0
--- /dev/null
+++ b/Tests/Test_QtVsTools.Package/Properties/AssemblyInfo.cs
@@ -0,0 +1,20 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Test_QtVsTools.Package")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Test_QtVsTools.Package")]
+[assembly: AssemblyCopyright("Copyright © 2022")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+
+[assembly: Guid("afd33401-2f15-4e72-ab35-42c3ee12e897")]
+
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Tests/Test_QtVsTools.Package/QtVsTestClient.cs b/Tests/Test_QtVsTools.Package/QtVsTestClient.cs
new file mode 100644
index 0000000..a98f68b
--- /dev/null
+++ b/Tests/Test_QtVsTools.Package/QtVsTestClient.cs
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.IO.Pipes;
+using System.Linq;
+using System.Text;
+
+namespace QtVsTools.Test
+{
+ public class QtVsTestClient : IDisposable
+ {
+ public NamedPipeClientStream Stream { get; }
+
+ public QtVsTestClient(int vsProcId)
+ {
+ Stream = new NamedPipeClientStream(".", $"QtVSTest_{vsProcId}", PipeDirection.InOut);
+ }
+
+ public static QtVsTestClient Attach(int? vsProcId = null)
+ {
+ if (vsProcId == null) {
+ var procs = Process.GetProcessesByName("devenv");
+ var vsProc = procs
+ .Where(p => p.Id != Process.GetCurrentProcess().Id
+ && !p.MainWindowTitle.StartsWith("vstools"))
+ .FirstOrDefault();
+ if (vsProc == null)
+ throw new InvalidOperationException("VS process not found");
+ vsProcId = vsProc.Id;
+ }
+ var client = new QtVsTestClient(vsProcId.Value);
+ client.Connect();
+ return client;
+ }
+
+ public void Connect() => Stream.Connect();
+
+ public void Dispose() => Stream?.Dispose();
+
+ public string RunMacro(string macroCode)
+ {
+ if (!Stream.IsConnected)
+ Connect();
+
+ var macroData = Encoding.UTF8.GetBytes(macroCode);
+ int macroDataSize = macroData.Length;
+ byte[] sizeData = BitConverter.GetBytes(macroDataSize);
+
+ Stream.Write(sizeData, 0, sizeof(int));
+ Stream.Write(macroData, 0, macroData.Length);
+ Stream.Flush();
+ if (!Stream.IsConnected)
+ return Error("Disconnected");
+
+ Stream.WaitForPipeDrain();
+ if (!Stream.IsConnected)
+ return Error("Disconnected");
+
+ for (int i = 0; i < sizeof(int); i++) {
+ int c = Stream.ReadByte();
+ if (c == -1)
+ return Error("Disconnected");
+ if (c < Byte.MinValue || c > Byte.MaxValue)
+ return Error("Pipe error");
+ sizeData[i] = (byte)c;
+ }
+
+ int replyDataSize = BitConverter.ToInt32(sizeData, 0);
+ byte[] replyData = new byte[replyDataSize];
+ int bytesRead = 0;
+ while (bytesRead < replyDataSize) {
+ if (!Stream.IsConnected)
+ return Error("Disconnected");
+ bytesRead += Stream.Read(replyData, bytesRead, replyDataSize - bytesRead);
+ }
+
+ return Encoding.UTF8.GetString(replyData);
+ }
+
+ public string RunMacroFile(string macroPath)
+ {
+ return LoadAndRunMacro(macroPath);
+ }
+
+ public string StoreMacro(string macroName, string macroCode)
+ {
+ if (string.IsNullOrEmpty(macroName))
+ return Error("Invalid macro name");
+ return RunMacro($"//# macro {macroName}\r\n{macroCode}");
+ }
+
+ public string StoreMacroFile(string macroName, string macroPath)
+ {
+ if (string.IsNullOrEmpty(macroName))
+ return Error("Invalid macro name");
+ return LoadAndRunMacro(macroPath, $"//# macro {macroName}");
+ }
+
+ string LoadAndRunMacro(string macroPath, string macroHeader = null)
+ {
+ var macroCode = File.ReadAllText(macroPath, Encoding.UTF8);
+ if (string.IsNullOrEmpty(macroCode))
+ return Error("Macro load failed");
+ if (!string.IsNullOrEmpty(macroHeader))
+ return RunMacro($"{macroHeader}\r\n{macroCode}");
+ else
+ return RunMacro(macroCode);
+ }
+
+ public const string MacroOk = "(ok)";
+ public const string MacroWarn = "(warn)";
+ public const string MacroError = "(error)";
+
+ static string Error(string msg) => $"{MacroError}\r\n{msg}";
+ }
+}
diff --git a/Tests/Test_QtVsTools.Package/Test_QtVersionsPage.cs b/Tests/Test_QtVsTools.Package/Test_QtVersionsPage.cs
new file mode 100644
index 0000000..7e57e2e
--- /dev/null
+++ b/Tests/Test_QtVsTools.Package/Test_QtVersionsPage.cs
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Microsoft.Win32;
+
+namespace QtVsTools.Test.Package
+{
+ [TestClass]
+ public class Test_QtVersionsPage
+ {
+ // UI automation property conditions
+ string SetGlobals => @"
+//# using System.IO
+var elementSubtree = (TreeScope.Element | TreeScope.Subtree);
+var isButton = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button);
+var isDataGrid = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.DataGrid);
+var isEdit = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit);
+var isText = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Text);
+var isWindow = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window);";
+
+ // Open menu: Tools > Options...
+ string OpenVsOptions => @"
+//# ui context VSROOT => ""MenuBar"", ""Tools""
+//# ui pattern Invoke
+//# ui context => ""Options...""
+//# ui pattern Invoke";
+
+ // Select options: page Qt > Versions
+ string SelectQtVersionsPage => @"
+//# ui context VSROOT => ""Options"", ""Qt""
+//# ui pattern ExpandCollapse qtOptions
+qtOptions.Expand();
+//# ui context => ""Versions""
+//# ui pattern SelectionItem qtVersions
+qtVersions.Select();";
+
+ // Get reference to data grid with Qt versions
+ string GetQtVersionsTable => @"
+//# ui context VSROOT => ""Options""
+//# ui find => elementSubtree, isDataGrid
+//# ui pattern Grid qtVersionsTable";
+
+ // Add new row to versions table
+ string AddNewRow => @"
+var lastRow = qtVersionsTable.Current.RowCount - 1;
+UiContext = qtVersionsTable.GetItem(lastRow, 1);
+//# ui find => elementSubtree, isButton
+//# ui pattern Invoke
+{
+ //# ui context VSROOT => ""Options""
+ //# ui find => elementSubtree, isDataGrid
+ //# ui pattern Grid qtVersionsTableAux
+ qtVersionsTable = qtVersionsTableAux;
+}
+UiContext = qtVersionsTable.GetItem(lastRow, 1);
+//# ui find => elementSubtree, isEdit
+//# ui pattern Value newVersionName
+newVersionName.SetValue(""TEST_"" + Path.GetRandomFileName());";
+
+ // Set UI context to the path field of the new row
+ string SelectNewRowPath => @"
+UiContext = qtVersionsTable.GetItem(lastRow, 3);
+//# ui find => elementSubtree, isEdit";
+
+ // Save changes to the versions table and close the VS options dialog
+ // * Any error message will be copied to 'Result'
+ string SaveChanges => @"
+//# ui context VSROOT => ""Options"", ""OK""
+//# ui pattern Invoke
+//# thread ui
+try {
+ //# ui context VSROOT 100 => ""Options""
+ //# ui find => elementSubtree, isWindow
+} catch (TimeoutException) {
+ return;
+}
+if (UiContext == null)
+ return;
+//# ui find => elementSubtree, isText
+Result = UiContext.Current.Name;
+//# ui context VSROOT => ""Options""
+//# ui find => elementSubtree, isWindow
+//# ui context => ""OK""
+//# ui pattern Invoke
+//# ui context VSROOT => ""Options"", ""Cancel""
+//# ui pattern Invoke";
+
+ // Add new variable 'qtPath' with the path to the Qt version in the top row
+ // * This is assumed to be a valid path to an existing Qt version
+ string GetFirstRowPath => @"
+if (qtVersionsTable.Current.RowCount <= 1) {
+ Result = MACRO_ERROR_MSG(""No Qt version registered."");
+ return;
+}
+UiContext = qtVersionsTable.GetItem(0, 3);
+//# ui find => elementSubtree, isEdit
+//# ui pattern Value path
+string qtPath = path.Current.Value;
+if (Path.GetFileName(qtPath).Equals(""qmake.exe"", StringComparison.InvariantCultureIgnoreCase))
+ qtPath = Path.GetDirectoryName(qtPath);
+if (Path.GetFileName(qtPath).Equals(""bin"", StringComparison.InvariantCultureIgnoreCase))
+ qtPath = Path.GetDirectoryName(qtPath);";
+
+ [TestMethod]
+ // Add new (empty) row => error
+ public void Test_EmptyVersion()
+ {
+ string result;
+ using (var vs = QtVsTestClient.Attach()) {
+ result = vs.RunMacro($@"
+ {SetGlobals}
+ {OpenVsOptions}
+ {SelectQtVersionsPage}
+ {GetQtVersionsTable}
+ {AddNewRow}
+ {SaveChanges}");
+ }
+ Assert.IsTrue(result.Contains("Invalid Qt versions"), result);
+ }
+
+ [TestMethod]
+ // Add new row and copy the path from the top row => OK
+ public void Test_AddNewVersion()
+ {
+ string result;
+ using (var vs = QtVsTestClient.Attach()) {
+ result = vs.RunMacro($@"
+ {SetGlobals}
+ {OpenVsOptions}
+ {SelectQtVersionsPage}
+ {GetQtVersionsTable}
+ {GetFirstRowPath}
+ {AddNewRow}
+ {SelectNewRowPath}
+ //# ui pattern Value newVersionPath
+ newVersionPath.SetValue(qtPath);
+ {SaveChanges}");
+ }
+ Assert.IsTrue(result.StartsWith(QtVsTestClient.MacroOk), result);
+ }
+
+ [TestMethod]
+ // Add new row, copy the path from the top row, and append "qmake.exe" => OK
+ public void Test_AddBinToPath()
+ {
+ string result;
+ using (var vs = QtVsTestClient.Attach()) {
+ result = vs.RunMacro($@"
+ {SetGlobals}
+ {OpenVsOptions}
+ {SelectQtVersionsPage}
+ {GetQtVersionsTable}
+ {GetFirstRowPath}
+ {AddNewRow}
+ {SelectNewRowPath}
+ //# ui pattern Value newVersionPath
+ newVersionPath.SetValue(Path.Combine(qtPath, ""bin""));
+ {SaveChanges}");
+ }
+ Assert.IsTrue(result.StartsWith(QtVsTestClient.MacroOk), result);
+ }
+
+ [TestMethod]
+ // Add new row, copy the path from the top row, and append "bin\qmake.exe" => OK
+ public void Test_AddBinQMakeToPath()
+ {
+ string result;
+ using (var vs = QtVsTestClient.Attach()) {
+ result = vs.RunMacro($@"
+ {SetGlobals}
+ {OpenVsOptions}
+ {SelectQtVersionsPage}
+ {GetQtVersionsTable}
+ {GetFirstRowPath}
+ {AddNewRow}
+ {SelectNewRowPath}
+ //# ui pattern Value newVersionPath
+ newVersionPath.SetValue(Path.Combine(qtPath, ""bin"", ""qmake.exe""));
+ {SaveChanges}");
+ }
+ Assert.IsTrue(result.StartsWith(QtVsTestClient.MacroOk), result);
+ }
+
+ [TestMethod]
+ // Add new row, copy the path from the top row, and append "include" => ERROR
+ public void Test_AddIncludeToPath()
+ {
+ string result;
+ using (var vs = QtVsTestClient.Attach()) {
+ result = vs.RunMacro($@"
+ {SetGlobals}
+ {OpenVsOptions}
+ {SelectQtVersionsPage}
+ {GetQtVersionsTable}
+ {GetFirstRowPath}
+ {AddNewRow}
+ {SelectNewRowPath}
+ //# ui pattern Value newVersionPath
+ newVersionPath.SetValue(Path.Combine(qtPath, ""include""));
+ {SaveChanges}");
+ }
+ Assert.IsTrue(result.Contains("Invalid Qt versions"), result);
+ }
+
+ [ClassCleanup]
+ // Remove registry keys created during tests
+ public static void RemoveTestKeys()
+ {
+ var qtVersions = Registry.CurrentUser
+ .OpenSubKey(@"Software\Digia\Versions", writable: true);
+ using (qtVersions) {
+ var allVersions = qtVersions.GetSubKeyNames();
+ var testVersions = allVersions.Where(k => k.StartsWith("TEST"));
+ foreach (var testVersion in testVersions)
+ qtVersions.DeleteSubKey(testVersion);
+ qtVersions.Close();
+ }
+ }
+ }
+}
diff --git a/Tests/Test_QtVsTools.Package/Test_QtVsTools.Package.csproj b/Tests/Test_QtVsTools.Package/Test_QtVsTools.Package.csproj
new file mode 100644
index 0000000..e2c41f0
--- /dev/null
+++ b/Tests/Test_QtVsTools.Package/Test_QtVsTools.Package.csproj
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="$(VisualStudioVersion)" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <!--
+ *****************************************************************************
+ **
+ ** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see https://www.qt.io/terms-conditions. For further
+ ** information use the contact form at https://www.qt.io/contact-us.
+ **
+ ** GNU General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU
+ ** General Public License version 3 as published by the Free Software
+ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+ ** included in the packaging of this file. Please review the following
+ ** information to ensure the GNU General Public License requirements will
+ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
+ ** $QT_END_LICENSE$
+ **
+ *****************************************************************************
+-->
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{AFD33401-2F15-4E72-AB35-42C3EE12E897}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Test_QtVsTools.Package</RootNamespace>
+ <AssemblyName>Test_QtVsTools.Package</AssemblyName>
+ <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
+ <IsCodedUITest>False</IsCodedUITest>
+ <TestProjectType>UnitTest</TestProjectType>
+ <NuGetPackageImportStamp>
+ </NuGetPackageImportStamp>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Global references
+ // -->
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // General package references
+ // -->
+ <Import Project="$(SolutionDir)\references.props" />
+ <ItemGroup>
+ <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
+ <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
+ <PackageReference Include="$(Name_Microsoft_Build)" Version="$(Version_Microsoft_Build)" />
+ <PackageReference Include="$(Name_Microsoft_Build_Tasks_Core)" Version="$(Version_Microsoft_Build_Tasks_Core)" />
+ <PackageReference Include="$(Name_MSTest_TestAdapter)" Version="$(Version_MSTest_TestAdapter)" />
+ <PackageReference Include="$(Name_MSTest_TestFramework)" Version="$(Version_MSTest_TestFramework)" />
+ </ItemGroup>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Version specific package references
+ // -->
+ <Choose>
+ <When Condition="'$(VisualStudioVersion)'=='17.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='16.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ <When Condition="'$(VisualStudioVersion)'=='15.0'">
+ <ItemGroup>
+ </ItemGroup>
+ </When>
+ </Choose>
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Project items
+ // -->
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Test_QtVersionsPage.cs" />
+ <Compile Include="QtVsTestClient.cs" />
+ </ItemGroup>
+ <Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(SolutionDir)\transform.targets" />
+</Project>
\ No newline at end of file
diff --git a/Tests/Test_QtVsTools.PriorityQueue/Properties/AssemblyInfo.cs b/Tests/Test_QtVsTools.PriorityQueue/Properties/AssemblyInfo.cs
index 8561057..91ed9f8 100644
--- a/Tests/Test_QtVsTools.PriorityQueue/Properties/AssemblyInfo.cs
+++ b/Tests/Test_QtVsTools.PriorityQueue/Properties/AssemblyInfo.cs
@@ -27,7 +27,6 @@
****************************************************************************/
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Test_QtVsTools.PriorityQueue")]
diff --git a/Tests/Test_QtVsTools.PriorityQueue/Test_PriorityQueue.cs b/Tests/Test_QtVsTools.PriorityQueue/Test_PriorityQueue.cs
index b5a2a4b..51f8213 100644
--- a/Tests/Test_QtVsTools.PriorityQueue/Test_PriorityQueue.cs
+++ b/Tests/Test_QtVsTools.PriorityQueue/Test_PriorityQueue.cs
@@ -89,12 +89,11 @@
public void TestTryPeek()
{
var q = new PunisherQueue<string>();
- string s;
- Assert.IsTrue(!q.TryPeek(out s));
+ Assert.IsTrue(!q.TryPeek(out _));
q.Enqueue("a");
q.Enqueue("b");
q.Enqueue("c");
- Assert.IsTrue(q.TryPeek(out s) && s == "a");
+ Assert.IsTrue(q.TryPeek(out string s) && s == "a");
Assert.IsTrue(string.Join("", q) == "abc");
}
@@ -121,12 +120,11 @@
public void TestTryDequeue()
{
var q = new PunisherQueue<string>();
- string s;
- Assert.IsTrue(!q.TryDequeue(out s));
+ Assert.IsTrue(!q.TryDequeue(out _));
q.Enqueue("a");
q.Enqueue("b");
q.Enqueue("c");
- Assert.IsTrue(q.TryDequeue(out s) && s == "a");
+ Assert.IsTrue(q.TryDequeue(out string s) && s == "a");
Assert.IsTrue(string.Join("", q) == "bc");
}
@@ -168,7 +166,7 @@
{
var q = new PunisherQueue<string>();
int n = 0;
- Task.Run(() =>
+ _ = Task.Run(() =>
{
for (int i = 0; i < 10000; ++i) {
q.Enqueue(Path.GetRandomFileName());
@@ -177,8 +175,7 @@
}
});
for (int i = 0; i < 10000; ++i) {
- string s;
- if (!q.TryDequeue(out s))
+ if (!q.TryDequeue(out _))
--i;
--n;
Thread.Yield();
diff --git a/Tests/Test_QtVsTools.PriorityQueue/Test_QtVsTools.PriorityQueue.csproj b/Tests/Test_QtVsTools.PriorityQueue/Test_QtVsTools.PriorityQueue.csproj
index 7cc709b..94ebaeb 100644
--- a/Tests/Test_QtVsTools.PriorityQueue/Test_QtVsTools.PriorityQueue.csproj
+++ b/Tests/Test_QtVsTools.PriorityQueue/Test_QtVsTools.PriorityQueue.csproj
@@ -76,12 +76,12 @@
</ItemGroup>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
- // Version specific references
+ // General package references
// -->
<Import Project="$(SolutionDir)\references.props" />
<ItemGroup>
- <PackageReference Include="MSTest.TestAdapter" Version="$(Version_MSTest_TestAdapter)" />
- <PackageReference Include="MSTest.TestFramework" Version="$(Version_MSTest_TestFramework)" />
+ <PackageReference Include="$(Name_MSTest_TestAdapter)" Version="$(Version_MSTest_TestAdapter)" />
+ <PackageReference Include="$(Name_MSTest_TestFramework)" Version="$(Version_MSTest_TestFramework)" />
</ItemGroup>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/Tests/Test_QtVsTools.RegExpr/Properties/AssemblyInfo.cs b/Tests/Test_QtVsTools.RegExpr/Properties/AssemblyInfo.cs
index 68ec694..2ab45a1 100644
--- a/Tests/Test_QtVsTools.RegExpr/Properties/AssemblyInfo.cs
+++ b/Tests/Test_QtVsTools.RegExpr/Properties/AssemblyInfo.cs
@@ -27,7 +27,6 @@
****************************************************************************/
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Test_QtVsTools.RegExpr")]
diff --git a/Tests/Test_QtVsTools.RegExpr/Test_MacroParser.cs b/Tests/Test_QtVsTools.RegExpr/Test_MacroParser.cs
index 5f29dc4..f8d8ad5 100644
--- a/Tests/Test_QtVsTools.RegExpr/Test_MacroParser.cs
+++ b/Tests/Test_QtVsTools.RegExpr/Test_MacroParser.cs
@@ -26,7 +26,6 @@
**
****************************************************************************/
-using System;
using System.Diagnostics;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -38,7 +37,7 @@
[TestClass]
public class Test_MacroParser
{
- MacroParser Parser = MacroParser.Get();
+ readonly MacroParser Parser = MacroParser.Get();
[TestMethod]
public void TestMacro()
diff --git a/Tests/Test_QtVsTools.RegExpr/Test_QtVsTools.RegExpr.csproj b/Tests/Test_QtVsTools.RegExpr/Test_QtVsTools.RegExpr.csproj
index 5622e2d..7a257c8 100644
--- a/Tests/Test_QtVsTools.RegExpr/Test_QtVsTools.RegExpr.csproj
+++ b/Tests/Test_QtVsTools.RegExpr/Test_QtVsTools.RegExpr.csproj
@@ -76,12 +76,12 @@
</ItemGroup>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
- // Version specific references
+ // General package references
// -->
<Import Project="$(SolutionDir)\references.props" />
<ItemGroup>
- <PackageReference Include="MSTest.TestAdapter" Version="$(Version_MSTest_TestAdapter)" />
- <PackageReference Include="MSTest.TestFramework" Version="$(Version_MSTest_TestFramework)" />
+ <PackageReference Include="$(Name_MSTest_TestAdapter)" Version="$(Version_MSTest_TestAdapter)" />
+ <PackageReference Include="$(Name_MSTest_TestFramework)" Version="$(Version_MSTest_TestFramework)" />
</ItemGroup>
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/Tests/Test_QtVsTools.RegExpr/Test_SubTokens.cs b/Tests/Test_QtVsTools.RegExpr/Test_SubTokens.cs
index 8118ea7..847557a 100644
--- a/Tests/Test_QtVsTools.RegExpr/Test_SubTokens.cs
+++ b/Tests/Test_QtVsTools.RegExpr/Test_SubTokens.cs
@@ -26,7 +26,6 @@
**
****************************************************************************/
-using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace QtVsTools.Test.RegExpr
diff --git a/Tests/Test_QtVsTools.RegExpr/Test_XmlIntParser.cs b/Tests/Test_QtVsTools.RegExpr/Test_XmlIntParser.cs
index bca023e..85aa5f6 100644
--- a/Tests/Test_QtVsTools.RegExpr/Test_XmlIntParser.cs
+++ b/Tests/Test_QtVsTools.RegExpr/Test_XmlIntParser.cs
@@ -26,7 +26,6 @@
**
****************************************************************************/
-using System;
using System.Diagnostics;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -224,7 +223,7 @@
return xmlInt.Render(CharSpace.Repeat());
}
- Parser Parser = GetParser();
+ readonly Parser Parser = GetParser();
[TestMethod]
public void TestConst()
diff --git a/doc/config/qtvstools-project.qdocconf b/doc/config/qtvstools-project.qdocconf
index 845c88c..a5fe990 100644
--- a/doc/config/qtvstools-project.qdocconf
+++ b/doc/config/qtvstools-project.qdocconf
@@ -6,6 +6,9 @@
project = "QtVSTools"
description = "Qt VS Tools Manual"
+#Words to ignore for auto-linking
+ignorewords += MainWindow
+
sourcedirs += ..
imagedirs += ../images
outputdir = $OUTDIR
@@ -22,7 +25,7 @@
qhp.QtVSTools.indexRoot =
qhp.QtVSTools.subprojects = manual
-qhp.QtVSTools.subprojects.manual.indexTitle = Qt VS Tools Manual
+qhp.QtVSTools.subprojects.manual.indexTitle = All Topics
qhp.QtVSTools.subprojects.manual.title = Qt VS Tools Manual
qhp.QtVSTools.subprojects.manual.type = manual
@@ -33,7 +36,10 @@
$QDOC_INDEX_DIR/qtgui/qtgui.index \
$QDOC_INDEX_DIR/qthelp/qthelp.index \
$QDOC_INDEX_DIR/qtlinguist/qtlinguist.index \
+ $QDOC_INDEX_DIR/qtqml/qtqml.index \
$QDOC_INDEX_DIR/qtquick/qtquick.index \
+ $QDOC_INDEX_DIR/qtqmlmodels/qtqmlmodels.index \
+ $QDOC_INDEX_DIR/qtquickcontrols/qtquickcontrols.index \
$QDOC_INDEX_DIR/qtwidgets/qtwidgets.index
# Doxygen compatibility commands
diff --git a/doc/config/style/qt5-sidebar.html b/doc/config/style/qt5-sidebar.html
index 60760ac..1b0e0ec 100644
--- a/doc/config/style/qt5-sidebar.html
+++ b/doc/config/style/qt5-sidebar.html
@@ -1,15 +1,50 @@
<div class="sectionlist normallist">
<div class="heading">
- <a name="reference"></a>
- <h2 id="reference">Qt VS Tools Manual</h2>
+ <h2>Getting Started</h2>
</div>
<div class="indexboxcont indexboxbar">
<ul>
- <li><a href="qtvstools-getting-started.html">Getting Started</a></li>
- <li><a href="qtvstools-managing-projects.html">Managing Projects</a></li>
- <li><a href="qtvstools-form-files.html">Adding Form Files to Projects</a></li>
- <li><a href="qtvstools-managing-resources.html">Managing Resources</a></li>
- <li><a href="qtvstools-translation-files.html">Creating Qt Translation Files for Projects</a></li>
- <li><a href="qtvstools-faq.html">FAQ</a></li>
+ <li><a href="qtvstools-qt-widgets-application.html">Tutorial: Qt Widgets Application</a></li>
+ <li><a href="qtvstools-qt-quick-application.html">Tutorial: Qt Quick Application</a></li>
</ul>
</div>
+</div>
+<div class="sectionlist normallist">
+ <div class="heading">
+ <h2>Configuring Builds</h2>
+ </div>
+ <ul>
+ <li><a href="qtvstools-managing-qt-versions.html">Managing Qt Versions</a></li>
+ <li><a href="qtvstools-building.html">Building</a></li>
+ <li><a href="qtvstools-cross-compiling.html">Cross-Compiling</a></li>
+ <li><a href="qtvstools-importing-and-exporting-projects.html">Importing and Exporting Projects</a></li>
+ </ul>
+</div>
+<div class="sectionlist normallist">
+ <div class="heading">
+ <h2>Managing Projects</h2>
+ </div>
+ <ul>
+ <li><a href="qtvstools-creating-projects.html">Creating Projects</a></li>
+ <li><a href="qtvstools-creating-files.html">Creating Files</a></li>
+ </ul>
+</div>
+<div class="sectionlist normallist">
+ <ul>
+ <li><a href="qtvstools-intellisense-info.html">Updating IntelliSense Info</a></li>
+ </ul>
+</div>
+<div class="sectionlist normallist">
+ <div class="heading">
+ <h2>Debugging</h2>
+ </div>
+ <ul>
+ <li><a href="qtvstools-debugging-qt-quick.html">Debugging Qt Quick Applications</a></li>
+ <li><a href="qtvstools-debugging-linux.html">Debugging on Linux</a></li>
+ </ul>
+</div>
+<div class="sectionlist normallist">
+ <ul>
+ <li><a href="qtvstools-getting-help.html">Getting Help</a></li>
+ </ul>
+</div>
diff --git a/doc/images/front-advanced.png b/doc/images/front-advanced.png
new file mode 100644
index 0000000..87780aa
--- /dev/null
+++ b/doc/images/front-advanced.png
Binary files differ
diff --git a/doc/images/front-coding.png b/doc/images/front-coding.png
new file mode 100644
index 0000000..edfc550
--- /dev/null
+++ b/doc/images/front-coding.png
Binary files differ
diff --git a/doc/images/front-gs.png b/doc/images/front-gs.png
new file mode 100644
index 0000000..27706a8
--- /dev/null
+++ b/doc/images/front-gs.png
Binary files differ
diff --git a/doc/images/front-help.png b/doc/images/front-help.png
new file mode 100644
index 0000000..d2f9d42
--- /dev/null
+++ b/doc/images/front-help.png
Binary files differ
diff --git a/doc/images/front-preview.png b/doc/images/front-preview.png
new file mode 100644
index 0000000..fe7aab3
--- /dev/null
+++ b/doc/images/front-preview.png
Binary files differ
diff --git a/doc/images/front-projects.png b/doc/images/front-projects.png
new file mode 100644
index 0000000..69414f4
--- /dev/null
+++ b/doc/images/front-projects.png
Binary files differ
diff --git a/doc/images/qtvstools-msbuild-diagram.png b/doc/images/qtvstools-msbuild-diagram.png
new file mode 100644
index 0000000..e136170
--- /dev/null
+++ b/doc/images/qtvstools-msbuild-diagram.png
Binary files differ
diff --git a/doc/images/qtvstools-options-qt-general.png b/doc/images/qtvstools-options-qt-general.png
new file mode 100644
index 0000000..6d1e62a
--- /dev/null
+++ b/doc/images/qtvstools-options-qt-general.png
Binary files differ
diff --git a/doc/images/qtvstools-qt-project-settings.png b/doc/images/qtvstools-qt-project-settings.png
index c7f7bc2..1367921 100644
--- a/doc/images/qtvstools-qt-project-settings.png
+++ b/doc/images/qtvstools-qt-project-settings.png
Binary files differ
diff --git a/doc/images/qtvstools-qt-translation-file-wizard.png b/doc/images/qtvstools-qt-translation-file-wizard.png
new file mode 100644
index 0000000..c39e3c5
--- /dev/null
+++ b/doc/images/qtvstools-qt-translation-file-wizard.png
Binary files differ
diff --git a/doc/images/qtvstools-qt-widget-class-wizard.png b/doc/images/qtvstools-qt-widget-class-wizard.png
index e6a30dd..37aba74 100644
--- a/doc/images/qtvstools-qt-widget-class-wizard.png
+++ b/doc/images/qtvstools-qt-widget-class-wizard.png
Binary files differ
diff --git a/doc/images/qtvstools-qtquick-app-modules.png b/doc/images/qtvstools-qtquick-app-modules.png
new file mode 100644
index 0000000..9c8054d
--- /dev/null
+++ b/doc/images/qtvstools-qtquick-app-modules.png
Binary files differ
diff --git a/doc/images/qtvstools-quick-addressbook-entries.png b/doc/images/qtvstools-quick-addressbook-entries.png
new file mode 100644
index 0000000..e283e38
--- /dev/null
+++ b/doc/images/qtvstools-quick-addressbook-entries.png
Binary files differ
diff --git a/doc/images/qtvstools-quick-addressbook-mainwindow.png b/doc/images/qtvstools-quick-addressbook-mainwindow.png
new file mode 100644
index 0000000..94b5a82
--- /dev/null
+++ b/doc/images/qtvstools-quick-addressbook-mainwindow.png
Binary files differ
diff --git a/doc/images/qtvstools-quick-addressbook-popup.png b/doc/images/qtvstools-quick-addressbook-popup.png
new file mode 100644
index 0000000..d5de412
--- /dev/null
+++ b/doc/images/qtvstools-quick-addressbook-popup.png
Binary files differ
diff --git a/doc/images/qtvstools-remote-debugging.png b/doc/images/qtvstools-remote-debugging.png
new file mode 100644
index 0000000..2a083a7
--- /dev/null
+++ b/doc/images/qtvstools-remote-debugging.png
Binary files differ
diff --git a/doc/qtvstools-online.qdocconf b/doc/qtvstools-online.qdocconf
index 95d3f7c..6cb5590 100644
--- a/doc/qtvstools-online.qdocconf
+++ b/doc/qtvstools-online.qdocconf
@@ -3,7 +3,7 @@
HTML.footer = \
" </div>\n" \
" <p class=\"copy-notice\">\n" \
- " <acronym title=\"Copyright\">©</acronym> 2016 The Qt Company Ltd.\n" \
+ " <acronym title=\"Copyright\">©</acronym> 2022 The Qt Company Ltd.\n" \
" Documentation contributions included herein are the copyrights of\n" \
" their respective owners. " \
" The documentation provided herein is licensed under the terms of the" \
diff --git a/doc/src/qtvstools.qdoc b/doc/src/qtvstools.qdoc
index 1b0eda9..85ef0fa 100644
--- a/doc/src/qtvstools.qdoc
+++ b/doc/src/qtvstools.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -36,10 +36,93 @@
or tools. You can install and update Qt VS Tools directly from Microsoft
Visual Studio.
+ \table
+ \row
+ \li {4,1} \b {\l{All Topics}}
+ \row
+ \li \inlineimage front-gs.png
+ \li \inlineimage front-advanced.png
+ \li \inlineimage front-projects.png
+ \row
+ \li \b {\l{Getting Started}}
+ \list
+ \li \l {Tutorial: Qt Widgets Application}
+ \li \l {Tutorial: Qt Quick Application}
+ \endlist
+ \li \b {\l {Configuring Builds}}
+ \list
+ \li \l {Managing Qt Versions}
+ \li \l {Building}
+ \li \l {Cross-Compiling}
+ \li \l {Importing and Exporting Projects}
+ \endlist
+ \li \b {\l {Managing Projects}}
+ \list
+ \li \l {Creating Projects}
+ \li \l {Creating Files}
+ \endlist
+ \row
+ \li \inlineimage front-coding.png
+ \li \inlineimage front-preview.png
+ \li \inlineimage front-help.png
+ \row
+ \li \b {\l {Updating IntelliSense Info}}
+ \li \b {\l {Debugging}}
+ \list
+ \li \l {Debugging Qt Quick Applications}
+ \li \l {Debugging on Linux}
+ \endlist
+ \li \b {\l {Getting Help}}
+ \endtable
+*/
+
+/*!
+ \page qtvstools-toc.html
+ \title All Topics
+
+ \list
+ \li \l {Getting Started}
+ \list
+ \li \l {Tutorial: Qt Widgets Application}
+ \li \l {Tutorial: Qt Quick Application}
+ \endlist
+ \li \l {Configuring Builds}
+ \list
+ \li \l {Managing Qt Versions}
+ \li \l {Building}
+ \li \l {Cross-Compiling}
+ \li \l {Importing and Exporting Projects}
+ \endlist
+ \li \l {Managing Projects}
+ \list
+ \li \l {Creating Projects}
+ \li \l {Creating Files}
+ \list
+ \li \l {Adding Form Files}
+ \li \l {Managing Resources}
+ \li \l {Creating Qt Translation Files}
+ \endlist
+ \endlist
+ \li \l {Updating IntelliSense Info}
+ \li \l {Debugging}
+ \list
+ \li \l {Debugging Qt Quick Applications}
+ \li \l {Debugging on Linux}
+ \endlist
+ \li \l {Getting Help}
+ \endlist
+*/
+
+/*!
+ \page qtvstools-getting-started.html
+ \previouspage Qt VS Tools Manual
+ \nextpage Tutorial: Qt Widgets Application
+ \title Getting Started
+
The main features of Qt VS Tools are:
\list
- \li Wizards for creating new Qt projects and classes.
+ \li Wizards for creating new Qt and Qt Quick projects and files.
\li Automated build setup for the \l {Using the Meta-Object Compiler
(moc)}{Meta-Object Compiler (moc)}, \l {User Interface Compiler
(uic)}, and \l {Resource Compiler (rcc)}.
@@ -55,36 +138,6 @@
\li Debugging extensions for Qt data types.
\endlist
- \section1 Table of Contents
-
- \list
- \li \l {Getting Started}
- \li \l {Managing Qt Versions}
- \li \l {Building}
- \li \l {Cross-Compiling}
- \li \l {Creating Projects}
- \li \l {Importing and Exporting Projects}
- \li \l {Adding Form Files to Projects}
- \li \l {Managing Resources}
- \li \l {Creating Qt Translation Files for Projects}
- \li \l {Updating IntelliSense Info}
- \li \l {Getting Help}
- \endlist
-*/
-
-/*!
- \page qtvstools-getting-started.html
- \previouspage Qt VS Tools Manual
- \nextpage Managing Qt Versions
- \title Getting Started
-
- This tutorial illustrates how to use Qt VS Tools to create a \l {Qt Widgets}
- application. You will create a project using a project wizard and design a
- widget-based UI using \QD. In addition, you will learn how to convert a
- Microsoft Visual Studio project file into a qmake compatible \c .pro file.
-
- You can use Qt VS Tools to develop also \l{Qt Quick} applications.
-
\section1 Install Qt VS Tools
In Microsoft Visual Studio, select \uicontrol Extensions >
@@ -97,6 +150,40 @@
To create a Qt VS Tools project, you must add at least one
\l{Managing Qt Versions}{Qt version}.
+ \section1 Create a Project
+
+ Follow the tutorials to create your first applications:
+
+ \list
+ \li \l {Tutorial: Qt Widgets Application}
+ \li \l {Tutorial: Qt Quick Application}
+ \endlist
+
+ For all the options you have, see \l {Creating Projects}.
+*/
+
+/*!
+ \page qtvstools-qt-widgets-application.html
+ \previouspage Getting Started
+ \nextpage Tutorial: Qt Quick Application
+ \title Tutorial: Qt Widgets Application
+
+ This tutorial illustrates how to use Qt VS Tools to create a \l {Qt Widgets}
+ application. You will create a project using a project wizard and design a
+ widget-based UI using \QD. In addition, you will learn how to convert a
+ Microsoft Visual Studio project file into a qmake compatible \c .pro file.
+
+ You can use Qt VS Tools to develop also \l{Qt Quick} applications.
+
+ \section1 Before You Start
+
+ Before you start, you have to:
+
+ \list
+ \li \l {Install Qt VS Tools}
+ \li \l {Add a Qt Version}
+ \endlist
+
\section1 Create a Qt Widgets Application Project
To create a Qt Widgets application project in Visual Studio:
@@ -104,8 +191,9 @@
\list 1
\li Select \uicontrol File > \uicontrol New > \uicontrol Project, and
search for \uicontrol {Qt Widgets Application}.
- \li In the \uicontrol Name field, enter \e AddressBook, and then select
- \uicontrol OK.
+ \li Select the project wizard, and then select \uicontrol Next.
+ \li In the \uicontrol {Project name} field, enter \e AddressBook,
+ and then select \uicontrol OK.
\li To acknowledge the \uicontrol Welcome dialog, select
\uicontrol Next.
\li Set up the \uicontrol Debug build configuration and select the
@@ -407,9 +495,366 @@
*/
/*!
+ \page qtvstools-qt-quick-application.html
+ \previouspage Tutorial: Qt Widgets Application
+ \nextpage Configuring Builds
+ \title Tutorial: Qt Quick Application
+
+ This tutorial illustrates how to use Qt VS Tools to create a \l {Qt Quick}
+ application. You will create a project using a project wizard and design a
+ Qt Quick UI. In addition, you will learn how to add QML module definitions
+ and QML files to your projects.
+
+ You can use Qt VS Tools to develop also \l{Qt Widgets} applications.
+
+ \section1 Before You Start
+
+ Before you start, you have to:
+
+ \list
+ \li \l {Install Qt VS Tools}
+ \li \l {Add a Qt Version}
+ \endlist
+
+ \section1 Create a Qt Quick Application Project
+
+ To create a Qt Quick application project in Visual Studio:
+
+ \list 1
+ \li Select \uicontrol File > \uicontrol New > \uicontrol Project, and
+ search for \uicontrol {Qt Quick Application}.
+ \li Select the project wizard, and then select \uicontrol Next.
+ \li In the \uicontrol {Project name} field, enter \e QuickAddressBook,
+ and then select \uicontrol Create.
+ \li To acknowledge the \uicontrol Welcome dialog, select
+ \uicontrol Next.
+ \li To set up debug and release build configurations, click in
+ \uicontrol {Quick Modules}, and select the \uicontrol {Quick} and
+ \uicontrol {Quick Controls2} modules to include in the project:
+ \image qtvstools-qtquick-app-modules.png "Selecting Qt modules in Qt Quick Application Wizard"
+ \li Select \uicontrol Finish to create the project.
+ \endlist
+
+ You now have a small working Qt Quick application. Select \uicontrol Build >
+ \uicontrol {Build Solution} to build it, and then select \uicontrol Debug >
+ \uicontrol {Start Debugging} to run it. For now, the result is an empty
+ window.
+
+ \section1 Design the Main Window
+
+ The wizard created a main QML file for you, which declares a root object of
+ the type \l Window. You can modify the file to design the application's main
+ window.
+
+ Specify values for the Window \c color and \c title properties to set the
+ background color and title of the application main window:
+
+ \quotefromfile QuickAddressBook/main.qml
+ \skipto Window {
+ \printuntil title
+
+ \section2 Add a Button
+
+ To create the \uicontrol Add button, declare an object of the \l Button type
+ from the \l {Qt Quick Controls} module. Set the value of the button \c text
+ property to \e Add and the value of the \c font.pointSize property to \e 24:
+
+ \skipto Button {
+ \printuntil font.pointSize
+
+ When you run the application, you should now see this:
+
+ \image qtvstools-quick-addressbook-mainwindow.png QuickAddressBook's main window
+
+ \section2 Connect the Button to an Action
+
+ QML has a signal and handler mechanism, where the signal is the event and
+ the signal is responded to through a signal handler. When a signal is
+ emitted, the corresponding signal handler is invoked. Placing logic such
+ as a script or other operations in the handler allows the component to
+ respond to the event.
+
+ To receive a notification when a particular signal is emitted for a
+ particular object, the object definition should declare a signal handler
+ named \c on<Signal>, where \c <Signal> is the name of the signal, with
+ the first letter capitalized. The signal handler should contain the
+ JavaScript code to be executed when the signal handler is invoked.
+
+ The \l Button type has a \c clicked signal, which is emitted when the users
+ click the button. To invoke a popup for adding an address book entry when
+ the users select the \uicontrol Add button in the main window, you must
+ connect the \c onClicked signal handler of the button to the \c open()
+ method of the popup. You will add the popup as a separate QML type later.
+
+ \printuntil }
+
+ \section2 Add a List Model
+
+ \image qtvstools-quick-addressbook-entries.png QuickAddressBook entries
+
+ Within the Window, declare an object of the \l ListModel type with the
+ \c id \e addressList for storing the contact data. A list model defines
+ a free-form list data source:
+
+ \quotefromfile QuickAddressBook/main.qml
+ \skipto ListModel {
+ \printuntil }
+
+ \section2 Declare a Popup
+
+ Declare an object of the custom \c NewAddressPopup type that
+ defines the popup where the users will add address book entries.
+ Use the \c onAddressAdded signal handler to determine that address
+ book entries are appended to the \e addressList model:
+
+ \printuntil }
+ \printuntil }
+
+ You will create the \c NewAddressPopup type later.
+
+ \section2 Position the Button
+
+ Declare an object of \l ColumnLayout type to position the \l Button object
+ and an instance of the \l Repeater type:
+
+ \printuntil }
+
+ Anchor the column layout to the left and right edges of its parent to make
+ the application scalable on different screen sizes. Set the \c spacing
+ between the rows in the column to \e 0.
+
+ \section2 Add a Repeater
+
+ The \l Repeater type is used to create a large number of similar items. It
+ has a model and a delegate: for each entry in the model, the delegate is
+ instantiated in a context seeded with data from the model. A repeater is
+ usually enclosed in an instance of a positioner type such as a
+ \l ColumnLayout to visually position the multiple delegate items created
+ by the repeater.
+
+ Specify \e addressList as the \c model to use for the repeater:
+
+ \printuntil anchors.right
+
+ Declare an object of the custom \c AddressBookItem type that the
+ repeater will use to instantiate address book entries:
+
+ \printuntil id:
+
+ You will create the \c AddressBookItem type later.
+
+ \section2 Connect the Remove Button to an Action
+
+ Use the \c onRemoved signal handler to specify that an address book entry
+ is removed from the list when the users click the \uicontrol Remove button
+ for an address book entry.
+
+ \printuntil }
+
+ \section1 Add a Popup
+
+ Now that the main window is ready, you can move on to create the popup
+ where users can add address book entries. The data that the
+ users enter is instantiated by the repeater in the main window, as
+ specified by the \c AddressBookItem type.
+
+ \image qtvstools-quick-addressbook-popup.png QuickAddressBook's popup
+
+ You can use a Qt file wizard in Visual Studio to create a custom type
+ that defines the popup.
+
+ To create custom QML types, you must first add a QML Module Definition
+ (\c qmldir) file to the project.
+
+ \section2 Add a QML Module Definition
+
+ A QML module definition (\c qmldir) maps each custom QML type to its
+ corresponding source file.
+
+ To add a QML module definition, select \uicontrol Project >
+ \uicontrol {Add New Item} > \uicontrol Qt >
+ \uicontrol {Qt QML Module Definition} > \uicontrol Add.
+
+ In the \c qmldir file, add QML type definitions for \e AddressBookItem and
+ \e NewAddressPopup:
+
+ \quotefile QuickAddressBook/qmldir
+
+ Next, you will create the QML types.
+
+ \section2 Create a Popup
+
+ To add a custom QML type to the project:
+
+ \list 1
+ \li Select \uicontrol Project > \uicontrol {Add New File} >
+ \uicontrol Qt > \uicontrol {Qt QML File} > \uicontrol Add.
+ \li In the \uicontrol Name field, enter \e NewAddressPopup.
+ \li Select \uicontrol Finish to create a custom QML type.
+ \endlist
+
+ \section2 Design the Popup
+
+ In \e NewAddressPopup.qml, declare a root object of the type \l Popup to
+ create a popup that can be opened within a \l Window. A popup does not
+ provide a layout of its own, so you will use a \l ColumnLayout and a
+ \l RowLayout to position the \uicontrol Name and \uicontrol {E-Mail Address}
+ fields.
+
+ \quotefromfile QuickAddressBook/QuickAddressBookTypes/NewAddressPopup.qml
+ \skipto Popup {
+ \printuntil id:
+
+ Set the \c modal property to \c true to specify that the popup is modal. Set
+ the \c focus property to \c true to specify that the popup requests focus:
+
+ \printuntil focus:
+
+ Specify values for the \c width, \c x, and \c y properties to determine the
+ position and size of the popup on top of the main window:
+
+ \printuntil y:
+
+ \section2 Reset Popup Controls
+
+ When the popup opens, the \uicontrol Name and \uicontrol {E-Mail Address}
+ fields should display placeholder text and any values entered previously
+ should be cleared. You use the \c onOpened signal handler to reset the
+ values of the fields and give focus to the \uicontrol Name field:
+
+ \printuntil }
+
+ \section2 Position Fields
+
+ Use an instance of the \l ColumnLayout type to position the \l TextField
+ objects that specify the \uicontrol Name and \uicontrol {E-Mail Address}
+ fields of the popup:
+
+ \skipto ColumnLayout {
+ \printuntil id: addrField
+ \printuntil }
+ \printuntil }
+
+ \section2 Position Buttons
+
+ Use an instance of a \l RowLayout type to position two \l Button objects
+ that specify the \uicontrol Add and \uicontrol Cancel buttons:
+
+ \printuntil Layout.fillWidth: true
+
+ \section2 Connect Buttons to Actions
+
+ When the users click the \uicontrol Add button, the values they entered to
+ the \uicontrol Name and \uicontrol {E-Mail Address} fields are added to the
+ address list in the main window and the popup is closed.
+
+ To enable this, add the \c {addressAdded(string newName, string newAddr)}
+ signal:
+
+ \quotefromfile QuickAddressBook/QuickAddressBookTypes/NewAddressPopup.qml
+ \skipto addressAdded(
+ \printuntil )
+
+ Connect the \c onClicked signal handler of the \uicontrol Add button to
+ the \c addressAdded() signal and to the popup's \c close() method:
+
+ \skipto Button {
+ \printuntil }
+ \printuntil }
+
+ For the \uicontrol Cancel button, connect the \c onClicked signal handler to
+ the to the popup's \c close() method to close the popup without saving the
+ data:
+
+ \printuntil }
+
+ \section1 Define an Address Book Entry
+
+ Address book entries are presented in the main window as specified by a
+ custom \c AddressBookItem type.
+
+ Select \uicontrol Project > \uicontrol {Add New File} > \uicontrol Qt >
+ \uicontrol {Qt QML File} > \uicontrol Add, to create a new QML file
+ called \e AddressBookItem.qml.
+
+ \section2 Design the Entry
+
+ First, you will declare a root object of type \l Rectangle. It is one of the
+ basic building blocks you can use to create an application in QML. Give it
+ an \c id to be able to refer to it later.
+
+ \quotefromfile QuickAddressBook/QuickAddressBookTypes/AddressBookItem.qml
+ \skipto Rectangle {
+ \printuntil id:
+
+ To use alternating colors for rows, set the value of the \c color property:
+
+ \printuntil color:
+
+ Anchor the rectangle to the left and right edges of its parent to make
+ the application scalable on different screen sizes. Bind the rectangle
+ \c height property to the height of the text items it will contain:
+
+ \printuntil height:
+
+ \section2 Connect the Remove Button to an Action
+
+ Add the \c removed() signal that you will connect to the \onClicked
+ signal handler of the remove button. This removes an address book entry
+ from the main window when users click the button:
+
+ \printuntil signal removed()
+
+ \section2 Position the Button and Text
+
+ Use instances of the \l RoundButton and \l Text types within an instance of
+ a \l RowLayout type to define an address book entry:
+
+ \printuntil }
+
+ \section2 Format the Text
+
+ Set the value of the \c text property to combine the values of the \c name
+ and \c addr fields from the popup and to use bold and italic formatting for
+ the values:
+
+ \printuntil }
+
+ Your application is now complete.
+
+ \section1 Create Project Files
+
+ To build the application on other platforms, you need to create a \c .pro
+ file for the project, as instructed in \l{Create Qt Project Files}.
+
+*/
+
+/*!
+ \page qtvstools-managing-projects.html
+ \previouspage Importing and Exporting Projects
+ \nextpage Creating Projects
+ \title Managing Projects
+
+ Qt VS Tools provides wizards for creating several types of Qt and Qt Quick
+ projects and files that you can add to the projects, such as classes, form
+ files, or custom QML types.
+
+ You can use the integrated Qt Resource editor to manage the resources in
+ Qt projects.
+
+ In addition, you can create a Qt translation source (TS) file and start
+ \QL from Visual Studio to translate the strings in your application.
+
+ \list
+ \li \l {Creating Projects}
+ \li \l {Creating Files}
+ \endlist
+*/
+
+/*!
\page qtvstools-creating-projects.html
- \previouspage Cross-Compiling
- \nextpage Importing and Exporting Projects
+ \previouspage Managing Projects
+ \nextpage Creating Files
\title Creating Projects
Once you have installed Qt VS Tools, you can search for and then select
@@ -439,11 +884,158 @@
To start writing Qt code and building your projects, you must tell Visual
Studio where to find the \l{Managing Qt Versions}{Qt version} that you want
to use.
+
+ The application tutorials contain examples of using the project templates:
+
+ \list
+ \li \l {Tutorial: Qt Widgets Application}
+ \li \l {Tutorial: Qt Quick Application}
+ \endlist
+*/
+
+/*!
+ \page qtvstools-creating-files.html
+ \previouspage Creating Projects
+ \nextpage Adding Form Files
+ \title Creating Files
+
+ You can use file templates to add the following types of files to projects
+ by selecting \uicontrol Project > \uicontrol {Add New Item} >
+ \uicontrol Installed > \uicontrol {Visual C++} > \uicontrol Qt:
+
+ \list
+ \li \uicontrol {Qt Class} adds a Qt class to an Application project.
+ \li \uicontrol {Qt Dialog Form File (Button Bottom)} adds a dialog with
+ \uicontrol OK and \uicontrol Cancel buttons at its bottom to a
+ Qt Widgets Application project.
+ \li \uicontrol {Qt Dialog Form File (Button Right)} adds a dialog with
+ buttons at its right edge to a Qt Widgets Application project.
+ \li \uicontrol {Qt MainWindow Form File} adds a form file to a
+ Qt Widgets Application project.
+ \li \uicontrol {Qt QML File} adds a custom QML type to a Qt Quick
+ Application project.
+ \li \uicontrol {Qt QML Module Definition} adds a qmldir file that
+ specifies the custom QML types used in a Qt Quick Application
+ project.
+ \li \uicontrol {Qt Resource File} adds a Qt resource file (.qrc) to
+ an Application project.
+ \li \uicontrol {Qt Translation File} adds a Qt translation file (.ts)
+ to an Application project.
+ \li \uicontrol {Qt Widget Class} adds a Qt Widgets class to a
+ Qt Widgets Application project.
+ \li \uicontrol {Qt Widget Form File} adds a Qt Widgets form file (.ui)
+ to an Application project.
+ \endlist
+
+ The following sections describe how to add different types of files to
+ projects:
+
+ \list
+ \li \l {Adding Form Files}
+ \li \l {Managing Resources}
+ \li \l {Creating Qt Translation Files}
+ \endlist
+
+ The application tutorials contain examples of using file templates to add
+ files to projects:
+
+ \list
+ \li \l {Tutorial: Qt Widgets Application}
+ \li \l {Tutorial: Qt Quick Application}
+ \endlist
+*/
+
+/*!
+ \page qtvstools-configuring-builds.html
+ \previouspage Tutorial: Qt Quick Application
+ \nextpage Managing Qt Versions
+ \title Configuring Builds
+
+ In Visual Studio, C++ projects are built using the Project System,
+ where MSBuild provides the project file format and build framework.
+ Qt VS Tools make use of the extensibility of MSBuild to provide
+ design-time and build-time integration of Qt in Visual Studio projects.
+
+ Qt uses \c .pro files with \l {qmake Manual}{qmake} to build projects,
+ whereas Visual Studio uses \c .vcproj files. Qt VS Tools enables you to
+ import Qt project files into Visual Studio and export them back into
+ Qt build files. In addition, you can convert Qt VS Tools projects into
+ a qmake project, or the other way around.
+
+ \list
+ \li \l {Managing Qt Versions}
+ \li \l {Building}
+ \li \l {Cross-Compiling}
+ \li \l {Importing and Exporting Projects}
+ \endlist
+
+ \section1 MSBuild Configurations
+
+ At very general level, MSBuild might be described as follows:
+
+ \list
+ \li An MSBuild project consists of references to source files and
+ descriptions of actions to take in order to process those source
+ files that are called \e targets.
+ \li The build process runs in the context of a project configuration,
+ such as \e Debug or \e Release. A project may contain any number
+ of configurations.
+ \li Data associated to source files and the project itself is accessible
+ through \e properties. MSBuild properties are name-value definitions,
+ specified per configuration. That is, each configuration has its own
+ set of property definitions.
+ \endlist
+
+ \image qtvstools-msbuild-diagram.png "Diagram showing Visual Studio Project and MSBuild"
+
+ \section2 Properties
+
+ Properties may apply to the project itself or to a specific file in the
+ project, and can be defined either globally or locally:
+
+ \list
+ \li Project scope properties are always global. For example, the
+ project's output directory or target file name.
+ \li Properties applied to source files can be defined globally, in
+ which case the same value will apply to all files. For example,
+ the default compiler warning level could be defined globally at
+ level 3.
+ \li Such a global, file-scope definition may be overridden for a
+ specific file by a locally defined property with the same name.
+ For example, one of the source files needs to be compiled with
+ warning level 4.
+ \li Global definitions are stored in the project file or imported from
+ property sheet files.
+ \li Local property definitions are stored in the project file, within
+ the associated source file references.
+ \endlist
+
+ \section2 Qt Settings
+
+ Qt Visual Studio Tools integrate with the MSBuild project system by
+ providing a set of Qt-specific targets that describe how to process
+ files such as moc headers by using the appropriate Qt tools.
+
+ \image qtvstools-qt-project-settings.png "Qt Project Settings"
+
+ Qt settings are fully-fledged project properties, which ensures that:
+
+ \list
+ \li Changes in Qt settings are synchronized with all the other
+ properties in the project.
+ \li You can specify Qt settings, such as Qt versions and modules,
+ separately for each build configuration.
+ \li You can override compiler properties for files generated by
+ Qt tools in project settings
+ \li You can share Qt settings within a team or organization by
+ exporting and importing them to and from shared \e {property sheet}
+ files (\c .props).
+ \endlist
*/
/*!
\page qtvstools-managing-qt-versions.html
- \previouspage Getting Started
+ \previouspage Configuring Builds
\nextpage Building
\title Managing Qt Versions
@@ -529,7 +1121,7 @@
/*!
\page qtvstools-cross-compiling.html
\previouspage Building
- \nextpage Creating Projects
+ \nextpage Importing and Exporting Projects
\title Cross-Compiling
Qt VS Tools supports cross-compilation of Qt projects by integrating
@@ -589,8 +1181,8 @@
/*!
\page qtvstools-importing-and-exporting-projects.html
- \previouspage Creating Projects
- \nextpage Adding Form Files to Projects
+ \previouspage Cross-Compiling
+ \nextpage Managing Projects
\title Importing and Exporting Projects
Qt and Visual Studio use different file formats to save projects. If you
@@ -659,16 +1251,16 @@
/*!
\page qtvstools-form-files.html
- \previouspage Importing and Exporting Projects
+ \previouspage Creating Files
\nextpage Managing Resources
- \title Adding Form Files to Projects
+ \title Adding Form Files
You can start \QD from Qt VS Tools by double-clicking a \c .ui file. For
more information about using \QD, see the \l{Qt Designer Manual}.
To add a new \c .ui file to the project, select \uicontrol Project >
- \uicontrol {Add Qt Class} > \uicontrol Installed > \uicontrol {Visual C++} >
- \uicontrol Qt > \uicontrol {Qt Widget Class}.
+ \uicontrol {Add New Item} > \uicontrol Installed > \uicontrol {Visual C++} >
+ \uicontrol Qt > \uicontrol {Qt Widgets Form File}.
\image qtvstools-qt-widget-class-wizard.png
@@ -679,8 +1271,8 @@
/*!
\page qtvstools-managing-resources.html
- \previouspage Adding Form Files to Projects
- \nextpage Creating Qt Translation Files for Projects
+ \previouspage Adding Form Files
+ \nextpage Creating Qt Translation Files
\title Managing Resources
Adding new resources to a Qt project is similar to adding resources to a
@@ -727,18 +1319,20 @@
\page qtvstools-translation-files.html
\previouspage Managing Resources
\nextpage Updating IntelliSense Info
- \title Creating Qt Translation Files for Projects
+ \title Creating Qt Translation Files
To add a new translation file to the project:
+ \image qtvstools-qt-translation-file-wizard.png
+
\list 1
- \li Select \uicontrol Extensions > \uicontrol {Qt VS Tools} >
- \uicontrol {Create New Translation File}.
- \li In the \uicontrol Language field, select a language from the list of
- supported languages.
- \li In the \uicontrol Filename field, enter a filename for the
- translation file.
- \li Select \uicontrol OK to create the file and have it listed in
+ \li Select \uicontrol Project > \uicontrol {Add New Item} > \uicontrol Installed >
+ \uicontrol {Visual C++} > \uicontrol Qt > \uicontrol {Qt Translation File}.
+ \li In \uicontrol {Select a Language}, you can choose a language from the list
+ of supported languages. You can use \uicontrol Search to filter for a specific
+ language.
+ \li In the \uicontrol {Save as} field, enter a filename for the translation file.
+ \li Select \uicontrol Finish to create the file and have it listed in
\uicontrol {Translation Files} in Visual Studio's Solution Explorer.
\li Right-click a translation file to open a context menu with options
for running \c lupdate and \c lrelease.
@@ -761,7 +1355,7 @@
/*!
\page qtvstools-getting-help.html
- \previouspage Updating IntelliSense Info
+ \previouspage Debugging on Linux
\title Getting Help
By default, Qt VS Tools tries to display Qt online documentation when you
@@ -790,8 +1384,8 @@
/*!
\page qtvstools-intellisense-info.html
- \previouspage Creating Qt Translation Files for Projects
- \nextpage Getting Help
+ \previouspage Creating Qt Translation Files
+ \nextpage Debugging
\title Updating IntelliSense Info
Visual Studio provides IntelliSense code editing features for C++ types
@@ -822,6 +1416,164 @@
\li \uicontrol {Verbosity of background build log} determines the amount
of info recorded in the background build log.
\endlist
-
*/
+/*!
+ \page qtvstools-debugging.html
+ \previouspage Updating IntelliSense Info
+ \nextpage Debugging Qt Quick Applications
+ \title Debugging
+
+ Visual Studio supports debugging Qt C++ applications using the Visual Studio
+ debugger and Qt Quick applications using the \e {QML debug engine}. To debug
+ applications on Linux, you can use GDB.
+
+ You can debug Qt and Qt Quick applications in Visual Studio by setting
+ breakpoints in C++ and QML files and stepping through the execution of code.
+ While in break mode, you can watch variables and change their values, as
+ well as evaluate arbitrary expressions. For Qt Quick applications, a QML
+ debugging session runs concurrently to a C++ debugging session, which
+ enables you to set breakpoints and watch variables in both C++ and QML
+ during the same debugging session.
+
+ To start a debugging session, select \uicontrol Debug >
+ \uicontrol {Start Debugging} or press \key F5.
+
+ \list
+ \li \l {Debugging Qt Quick Applications}
+ \li \l {Debugging on Linux}
+ \endlist
+*/
+
+/*!
+ \page qtvstools-debugging-qt-quick.html
+ \previouspage Debugging
+ \nextpage Debugging on Linux
+ \title Debugging Qt Quick Applications
+
+ A \e {QML debug engine} extends the Visual Studio debugger with features of
+ the \l{QML Debugging Infrastructure}{QML debugging infrastructure}, which is
+ a part of the \l{Qt QML} module that provides services for debugging,
+ inspecting, and profiling applications via a TCP port. The debug engine
+ implements interfaces from the Active Debugging 7 (AD7) extensibility
+ framework for the Visual Studio debugger.
+
+ If a Qt project contains QML resource files, starting a debugging session
+ (for example, by pressing \key F5) launches the native application and
+ connects to the QML debugging infrastructure of that application. This can
+ be seen in the Processes window of the Visual Studio debugger. Two processes
+ are listed: a native process that corresponds to the actual physical
+ process created for the C++ debugging session and a QML process that does
+ not correspond to any physical process that is running on the machine, but
+ rather represents the connection to the QML debugging runtime within the
+ native process.
+
+ The presence of both a native process and a QML process enables setting
+ breakpoints both in C++ or QML code. The Visual Studio debugger forwards
+ breakpoint requests to the appropriate debug engine. A filled circular
+ breakpoint marker in QML code indicates a valid breakpoint. This means that
+ a breakpoint request for that file position was sent to the QML runtime
+ and was confirmed by it.
+
+ When a breakpoint is hit, Visual Studio shows the current state of the call
+ stack. Unlike other scenarios of debugging applications that mix several
+ languages, such as .NET and native debugging, the QML debug engine does not
+ provide true mixed mode debugging. It runs concurrently with the native
+ debug engine and is not considered to be related to the native process by
+ the Visual Studio debugger. Therefore, even though you can debug both C++
+ and QML in the same debugging session, the stack that is shown when a QML
+ breakpoint is hit includes only QML function calls. The C++ context of those
+ calls will not be available.
+
+ As in the case of native debugging, while in break mode, it is possible to
+ view and modify the values of local variables in the context of the
+ currently active call stack frame, as well as to create watches for any
+ variable or expression. In the Immediate window, you can evaluate any
+ expression in the context of the current stack frame.
+
+ Move the mouse over a QML expression to display an instant watch window.
+ The value of that expression in the current context is displayed and can
+ be modified.
+
+ \section1 Enabling QML Debugging
+
+ QML debugging is enabled by default. To disable processing of all QML
+ debug events by the QML debug engine, select \uicontrol Extensions >
+ \uicontrol {Qt VS Tools} > \uicontrol Options > \uicontrol Qt
+ \uicontrol General > \uicontrol {QML Debugging}, and set
+ \uicontrol {Process debug events} to \uicontrol False.
+ This effectively excludes the QML debug engine from the debugging
+ environment and disables debugging of QML code for all projects.
+
+ \image qtvstools-options-qt-general.png "Qt General Options"
+
+ To increase or decrease the timeout for debugging connections in
+ milliseconds, edit the value of \uicontrol {Runtime connection timeout}.
+ To remove the timeout, set the value to \uicontrol Disabled.
+
+ For more information about debugging Qt Quick applications on Linux devices,
+ see \l {Remote QML Debugging}.
+*/
+
+/*!
+ \page qtvstools-debugging-linux.html
+ \previouspage Debugging Qt Quick Applications
+ \nextpage Getting Help
+ \title Debugging on Linux
+
+ If you have set up Qt VS Tools for \l {Cross-Compiling}{cross-compilation}
+ on Linux, you can debug applications running on a Linux devices. First
+ launch the application using \c gdbserver and then configure GDB to connect
+ to the device and start a remote debugging session.
+
+ \image qtvstools-remote-debugging.png
+
+ For this to work, the GDB installed in the WSL must support the target
+ device architecture. A simple way to achieve this is to install
+ \c gdb-multiarch. To ensure the Visual Studio uses the correct debugger,
+ create a symbolic link from \c gdb to \c gdb-multiarch.
+
+ To set up the remote debugging session in Visual Studio, you must
+ pass additional commands to GDB. Select \uicontrol Project >
+ \uicontrol Properties > \uicontrol Debugging, and then select
+ \uicontrol {GDB Debugger} in \uicontrol {Debugger to launch}. In
+ \uicontrol {Additional Debugger Commands}, add the following commands:
+
+ \badcode
+ target extended-remote <IP_address>:<port>
+ set remote exec-file <path_to_executable>
+ \endcode
+
+ Before starting the remote debugging session, set the required environment
+ variables and launch \c gdbserver on the device:
+
+ \list
+ \li \l{https://man7.org/linux/man-pages/man8/ld.so.8.html}
+ {LD_LIBRARY_PATH} specifies the path to the directory
+ where Qt binaries are installed.
+ \li \l {Qt for Embedded Linux}{QT_QPA_PLATFORM} specifies the platform
+ plugin, such as EGLFS, LinuxFB, DirectFB, or Wayland.
+ \li \c QT_QPA_PLATFORM_PLUGIN_PATH specifies the path to the
+ directory where the platform plugin is installed.
+ \li For the \l {EGLFS} platform, \c QT_QPA_EGLFS_PHYSICAL_WIDTH and
+ \c QT_QPA_EGLFS_PHYSICAL_HEIGHT specify the screen width and
+ height in millimeters.
+ \li \l{QML Import Path}{QML2_IMPORT_PATH} specifies the path to the
+ directory where QML modules are installed.
+ \endlist
+
+ Press \key F5 to start the remote debugging session.
+
+ \section1 Remote QML Debugging
+
+ To debug Qt Quick applications on Linux devices, \l{Enabling QML Debugging}
+ {enable QML debugging} and set up program arguments for starting a QML
+ debugging session. \uicontrol Project > \uicontrol Properties >
+ \uicontrol Debugging, and then select \uicontrol {GDB Debugger} in
+ \uicontrol {Debugger to launch}. In
+ \uicontrol {Additional Debugger Commands}, add the following command:
+
+ \badcode
+ -qmljsdebugger=port:<port>,host:<IP_address>,block
+ \endcode
+*/
diff --git a/doc/tutorial/AddressBook/adddialog.h b/doc/tutorial/AddressBook/adddialog.h
index 68b312d..13d05f2 100644
--- a/doc/tutorial/AddressBook/adddialog.h
+++ b/doc/tutorial/AddressBook/adddialog.h
@@ -48,6 +48,6 @@
Q_OBJECT
public:
- AddDialog(QWidget *parent = Q_NULLPTR);
+ AddDialog(QWidget *parent = nullptr);
~AddDialog();
};
diff --git a/doc/tutorial/QuickAddressBook/QuickAddressBook.sln b/doc/tutorial/QuickAddressBook/QuickAddressBook.sln
new file mode 100644
index 0000000..b774435
--- /dev/null
+++ b/doc/tutorial/QuickAddressBook/QuickAddressBook.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31919.166
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuickAddressBook", "QuickAddressBook.vcxproj", "{09DCDDDF-9469-4F20-84EF-7D8481C6FFE1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {09DCDDDF-9469-4F20-84EF-7D8481C6FFE1}.Debug|x64.ActiveCfg = Debug|x64
+ {09DCDDDF-9469-4F20-84EF-7D8481C6FFE1}.Debug|x64.Build.0 = Debug|x64
+ {09DCDDDF-9469-4F20-84EF-7D8481C6FFE1}.Release|x64.ActiveCfg = Release|x64
+ {09DCDDDF-9469-4F20-84EF-7D8481C6FFE1}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {7D002559-106F-4ED4-A8D0-DCF37C96FDA8}
+ EndGlobalSection
+EndGlobal
diff --git a/doc/tutorial/QuickAddressBook/QuickAddressBook.vcxproj b/doc/tutorial/QuickAddressBook/QuickAddressBook.vcxproj
new file mode 100644
index 0000000..005fe3f
--- /dev/null
+++ b/doc/tutorial/QuickAddressBook/QuickAddressBook.vcxproj
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+-->
+<Project ToolsVersion="$(VisualStudioVersion)" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{09DCDDDF-9469-4F20-84EF-7D8481C6FFE1}</ProjectGuid>
+ <Keyword>QtVS_v304</Keyword>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion Condition="'$(VisualStudioVersion)'=='15.0'">10.0.17763.0</WindowsTargetPlatformVersion>
+ <QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup>
+ <PlatformToolset Condition="'$(VisualStudioVersion)'=='15.0'">v141</PlatformToolset>
+ <PlatformToolset Condition="'$(VisualStudioVersion)'=='16.0'">v142</PlatformToolset>
+ <PlatformToolset Condition="'$(VisualStudioVersion)'=='17.0'">v143</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
+ <Import Project="$(QtMsBuild)\qt_defaults.props" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
+ <QtInstall>$(DefaultQtVersion)</QtInstall>
+ <QtModules>quick</QtModules>
+ <QtBuildConfig>debug</QtBuildConfig>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
+ <QtInstall>$(DefaultQtVersion)</QtInstall>
+ <QtModules>quick</QtModules>
+ <QtBuildConfig>release</QtBuildConfig>
+ </PropertyGroup>
+ <Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
+ <Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
+ </Target>
+ <ImportGroup Label="ExtensionSettings" />
+ <ImportGroup Label="Shared" />
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(QtMsBuild)\Qt.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(QtMsBuild)\Qt.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
+ <ClCompile>
+ <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <Optimization>MaxSpeed</Optimization>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp" />
+ <None Include="qmldir" />
+ <None Include="QuickAddressBookTypes\AddressBookItem.qml" />
+ <None Include="main.qml" />
+ <None Include="QuickAddressBookTypes\NewAddressPopup.qml" />
+ </ItemGroup>
+ <ItemGroup>
+ <QtRcc Include="qml.qrc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
+ <Import Project="$(QtMsBuild)\qt.targets" />
+ </ImportGroup>
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/doc/tutorial/QuickAddressBook/QuickAddressBook.vcxproj.filters b/doc/tutorial/QuickAddressBook/QuickAddressBook.vcxproj.filters
new file mode 100644
index 0000000..ae4de39
--- /dev/null
+++ b/doc/tutorial/QuickAddressBook/QuickAddressBook.vcxproj.filters
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="Translation Files">
+ <UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
+ <Extensions>ts</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <None Include="main.qml">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="QuickAddressBookTypes\AddressBookItem.qml">
+ <Filter>Source Files</Filter>
+ </None>
+ <None Include="qmldir">
+ <Filter>Source Files</Filter>
+ </None>
+ <None Include="QuickAddressBookTypes\NewAddressPopup.qml">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <QtRcc Include="qml.qrc">
+ <Filter>Resource Files</Filter>
+ </QtRcc>
+ </ItemGroup>
+</Project>
diff --git a/doc/tutorial/QuickAddressBook/QuickAddressBookTypes/AddressBookItem.qml b/doc/tutorial/QuickAddressBook/QuickAddressBookTypes/AddressBookItem.qml
new file mode 100644
index 0000000..7374265
--- /dev/null
+++ b/doc/tutorial/QuickAddressBook/QuickAddressBookTypes/AddressBookItem.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.9
+import QtQuick.Window 2.2
+import QtQuick.Controls 2.5
+import QtQuick.Layouts 1.12
+
+Rectangle {
+ id: addressBookItem
+ color: (index % 2) == 0 ? "dimgray" : "lightgray"
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: itemText.height + 12
+
+ signal removed()
+
+ RowLayout {
+ spacing: 12
+ anchors.left: parent.left
+ anchors.leftMargin: spacing
+ RoundButton {
+ id: deleteButton
+ text: "🗙"
+ font.pointSize: 12
+ palette.buttonText: "red"
+ onClicked: addressBookItem.removed()
+ }
+ Text {
+ id: itemText
+ font.pointSize: 24
+ text: "<b>" + name + "</b><br><i>" + addr + "</i>"
+ }
+ }
+}
diff --git a/doc/tutorial/QuickAddressBook/QuickAddressBookTypes/NewAddressPopup.qml b/doc/tutorial/QuickAddressBook/QuickAddressBookTypes/NewAddressPopup.qml
new file mode 100644
index 0000000..6513ec3
--- /dev/null
+++ b/doc/tutorial/QuickAddressBook/QuickAddressBookTypes/NewAddressPopup.qml
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.9
+import QtQuick.Window 2.2
+import QtQuick.Controls 2.5
+import QtQuick.Layouts 1.12
+
+Popup {
+ id: newAddressPopup
+ modal: true
+ focus: true
+ width: parent.width * 0.9
+ x: (parent.width - width) / 2
+ y: 35
+ onOpened: {
+ nameField.text = "";
+ addrField.text = "";
+ nameField.focus = true;
+ }
+
+ signal addressAdded(string newName, string newAddr)
+
+ ColumnLayout {
+ anchors.fill: parent
+ TextField {
+ id: nameField
+ placeholderText: qsTr("Name")
+ font.pointSize: 24
+ background: Rectangle { color: "lightgray" }
+ Layout.preferredWidth: newAddressPopup / 2
+ Layout.fillWidth: true
+ }
+ TextField {
+ id: addrField
+ placeholderText: qsTr("E-Mail Address")
+ font.pointSize: 24
+ background: Rectangle { color: "lightgray" }
+ Layout.preferredWidth: newAddressPopup / 2
+ Layout.fillWidth: true
+ }
+ RowLayout {
+ anchors.left: parent.left; anchors.right: parent.right
+ Button {
+ text: "Add"
+ enabled: nameField.length > 0 && addrField.length > 0
+ font.pointSize: 24
+ Layout.preferredWidth: newAddressPopup / 2
+ Layout.fillWidth: true
+ onClicked: {
+ newAddressPopup.addressAdded(nameField.text, addrField.text)
+ newAddressPopup.close()
+ }
+ }
+ Button {
+ text: "Cancel"
+ font.pointSize: 24
+ Layout.preferredWidth: newAddressPopup / 2
+ Layout.fillWidth: true
+ onClicked: newAddressPopup.close()
+ }
+ }
+ }
+}
diff --git a/doc/tutorial/QuickAddressBook/main.cpp b/doc/tutorial/QuickAddressBook/main.cpp
new file mode 100644
index 0000000..a02a02f
--- /dev/null
+++ b/doc/tutorial/QuickAddressBook/main.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+
+int main(int argc, char *argv[])
+{
+#if defined(Q_OS_WIN)
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+#endif
+
+ QGuiApplication app(argc, argv);
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ if (engine.rootObjects().isEmpty())
+ return -1;
+
+ return app.exec();
+}
diff --git a/doc/tutorial/QuickAddressBook/main.qml b/doc/tutorial/QuickAddressBook/main.qml
new file mode 100644
index 0000000..01e6e68
--- /dev/null
+++ b/doc/tutorial/QuickAddressBook/main.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.9
+import QtQuick.Window 2.2
+import QtQuick.Controls 2.5
+import QtQuick.Layouts 1.12
+import "QuickAddressBookTypes"
+
+Window {
+ id: mainWindow
+ visible: true
+ width: 480
+ height: 640
+ color: "darkgray"
+ title: qsTr("Address Book")
+
+ ListModel {
+ id: addressList
+ }
+
+ NewAddressPopup {
+ id: newAddressPopup
+ onAddressAdded: addressList.append({name: newName, addr: newAddr})
+ }
+
+ ColumnLayout {
+ id: mainWindowLayout
+ anchors.left: parent.left; anchors.right: parent.right
+ spacing: 0
+ Button {
+ id: addButton
+ anchors.left: parent.left
+ anchors.right: parent.right
+ text: "Add..."
+ font.pointSize: 24
+ onClicked: newAddressPopup.open()
+ }
+ Repeater {
+ id: addressListViewer
+ model: addressList
+ anchors.left: parent.left
+ anchors.right: parent.right
+ AddressBookItem {
+ id: addressBookItem
+ onRemoved: addressList.remove(index)
+ }
+ }
+ }
+}
diff --git a/doc/tutorial/QuickAddressBook/qml.qrc b/doc/tutorial/QuickAddressBook/qml.qrc
new file mode 100644
index 0000000..f5a34f3
--- /dev/null
+++ b/doc/tutorial/QuickAddressBook/qml.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>qmldir</file>
+ <file>QuickAddressBookTypes/AddressBookItem.qml</file>
+ <file>QuickAddressBookTypes/NewAddressPopup.qml</file>
+ </qresource>
+</RCC>
diff --git a/doc/tutorial/QuickAddressBook/qmldir b/doc/tutorial/QuickAddressBook/qmldir
new file mode 100644
index 0000000..23d4e49
--- /dev/null
+++ b/doc/tutorial/QuickAddressBook/qmldir
@@ -0,0 +1,2 @@
+AddressBookItem 1.0 AddressBookItem.qml
+NewAddressPopup 1.0 NewAddressPopup.qml
diff --git a/references.props b/references.props
index 0f4a231..b38e5f9 100644
--- a/references.props
+++ b/references.props
@@ -2,124 +2,73 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
- // References versions
+ // Package References names/version
// -->
<!-- // Common -->
<PropertyGroup>
- <Version_Microsoft_Bcl_AsyncInterfaces
- >5.0.0</Version_Microsoft_Bcl_AsyncInterfaces>
- <Version_Stub_System_Data_SQLite_Core_NetFramework
- >1.0.115</Version_Stub_System_Data_SQLite_Core_NetFramework>
- <Version_System_Collections_Immutable
- >5.0.0</Version_System_Collections_Immutable>
- <Version_System_ComponentModel_Composition
- >5.0.0</Version_System_ComponentModel_Composition>
- <Version_Newtonsoft_Json
- >13.0.1</Version_Newtonsoft_Json>
- <Version_MSTest_TestAdapter
- >2.2.8</Version_MSTest_TestAdapter>
- <Version_MSTest_TestFramework
- >2.2.8</Version_MSTest_TestFramework>
+ <Name_Microsoft_Build>Microsoft.Build</Name_Microsoft_Build>
+ <Name_Microsoft_Build_Tasks_Core>Microsoft.Build.Tasks.Core</Name_Microsoft_Build_Tasks_Core>
+ <Name_Microsoft_VSSDK_BuildTools>Microsoft.VSSDK.BuildTools</Name_Microsoft_VSSDK_BuildTools>
+ <Name_Microsoft_VisualStudio_SDK>Microsoft.VisualStudio.SDK</Name_Microsoft_VisualStudio_SDK>
+ <Name_Microsoft_Bcl_AsyncInterfaces>Microsoft.Bcl.AsyncInterfaces</Name_Microsoft_Bcl_AsyncInterfaces>
+ <Name_Microsoft_VisualStudio_Validation>Microsoft.VisualStudio.Validation</Name_Microsoft_VisualStudio_Validation>
+ <Name_Microsoft_VisualStudio_RpcContracts>Microsoft.VisualStudio.RpcContracts</Name_Microsoft_VisualStudio_RpcContracts>
+ <Name_Microsoft_VisualStudio_ProjectSystem>Microsoft.VisualStudio.ProjectSystem</Name_Microsoft_VisualStudio_ProjectSystem>
+ <Name_Microsoft_VisualStudio_VCProjectEngine>Microsoft.VisualStudio.VCProjectEngine</Name_Microsoft_VisualStudio_VCProjectEngine>
+ <Name_Microsoft_VisualStudio_Shell_15>Microsoft.VisualStudio.Shell.15.0</Name_Microsoft_VisualStudio_Shell_15>
+ <Name_Microsoft_VisualStudio_Shell_Framework>Microsoft.VisualStudio.Shell.Framework</Name_Microsoft_VisualStudio_Shell_Framework>
+ <Name_Microsoft_VisualStudio_TemplateWizardInterface>Microsoft.VisualStudio.TemplateWizardInterface</Name_Microsoft_VisualStudio_TemplateWizardInterface>
+
+ <Name_MSTest_TestAdapter>MSTest.TestAdapter</Name_MSTest_TestAdapter>
+ <Version_MSTest_TestAdapter>2.2.8</Version_MSTest_TestAdapter>
+
+ <Name_MSTest_TestFramework>MSTest.TestFramework</Name_MSTest_TestFramework>
+ <Version_MSTest_TestFramework>2.2.8</Version_MSTest_TestFramework>
+
+ <Name_Newtonsoft_Json>Newtonsoft.Json</Name_Newtonsoft_Json>
+ <Version_Newtonsoft_Json>13.0.1</Version_Newtonsoft_Json>
+
+ <Name_Stub_System_Data_SQLite_Core_NetFramework>Stub.System.Data.SQLite.Core.NetFramework</Name_Stub_System_Data_SQLite_Core_NetFramework>
+ <Version_Stub_System_Data_SQLite_Core_NetFramework>1.0.115.5</Version_Stub_System_Data_SQLite_Core_NetFramework>
</PropertyGroup>
- <PropertyGroup>
- <Name_DummyPackage
- >Stub.System.Data.SQLite.Core.NetFramework</Name_DummyPackage>
- <Version_DummyPackage
- >$(Version_Stub_System_Data_SQLite_Core_NetFramework)</Version_DummyPackage>
- </PropertyGroup>
+
<!-- // Visual Studio 2022 -->
<PropertyGroup Condition="'$(VisualStudioVersion)'=='17.0'">
- <Version_Microsoft_Build
- >16.11.0</Version_Microsoft_Build>
- <Version_Microsoft_Build_Framework
- >16.11.0</Version_Microsoft_Build_Framework>
- <Version_Microsoft_Build_Tasks_Core
- >16.11.0</Version_Microsoft_Build_Tasks_Core>
- <Version_Microsoft_VisualStudio_SDK
- >17.0.0-previews-4-31709-430</Version_Microsoft_VisualStudio_SDK>
- <Version_Microsoft_VSSDK_BuildTools
- >17.0.5232</Version_Microsoft_VSSDK_BuildTools>
- <Version_Microsoft_VisualStudio_ProjectSystem
- >17.0.667-pre</Version_Microsoft_VisualStudio_ProjectSystem>
- <Version_Microsoft_VisualStudio_Validation
- >17.0.34</Version_Microsoft_VisualStudio_Validation>
- <Version_Microsoft_VisualStudio_Shell_Framework
- >17.0.0-previews-5-31722-452</Version_Microsoft_VisualStudio_Shell_Framework>
- <Name_Microsoft_VisualStudio_VCProjectEngine
- >Microsoft.VisualStudio.VCProjectEngine</Name_Microsoft_VisualStudio_VCProjectEngine>
- <Version_Microsoft_VisualStudio_VCProjectEngine
- >17.0.0-previews-4-31709-430</Version_Microsoft_VisualStudio_VCProjectEngine>
- <Name_Microsoft_VisualStudio_TemplateWizardInterface
- >Microsoft.VisualStudio.TemplateWizardInterface</Name_Microsoft_VisualStudio_TemplateWizardInterface>
- <Version_Microsoft_VisualStudio_TemplateWizardInterface
- >17.0.0-previews-1-31410-258</Version_Microsoft_VisualStudio_TemplateWizardInterface>
- <Name_Microsoft_VisualStudio_Threading
- >$(Name_DummyPackage)</Name_Microsoft_VisualStudio_Threading>
- <Version_Microsoft_VisualStudio_Threading
- >$(Version_DummyPackage)</Version_Microsoft_VisualStudio_Threading>
- <Version_System_Collections_Immutable
- >5.0.0</Version_System_Collections_Immutable>
+ <Version_Microsoft_Build>17.0.0</Version_Microsoft_Build>
+ <Version_Microsoft_Build_Tasks_Core>17.0.0</Version_Microsoft_Build_Tasks_Core>
+ <Version_Microsoft_VSSDK_BuildTools>17.0.5234</Version_Microsoft_VSSDK_BuildTools>
+ <Version_Microsoft_Bcl_AsyncInterfaces>6.0.0</Version_Microsoft_Bcl_AsyncInterfaces>
+ <Version_Microsoft_VisualStudio_SDK>17.0.32112.339</Version_Microsoft_VisualStudio_SDK>
+ <Version_Microsoft_VisualStudio_ProjectSystem>17.0.1313-pre</Version_Microsoft_VisualStudio_ProjectSystem>
+ <Version_Microsoft_VisualStudio_TemplateWizardInterface>17.0.31902.203</Version_Microsoft_VisualStudio_TemplateWizardInterface>
+ <Version_Microsoft_VisualStudio_Shell_15>17.0.32112.339</Version_Microsoft_VisualStudio_Shell_15>
</PropertyGroup>
+
<!-- // Visual Studio 2019 -->
<PropertyGroup Condition="'$(VisualStudioVersion)'=='16.0'">
- <Version_Microsoft_Build
- >16.8.0</Version_Microsoft_Build>
- <Version_Microsoft_Build_Framework
- >16.8.0</Version_Microsoft_Build_Framework>
- <Version_Microsoft_Build_Tasks_Core
- >16.8.0</Version_Microsoft_Build_Tasks_Core>
- <Version_Microsoft_VisualStudio_SDK
- >16.0.206</Version_Microsoft_VisualStudio_SDK>
- <Version_Microsoft_VSSDK_BuildTools
- >16.4.1060</Version_Microsoft_VSSDK_BuildTools>
- <Version_Microsoft_VisualStudio_ProjectSystem
- >16.2.133-pre</Version_Microsoft_VisualStudio_ProjectSystem>
- <Version_Microsoft_VisualStudio_Validation
- >16.8.33</Version_Microsoft_VisualStudio_Validation>
- <Version_Microsoft_VisualStudio_Shell_Framework
- >16.4.29519.181</Version_Microsoft_VisualStudio_Shell_Framework>
- <Name_Microsoft_VisualStudio_VCProjectEngine
- >Microsoft.VisualStudio.VCProjectEngine</Name_Microsoft_VisualStudio_VCProjectEngine>
- <Version_Microsoft_VisualStudio_VCProjectEngine
- >16.7.30328.74</Version_Microsoft_VisualStudio_VCProjectEngine>
- <Name_Microsoft_VisualStudio_TemplateWizardInterface
- >$(Name_DummyPackage)</Name_Microsoft_VisualStudio_TemplateWizardInterface>
- <Version_Microsoft_VisualStudio_TemplateWizardInterface
- >$(Version_DummyPackage)</Version_Microsoft_VisualStudio_TemplateWizardInterface>
- <Name_Microsoft_VisualStudio_Threading
- >$(Name_DummyPackage)</Name_Microsoft_VisualStudio_Threading>
- <Version_Microsoft_VisualStudio_Threading
- >$(Version_DummyPackage)</Version_Microsoft_VisualStudio_Threading>
- <Version_System_Collections_Immutable
- >1.5.0</Version_System_Collections_Immutable>
+ <Version_Microsoft_Build>16.11.0</Version_Microsoft_Build>
+ <Version_Microsoft_Build_Tasks_Core>16.11.0</Version_Microsoft_Build_Tasks_Core>
+ <Version_Microsoft_VSSDK_BuildTools>16.11.35</Version_Microsoft_VSSDK_BuildTools>
+ <Version_Microsoft_Bcl_AsyncInterfaces>5.0.0</Version_Microsoft_Bcl_AsyncInterfaces>
+ <Version_Microsoft_VisualStudio_SDK>16.10.31321.278</Version_Microsoft_VisualStudio_SDK>
+ <Version_Microsoft_VisualStudio_Validation>16.10.35</Version_Microsoft_VisualStudio_Validation>
+ <Version_Microsoft_VisualStudio_RpcContracts>17.0.51</Version_Microsoft_VisualStudio_RpcContracts>
+ <Version_Microsoft_VisualStudio_ProjectSystem>16.2.133-pre</Version_Microsoft_VisualStudio_ProjectSystem>
+ <Version_Microsoft_VisualStudio_VCProjectEngine>16.10.31320.204</Version_Microsoft_VisualStudio_VCProjectEngine>
+ <Version_Microsoft_VisualStudio_TemplateWizardInterface>16.10.31320.204</Version_Microsoft_VisualStudio_TemplateWizardInterface>
+ <Version_Microsoft_VisualStudio_Shell_15>16.10.31321.278</Version_Microsoft_VisualStudio_Shell_15>
</PropertyGroup>
+
<!-- // Visual Studio 2017 -->
<PropertyGroup Condition="'$(VisualStudioVersion)'=='15.0'">
- <Version_Microsoft_Build
- >15.9.20</Version_Microsoft_Build>
- <Version_Microsoft_Build_Framework
- >15.9.20</Version_Microsoft_Build_Framework>
- <Version_Microsoft_Build_Tasks_Core
- >15.9.20</Version_Microsoft_Build_Tasks_Core>
- <Version_Microsoft_VisualStudio_SDK
- >15.0.1</Version_Microsoft_VisualStudio_SDK>
- <Version_Microsoft_VSSDK_BuildTools
- >15.9.3039</Version_Microsoft_VSSDK_BuildTools>
- <Version_Microsoft_VisualStudio_ProjectSystem
- >15.8.243</Version_Microsoft_VisualStudio_ProjectSystem>
- <Version_Microsoft_VisualStudio_Validation
- >15.5.31</Version_Microsoft_VisualStudio_Validation>
- <Version_Microsoft_VisualStudio_Shell_Framework
- >15.9.28307</Version_Microsoft_VisualStudio_Shell_Framework>
- <Name_Microsoft_VisualStudio_TemplateWizardInterface
- >$(Name_DummyPackage)</Name_Microsoft_VisualStudio_TemplateWizardInterface>
- <Version_Microsoft_VisualStudio_TemplateWizardInterface
- >$(Version_DummyPackage)</Version_Microsoft_VisualStudio_TemplateWizardInterface>
- <Name_Microsoft_VisualStudio_Threading
- >Microsoft.VisualStudio.Threading</Name_Microsoft_VisualStudio_Threading>
- <Version_Microsoft_VisualStudio_Threading
- >15.8.209</Version_Microsoft_VisualStudio_Threading>
- <Version_System_Collections_Immutable
- >1.5.0</Version_System_Collections_Immutable>
+ <Version_Microsoft_Build>15.9.20</Version_Microsoft_Build>
+ <Version_Microsoft_VisualStudio_SDK>15.0.1</Version_Microsoft_VisualStudio_SDK>
+ <Version_Microsoft_Build_Tasks_Core>15.9.20</Version_Microsoft_Build_Tasks_Core>
+ <Version_Microsoft_VSSDK_BuildTools>15.9.3039</Version_Microsoft_VSSDK_BuildTools>
+ <Version_Microsoft_Bcl_AsyncInterfaces>5.0.0</Version_Microsoft_Bcl_AsyncInterfaces>
+ <Version_Microsoft_VisualStudio_ProjectSystem>15.8.243</Version_Microsoft_VisualStudio_ProjectSystem>
+ <Version_Microsoft_VisualStudio_Shell_Framework>15.9.28307</Version_Microsoft_VisualStudio_Shell_Framework>
+ <Version_Microsoft_VisualStudio_Shell_15>15.9.28307</Version_Microsoft_VisualStudio_Shell_15>
</PropertyGroup>
+
</Project>
diff --git a/version.targets b/version.targets
index d6516b3..43fc5f6 100644
--- a/version.targets
+++ b/version.targets
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(QtVSToolsVersion)' == ''">
- <QtVSToolsVersion>2.8.1</QtVSToolsVersion>
+ <QtVSToolsVersion>2.9.0</QtVSToolsVersion>
</PropertyGroup>
</Project>
diff --git a/vsconfig/2017.vsconfig b/vsconfig/2017.vsconfig
new file mode 100644
index 0000000..6142b6e
--- /dev/null
+++ b/vsconfig/2017.vsconfig
@@ -0,0 +1,48 @@
+{
+ "version": "1.0",
+ "components": [
+ "Microsoft.VisualStudio.Component.CoreEditor",
+ "Microsoft.VisualStudio.Workload.CoreEditor",
+ "Microsoft.VisualStudio.Component.Roslyn.Compiler",
+ "Microsoft.Component.MSBuild",
+ "Microsoft.VisualStudio.Component.Static.Analysis.Tools",
+ "Microsoft.VisualStudio.Component.Roslyn.LanguageServices",
+ "Microsoft.VisualStudio.Component.PortableLibrary",
+ "Microsoft.Net.Component.4.6.1.SDK",
+ "Microsoft.Net.Component.4.6.1.TargetingPack",
+ "Microsoft.Net.ComponentGroup.DevelopmentPrerequisites",
+ "Microsoft.Component.ClickOnce",
+ "Microsoft.VisualStudio.Component.SQL.CLR",
+ "Microsoft.VisualStudio.Component.VisualStudioData",
+ "Microsoft.VisualStudio.Component.TextTemplating",
+ "Microsoft.VisualStudio.Component.ManagedDesktop.Core",
+ "Microsoft.VisualStudio.Component.ManagedDesktop.Prerequisites",
+ "Microsoft.Net.Component.4.TargetingPack",
+ "Microsoft.Net.Component.4.5.TargetingPack",
+ "Microsoft.Net.Component.4.5.1.TargetingPack",
+ "Microsoft.Net.Component.4.5.2.TargetingPack",
+ "Microsoft.Net.Component.4.6.TargetingPack",
+ "Microsoft.Net.ComponentGroup.TargetingPacks.Common",
+ "Microsoft.VisualStudio.Component.NuGet",
+ "Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions",
+ "Microsoft.VisualStudio.Workload.ManagedDesktop",
+ "Microsoft.VisualStudio.Component.VC.CoreIde",
+ "Microsoft.VisualStudio.Component.VC.Redist.14.Latest",
+ "Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core",
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
+ "Microsoft.VisualStudio.Component.Graphics.Win81",
+ "Microsoft.VisualStudio.Component.Graphics.Tools",
+ "Microsoft.VisualStudio.Component.VC.DiagnosticTools",
+ "Microsoft.VisualStudio.Component.Windows10SDK.17763",
+ "Microsoft.VisualStudio.Component.VC.CMake.Project",
+ "Microsoft.VisualStudio.Component.VC.ATL",
+ "Microsoft.VisualStudio.Workload.NativeDesktop",
+ "Microsoft.VisualStudio.Component.Windows10SDK",
+ "Microsoft.VisualStudio.Component.VSSDK",
+ "Microsoft.VisualStudio.ComponentGroup.VisualStudioExtension.Prerequisites",
+ "Microsoft.VisualStudio.Workload.VisualStudioExtension",
+ "Component.MDD.Linux",
+ "Component.Linux.CMake",
+ "Microsoft.VisualStudio.Workload.NativeCrossPlat"
+ ]
+}
\ No newline at end of file
diff --git a/vsconfig/2019.vsconfig b/vsconfig/2019.vsconfig
new file mode 100644
index 0000000..2bdc9aa
--- /dev/null
+++ b/vsconfig/2019.vsconfig
@@ -0,0 +1,44 @@
+{
+ "version": "1.0",
+ "components": [
+ "Microsoft.VisualStudio.Component.CoreEditor",
+ "Microsoft.VisualStudio.Workload.CoreEditor",
+ "Microsoft.NetCore.Component.Runtime.5.0",
+ "Microsoft.NetCore.Component.Runtime.3.1",
+ "Microsoft.NetCore.Component.SDK",
+ "Microsoft.VisualStudio.Component.NuGet",
+ "Microsoft.VisualStudio.Component.Roslyn.Compiler",
+ "Microsoft.VisualStudio.Component.Roslyn.LanguageServices",
+ "Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions",
+ "Microsoft.Net.Component.4.8.SDK",
+ "Microsoft.Net.Component.4.7.2.TargetingPack",
+ "Microsoft.Net.ComponentGroup.DevelopmentPrerequisites",
+ "Microsoft.VisualStudio.Component.TypeScript.4.3",
+ "Microsoft.VisualStudio.Component.JavaScript.TypeScript",
+ "Microsoft.Component.MSBuild",
+ "Microsoft.VisualStudio.Component.TextTemplating",
+ "Microsoft.Net.Component.4.6.TargetingPack",
+ "Microsoft.VisualStudio.Component.DiagnosticTools",
+ "Microsoft.VisualStudio.Component.Debugger.JustInTime",
+ "Component.Microsoft.VisualStudio.LiveShare",
+ "Microsoft.VisualStudio.Component.IntelliCode",
+ "Microsoft.VisualStudio.Component.VC.CoreIde",
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
+ "Microsoft.VisualStudio.Component.Graphics.Tools",
+ "Microsoft.VisualStudio.Component.VC.DiagnosticTools",
+ "Microsoft.VisualStudio.Component.Windows10SDK.19041",
+ "Microsoft.VisualStudio.Component.VC.Redist.14.Latest",
+ "Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core",
+ "Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions.CMake",
+ "Microsoft.VisualStudio.Component.VC.CMake.Project",
+ "Microsoft.VisualStudio.Component.VC.ATL",
+ "Microsoft.VisualStudio.Component.VC.ASAN",
+ "Microsoft.VisualStudio.Workload.NativeDesktop",
+ "Microsoft.VisualStudio.Component.VSSDK",
+ "Microsoft.VisualStudio.ComponentGroup.VisualStudioExtension.Prerequisites",
+ "Microsoft.VisualStudio.Workload.VisualStudioExtension",
+ "Component.MDD.Linux",
+ "Component.Linux.CMake",
+ "Microsoft.VisualStudio.Workload.NativeCrossPlat"
+ ]
+}
\ No newline at end of file
diff --git a/vsconfig/2022.vsconfig b/vsconfig/2022.vsconfig
new file mode 100644
index 0000000..ed6e494
--- /dev/null
+++ b/vsconfig/2022.vsconfig
@@ -0,0 +1,42 @@
+{
+ "version": "1.0",
+ "components": [
+ "Microsoft.VisualStudio.Component.CoreEditor",
+ "Microsoft.VisualStudio.Workload.CoreEditor",
+ "Microsoft.Net.Component.4.8.SDK",
+ "Microsoft.Net.Component.4.7.2.TargetingPack",
+ "Microsoft.Net.ComponentGroup.DevelopmentPrerequisites",
+ "Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions",
+ "Microsoft.VisualStudio.Component.Roslyn.Compiler",
+ "Microsoft.Component.MSBuild",
+ "Microsoft.VisualStudio.Component.Roslyn.LanguageServices",
+ "Microsoft.VisualStudio.Component.TextTemplating",
+ "Microsoft.VisualStudio.Component.NuGet",
+ "Microsoft.NetCore.Component.Runtime.6.0",
+ "Microsoft.NetCore.Component.SDK",
+ "Microsoft.VisualStudio.Component.DiagnosticTools",
+ "Microsoft.VisualStudio.Component.Debugger.JustInTime",
+ "Microsoft.VisualStudio.Component.IntelliCode",
+ "Microsoft.VisualStudio.Component.VC.CoreIde",
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
+ "Microsoft.VisualStudio.Component.Graphics.Tools",
+ "Microsoft.VisualStudio.Component.VC.DiagnosticTools",
+ "Microsoft.VisualStudio.Component.Windows10SDK.19041",
+ "Microsoft.VisualStudio.Component.VC.Redist.14.Latest",
+ "Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core",
+ "Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions.CMake",
+ "Microsoft.VisualStudio.Component.VC.CMake.Project",
+ "Microsoft.VisualStudio.Component.VC.ATL",
+ "Microsoft.VisualStudio.Component.VC.TestAdapterForBoostTest",
+ "Microsoft.VisualStudio.Component.VC.TestAdapterForGoogleTest",
+ "Microsoft.VisualStudio.Component.VC.ASAN",
+ "Microsoft.VisualStudio.Workload.NativeDesktop",
+ "Microsoft.Net.Component.4.6.TargetingPack",
+ "Microsoft.VisualStudio.Component.VSSDK",
+ "Microsoft.VisualStudio.ComponentGroup.VisualStudioExtension.Prerequisites",
+ "Microsoft.VisualStudio.Workload.VisualStudioExtension",
+ "Component.MDD.Linux",
+ "Component.Linux.CMake",
+ "Microsoft.VisualStudio.Workload.NativeCrossPlat"
+ ]
+}
\ No newline at end of file
diff --git a/vstools.bat b/vstools.bat
index ad05fd5..656576f 100644
--- a/vstools.bat
+++ b/vstools.bat
@@ -12,7 +12,9 @@
SET VSWHERE=%VSWHERE_EXE%
SET VSWHERE=%VSWHERE:(=^(%
SET VSWHERE=%VSWHERE:)=^)%
-SET QUERY=-latest -prerelease
+SET QUERY_LATEST=-latest -prerelease
+SET QUERY_ALL=-prerelease
+SET QUERY=%QUERY_LATEST%
SET VSWHERE_MAJOR=2
SET VSWHERE_MINOR=7
SET VSWHERE_PATCH=1
@@ -37,6 +39,7 @@
SET DO_INSTALL=%FALSE%
SET TRANSFORM_INCREMENTAL=true
SET START_VS=%FALSE%
+SET LIST_VERSIONS=%FALSE%
SET PLATFORM_VS2017="Any CPU"
SET PLATFORM_VS2019="Any CPU"
@@ -101,6 +104,10 @@
SET VS_LATEST=%VS2017%
SET VS_VERSIONS_DEFAULT=%FALSE%
SET FLAG_VS2017=
+ ) ELSE IF "%1"=="-list" (
+ SET LIST_VERSIONS=%TRUE%
+ ) ELSE IF "%1"=="-all" (
+ SET QUERY=%QUERY_ALL%
) ELSE IF "%1"=="-help" (
GOTO :usage
) ELSE (
@@ -203,15 +210,28 @@
IF %VERBOSE% ECHO ## catalog_productLineVersion: %%e
IF %VERBOSE% ECHO ## %VSWHERE% -path "%%p" -property displayName
- FOR /F %ALL% %%n IN (`"%VSWHERE% -path "%%p" -property displayName"`) DO (
- IF %VERBOSE% ECHO ## displayName: %%n
+ FOR /F %ALL% %%u IN (`"%VSWHERE% -path "%%p" -property displayName"`) DO (
+ IF %VERBOSE% ECHO ## displayName: %%u
+
+ IF %VERBOSE% ECHO ## %VSWHERE% -path "%%p" -property isPrerelease
+ FOR /F %ALL% %%b IN (`"%VSWHERE% -path "%%p" -property isPrerelease"`) DO (
+ IF %VERBOSE% ECHO ## isPrerelease: %%b
+
+ FOR /F %ALL% %%n IN (`"(ECHO %%b | FINDSTR /C:1 > NUL) && (ECHO %%u PREVIEW) || ECHO %%u"`) DO (
+ IF %VERBOSE% ECHO ## friendlyName: %%n
IF %VERBOSE% ECHO ## %VSWHERE% -path "%%p" -property installationVersion
FOR /F %ALL% %%i IN (`"%VSWHERE% -path "%%p" -property installationVersion"`) DO (
IF %VERBOSE% ECHO ## installationVersion: %%i
FOR /F %ALL% %%f IN (`CMD /C "ECHO %%PLATFORM_VS%%e%%"`) DO (
- IF %VERBOSE% ECHO ## platform: %%f
+ IF %VERBOSE% ECHO ## platform: %%f
+
+ IF %LIST_VERSIONS% (
+ IF %VERBOSE% ECHO ## listVersion
+ ECHO %%n ^(%%i^)
+ ECHO ^[%%p^]
+ ) ELSE (
IF "%%e"=="2022" (
IF %VERBOSE% ECHO ## CALL "%%p\VC\Auxiliary\Build\vcvars64.bat"
@@ -368,9 +388,9 @@
EXIT /B 0
)
- ECHO.
)
- ))))
+ ECHO.
+ )))))))
ENDLOCAL
)
@@ -397,6 +417,8 @@
ECHO -init .......... Initialize vstools solution for the specified version of VS
ECHO If multiple versions are specified, the last one is selected
ECHO -startvs ....... Open vstools solution in selected VS version
+ECHO -list .......... Print list of Visual Studio installations
+ECHO -help .......... Print tool usage instructions
ECHO.
ECHO If no operation is specified, -build is assumed by default.
ECHO.
@@ -409,6 +431,9 @@
ECHO -install .................... Install extension to selected VS version(s)
ECHO Only valid with -build or -rebuild
ECHO -startvs .................... Open vstools solution in selected VS version
+ECHO If multiple versions are specified, the last one is selected
+ECHO -all ........................ Include all VS installations
+ECHO By default, the latest installation is selected
ECHO -verbose .................... Print more detailed log information
ECHO -bl ......................... Generate MSBuild binary log
ECHO Only valid with -build or -rebuild
diff --git a/vstools.sln b/vstools.sln
index 8bbcdd4..b69cbcd 100644
--- a/vstools.sln
+++ b/vstools.sln
@@ -35,13 +35,19 @@
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QtTemplate.Item.QMLDir", "Templates\qmldir\QtTemplate.Item.QMLDir.csproj", "{7AF6C34B-65D2-4010-92F6-420E59DDE9BF}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QtTemplate.Item.QtClass", "Templates\qtclass\QtTemplate.Item.QtClass.csproj", "{4981AAE8-9AC7-4758-87EA-FB2397D6C404}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QtTemplate.Project.Quick", "Templates\quick\QtTemplate.Project.Quick.csproj", "{4833E4C7-FFFF-4DA5-A7A5-36C6C3840F16}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QtTemplate.Item.Resource", "Templates\resource\QtTemplate.Item.Resource.csproj", "{BDA1CD69-624B-4D9D-9B88-ACBEB14AC471}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QtTemplate.Project.Server", "Templates\server\QtTemplate.Project.Server.csproj", "{8AE9D385-A379-4F5F-A703-3DF643DA6742}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QtTemplate.Item.Translation", "Templates\translation\QtTemplate.Item.Translation.csproj", "{202F4A6D-77CD-4992-AA53-01B585463287}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QtTemplate.Item.Widget", "Templates\widget\QtTemplate.Item.Widget.csproj", "{40ADFD6A-64EA-4C77-9D4B-3A91D6AB76B4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QtTemplate.Item.WidgetsClass", "Templates\widgetsclass\QtTemplate.Item.WidgetsClass.csproj", "{020422DA-33AB-4495-A439-7DAC2690795C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Item", "Item", "{A7918293-56E9-465A-AE1C-0724576ADD66}"
EndProject
@@ -92,6 +98,10 @@
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_QtMsBuild.Tasks", "Tests\Test_QtMsBuild.Tasks\Test_QtMsBuild.Tasks.csproj", "{E809DDE3-AE76-4F7A-8DC5-775AC4900138}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_QtVsTools.Core", "Tests\Test_QtVsTools.Core\Test_QtVsTools.Core.csproj", "{4B8FC08C-4901-45D4-BC00-C0C461292FF2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_QtVsTools.Package", "tests\Test_QtVsTools.Package\Test_QtVsTools.Package.csproj", "{AFD33401-2F15-4E72-AB35-42C3EE12E897}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -376,6 +386,24 @@
{7AF6C34B-65D2-4010-92F6-420E59DDE9BF}.Tests|x64.Build.0 = Release|Any CPU
{7AF6C34B-65D2-4010-92F6-420E59DDE9BF}.Tests|x86.ActiveCfg = Release|Any CPU
{7AF6C34B-65D2-4010-92F6-420E59DDE9BF}.Tests|x86.Build.0 = Release|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Debug|x64.Build.0 = Debug|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Debug|x86.ActiveCfg = Debug|x86
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Debug|x86.Build.0 = Debug|x86
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Release|x64.ActiveCfg = Release|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Release|x64.Build.0 = Release|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Release|x86.ActiveCfg = Release|x86
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Release|x86.Build.0 = Release|x86
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Tests|Any CPU.ActiveCfg = Debug|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Tests|Any CPU.Build.0 = Debug|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Tests|x64.ActiveCfg = Debug|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Tests|x64.Build.0 = Debug|Any CPU
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Tests|x86.ActiveCfg = Debug|x86
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404}.Tests|x86.Build.0 = Debug|x86
{4833E4C7-FFFF-4DA5-A7A5-36C6C3840F16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4833E4C7-FFFF-4DA5-A7A5-36C6C3840F16}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4833E4C7-FFFF-4DA5-A7A5-36C6C3840F16}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -448,6 +476,24 @@
{40ADFD6A-64EA-4C77-9D4B-3A91D6AB76B4}.Tests|x64.Build.0 = Release|Any CPU
{40ADFD6A-64EA-4C77-9D4B-3A91D6AB76B4}.Tests|x86.ActiveCfg = Release|Any CPU
{40ADFD6A-64EA-4C77-9D4B-3A91D6AB76B4}.Tests|x86.Build.0 = Release|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Debug|x64.Build.0 = Debug|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Debug|x86.ActiveCfg = Debug|x86
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Debug|x86.Build.0 = Debug|x86
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Release|x64.ActiveCfg = Release|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Release|x64.Build.0 = Release|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Release|x86.ActiveCfg = Release|x86
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Release|x86.Build.0 = Release|x86
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Tests|Any CPU.ActiveCfg = Debug|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Tests|Any CPU.Build.0 = Debug|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Tests|x64.ActiveCfg = Debug|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Tests|x64.Build.0 = Debug|Any CPU
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Tests|x86.ActiveCfg = Debug|x86
+ {020422DA-33AB-4495-A439-7DAC2690795C}.Tests|x86.Build.0 = Debug|x86
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|Any CPU.ActiveCfg = Debug|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|Any CPU.Build.0 = Debug|Win32
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|x64
@@ -571,6 +617,54 @@
{E809DDE3-AE76-4F7A-8DC5-775AC4900138}.Tests|x64.Build.0 = Release|Any CPU
{E809DDE3-AE76-4F7A-8DC5-775AC4900138}.Tests|x86.ActiveCfg = Release|Any CPU
{E809DDE3-AE76-4F7A-8DC5-775AC4900138}.Tests|x86.Build.0 = Release|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Debug|x64.Build.0 = Debug|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Debug|x86.ActiveCfg = Debug|x86
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Debug|x86.Build.0 = Debug|x86
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Release|Any CPU.Build.0 = Release|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Release|x64.ActiveCfg = Release|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Release|x64.Build.0 = Release|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Release|x86.ActiveCfg = Release|x86
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Release|x86.Build.0 = Release|x86
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Tests|Any CPU.ActiveCfg = Debug|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Tests|Any CPU.Build.0 = Debug|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Tests|x64.ActiveCfg = Debug|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Tests|x64.Build.0 = Debug|Any CPU
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Tests|x86.ActiveCfg = Debug|x86
+ {202F4A6D-77CD-4992-AA53-01B585463287}.Tests|x86.Build.0 = Debug|x86
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Debug|x64.Build.0 = Debug|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Debug|x86.Build.0 = Debug|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Release|x64.ActiveCfg = Release|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Release|x86.ActiveCfg = Release|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Tests|Any CPU.ActiveCfg = Debug|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Tests|Any CPU.Build.0 = Debug|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Tests|x64.ActiveCfg = Debug|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Tests|x64.Build.0 = Debug|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Tests|x86.ActiveCfg = Debug|Any CPU
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2}.Tests|x86.Build.0 = Debug|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Debug|x64.Build.0 = Debug|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Debug|x86.Build.0 = Debug|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Release|x64.ActiveCfg = Release|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Release|x86.ActiveCfg = Release|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Tests|Any CPU.ActiveCfg = Debug|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Tests|Any CPU.Build.0 = Debug|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Tests|x64.ActiveCfg = Debug|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Tests|x64.Build.0 = Debug|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Tests|x86.ActiveCfg = Debug|Any CPU
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897}.Tests|x86.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -586,10 +680,12 @@
{20055427-1352-44FB-8442-BF7F15F9C59E} = {A7918293-56E9-465A-AE1C-0724576ADD66}
{DC1AE91B-45CE-4C5B-8F77-CDB58566038F} = {A7918293-56E9-465A-AE1C-0724576ADD66}
{7AF6C34B-65D2-4010-92F6-420E59DDE9BF} = {A7918293-56E9-465A-AE1C-0724576ADD66}
+ {4981AAE8-9AC7-4758-87EA-FB2397D6C404} = {A7918293-56E9-465A-AE1C-0724576ADD66}
{4833E4C7-FFFF-4DA5-A7A5-36C6C3840F16} = {DD307619-BF80-4E5D-AE54-196057187702}
{BDA1CD69-624B-4D9D-9B88-ACBEB14AC471} = {A7918293-56E9-465A-AE1C-0724576ADD66}
{8AE9D385-A379-4F5F-A703-3DF643DA6742} = {DD307619-BF80-4E5D-AE54-196057187702}
{40ADFD6A-64EA-4C77-9D4B-3A91D6AB76B4} = {A7918293-56E9-465A-AE1C-0724576ADD66}
+ {020422DA-33AB-4495-A439-7DAC2690795C} = {A7918293-56E9-465A-AE1C-0724576ADD66}
{A7918293-56E9-465A-AE1C-0724576ADD66} = {9D9290B2-9E87-46EA-84EA-02836F699BB8}
{DD307619-BF80-4E5D-AE54-196057187702} = {9D9290B2-9E87-46EA-84EA-02836F699BB8}
{B12702AD-ABFB-343A-A199-8E24837244A3} = {9B109DDA-0521-46AD-B087-B7CBCB33FEE5}
@@ -602,6 +698,9 @@
{A5320606-37B8-4F15-97E2-16314109CAF9} = {D6FB29A4-8921-46F5-B170-B15538AB4D69}
{12857847-9877-466C-B056-DD286A219093} = {D6FB29A4-8921-46F5-B170-B15538AB4D69}
{E809DDE3-AE76-4F7A-8DC5-775AC4900138} = {D6FB29A4-8921-46F5-B170-B15538AB4D69}
+ {202F4A6D-77CD-4992-AA53-01B585463287} = {A7918293-56E9-465A-AE1C-0724576ADD66}
+ {4B8FC08C-4901-45D4-BC00-C0C461292FF2} = {D6FB29A4-8921-46F5-B170-B15538AB4D69}
+ {AFD33401-2F15-4E72-AB35-42C3EE12E897} = {D6FB29A4-8921-46F5-B170-B15538AB4D69}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {17FF4AFE-273C-47CD-8D84-F0D023B10BE5}
diff --git "a/\320\241\320\261\320\276\321\200\320\272\320\260.md" "b/\320\241\320\261\320\276\321\200\320\272\320\260.md"
index dd25307..b3d918f 100644
--- "a/\320\241\320\261\320\276\321\200\320\272\320\260.md"
+++ "b/\320\241\320\261\320\276\321\200\320\272\320\260.md"
@@ -63,7 +63,7 @@
`Сборка под VS2022:`
Обязательно наличие VS 2022
-Установить переменную среды QTBUILD_STATIC_VS2022 (Пример QTBUILD_STATIC_VS2022=C:\build\qt_5.12.9_msvc2022_x64) для VS 2012 только QT x64
+Установить переменную среды QTBUILD_STATIC_VS2022 (Пример QTBUILD_STATIC_VS2022=C:\build\qt_5.12.9_msvc2022_x64) для VS 2022 только QT x64
В директории через cmd вызвать
vstools -vs2022 -init -config Release или Debug -rebuild -deploy Path -startvs
--
Gitblit v1.9.1