| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | 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;
|
| | |
|
| | |
| | | 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;
|
| | |
| | | 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;
|
| | |
| | |
|
| | | public void Disconnect()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (buildEvents != null) {
|
| | | buildEvents.OnBuildBegin -= buildEvents_OnBuildBegin;
|
| | | buildEvents.OnBuildProjConfigBegin -= OnBuildProjConfigBegin;
|
| | |
| | | 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;
|
| | |
|
| | |
| | | break;
|
| | | }
|
| | | }
|
| | | if (project == null || !HelperFunctions.IsQtProject(project))
|
| | | if (project == null || !HelperFunctions.IsVsToolsProject(project))
|
| | | return;
|
| | |
|
| | | if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_Settings)
|
| | |
| | |
|
| | | 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);
|
| | |
| | |
|
| | | 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;
|
| | |
| | | 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;
|
| | |
| | |
|
| | | void ProjectItemsEvents_ItemRenamed(ProjectItem ProjectItem, string OldName)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (OldName == null)
|
| | | return;
|
| | | var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
|
| | |
| | |
|
| | | 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;
|
| | |
| | |
|
| | | 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);
|
| | | }
|
| | |
| | |
|
| | | 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;
|
| | |
|
| | |
| | | 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.");
|
| | | }
|
| | |
| | |
|
| | | 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.
|
| | |
| | | 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)
|
| | |
| | | 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)
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | 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;
|
| | |
| | | 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;
|
| | | }
|
| | | }
|