diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qtprojectlib/QtProject.cs | 248 | ||||
-rw-r--r-- | src/qtprojectlib/QtVSIPSettings.cs | 20 | ||||
-rw-r--r-- | src/qtvstools/DteEventsHandler.cs | 25 | ||||
-rw-r--r-- | src/qtvstools/ProjectQtSettings.cs | 77 |
4 files changed, 358 insertions, 12 deletions
diff --git a/src/qtprojectlib/QtProject.cs b/src/qtprojectlib/QtProject.cs index 7c88da3c..7dd1a248 100644 --- a/src/qtprojectlib/QtProject.cs +++ b/src/qtprojectlib/QtProject.cs @@ -85,6 +85,7 @@ namespace QtProjectLib dte = envPro.DTE; vcPro = envPro.Object as VCProject; qtMsBuild = new QtMsBuildContainer(new VCPropertyStorageProvider()); + InitializeQmlJsDebugger(vcPro); } public VCProject VCProject @@ -3405,6 +3406,253 @@ namespace QtProjectLib } HelperFunctions.SetDebuggingEnvironment(envPro); + InitializeQmlJsDebugger(envPro.Object as VCProject); + } + + public class CppConfig + { + public VCConfiguration Config; + public IVCRulePropertyStorage Cpp; + + public string GetUserPropertyValue(string pszPropName) + { + var vcProj = Config.project as VCProject; + 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); + return string.Empty; + } + } + + public void SetUserPropertyValue(string pszPropName, string pszPropValue) + { + var vcProj = Config.project as VCProject; + 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); + } + } + + public void RemoveUserProperty(string pszPropName) + { + var vcProj = Config.project as VCProject; + 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); + } + } + } + + public static IEnumerable<CppConfig> GetCppConfigs(VCProject vcPro) + { + return ((IVCCollection)vcPro.Configurations).Cast<VCConfiguration>() + .Select(x => new CppConfig + { + Config = x, + Cpp = x.Rules.Item("CL") as IVCRulePropertyStorage, + }) + .Where(x => x.Cpp != null); + } + + public static IEnumerable<CppConfig> GetCppDebugConfigs(VCProject vcPro) + { + return GetCppConfigs(vcPro).Where(x => x.Cpp + .GetEvaluatedPropertyValue("PreprocessorDefinitions").Split(new char[] { ';' }) + .Contains("QT_NO_DEBUG") == false); + } + + public static bool IsQtQmlDebugDefined(VCProject vcPro) + { + return (GetCppDebugConfigs(vcPro).Where(x => x.Cpp + .GetEvaluatedPropertyValue("PreprocessorDefinitions").Split(new char[] { ';' }) + .Contains("QT_QML_DEBUG") == false) + .Any() == false); + } + + public static void DefineQtQmlDebug(VCProject vcPro) + { + var configs = GetCppDebugConfigs(vcPro).Where(x => x.Cpp + .GetEvaluatedPropertyValue("PreprocessorDefinitions").Split(new char[] { ';' }) + .Contains("QT_QML_DEBUG") == false) + .Select(x => new + { + x.Cpp, + Macros = x.Cpp.GetUnevaluatedPropertyValue("PreprocessorDefinitions") + }); + + foreach (var config in configs) { + config.Cpp.SetPropertyValue("PreprocessorDefinitions", + string.Format("QT_QML_DEBUG;{0}", config.Macros)); + } + } + + public static void UndefineQtQmlDebug(VCProject vcPro) + { + var configs = GetCppDebugConfigs(vcPro).Where(x => x.Cpp + .GetEvaluatedPropertyValue("PreprocessorDefinitions").Split(new char[] { ';' }) + .Contains("QT_QML_DEBUG") == true) + .Select(x => new + { + x.Cpp, + Macros = x.Cpp.GetUnevaluatedPropertyValue("PreprocessorDefinitions") + .Split(new char[] { ';' }).ToList() + }); + + foreach (var config in configs) { + config.Macros.Remove("QT_QML_DEBUG"); + config.Cpp.SetPropertyValue("PreprocessorDefinitions", + string.Join(";", config.Macros)); + } + } + + public static bool IsQmlJsDebuggerInitialized(VCProject vcPro) + { + foreach (var config in GetCppDebugConfigs(vcPro)) { + var qmlDebugPort = config.GetUserPropertyValue("QmlDebugPort"); + if (string.IsNullOrEmpty(qmlDebugPort)) + return false; + + if (qmlDebugPort != "false" && !IsQtQmlDebugDefined(vcPro)) + return false; + } + return true; + } + + public static void InitializeQmlJsDebugger(VCProject vcPro) + { + if (vcPro == null || !IsQtMsBuildEnabled(vcPro)) + return; + + if (!IsQmlJsDebuggerInitialized(vcPro)) { + DefineQtQmlDebug(vcPro); + DefineQmlJsDebugger(vcPro); + } + } + + public static bool IsQmlJsDebuggerDefined(VCProject vcPro) + { + foreach (var config in GetCppDebugConfigs(vcPro)) { + var qmlDebug = config.GetUserPropertyValue("QmlDebug"); + if (string.IsNullOrEmpty(qmlDebug)) + return false; + var debugArgs = config.GetUserPropertyValue("LocalDebuggerCommandArguments"); + if (string.IsNullOrEmpty(debugArgs)) + return false; + if (!debugArgs.Contains(qmlDebug)) + return false; + } + return true; + } + + public static readonly ushort DefaultQmlDebugPort // 0x7451 = 29777 + = BitConverter.ToUInt16(Encoding.ASCII.GetBytes("Qt"), 0); + + public static void DefineQmlJsDebugger(VCProject vcPro) + { + var configs = GetCppDebugConfigs(vcPro) + .Select(x => new + { + Self = x, + QmlDebug = x.GetUserPropertyValue("QmlDebug"), + Args = x.GetUserPropertyValue("LocalDebuggerCommandArguments") + }) + .Where(x => string.IsNullOrEmpty(x.QmlDebug) || !x.Args.Contains(x.QmlDebug)); + + foreach (var config in configs) { + + config.Self.RemoveUserProperty("LocalDebuggerCommandArguments"); + config.Self.RemoveUserProperty("QmlDebug"); + config.Self.RemoveUserProperty("QmlDebugPort"); + + config.Self.SetUserPropertyValue("QmlDebugPort", + DefaultQmlDebugPort.ToString()); + + config.Self.SetUserPropertyValue("QmlDebug", + "-qmljsdebugger=port:$(QmlDebugPort),block"); + + config.Self.SetUserPropertyValue("LocalDebuggerCommandArguments", + string.Join(" ", new[] { config.Args, "$(QmlDebug)" }).Trim()); + } + } + + public static void UndefineQmlJsDebugger(VCProject vcPro) + { + var configs = GetCppDebugConfigs(vcPro) + .Select(x => new + { + Self = x, + QmlDebug = x.GetUserPropertyValue("QmlDebug"), + Args = x.GetUserPropertyValue("LocalDebuggerCommandArguments") + }) + .Where(x => !string.IsNullOrEmpty(x.QmlDebug) && x.Args.Contains(x.QmlDebug)); + + foreach (var config in configs) { + + config.Self.SetUserPropertyValue("QmlDebug", "##QMLDEBUG##"); + var args = config.Self.GetUserPropertyValue("LocalDebuggerCommandArguments"); + + var newArgs = args.Replace("##QMLDEBUG##", "").Trim(); + if (string.IsNullOrEmpty(newArgs)) + config.Self.RemoveUserProperty("LocalDebuggerCommandArguments"); + else + config.Self.SetUserPropertyValue("LocalDebuggerCommandArguments", newArgs); + + config.Self.RemoveUserProperty("QmlDebug"); + config.Self.SetUserPropertyValue("QmlDebugPort", "false"); + } + } + + public bool QmlDebug + { + get + { + return IsQtQmlDebugDefined(vcPro) && IsQmlJsDebuggerDefined(vcPro); + } + set + { + bool enabled = (IsQtQmlDebugDefined(vcPro) && IsQmlJsDebuggerDefined(vcPro)); + if (value == enabled) + return; + + if (value) { + DefineQtQmlDebug(vcPro); + DefineQmlJsDebugger(vcPro); + } else { + UndefineQtQmlDebug(vcPro); + UndefineQmlJsDebugger(vcPro); + } + } + } + + public ushort QmlDebugPort + { + get + { + if (!QmlDebug) + return DefaultQmlDebugPort; + var portString = GetCppDebugConfigs(vcPro).First() + .GetUserPropertyValue("QmlDebugPort"); + ushort port; + if (!ushort.TryParse(portString, out port)) + return DefaultQmlDebugPort; + return port; + } + set + { + if (QmlDebug) { + foreach (var config in GetCppDebugConfigs(vcPro)) + config.SetUserPropertyValue("QmlDebugPort", value.ToString()); + } + } } } diff --git a/src/qtprojectlib/QtVSIPSettings.cs b/src/qtprojectlib/QtVSIPSettings.cs index 93fb20b8..230eeeb8 100644 --- a/src/qtprojectlib/QtVSIPSettings.cs +++ b/src/qtprojectlib/QtVSIPSettings.cs @@ -506,5 +506,25 @@ namespace QtProjectLib 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; + } + + public static ushort GetQmlDebugPort(EnvDTE.Project project) + { + return QtProject.Create(project).QmlDebugPort; + } + + public static void SaveQmlDebugPort(EnvDTE.Project project, ushort port) + { + QtProject.Create(project).QmlDebugPort = port; + } } } diff --git a/src/qtvstools/DteEventsHandler.cs b/src/qtvstools/DteEventsHandler.cs index 23b8671f..af446568 100644 --- a/src/qtvstools/DteEventsHandler.cs +++ b/src/qtvstools/DteEventsHandler.cs @@ -94,7 +94,7 @@ namespace QtVsTools dispId_VCCLCompilerTool_PrecompiledHeaderThrough = GetPropertyDispId(typeof(VCCLCompilerTool), "PrecompiledHeaderThrough"); dispId_VCCLCompilerTool_PreprocessorDefinitions = GetPropertyDispId(typeof(VCCLCompilerTool), "PreprocessorDefinitions"); dispId_VCCLCompilerTool_AdditionalIncludeDirectories = GetPropertyDispId(typeof(VCCLCompilerTool), "AdditionalIncludeDirectories"); - RegisterVCProjectEngineEvents(); + InitializeVCProjects(); DefaultEditorsClient.Initialize(this); DefaultEditorsClient.Instance.Listen(); @@ -498,7 +498,7 @@ namespace QtVsTools void SolutionEvents_ProjectAdded(Project project) { if (HelperFunctions.IsQMakeProject(project)) { - RegisterVCProjectEngineEvents(project); + InitializeVCProject(project); var vcpro = project.Object as VCProject; VCFilter filter = null; foreach (VCFilter f in vcpro.Filters as IVCCollection) { @@ -541,7 +541,7 @@ namespace QtVsTools { foreach (var p in HelperFunctions.ProjectsInSolution(Vsix.Instance.Dte)) { if (HelperFunctions.IsQtProject(p)) - RegisterVCProjectEngineEvents(p); + InitializeVCProject(p); } } @@ -550,26 +550,24 @@ namespace QtVsTools QtProject.ClearInstances(); } - /// <summary> - /// Tries to get a VCProjectEngine from the loaded projects and registers the handlers for VCProjectEngineEvents. - /// </summary> - void RegisterVCProjectEngineEvents() + void InitializeVCProjects() { foreach (var project in HelperFunctions.ProjectsInSolution(dte)) { if (project != null && HelperFunctions.IsQtProject(project)) - RegisterVCProjectEngineEvents(project); + InitializeVCProject(project); } } - /// <summary> - /// Retrieves the VCProjectEngine from the given project and registers the handlers for VCProjectEngineEvents. - /// </summary> - void RegisterVCProjectEngineEvents(Project p) + void InitializeVCProject(Project p) { if (vcProjectEngineEvents != null) return; var vcPrj = p.Object as VCProject; + if (vcPrj == null) + return; + + // Retrieves the VCProjectEngine from the given project and registers the handlers for VCProjectEngineEvents. var prjEngine = vcPrj.VCProjectEngine as VCProjectEngine; if (prjEngine != null) { vcProjectEngineEvents = prjEngine.Events as VCProjectEngineEvents; @@ -581,6 +579,9 @@ namespace QtVsTools } } } + + // Initialize QML debugger settings + QtProject.InitializeQmlJsDebugger(vcPrj); } private void OnVCProjectEngineItemPropertyChange(object item, object tool, int dispid) diff --git a/src/qtvstools/ProjectQtSettings.cs b/src/qtvstools/ProjectQtSettings.cs index 2fdff725..78cd8806 100644 --- a/src/qtvstools/ProjectQtSettings.cs +++ b/src/qtvstools/ProjectQtSettings.cs @@ -29,6 +29,7 @@ using QtProjectLib; using System; using System.ComponentModel; +using System.Globalization; using System.Text.RegularExpressions; namespace QtVsTools @@ -48,6 +49,8 @@ namespace QtVsTools newLUpdateOptions = oldLUpdateOptions = QtVSIPSettings.GetLUpdateOptions(project); newLReleaseOptions = oldLReleaseOptions = QtVSIPSettings.GetLReleaseOptions(project); newQtVersion = oldQtVersion = versionManager.GetProjectQtVersion(project); + QmlDebug = oldQmlDebug = QtVSIPSettings.GetQmlDebug(project); + QmlDebugPort = oldQmlDebugPort = QtVSIPSettings.GetQmlDebugPort(project); } private QtVersionManager versionManager; @@ -61,6 +64,8 @@ namespace QtVsTools private bool oldLUpdateOnBuild; private string oldLUpdateOptions; private string oldLReleaseOptions; + private bool oldQmlDebug; + private ushort oldQmlDebugPort; private string newMocDir; private string newMocOptions; @@ -106,6 +111,12 @@ namespace QtVsTools if (oldLReleaseOptions != newLReleaseOptions) QtVSIPSettings.SaveLReleaseOptions(project, newLReleaseOptions); + if (oldQmlDebug != QmlDebug) + QtVSIPSettings.SaveQmlDebug(project, QmlDebug); + + if (oldQmlDebugPort != QmlDebugPort) + QtVSIPSettings.SaveQmlDebugPort(project, QmlDebugPort); + if (oldQtVersion != newQtVersion) { if (qtPro.PromptChangeQtVersion(oldQtVersion, newQtVersion)) { var newProjectCreated = false; @@ -229,6 +240,72 @@ namespace QtVsTools } } + [DisplayName("QML Debug")] + [TypeConverter(typeof(QmlDebugConverter))] + public bool QmlDebug { get; set; } + + 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"; + } + } + + [DisplayName("QML Debug Port")] + [TypeConverter(typeof(QmlDebugPortConverter))] + public ushort QmlDebugPort { get; set; } + + internal class QmlDebugPortConverter : UInt16Converter + { + public override object ConvertTo( + ITypeDescriptorContext context, + CultureInfo culture, + object value, + Type destinationType) + { + var obj = context.Instance as ProjectQtSettings; + if (obj == null) + return QtProject.DefaultQmlDebugPort.ToString(); + + if (obj.QmlDebug) + return value.ToString(); + + return "Disabled"; + } + + public override object ConvertFrom( + ITypeDescriptorContext context, + CultureInfo culture, + object value) + { + ushort port; + if (!ushort.TryParse((string)value, out port) || port == 0) + return QtProject.DefaultQmlDebugPort; + + var obj = context.Instance as ProjectQtSettings; + if (obj == null) + return QtProject.DefaultQmlDebugPort; + + if (obj.QmlDebug) + return port; + + return QtProject.DefaultQmlDebugPort; + } + } + [TypeConverter(typeof(VersionConverter))] public string Version { |