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

---
 QtVsTools.Core/QtProject.cs |  944 ++++++++++++----------------------------------------------
 1 files changed, 197 insertions(+), 747 deletions(-)

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)

--
Gitblit v1.9.1