/**************************************************************************** ** ** 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 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.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(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; } } }